PERFORCE change 163665 for review
Alexander Motin
mav at FreeBSD.org
Sat Jun 6 21:21:21 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163665
Change 163665 by mav at mav_mavbook on 2009/06/06 21:20:54
Add minimal SATA PHY events handling.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#13 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#13 (text+ko) ====
@@ -638,6 +638,30 @@
DRIVER_MODULE(ahcich, ahci, ahcich_driver, ahci_devclass, 0, 0);
static void
+ahci_phy_check_events(device_t dev)
+{
+ struct ahci_channel *ch = device_get_softc(dev);
+ u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
+
+ /* clear error bits/interrupt */
+ ATA_IDX_OUTL(ch, ATA_SERROR, error);
+
+ /* if we have a connection event deal with it */
+ if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
+ if (bootverbose) {
+ u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
+ if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+ ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+ ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) {
+ device_printf(dev, "CONNECT requested\n");
+ } else
+ device_printf(dev, "DISCONNECT requested\n");
+ }
+// taskqueue_enqueue(taskqueue_thread, &ch->conntask);
+ }
+}
+
+static void
ahci_ch_intr(void *data)
{
device_t dev = (device_t)data;
@@ -657,8 +681,8 @@
ATA_OUTL(ch->r_mem, AHCI_P_IS, istatus);
/* Process PHY events */
-// if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
-// ata_sata_phy_check_events(dev);
+ if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
+ ahci_phy_check_events(dev);
#define AHCI_STATBITS \
(AHCI_P_IX_IF|AHCI_P_IX_HBD|AHCI_P_IX_HBF|AHCI_P_IX_TFE)
@@ -1581,75 +1605,72 @@
static int
ata_sata_connect(struct ahci_channel *ch)
{
- u_int32_t status;
- int timeout;
+ u_int32_t status;
+ int timeout;
- /* wait up to 1 second for "connect well" */
- for (timeout = 0; timeout < 100 ; timeout++) {
- status = ATA_IDX_INL(ch, ATA_SSTATUS);
- if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
- (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
- break;
- DELAY(10000);
- }
- if (timeout >= 100) {
+ /* wait up to 1 second for "connect well" */
+ for (timeout = 0; timeout < 100 ; timeout++) {
+ status = ATA_IDX_INL(ch, ATA_SSTATUS);
+ if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+ ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+ ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
+ break;
+ DELAY(10000);
+ }
+ if (timeout >= 100) {
+ if (bootverbose) {
+ device_printf(ch->dev, "SATA connect timeout status=%08x\n",
+ status);
+ }
+ return (0);
+ }
if (bootverbose) {
- device_printf(ch->dev, "SATA connect timeout status=%08x\n",
- status);
+ device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
+ timeout * 10, status);
}
- return 0;
- }
- if (bootverbose) {
- device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
- timeout * 10, status);
- }
- /* clear SATA error register */
- ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff);
-
- return 1;
+ /* clear SATA error register */
+ ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff);
+ return (1);
}
static int
ata_sata_phy_reset(device_t dev, int quick)
{
- struct ahci_channel *ch = device_get_softc(dev);
- int loop, retry;
- uint32_t val;
+ struct ahci_channel *ch = device_get_softc(dev);
+ int loop, retry;
+ uint32_t val;
- if (quick) {
- val = ATA_IDX_INL(ch, ATA_SCONTROL);
- return (0);
- if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
- return ata_sata_connect(ch);
- }
+ if (quick) {
+ val = ATA_IDX_INL(ch, ATA_SCONTROL);
+ if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
+ return (ata_sata_connect(ch));
+ }
- if (bootverbose) {
- device_printf(dev, "hardware reset ...\n");
- }
- for (retry = 0; retry < 10; retry++) {
- for (loop = 0; loop < 10; loop++) {
- ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
- DELAY(100);
- val = ATA_IDX_INL(ch, ATA_SCONTROL);
- if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
- break;
+ if (bootverbose)
+ device_printf(dev, "hardware reset ...\n");
+ for (retry = 0; retry < 10; retry++) {
+ for (loop = 0; loop < 10; loop++) {
+ ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
+ DELAY(100);
+ val = ATA_IDX_INL(ch, ATA_SCONTROL);
+ if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
+ break;
+ }
+ DELAY(5000);
+ for (loop = 0; loop < 10; loop++) {
+ ATA_IDX_OUTL(ch, ATA_SCONTROL,
+ ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
+ ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
+ DELAY(100);
+ val = ATA_IDX_INL(ch, ATA_SCONTROL);
+ if ((val & ATA_SC_DET_MASK) == 0)
+ return (ata_sata_connect(ch));
+ }
}
- DELAY(5000);
- for (loop = 0; loop < 10; loop++) {
- ATA_IDX_OUTL(ch, ATA_SCONTROL,
- ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
- ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
- DELAY(100);
- val = ATA_IDX_INL(ch, ATA_SCONTROL);
- if ((val & ATA_SC_DET_MASK) == 0)
- return ata_sata_connect(ch);
- }
- }
- return 0;
+ return (0);
}
-
static void
ahciaction(struct cam_sim *sim, union ccb *ccb)
{
More information about the p4-projects
mailing list