| @@ -1,41 +1,41 @@ | | | @@ -1,41 +1,41 @@ |
1 | /* $NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $ */ | | 1 | /* $NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. | | 4 | * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ | | 25 | */ |
26 | | | 26 | |
27 | #include <sys/cdefs.h> | | 27 | #include <sys/cdefs.h> |
28 | __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $"); | | 28 | __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $"); |
29 | | | 29 | |
30 | #include "opt_ata.h" | | 30 | #include "opt_ata.h" |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/systm.h> | | 33 | #include <sys/systm.h> |
34 | #include <sys/kernel.h> | | 34 | #include <sys/kernel.h> |
35 | #include <sys/malloc.h> | | 35 | #include <sys/malloc.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | #include <sys/conf.h> | | 37 | #include <sys/conf.h> |
38 | #include <sys/fcntl.h> | | 38 | #include <sys/fcntl.h> |
39 | #include <sys/proc.h> | | 39 | #include <sys/proc.h> |
40 | #include <sys/kthread.h> | | 40 | #include <sys/kthread.h> |
41 | #include <sys/errno.h> | | 41 | #include <sys/errno.h> |
| @@ -1239,76 +1239,76 @@ ata_exec_xfer(struct ata_channel *chp, s | | | @@ -1239,76 +1239,76 @@ ata_exec_xfer(struct ata_channel *chp, s |
1239 | /* | | 1239 | /* |
1240 | * Start I/O on a controller, for the given channel. | | 1240 | * Start I/O on a controller, for the given channel. |
1241 | * The first xfer may be not for our channel if the channel queues | | 1241 | * The first xfer may be not for our channel if the channel queues |
1242 | * are shared. | | 1242 | * are shared. |
1243 | * | | 1243 | * |
1244 | * MUST BE CALLED AT splbio()! | | 1244 | * MUST BE CALLED AT splbio()! |
1245 | */ | | 1245 | */ |
1246 | void | | 1246 | void |
1247 | atastart(struct ata_channel *chp) | | 1247 | atastart(struct ata_channel *chp) |
1248 | { | | 1248 | { |
1249 | struct atac_softc *atac = chp->ch_atac; | | 1249 | struct atac_softc *atac = chp->ch_atac; |
1250 | struct ata_queue *chq = chp->ch_queue; | | 1250 | struct ata_queue *chq = chp->ch_queue; |
1251 | struct ata_xfer *xfer, *axfer; | | 1251 | struct ata_xfer *xfer, *axfer; |
1252 | bool immediate; | | 1252 | bool recovery; |
1253 | | | 1253 | |
1254 | #ifdef ATA_DEBUG | | 1254 | #ifdef ATA_DEBUG |
1255 | int spl1, spl2; | | 1255 | int spl1, spl2; |
1256 | | | 1256 | |
1257 | spl1 = splbio(); | | 1257 | spl1 = splbio(); |
1258 | spl2 = splbio(); | | 1258 | spl2 = splbio(); |
1259 | if (spl2 != spl1) { | | 1259 | if (spl2 != spl1) { |
1260 | printf("atastart: not at splbio()\n"); | | 1260 | printf("atastart: not at splbio()\n"); |
1261 | panic("atastart"); | | 1261 | panic("atastart"); |
1262 | } | | 1262 | } |
1263 | splx(spl2); | | 1263 | splx(spl2); |
1264 | splx(spl1); | | 1264 | splx(spl1); |
1265 | #endif /* ATA_DEBUG */ | | 1265 | #endif /* ATA_DEBUG */ |
1266 | | | 1266 | |
1267 | again: | | 1267 | again: |
1268 | mutex_enter(&chp->ch_lock); | | 1268 | mutex_enter(&chp->ch_lock); |
1269 | | | 1269 | |
1270 | KASSERT(chq->queue_active <= chq->queue_openings); | | 1270 | KASSERT(chq->queue_active <= chq->queue_openings); |
1271 | if (chq->queue_active == chq->queue_openings) { | | 1271 | if (chq->queue_active == chq->queue_openings) { |
1272 | goto out; /* channel completely busy */ | | 1272 | goto out; /* channel completely busy */ |
1273 | } | | 1273 | } |
1274 | | | 1274 | |
1275 | /* is there a xfer ? */ | | 1275 | /* is there a xfer ? */ |
1276 | if ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) == NULL) | | 1276 | if ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) == NULL) |
1277 | goto out; | | 1277 | goto out; |
1278 | | | 1278 | |
1279 | immediate = ISSET(xfer->c_flags, C_RECOVERY); | | 1279 | recovery = ISSET(xfer->c_flags, C_RECOVERY); |
1280 | | | 1280 | |
1281 | /* is the queue frozen? */ | | 1281 | /* is the queue frozen? */ |
1282 | if (__predict_false(!immediate && chq->queue_freeze > 0)) { | | 1282 | if (__predict_false(!recovery && chq->queue_freeze > 0)) { |
1283 | if (chq->queue_flags & QF_IDLE_WAIT) { | | 1283 | if (chq->queue_flags & QF_IDLE_WAIT) { |
1284 | chq->queue_flags &= ~QF_IDLE_WAIT; | | 1284 | chq->queue_flags &= ~QF_IDLE_WAIT; |
1285 | wakeup(&chq->queue_flags); | | 1285 | wakeup(&chq->queue_flags); |
1286 | } | | 1286 | } |
1287 | goto out; /* queue frozen */ | | 1287 | goto out; /* queue frozen */ |
1288 | } | | 1288 | } |
1289 | | | 1289 | |
1290 | /* all xfers on same queue must belong to the same channel */ | | 1290 | /* all xfers on same queue must belong to the same channel */ |
1291 | KASSERT(xfer->c_chp == chp); | | 1291 | KASSERT(xfer->c_chp == chp); |
1292 | | | 1292 | |
1293 | /* | | 1293 | /* |
1294 | * Can only take the command if there are no current active | | 1294 | * Can only take the command if there are no current active |
1295 | * commands, or if the command is NCQ and the active commands are also | | 1295 | * commands, or if the command is NCQ and the active commands are also |
1296 | * NCQ. If PM is in use and HBA driver doesn't support/use FIS-based | | 1296 | * NCQ. If PM is in use and HBA driver doesn't support/use FIS-based |
1297 | * switching, can only send commands to single drive. | | 1297 | * switching, can only send commands to single drive. |
1298 | * Need only check first xfer. | | 1298 | * Need only check first xfer. |
1299 | * XXX FIS-based switching - revisit | | 1299 | * XXX FIS-based switching - revisit |
1300 | */ | | 1300 | */ |
1301 | if (!immediate && (axfer = TAILQ_FIRST(&chp->ch_queue->active_xfers))) { | | 1301 | if (!recovery && (axfer = TAILQ_FIRST(&chp->ch_queue->active_xfers))) { |
1302 | if (!ISSET(xfer->c_flags, C_NCQ) || | | 1302 | if (!ISSET(xfer->c_flags, C_NCQ) || |
1303 | !ISSET(axfer->c_flags, C_NCQ) || | | 1303 | !ISSET(axfer->c_flags, C_NCQ) || |
1304 | xfer->c_drive != axfer->c_drive) | | 1304 | xfer->c_drive != axfer->c_drive) |
1305 | goto out; | | 1305 | goto out; |
1306 | } | | 1306 | } |
1307 | | | 1307 | |
1308 | struct ata_drive_datas * const drvp = &chp->ch_drive[xfer->c_drive]; | | 1308 | struct ata_drive_datas * const drvp = &chp->ch_drive[xfer->c_drive]; |
1309 | | | 1309 | |
1310 | /* | | 1310 | /* |
1311 | * if someone is waiting for the command to be active, wake it up | | 1311 | * if someone is waiting for the command to be active, wake it up |
1312 | * and let it process the command | | 1312 | * and let it process the command |
1313 | */ | | 1313 | */ |
1314 | if (xfer->c_flags & C_WAITACT) { | | 1314 | if (xfer->c_flags & C_WAITACT) { |
| @@ -1334,28 +1334,28 @@ again: | | | @@ -1334,28 +1334,28 @@ again: |
1334 | ata_activate_xfer_locked(chp, xfer); | | 1334 | ata_activate_xfer_locked(chp, xfer); |
1335 | | | 1335 | |
1336 | if (atac->atac_cap & ATAC_CAP_NOIRQ) | | 1336 | if (atac->atac_cap & ATAC_CAP_NOIRQ) |
1337 | KASSERT(xfer->c_flags & C_POLL); | | 1337 | KASSERT(xfer->c_flags & C_POLL); |
1338 | | | 1338 | |
1339 | mutex_exit(&chp->ch_lock); | | 1339 | mutex_exit(&chp->ch_lock); |
1340 | | | 1340 | |
1341 | /* | | 1341 | /* |
1342 | * XXX MPSAFE can't keep the lock, xfer->c_start() might call the done | | 1342 | * XXX MPSAFE can't keep the lock, xfer->c_start() might call the done |
1343 | * routine for polled commands. | | 1343 | * routine for polled commands. |
1344 | */ | | 1344 | */ |
1345 | xfer->c_start(chp, xfer); | | 1345 | xfer->c_start(chp, xfer); |
1346 | | | 1346 | |
1347 | /* Queue more commands if possible */ | | 1347 | /* Queue more commands if possible, but not during recovery */ |
1348 | if (chq->queue_active < chq->queue_openings) | | 1348 | if (!recovery && chq->queue_active < chq->queue_openings) |
1349 | goto again; | | 1349 | goto again; |
1350 | | | 1350 | |
1351 | return; | | 1351 | return; |
1352 | | | 1352 | |
1353 | out: | | 1353 | out: |
1354 | mutex_exit(&chp->ch_lock); | | 1354 | mutex_exit(&chp->ch_lock); |
1355 | } | | 1355 | } |
1356 | | | 1356 | |
1357 | /* | | 1357 | /* |
1358 | * Does it's own locking, does not require splbio(). | | 1358 | * Does it's own locking, does not require splbio(). |
1359 | * flags - whether to block waiting for free xfer | | 1359 | * flags - whether to block waiting for free xfer |
1360 | * openings - limit of openings supported by device, <= 0 means tag not | | 1360 | * openings - limit of openings supported by device, <= 0 means tag not |
1361 | * relevant, and any available xfer can be returned | | 1361 | * relevant, and any available xfer can be returned |