Hang on boot - "ATAPI_RESET no interrupt" with DVD+RW
Brian Fundakowski Feldman
green at freebsd.org
Tue Jul 13 16:56:11 PDT 2004
On Tue, Jul 13, 2004 at 03:19:51PM -0700, Brian Rogers wrote:
> Since last night and continuing today, the kernel from -CURRENT usually
> hangs during boot. Safe mode worked once, but the second time it didn't
> work. I now got in through single-user mode, so it appears to just work
> every once in a while, randomly.
>
> I have a dmesg from the booted system below. When it hangs, it stops
> one line after "ata1-slave: FAILURE - ATAPI_RESET no interrupt", in
> other words it hangs after detecting ata1-master but before detecting
> ata1-slave, my DVD+RW drive.
Try using these diffs to src/sys/dev/ata; they fixed it for me.
cvs diff: Diffing .
Index: ata-all.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.214
diff -u -r1.214 ata-all.c
--- ata-all.c 22 Jun 2004 11:18:24 -0000 1.214
+++ ata-all.c 26 Jun 2004 03:38:25 -0000
@@ -183,17 +183,20 @@
if (!dev || !(ch = device_get_softc(dev)) || !ch->r_irq)
return ENXIO;
- /* detach devices on this channel */
if (ch->device[MASTER].detach)
- ch->device[MASTER].detach(&ch->device[MASTER]);
+ ch->device[MASTER].flags |= ATA_D_DETACHING;
if (ch->device[SLAVE].detach)
- ch->device[SLAVE].detach(&ch->device[SLAVE]);
+ ch->device[SLAVE].flags |= ATA_D_DETACHING;
+ /* fail outstanding requests on this channel */
+ ata_fail_requests(ch, NULL);
#ifdef DEV_ATAPICAM
atapi_cam_detach_bus(ch);
#endif
-
- /* fail outstanding requests on this channel */
- ata_fail_requests(ch, NULL);
+ /* detach devices on this channel */
+ if (ch->device[MASTER].detach)
+ ch->device[MASTER].detach(&ch->device[MASTER]);
+ if (ch->device[SLAVE].detach)
+ ch->device[SLAVE].detach(&ch->device[SLAVE]);
/* flush cache and powerdown device */
if (ch->device[MASTER].param) {
@@ -254,8 +257,9 @@
request->result = ENXIO;
request->retries = 0;
}
- ch->device[MASTER].detach(&ch->device[MASTER]);
+ ch->device[MASTER].flags |= ATA_D_DETACHING;
ata_fail_requests(ch, &ch->device[MASTER]);
+ ch->device[MASTER].detach(&ch->device[MASTER]);
free(ch->device[MASTER].param, M_ATA);
ch->device[MASTER].param = NULL;
}
@@ -265,8 +269,9 @@
request->result = ENXIO;
request->retries = 0;
}
- ch->device[SLAVE].detach(&ch->device[SLAVE]);
+ ch->device[SLAVE].flags |= ATA_D_DETACHING;
ata_fail_requests(ch, &ch->device[SLAVE]);
+ ch->device[SLAVE].detach(&ch->device[SLAVE]);
free(ch->device[SLAVE].param, M_ATA);
ch->device[SLAVE].param = NULL;
}
Index: ata-disk.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-disk.c,v
retrieving revision 1.173
diff -u -r1.173 ata-disk.c
--- ata-disk.c 22 Jun 2004 11:18:24 -0000 1.173
+++ ata-disk.c 26 Jun 2004 03:38:25 -0000
@@ -160,7 +160,6 @@
{
struct ad_softc *adp = atadev->softc;
- atadev->flags |= ATA_D_DETACHING;
#ifdef DEV_ATARAID
if (adp->flags & AD_F_RAID_SUBDISK)
ata_raiddisk_detach(adp);
Index: ata-lowlevel.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-lowlevel.c,v
retrieving revision 1.38
diff -u -r1.38 ata-lowlevel.c
--- ata-lowlevel.c 11 Jun 2004 07:39:15 -0000 1.38
+++ ata-lowlevel.c 26 Jun 2004 03:38:25 -0000
@@ -476,7 +476,8 @@
break;
default:
- ata_prtdev(request->device, "unknown transfer phase\n");
+ ata_prtdev(request->device, "unknown transfer phase %#x:%#x\n",
+ ATA_IDX_INB(ch, ATA_IREASON), request->status);
request->status = ATA_S_ERROR;
}
Index: ata-queue.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-queue.c,v
retrieving revision 1.29
diff -u -r1.29 ata-queue.c
--- ata-queue.c 1 Jun 2004 12:26:08 -0000 1.29
+++ ata-queue.c 30 Jun 2004 00:15:39 -0000
@@ -211,7 +211,8 @@
ATA_DEBUG_RQ(request, "taskqueue completition");
/* request is done schedule it for completition */
- if (request->device->channel->flags & ATA_IMMEDIATE_MODE) {
+ if (request->device->channel->flags & ATA_IMMEDIATE_MODE ||
+ request->result != 0) {
ata_completed(request, 0);
}
else {
Index: atapi-cd.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/atapi-cd.c,v
retrieving revision 1.168
diff -u -r1.168 atapi-cd.c
--- atapi-cd.c 22 Jun 2004 11:18:24 -0000 1.168
+++ atapi-cd.c 30 Jun 2004 01:49:02 -0000
@@ -113,6 +113,8 @@
}
ata_set_name(atadev, "acd", cdp->lun);
+ /* perform a reset to get hardware in a known state */
+ (void)ata_controlcmd(atadev, ATA_ATAPI_RESET, 0, 0, 0);
acd_get_cap(cdp);
/* if this is a changer device, allocate the neeeded lun's */
@@ -154,7 +156,7 @@
tmpcdp->driver = cdparr;
tmpcdp->slot = count;
tmpcdp->changer_info = chp;
- g_post_event(acd_geom_create, tmpcdp, M_WAITOK, NULL);
+ g_waitfor_event(acd_geom_create, tmpcdp, M_WAITOK, NULL);
}
if (!(name = malloc(strlen(atadev->name) + 2, M_ACD, M_NOWAIT))) {
ata_prtdev(atadev, "out of memory\n");
@@ -169,7 +171,7 @@
}
}
else
- g_post_event(acd_geom_create, cdp, M_WAITOK, NULL);
+ g_waitfor_event(acd_geom_create, cdp, M_WAITOK, NULL);
/* setup the function ptrs */
atadev->detach = acd_detach;
--
Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\
<> green at FreeBSD.org \ The Power to Serve! \
Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\
More information about the freebsd-current
mailing list