Tue Aug 15 11:21:32 2017 UTC ()
explicitly do not try to activate any further commands when running recovery
xfer; it was kind of implied since the code would not queue another non-NCQ
command when non-NCQ command is active, but this is better for readibility


(jdolecek)
diff -r1.132.8.28 -r1.132.8.29 src/sys/dev/ata/ata.c

cvs diff -r1.132.8.28 -r1.132.8.29 src/sys/dev/ata/ata.c (expand / switch to unified diff)

--- src/sys/dev/ata/ata.c 2017/08/12 22:31:50 1.132.8.28
+++ src/sys/dev/ata/ata.c 2017/08/15 11:21:32 1.132.8.29
@@ -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 */
1246void 1246void
1247atastart(struct ata_channel *chp) 1247atastart(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
1267again: 1267again:
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
1353out: 1353out:
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