kern/103602: drive gets wedged on READ CD CAPACITY if no disc
is in
Thomas Quinot
thomas at FreeBSD.ORG
Tue Apr 24 16:58:45 UTC 2007
* Josh Carroll, 2007-04-24 :
> Here is my output (first with no disk, second with). I see sk=02 here as
> well:
>
> % ./readcap /dev/acd0
> ioctl returned error 5 Input/output error
> Sense data: error=70 sk=02 asc=3a ascq=00
>
> % ./readcap /dev/acd0
> ioctl returned error 0 Unknown error: 0
> Sense data: error=00 sk=00 asc=00 ascq=00
> LBA of last sector in last session: 185805
> Sector size: 2048
It just occurred to me that there is one point that is different when
using readcap, compared to sg_readcap+ATAPI/CAM: only in the latter case
is DMA used.
*And* you mentioned, very early in this PR, that disabling DMA
altogether made the problem disappear. So, let's try something: enable
DMA only for READ and WRITE commands (where it's most useful).
Apparently it's not a completely unhead-of situation that some drives
have problems with DMA for commands other than READ and WRITE, see:
http://www.mail-archive.com/linux-ide@vger.kernel.org/msg05425.html
Patch attached.
Thomas.
-------------- next part --------------
Index: sys/dev/ata/atapi-cam.c
===================================================================
RCS file: /space/mirror/ncvs/src/sys/dev/ata/atapi-cam.c,v
retrieving revision 1.50
diff -u -r1.50 atapi-cam.c
--- sys/dev/ata/atapi-cam.c 14 Mar 2007 01:59:00 -0000 1.50
+++ sys/dev/ata/atapi-cam.c 24 Apr 2007 16:57:11 -0000
@@ -516,10 +516,10 @@
switch (ccb_h->flags & CAM_DIR_MASK) {
case CAM_DIR_IN:
- request_flags |= ATA_R_READ|ATA_R_DMA;
+ request_flags |= ATA_R_READ;
break;
case CAM_DIR_OUT:
- request_flags |= ATA_R_WRITE|ATA_R_DMA;
+ request_flags |= ATA_R_WRITE;
break;
case CAM_DIR_NONE:
/* No flags need to be set */
@@ -528,8 +528,6 @@
device_printf(softc->dev, "unknown IO operation\n");
goto action_invalid;
}
- if (softc->atadev[tid]->mode < ATA_DMA)
- request_flags &= ~ATA_R_DMA;
if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) {
printf("cannot allocate ATAPI/CAM hcb\n");
@@ -594,7 +592,23 @@
request->u.atapi.ccb[3] = request->u.atapi.ccb[1] & 0x1f;
request->u.atapi.ccb[2] = 0;
request->u.atapi.ccb[1] = 0;
+
+ case READ_10:
+ /* FALLTHROUGH */
+ case WRITE_10:
+ /* FALLTHROUGH */
+ case READ_12:
+ /* FALLTHROUGH */
+ case WRITE_12:
+ /*
+ * Enable DMA (if target supports it) for READ and WRITE commands
+ * only, as some combinations of drive, controller and chipset do
+ * not behave correctly when DMA is enabled for other commands.
+ */
+ if (softc->atadev[tid]->mode >= ATA_DMA)
+ request_flags |= ATA_R_DMA;
break;
+
}
if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) {
@@ -616,7 +630,7 @@
/*
* no retries are to be performed at the ATA level; any retries
- * will be done by CAM .
+ * will be done by CAM.
*/
request->retries = 0;
More information about the freebsd-scsi
mailing list