From owner-freebsd-current@FreeBSD.ORG Wed Jun 30 02:09:35 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from green.homeunix.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 6E26F16A4CE; Wed, 30 Jun 2004 02:09:35 +0000 (GMT) Received: from green.homeunix.org (green@localhost [127.0.0.1]) by green.homeunix.org (8.12.11/8.12.11) with ESMTP id i5U29Yfk001074; Tue, 29 Jun 2004 22:09:34 -0400 (EDT) (envelope-from green@green.homeunix.org) Received: (from green@localhost) by green.homeunix.org (8.12.11/8.12.11/Submit) id i5U29YiT001073; Tue, 29 Jun 2004 22:09:34 -0400 (EDT) (envelope-from green) Date: Tue, 29 Jun 2004 22:09:33 -0400 From: Brian Fundakowski Feldman To: current@FreeBSD.org Message-ID: <20040630020933.GA946@green.homeunix.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i cc: sos@FreeBSD.org Subject: [FIXED] ATAPI CD boot problems X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jun 2004 02:09:35 -0000 I've found and fixed several problems in ata/acd/atapicam locally, but I've identified several more. Of note, here are the simple ones. The first one is the most important! 1. ATAPI devices come up in an inconsistent state sometimes. Issuing an ATAPI reset seems to fix this completely; normally I would see, most of the time, these messages: acd0: MODE_SENSE_BIG trying to write on read buffer acd0: timeout waiting for ATAPI ready acd0: unknown transfer phase 0x1:0x50 acd0: timeout waiting for ATAPI ready 2. Unknown transfer phase what? The old message was very undescriptive. 3. If using ATAPICAM and the attach fails, it'll crash due to freeing in-flight CCBs out from underneath. [not fixed] 4. If not using ATAPICAM, the timeout() function is set and never reset after each "timeout waiting for ATAPI ready". I made it untimeout() immediately if that happens, and things are much smoother (at least without ATAPICAM, when failing to attach an acd device). 5. An acd device finishes attaching before GEOM has fully attached to it. 6. Detachment is done at the wrong places, so generally requests are still queued to a dying device. There are still lots of detachment issues and furthermore I don't think that my computer won't lock up when trying to rip one of my new CDs, but this is a huge improvement, so see if it helps your problems with ATAPI CD/DVD drives in current. 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@FreeBSD.org \ The Power to Serve! \ Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\