Re: Hang on boot - "ATAPI_RESET no interrupt" with DVD+RW

From: Brian Fundakowski Feldman <green_at_freebsd.org>
Date: Tue, 13 Jul 2004 19:56:09 -0400
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
_at__at_ -183,17 +183,20 _at__at_
     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) {
_at__at_ -254,8 +257,9 _at__at_
 		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;
 	}
_at__at_ -265,8 +269,9 _at__at_
 		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
_at__at_ -160,7 +160,6 _at__at_
 {
     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
_at__at_ -476,7 +476,8 _at__at_
 	    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
_at__at_ -211,7 +211,8 _at__at_
     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
_at__at_ -113,6 +113,8 _at__at_
     }
 
     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 */
_at__at_ -154,7 +156,7 _at__at_
 		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");
_at__at_ -169,7 +171,7 _at__at_
 	}
     }
     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.                       \,,,,,,,,,,,,,,,,,,,,,,\
Received on Tue Jul 13 2004 - 21:56:11 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:01 UTC