|
Lines 103-108
static MALLOC_DEFINE(M_AHCI, "AHCI driver", "AHCI driver data buffers");
Link Here
|
| 103 |
#define RECOVERY_REQUEST_SENSE 2 |
103 |
#define RECOVERY_REQUEST_SENSE 2 |
| 104 |
#define recovery_slot spriv_field1 |
104 |
#define recovery_slot spriv_field1 |
| 105 |
|
105 |
|
|
|
106 |
SYSCTL_NODE(_hw, OID_AUTO, ahci, CTLFLAG_RW, 0, "AHCI debugging"); |
| 107 |
|
| 108 |
int ahci_verbose = 0; |
| 109 |
SYSCTL_INT(_hw_ahci, OID_AUTO, verbose, CTLFLAG_RWTUN, |
| 110 |
&ahci_verbose, 0, "AHCI debug verbosity"); |
| 111 |
|
| 106 |
static uint32_t |
112 |
static uint32_t |
| 107 |
ahci_ch_detval(struct ahci_channel *ch, uint32_t val) |
113 |
ahci_ch_detval(struct ahci_channel *ch, uint32_t val) |
| 108 |
{ |
114 |
{ |
|
Lines 125-131
ahci_ctlr_setup(device_t dev)
Link Here
|
| 125 |
AHCI_CCCC_EN); |
131 |
AHCI_CCCC_EN); |
| 126 |
ctlr->cccv = (ATA_INL(ctlr->r_mem, AHCI_CCCC) & |
132 |
ctlr->cccv = (ATA_INL(ctlr->r_mem, AHCI_CCCC) & |
| 127 |
AHCI_CCCC_INT_MASK) >> AHCI_CCCC_INT_SHIFT; |
133 |
AHCI_CCCC_INT_MASK) >> AHCI_CCCC_INT_SHIFT; |
| 128 |
if (bootverbose) { |
134 |
if (bootverbose || ahci_verbose) { |
| 129 |
device_printf(dev, |
135 |
device_printf(dev, |
| 130 |
"CCC with %dms/4cmd enabled on vector %d\n", |
136 |
"CCC with %dms/4cmd enabled on vector %d\n", |
| 131 |
ctlr->ccc, ctlr->cccv); |
137 |
ctlr->ccc, ctlr->cccv); |
|
Lines 320-326
ahci_attach(device_t dev)
Link Here
|
| 320 |
device_printf(dev, "quirks=0x%b\n", ctlr->quirks, |
326 |
device_printf(dev, "quirks=0x%b\n", ctlr->quirks, |
| 321 |
AHCI_Q_BIT_STRING); |
327 |
AHCI_Q_BIT_STRING); |
| 322 |
} |
328 |
} |
| 323 |
if (bootverbose) { |
329 |
if (bootverbose || ahci_verbose) { |
| 324 |
device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps", |
330 |
device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps", |
| 325 |
(ctlr->caps & AHCI_CAP_64BIT) ? " 64bit":"", |
331 |
(ctlr->caps & AHCI_CAP_64BIT) ? " 64bit":"", |
| 326 |
(ctlr->caps & AHCI_CAP_SNCQ) ? " NCQ":"", |
332 |
(ctlr->caps & AHCI_CAP_SNCQ) ? " NCQ":"", |
|
Lines 345-351
ahci_attach(device_t dev)
Link Here
|
| 345 |
(ctlr->caps & AHCI_CAP_SXS) ? " eSATA":"", |
351 |
(ctlr->caps & AHCI_CAP_SXS) ? " eSATA":"", |
| 346 |
(ctlr->caps & AHCI_CAP_NPMASK) + 1); |
352 |
(ctlr->caps & AHCI_CAP_NPMASK) + 1); |
| 347 |
} |
353 |
} |
| 348 |
if (bootverbose && version >= 0x00010200) { |
354 |
if ((bootverbose || ahci_verbose) && version >= 0x00010200) { |
| 349 |
device_printf(dev, "Caps2:%s%s%s%s%s%s\n", |
355 |
device_printf(dev, "Caps2:%s%s%s%s%s%s\n", |
| 350 |
(ctlr->caps2 & AHCI_CAP2_DESO) ? " DESO":"", |
356 |
(ctlr->caps2 & AHCI_CAP2_DESO) ? " DESO":"", |
| 351 |
(ctlr->caps2 & AHCI_CAP2_SADM) ? " SADM":"", |
357 |
(ctlr->caps2 & AHCI_CAP2_SADM) ? " SADM":"", |
|
Lines 860-866
ahci_ch_attach(device_t dev)
Link Here
|
| 860 |
ch->chcaps |= AHCI_P_CMD_FBSCP; |
866 |
ch->chcaps |= AHCI_P_CMD_FBSCP; |
| 861 |
if (ch->caps2 & AHCI_CAP2_SDS) |
867 |
if (ch->caps2 & AHCI_CAP2_SDS) |
| 862 |
ch->chscaps = ATA_INL(ch->r_mem, AHCI_P_DEVSLP); |
868 |
ch->chscaps = ATA_INL(ch->r_mem, AHCI_P_DEVSLP); |
| 863 |
if (bootverbose) { |
869 |
if (bootverbose || ahci_verbose) { |
| 864 |
device_printf(dev, "Caps:%s%s%s%s%s%s\n", |
870 |
device_printf(dev, "Caps:%s%s%s%s%s%s\n", |
| 865 |
(ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"", |
871 |
(ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"", |
| 866 |
(ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"", |
872 |
(ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"", |
|
Lines 983-988
ahci_ch_init(device_t dev)
Link Here
|
| 983 |
struct ahci_channel *ch = device_get_softc(dev); |
989 |
struct ahci_channel *ch = device_get_softc(dev); |
| 984 |
uint64_t work; |
990 |
uint64_t work; |
| 985 |
|
991 |
|
|
|
992 |
if (ahci_verbose > 2) |
| 993 |
device_printf(dev, "ahci_ch_init: Start\n"); |
| 994 |
|
| 986 |
/* Disable port interrupts */ |
995 |
/* Disable port interrupts */ |
| 987 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
996 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
| 988 |
/* Setup work areas */ |
997 |
/* Setup work areas */ |
|
Lines 999-1004
ahci_ch_init(device_t dev)
Link Here
|
| 999 |
((ch->pm_level > 2) ? AHCI_P_CMD_ASP : 0 ))); |
1008 |
((ch->pm_level > 2) ? AHCI_P_CMD_ASP : 0 ))); |
| 1000 |
ahci_start_fr(ch); |
1009 |
ahci_start_fr(ch); |
| 1001 |
ahci_start(ch, 1); |
1010 |
ahci_start(ch, 1); |
|
|
1011 |
|
| 1012 |
if (ahci_verbose > 2) |
| 1013 |
device_printf(dev, "ahci_ch_init: Done\n"); |
| 1002 |
return (0); |
1014 |
return (0); |
| 1003 |
} |
1015 |
} |
| 1004 |
|
1016 |
|
|
Lines 1007-1012
ahci_ch_deinit(device_t dev)
Link Here
|
| 1007 |
{ |
1019 |
{ |
| 1008 |
struct ahci_channel *ch = device_get_softc(dev); |
1020 |
struct ahci_channel *ch = device_get_softc(dev); |
| 1009 |
|
1021 |
|
|
|
1022 |
if (ahci_verbose > 2) |
| 1023 |
device_printf(dev, "ahci_ch_deinit: Start\n"); |
| 1024 |
|
| 1010 |
/* Disable port interrupts. */ |
1025 |
/* Disable port interrupts. */ |
| 1011 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
1026 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
| 1012 |
/* Reset command register. */ |
1027 |
/* Reset command register. */ |
|
Lines 1020-1025
ahci_ch_deinit(device_t dev)
Link Here
|
| 1020 |
DELAY(100); |
1035 |
DELAY(100); |
| 1021 |
/* Disable PHY. */ |
1036 |
/* Disable PHY. */ |
| 1022 |
ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE); |
1037 |
ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE); |
|
|
1038 |
|
| 1039 |
if (ahci_verbose > 2) |
| 1040 |
device_printf(dev, "ahci_ch_deinit: Done\n"); |
| 1041 |
|
| 1023 |
return (0); |
1042 |
return (0); |
| 1024 |
} |
1043 |
} |
| 1025 |
|
1044 |
|
|
Lines 1048-1058
ahci_ch_resume(device_t dev)
Link Here
|
| 1048 |
{ |
1067 |
{ |
| 1049 |
struct ahci_channel *ch = device_get_softc(dev); |
1068 |
struct ahci_channel *ch = device_get_softc(dev); |
| 1050 |
|
1069 |
|
|
|
1070 |
if (ahci_verbose > 2) |
| 1071 |
device_printf(dev, "ahci_ch_resume: Start\n"); |
| 1072 |
|
| 1051 |
mtx_lock(&ch->mtx); |
1073 |
mtx_lock(&ch->mtx); |
| 1052 |
ahci_ch_init(dev); |
1074 |
ahci_ch_init(dev); |
| 1053 |
ahci_reset(ch); |
1075 |
ahci_reset(ch); |
| 1054 |
xpt_release_simq(ch->sim, TRUE); |
1076 |
xpt_release_simq(ch->sim, TRUE); |
| 1055 |
mtx_unlock(&ch->mtx); |
1077 |
mtx_unlock(&ch->mtx); |
|
|
1078 |
|
| 1079 |
if (ahci_verbose > 2) |
| 1080 |
device_printf(dev, "ahci_ch_resume: Done\n"); |
| 1056 |
return (0); |
1081 |
return (0); |
| 1057 |
} |
1082 |
} |
| 1058 |
|
1083 |
|
|
Lines 1221-1233
ahci_slotsfree(device_t dev)
Link Here
|
| 1221 |
static int |
1246 |
static int |
| 1222 |
ahci_phy_check_events(struct ahci_channel *ch, u_int32_t serr) |
1247 |
ahci_phy_check_events(struct ahci_channel *ch, u_int32_t serr) |
| 1223 |
{ |
1248 |
{ |
| 1224 |
|
|
|
| 1225 |
if (((ch->pm_level == 0) && (serr & ATA_SE_PHY_CHANGED)) || |
1249 |
if (((ch->pm_level == 0) && (serr & ATA_SE_PHY_CHANGED)) || |
| 1226 |
((ch->pm_level != 0 || ch->listening) && (serr & ATA_SE_EXCHANGED))) { |
1250 |
((ch->pm_level != 0 || ch->listening) && (serr & ATA_SE_EXCHANGED))) { |
| 1227 |
u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS); |
1251 |
u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS); |
| 1228 |
union ccb *ccb; |
1252 |
union ccb *ccb; |
| 1229 |
|
1253 |
|
| 1230 |
if (bootverbose) { |
1254 |
if (bootverbose || ahci_verbose) { |
| 1231 |
if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) |
1255 |
if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) |
| 1232 |
device_printf(ch->dev, "CONNECT requested\n"); |
1256 |
device_printf(ch->dev, "CONNECT requested\n"); |
| 1233 |
else |
1257 |
else |
|
Lines 1262-1268
ahci_cpd_check_events(struct ahci_channel *ch)
Link Here
|
| 1262 |
if ((status & AHCI_P_CMD_CPD) == 0) |
1286 |
if ((status & AHCI_P_CMD_CPD) == 0) |
| 1263 |
return; |
1287 |
return; |
| 1264 |
|
1288 |
|
| 1265 |
if (bootverbose) { |
1289 |
if (bootverbose || ahci_verbose) { |
| 1266 |
dev = ch->dev; |
1290 |
dev = ch->dev; |
| 1267 |
if (status & AHCI_P_CMD_CPS) { |
1291 |
if (status & AHCI_P_CMD_CPS) { |
| 1268 |
device_printf(dev, "COLD CONNECT requested\n"); |
1292 |
device_printf(dev, "COLD CONNECT requested\n"); |
|
Lines 1288-1294
ahci_notify_events(struct ahci_channel *ch, u_int32_t status)
Link Here
|
| 1288 |
|
1312 |
|
| 1289 |
if (ch->caps & AHCI_CAP_SSNTF) |
1313 |
if (ch->caps & AHCI_CAP_SSNTF) |
| 1290 |
ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status); |
1314 |
ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status); |
| 1291 |
if (bootverbose) |
1315 |
if (bootverbose || ahci_verbose) |
| 1292 |
device_printf(ch->dev, "SNTF 0x%04x\n", status); |
1316 |
device_printf(ch->dev, "SNTF 0x%04x\n", status); |
| 1293 |
for (i = 0; i < 16; i++) { |
1317 |
for (i = 0; i < 16; i++) { |
| 1294 |
if ((status & (1 << i)) == 0) |
1318 |
if ((status & (1 << i)) == 0) |
|
Lines 1675-1680
ahci_execute_transaction(struct ahci_slot *slot)
Link Here
|
| 1675 |
uint8_t val; |
1699 |
uint8_t val; |
| 1676 |
uint16_t cmd_flags; |
1700 |
uint16_t cmd_flags; |
| 1677 |
|
1701 |
|
|
|
1702 |
if (!mtx_owned(&ch->mtx)) |
| 1703 |
device_printf(ch->dev, "ahci_execute_transaction: channel mutex not owned!\n"); |
| 1704 |
|
| 1678 |
/* Get a piece of the workspace for this request */ |
1705 |
/* Get a piece of the workspace for this request */ |
| 1679 |
ctp = (struct ahci_cmd_tab *)(ch->dma.work + slot->ct_offset); |
1706 |
ctp = (struct ahci_cmd_tab *)(ch->dma.work + slot->ct_offset); |
| 1680 |
/* Setup the FIS for this request */ |
1707 |
/* Setup the FIS for this request */ |
|
Lines 1699-1704
ahci_execute_transaction(struct ahci_slot *slot)
Link Here
|
| 1699 |
if (ccb->ataio.cmd.control & ATA_A_RESET) { |
1726 |
if (ccb->ataio.cmd.control & ATA_A_RESET) { |
| 1700 |
softreset = 1; |
1727 |
softreset = 1; |
| 1701 |
/* Kick controller into sane state */ |
1728 |
/* Kick controller into sane state */ |
|
|
1729 |
if (ahci_verbose > 2) |
| 1730 |
device_printf(ch->dev, "ahci_execute_transaction: Kicking controller into sane state\n"); |
| 1702 |
ahci_stop(ch); |
1731 |
ahci_stop(ch); |
| 1703 |
ahci_clo(ch); |
1732 |
ahci_clo(ch); |
| 1704 |
ahci_start(ch, 0); |
1733 |
ahci_start(ch, 0); |
|
Lines 1944-1949
ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
Link Here
|
| 1944 |
int lastto; |
1973 |
int lastto; |
| 1945 |
uint32_t sig; |
1974 |
uint32_t sig; |
| 1946 |
|
1975 |
|
|
|
1976 |
if (!mtx_owned(&ch->mtx)) |
| 1977 |
device_printf(ch->dev, "ahci_end_transaction: channel mutex not owned!\n"); |
| 1978 |
|
| 1947 |
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, |
1979 |
bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, |
| 1948 |
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
1980 |
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
| 1949 |
clp = (struct ahci_cmd_list *) |
1981 |
clp = (struct ahci_cmd_list *) |
|
Lines 2117-2126
ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
Link Here
|
| 2117 |
if (ch->rslots == 0) { |
2149 |
if (ch->rslots == 0) { |
| 2118 |
/* if there was fatal error - reset port. */ |
2150 |
/* if there was fatal error - reset port. */ |
| 2119 |
if (ch->toslots != 0 || ch->fatalerr) { |
2151 |
if (ch->toslots != 0 || ch->fatalerr) { |
|
|
2152 |
if (ahci_verbose > 2) |
| 2153 |
device_printf(ch->dev, "ahci_end_transaction: Calling ahci_reset\n"); |
| 2120 |
ahci_reset(ch); |
2154 |
ahci_reset(ch); |
| 2121 |
} else { |
2155 |
} else { |
| 2122 |
/* if we have slots in error, we can reinit port. */ |
2156 |
/* if we have slots in error, we can reinit port. */ |
| 2123 |
if (ch->eslots != 0) { |
2157 |
if (ch->eslots != 0) { |
|
|
2158 |
if (ahci_verbose > 2) |
| 2159 |
device_printf(ch->dev, "ahci_end_transaction: Reinit port (eslots=%08x)\n", ch->eslots); |
| 2124 |
ahci_stop(ch); |
2160 |
ahci_stop(ch); |
| 2125 |
ahci_clo(ch); |
2161 |
ahci_clo(ch); |
| 2126 |
ahci_start(ch, 1); |
2162 |
ahci_start(ch, 1); |
|
Lines 2175-2180
ahci_issue_recovery(struct ahci_channel *ch)
Link Here
|
| 2175 |
ch->hold[i] = NULL; |
2211 |
ch->hold[i] = NULL; |
| 2176 |
ch->numhslots--; |
2212 |
ch->numhslots--; |
| 2177 |
} |
2213 |
} |
|
|
2214 |
if (ahci_verbose > 2) |
| 2215 |
device_printf(ch->dev, "ahci_issue_recovery: Calling ahci_reset\n"); |
| 2178 |
ahci_reset(ch); |
2216 |
ahci_reset(ch); |
| 2179 |
return; |
2217 |
return; |
| 2180 |
} |
2218 |
} |
|
Lines 2309-2314
ahci_start(struct ahci_channel *ch, int fbs)
Link Here
|
| 2309 |
{ |
2347 |
{ |
| 2310 |
u_int32_t cmd; |
2348 |
u_int32_t cmd; |
| 2311 |
|
2349 |
|
|
|
2350 |
if (ahci_verbose > 2) |
| 2351 |
device_printf(ch->dev, "AHCI engine(fbs=%d): starting\n", fbs); |
| 2352 |
|
| 2312 |
/* Run the channel start callback, if any. */ |
2353 |
/* Run the channel start callback, if any. */ |
| 2313 |
if (ch->start) |
2354 |
if (ch->start) |
| 2314 |
ch->start(ch); |
2355 |
ch->start(ch); |
|
Lines 2328-2333
ahci_start(struct ahci_channel *ch, int fbs)
Link Here
|
| 2328 |
cmd &= ~AHCI_P_CMD_PMA; |
2369 |
cmd &= ~AHCI_P_CMD_PMA; |
| 2329 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | |
2370 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | |
| 2330 |
(ch->pm_present ? AHCI_P_CMD_PMA : 0)); |
2371 |
(ch->pm_present ? AHCI_P_CMD_PMA : 0)); |
|
|
2372 |
|
| 2373 |
if (ahci_verbose > 2) |
| 2374 |
device_printf(ch->dev, "ahci_start: Done\n"); |
| 2331 |
} |
2375 |
} |
| 2332 |
|
2376 |
|
| 2333 |
static void |
2377 |
static void |
|
Lines 2335-2354
ahci_stop(struct ahci_channel *ch)
Link Here
|
| 2335 |
{ |
2379 |
{ |
| 2336 |
u_int32_t cmd; |
2380 |
u_int32_t cmd; |
| 2337 |
int timeout; |
2381 |
int timeout; |
| 2338 |
|
2382 |
int delay_time = 10; |
|
|
2383 |
int timeout_limit = 100000; /* 50000 */ |
| 2384 |
int ci = -1; |
| 2385 |
int last_ci = 0; |
| 2386 |
int sact = -1; |
| 2387 |
int last_sact = 0; |
| 2388 |
int ccs = -1; |
| 2389 |
int last_ccs = 0; |
| 2390 |
int cr = 1; |
| 2391 |
int last_cr = 0; |
| 2392 |
|
| 2393 |
if (ahci_verbose > 2) |
| 2394 |
device_printf(ch->dev, "AHCI engine: stopping\n"); |
| 2395 |
|
| 2339 |
/* Kill all activity on this channel */ |
2396 |
/* Kill all activity on this channel */ |
| 2340 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
2397 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
|
|
2398 |
if ((cmd & AHCI_P_CMD_ST) == 0) { |
| 2399 |
/* Not started */ |
| 2400 |
if (ahci_verbose > 2) |
| 2401 |
device_printf(ch->dev, "AHCI engine already stopped (ignoring)\n"); |
| 2402 |
return; |
| 2403 |
} |
| 2404 |
|
| 2405 |
last_cr = ((cmd & AHCI_P_CMD_CR) != 0); |
| 2406 |
if (!last_cr) { |
| 2407 |
/* No Commands Running */ |
| 2408 |
if (ahci_verbose > 2) |
| 2409 |
device_printf(ch->dev, "AHCI engine not running (notice only)\n"); |
| 2410 |
} |
| 2411 |
|
| 2341 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_ST); |
2412 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_ST); |
|
|
2413 |
|
| 2342 |
/* Wait for activity stop. */ |
2414 |
/* Wait for activity stop. */ |
| 2343 |
timeout = 0; |
2415 |
timeout = 0; |
| 2344 |
do { |
2416 |
do { |
| 2345 |
DELAY(10); |
2417 |
DELAY(delay_time); |
| 2346 |
if (timeout++ > 50000) { |
2418 |
if (++timeout >= timeout_limit) { |
| 2347 |
device_printf(ch->dev, "stopping AHCI engine failed\n"); |
2419 |
device_printf(ch->dev, |
|
|
2420 |
"stopping AHCI engine: timeout at %d us (cr=%d, ccs=%d, ci=%d, sact=%d)\n", |
| 2421 |
timeout*delay_time, cr, ccs, ci, sact); |
| 2348 |
break; |
2422 |
break; |
| 2349 |
} |
2423 |
} |
| 2350 |
} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CR); |
2424 |
|
|
|
2425 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
| 2426 |
cr = ((cmd & AHCI_P_CMD_CR) != 0); |
| 2427 |
ccs = ((cmd & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT); |
| 2428 |
|
| 2429 |
ci = ATA_INL(ch->r_mem, AHCI_P_CI); |
| 2430 |
sact = ATA_INL(ch->r_mem, AHCI_P_SACT); |
| 2431 |
|
| 2432 |
if (cr != last_cr) { |
| 2433 |
if (ahci_verbose > 2) |
| 2434 |
device_printf(ch->dev, "stopping AHCI engine: cr: %d -> %d at time %d us\n", |
| 2435 |
last_cr, cr, timeout*delay_time); |
| 2436 |
last_cr = cr; |
| 2437 |
} |
| 2438 |
|
| 2439 |
if (ci != last_ci) { |
| 2440 |
if (ahci_verbose > 2) |
| 2441 |
device_printf(ch->dev, "stopping AHCI engine: ci: %d -> %d at time %d us\n", |
| 2442 |
last_ci, ci, timeout*delay_time); |
| 2443 |
last_ci = ci; |
| 2444 |
} |
| 2445 |
|
| 2446 |
if (sact != last_sact) { |
| 2447 |
if (ahci_verbose > 2) |
| 2448 |
device_printf(ch->dev, "stopping AHCI engine: sact: %d -> %d at time %d us\n", |
| 2449 |
last_sact, sact, timeout*delay_time); |
| 2450 |
last_sact = sact; |
| 2451 |
} |
| 2452 |
|
| 2453 |
if (ccs != last_ccs) { |
| 2454 |
if (ahci_verbose > 2) |
| 2455 |
device_printf(ch->dev, "stopping AHCI engine: ccs: %d -> %d at time %d us\n", |
| 2456 |
last_ccs, ccs, timeout*delay_time); |
| 2457 |
last_ccs = ccs; |
| 2458 |
} |
| 2459 |
} while (cr); |
| 2351 |
ch->eslots = 0; |
2460 |
ch->eslots = 0; |
|
|
2461 |
|
| 2462 |
if (ahci_verbose && timeout < timeout_limit) |
| 2463 |
device_printf(ch->dev, "AHCI engine stopped at time %d us\n", timeout*delay_time); |
| 2352 |
} |
2464 |
} |
| 2353 |
|
2465 |
|
| 2354 |
static void |
2466 |
static void |
|
Lines 2357-2362
ahci_clo(struct ahci_channel *ch)
Link Here
|
| 2357 |
u_int32_t cmd; |
2469 |
u_int32_t cmd; |
| 2358 |
int timeout; |
2470 |
int timeout; |
| 2359 |
|
2471 |
|
|
|
2472 |
if (ahci_verbose > 2) |
| 2473 |
device_printf(ch->dev, "ahci_clo: Start\n"); |
| 2474 |
|
| 2360 |
/* Issue Command List Override if supported */ |
2475 |
/* Issue Command List Override if supported */ |
| 2361 |
if (ch->caps & AHCI_CAP_SCLO) { |
2476 |
if (ch->caps & AHCI_CAP_SCLO) { |
| 2362 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
2477 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
|
Lines 2371-2384
ahci_clo(struct ahci_channel *ch)
Link Here
|
| 2371 |
} |
2486 |
} |
| 2372 |
} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CLO); |
2487 |
} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CLO); |
| 2373 |
} |
2488 |
} |
|
|
2489 |
if (ahci_verbose > 2) |
| 2490 |
device_printf(ch->dev, "ahci_clo: Done\n"); |
| 2374 |
} |
2491 |
} |
| 2375 |
|
2492 |
|
|
|
2493 |
|
| 2376 |
static void |
2494 |
static void |
| 2377 |
ahci_stop_fr(struct ahci_channel *ch) |
2495 |
ahci_stop_fr(struct ahci_channel *ch) |
| 2378 |
{ |
2496 |
{ |
| 2379 |
u_int32_t cmd; |
2497 |
u_int32_t cmd; |
| 2380 |
int timeout; |
2498 |
int timeout; |
| 2381 |
|
2499 |
|
|
|
2500 |
if (ahci_verbose > 2) |
| 2501 |
device_printf(ch->dev, "ahci_stop_fr: Start\n"); |
| 2502 |
|
| 2382 |
/* Kill all FIS reception on this channel */ |
2503 |
/* Kill all FIS reception on this channel */ |
| 2383 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
2504 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
| 2384 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_FRE); |
2505 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_FRE); |
|
Lines 2391-2396
ahci_stop_fr(struct ahci_channel *ch)
Link Here
|
| 2391 |
break; |
2512 |
break; |
| 2392 |
} |
2513 |
} |
| 2393 |
} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_FR); |
2514 |
} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_FR); |
|
|
2515 |
if (ahci_verbose > 2) |
| 2516 |
device_printf(ch->dev, "ahci_stop_fr: Done\n"); |
| 2394 |
} |
2517 |
} |
| 2395 |
|
2518 |
|
| 2396 |
static void |
2519 |
static void |
|
Lines 2398-2406
ahci_start_fr(struct ahci_channel *ch)
Link Here
|
| 2398 |
{ |
2521 |
{ |
| 2399 |
u_int32_t cmd; |
2522 |
u_int32_t cmd; |
| 2400 |
|
2523 |
|
|
|
2524 |
if (ahci_verbose > 2) |
| 2525 |
device_printf(ch->dev, "ahci_start_fr: Start\n"); |
| 2526 |
|
| 2401 |
/* Start FIS reception on this channel */ |
2527 |
/* Start FIS reception on this channel */ |
| 2402 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
2528 |
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD); |
| 2403 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_FRE); |
2529 |
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_FRE); |
|
|
2530 |
|
| 2531 |
if (ahci_verbose > 2) |
| 2532 |
device_printf(ch->dev, "ahci_start_fr: Done\n"); |
| 2404 |
} |
2533 |
} |
| 2405 |
|
2534 |
|
| 2406 |
static int |
2535 |
static int |
|
Lines 2423-2429
ahci_wait_ready(struct ahci_channel *ch, int t, int t0)
Link Here
|
| 2423 |
DELAY(1000); |
2552 |
DELAY(1000); |
| 2424 |
timeout++; |
2553 |
timeout++; |
| 2425 |
} |
2554 |
} |
| 2426 |
if (bootverbose) |
2555 |
if (bootverbose || ahci_verbose) |
| 2427 |
device_printf(ch->dev, "AHCI reset: device ready after %dms\n", |
2556 |
device_printf(ch->dev, "AHCI reset: device ready after %dms\n", |
| 2428 |
timeout + t0); |
2557 |
timeout + t0); |
| 2429 |
return (0); |
2558 |
return (0); |
|
Lines 2434-2450
ahci_reset_to(void *arg)
Link Here
|
| 2434 |
{ |
2563 |
{ |
| 2435 |
struct ahci_channel *ch = arg; |
2564 |
struct ahci_channel *ch = arg; |
| 2436 |
|
2565 |
|
|
|
2566 |
if (ahci_verbose > 2) |
| 2567 |
device_printf(ch->dev, "ahci_reset_to: Timeout!\n"); |
| 2568 |
|
| 2437 |
if (ch->resetting == 0) |
2569 |
if (ch->resetting == 0) |
| 2438 |
return; |
2570 |
return; |
| 2439 |
ch->resetting--; |
2571 |
ch->resetting--; |
| 2440 |
if (ahci_wait_ready(ch, ch->resetting == 0 ? -1 : 0, |
2572 |
if (ahci_wait_ready(ch, ch->resetting == 0 ? -1 : 0, |
| 2441 |
(310 - ch->resetting) * 100) == 0) { |
2573 |
(310 - ch->resetting) * 100) == 0) { |
| 2442 |
ch->resetting = 0; |
2574 |
ch->resetting = 0; |
|
|
2575 |
if (ahci_verbose > 2) |
| 2576 |
device_printf(ch->dev, "ahci_reset_to: Starting up channel!\n"); |
| 2443 |
ahci_start(ch, 1); |
2577 |
ahci_start(ch, 1); |
| 2444 |
xpt_release_simq(ch->sim, TRUE); |
2578 |
xpt_release_simq(ch->sim, TRUE); |
| 2445 |
return; |
2579 |
return; |
| 2446 |
} |
2580 |
} |
| 2447 |
if (ch->resetting == 0) { |
2581 |
if (ch->resetting == 0) { |
|
|
2582 |
if (ahci_verbose > 2) |
| 2583 |
device_printf(ch->dev, "ahci_reset_to: Restarting channel!\n"); |
| 2448 |
ahci_clo(ch); |
2584 |
ahci_clo(ch); |
| 2449 |
ahci_start(ch, 1); |
2585 |
ahci_start(ch, 1); |
| 2450 |
xpt_release_simq(ch->sim, TRUE); |
2586 |
xpt_release_simq(ch->sim, TRUE); |
|
Lines 2458-2466
ahci_reset(struct ahci_channel *ch)
Link Here
|
| 2458 |
{ |
2594 |
{ |
| 2459 |
struct ahci_controller *ctlr = device_get_softc(device_get_parent(ch->dev)); |
2595 |
struct ahci_controller *ctlr = device_get_softc(device_get_parent(ch->dev)); |
| 2460 |
int i; |
2596 |
int i; |
| 2461 |
|
2597 |
|
|
|
2598 |
if (ahci_verbose > 2) |
| 2599 |
device_printf(ch->dev, "ahci_reset: Start\n"); |
| 2600 |
|
| 2462 |
xpt_freeze_simq(ch->sim, 1); |
2601 |
xpt_freeze_simq(ch->sim, 1); |
| 2463 |
if (bootverbose) |
2602 |
if (bootverbose || ahci_verbose) |
| 2464 |
device_printf(ch->dev, "AHCI reset...\n"); |
2603 |
device_printf(ch->dev, "AHCI reset...\n"); |
| 2465 |
/* Forget about previous reset. */ |
2604 |
/* Forget about previous reset. */ |
| 2466 |
if (ch->resetting) { |
2605 |
if (ch->resetting) { |
|
Lines 2507-2513
ahci_reset(struct ahci_channel *ch)
Link Here
|
| 2507 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
2646 |
ATA_OUTL(ch->r_mem, AHCI_P_IE, 0); |
| 2508 |
/* Reset and reconnect PHY, */ |
2647 |
/* Reset and reconnect PHY, */ |
| 2509 |
if (!ahci_sata_phy_reset(ch)) { |
2648 |
if (!ahci_sata_phy_reset(ch)) { |
| 2510 |
if (bootverbose) |
2649 |
if (bootverbose || ahci_verbose) |
| 2511 |
device_printf(ch->dev, |
2650 |
device_printf(ch->dev, |
| 2512 |
"AHCI reset: device not found\n"); |
2651 |
"AHCI reset: device not found\n"); |
| 2513 |
ch->devices = 0; |
2652 |
ch->devices = 0; |
|
Lines 2516-2524
ahci_reset(struct ahci_channel *ch)
Link Here
|
| 2516 |
(((ch->pm_level != 0) ? AHCI_P_IX_CPD | AHCI_P_IX_MP : 0) | |
2655 |
(((ch->pm_level != 0) ? AHCI_P_IX_CPD | AHCI_P_IX_MP : 0) | |
| 2517 |
AHCI_P_IX_PRC | AHCI_P_IX_PC)); |
2656 |
AHCI_P_IX_PRC | AHCI_P_IX_PC)); |
| 2518 |
xpt_release_simq(ch->sim, TRUE); |
2657 |
xpt_release_simq(ch->sim, TRUE); |
|
|
2658 |
if (ahci_verbose > 2) |
| 2659 |
device_printf(ch->dev, "ahci_reset: Done (ahci_sata_phy_reset failed)\n"); |
| 2519 |
return; |
2660 |
return; |
| 2520 |
} |
2661 |
} |
| 2521 |
if (bootverbose) |
2662 |
if (bootverbose || ahci_verbose) |
| 2522 |
device_printf(ch->dev, "AHCI reset: device found\n"); |
2663 |
device_printf(ch->dev, "AHCI reset: device found\n"); |
| 2523 |
/* Wait for clearing busy status. */ |
2664 |
/* Wait for clearing busy status. */ |
| 2524 |
if (ahci_wait_ready(ch, dumping ? 31000 : 0, 0)) { |
2665 |
if (ahci_wait_ready(ch, dumping ? 31000 : 0, 0)) { |
|
Lines 2542-2547
ahci_reset(struct ahci_channel *ch)
Link Here
|
| 2542 |
ahci_start(ch, 1); |
2683 |
ahci_start(ch, 1); |
| 2543 |
xpt_release_simq(ch->sim, TRUE); |
2684 |
xpt_release_simq(ch->sim, TRUE); |
| 2544 |
} |
2685 |
} |
|
|
2686 |
if (ahci_verbose > 2) |
| 2687 |
device_printf(ch->dev, "ahci_reset: Done\n"); |
| 2545 |
} |
2688 |
} |
| 2546 |
|
2689 |
|
| 2547 |
static int |
2690 |
static int |
|
Lines 2606-2646
ahci_sata_connect(struct ahci_channel *ch)
Link Here
|
| 2606 |
{ |
2749 |
{ |
| 2607 |
u_int32_t status; |
2750 |
u_int32_t status; |
| 2608 |
int timeout, found = 0; |
2751 |
int timeout, found = 0; |
| 2609 |
|
2752 |
int last_status = 0; |
| 2610 |
/* Wait up to 100ms for "connect well" */ |
2753 |
int delay_time = 10; /* 10 us */ |
| 2611 |
for (timeout = 0; timeout < 1000 ; timeout++) { |
2754 |
int timeout_full_limit = 100000 / delay_time; /* 100ms */ |
|
|
2755 |
int timeout_detect_limit = 10000 / delay_time; /* 10ms */ |
| 2756 |
|
| 2757 |
if (ahci_verbose > 2) |
| 2758 |
device_printf(ch->dev, "ahci_sata_connect: Start\n"); |
| 2759 |
|
| 2760 |
for (timeout = 0; timeout < timeout_full_limit ; timeout++) { |
| 2612 |
status = ATA_INL(ch->r_mem, AHCI_P_SSTS); |
2761 |
status = ATA_INL(ch->r_mem, AHCI_P_SSTS); |
| 2613 |
if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) |
2762 |
|
|
|
2763 |
if (status != last_status) { |
| 2764 |
if (ahci_verbose > 1) |
| 2765 |
device_printf(ch->dev, "SATA changed status 0x%08x -> 0x%08x at time=%dus\n", |
| 2766 |
last_status, status, timeout * delay_time); |
| 2767 |
last_status = status; |
| 2768 |
} |
| 2769 |
if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) { |
| 2614 |
found = 1; |
2770 |
found = 1; |
|
|
2771 |
/* Increase timeout to 500ms after first status change to allow for slow devices |
| 2772 |
(needed on Dell BOSS-S1 with later firmwares) */ |
| 2773 |
if (ch->quirks & AHCI_Q_SLOWDEV) |
| 2774 |
timeout_full_limit = 500000 / delay_time; |
| 2775 |
} |
| 2615 |
if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && |
2776 |
if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && |
| 2616 |
((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && |
2777 |
((ch->quirks & AHCI_Q_NOSPD) || (status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && |
| 2617 |
((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) |
2778 |
((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) |
| 2618 |
break; |
2779 |
break; |
| 2619 |
if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) { |
2780 |
if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) { |
| 2620 |
if (bootverbose) { |
2781 |
if (bootverbose || ahci_verbose) { |
| 2621 |
device_printf(ch->dev, "SATA offline status=%08x\n", |
2782 |
device_printf(ch->dev, "SATA offline status 0x%08x at time=%dus\n", |
| 2622 |
status); |
2783 |
status, timeout * delay_time); |
| 2623 |
} |
2784 |
} |
|
|
2785 |
if (ahci_verbose > 2) |
| 2786 |
device_printf(ch->dev, "ahci_sata_connect: Done (0)\n"); |
| 2624 |
return (0); |
2787 |
return (0); |
| 2625 |
} |
2788 |
} |
| 2626 |
if (found == 0 && timeout >= 100) |
2789 |
if (found == 0 && timeout >= timeout_detect_limit) |
| 2627 |
break; |
2790 |
break; |
| 2628 |
DELAY(100); |
2791 |
DELAY(delay_time); |
| 2629 |
} |
2792 |
} |
| 2630 |
if (timeout >= 1000 || !found) { |
2793 |
if (!found || timeout >= timeout_full_limit) { |
| 2631 |
if (bootverbose) { |
2794 |
if (bootverbose || ahci_verbose) { |
| 2632 |
device_printf(ch->dev, |
2795 |
device_printf(ch->dev, |
| 2633 |
"SATA connect timeout time=%dus status=%08x\n", |
2796 |
"SATA connect timeout status 0x%08x at time=%dus\n", |
| 2634 |
timeout * 100, status); |
2797 |
status, timeout * delay_time); |
| 2635 |
} |
2798 |
} |
|
|
2799 |
if (ahci_verbose > 2) |
| 2800 |
device_printf(ch->dev, "ahci_sata_connect: Done (0)\n"); |
| 2636 |
return (0); |
2801 |
return (0); |
| 2637 |
} |
2802 |
} |
| 2638 |
if (bootverbose) { |
2803 |
if (bootverbose || ahci_verbose) { |
| 2639 |
device_printf(ch->dev, "SATA connect time=%dus status=%08x\n", |
2804 |
device_printf(ch->dev, "SATA connect status 0x%08x at time=%dus\n", |
| 2640 |
timeout * 100, status); |
2805 |
status, timeout * delay_time); |
| 2641 |
} |
2806 |
} |
| 2642 |
/* Clear SATA error register */ |
2807 |
/* Clear SATA error register */ |
| 2643 |
ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xffffffff); |
2808 |
ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xffffffff); |
|
|
2809 |
if (ahci_verbose > 2) |
| 2810 |
device_printf(ch->dev, "ahci_sata_connect: Done (1)\n"); |
| 2644 |
return (1); |
2811 |
return (1); |
| 2645 |
} |
2812 |
} |
| 2646 |
|
2813 |
|
|
Lines 2650-2655
ahci_sata_phy_reset(struct ahci_channel *ch)
Link Here
|
| 2650 |
int sata_rev; |
2817 |
int sata_rev; |
| 2651 |
uint32_t val, detval; |
2818 |
uint32_t val, detval; |
| 2652 |
|
2819 |
|
|
|
2820 |
if (ahci_verbose > 2) |
| 2821 |
device_printf(ch->dev, "ahci_sata_phy_reset: Start\n"); |
| 2822 |
|
| 2653 |
if (ch->listening) { |
2823 |
if (ch->listening) { |
| 2654 |
val = ATA_INL(ch->r_mem, AHCI_P_CMD); |
2824 |
val = ATA_INL(ch->r_mem, AHCI_P_CMD); |
| 2655 |
val |= AHCI_P_CMD_SUD; |
2825 |
val |= AHCI_P_CMD_SUD; |
|
Lines 2682-2689
ahci_sata_phy_reset(struct ahci_channel *ch)
Link Here
|
| 2682 |
ch->listening = 1; |
2852 |
ch->listening = 1; |
| 2683 |
} else if (ch->pm_level > 0) |
2853 |
} else if (ch->pm_level > 0) |
| 2684 |
ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE); |
2854 |
ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE); |
|
|
2855 |
if (ahci_verbose > 2) |
| 2856 |
device_printf(ch->dev, "ahci_sata_phy_reset: Done (0)\n"); |
| 2685 |
return (0); |
2857 |
return (0); |
| 2686 |
} |
2858 |
} |
|
|
2859 |
if (ahci_verbose > 2) |
| 2860 |
device_printf(ch->dev, "ahci_sata_phy_reset: Done (1)\n"); |
| 2687 |
return (1); |
2861 |
return (1); |
| 2688 |
} |
2862 |
} |
| 2689 |
|
2863 |
|
|
Lines 2832-2837
ahciaction(struct cam_sim *sim, union ccb *ccb)
Link Here
|
| 2832 |
} |
3006 |
} |
| 2833 |
case XPT_RESET_BUS: /* Reset the specified SCSI bus */ |
3007 |
case XPT_RESET_BUS: /* Reset the specified SCSI bus */ |
| 2834 |
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ |
3008 |
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ |
|
|
3009 |
if (ahci_verbose > 2) |
| 3010 |
device_printf(ch->dev, "ahciaction: Calling ahci_reset (%s)\n", |
| 3011 |
(ccb->ccb_h.func_code == XPT_RESET_BUS ? "XPT_RESET_BUS" : "XPT_RESET_DEV")); |
| 2835 |
ahci_reset(ch); |
3012 |
ahci_reset(ch); |
| 2836 |
ccb->ccb_h.status = CAM_REQ_CMP; |
3013 |
ccb->ccb_h.status = CAM_REQ_CMP; |
| 2837 |
break; |
3014 |
break; |