Date: Wed, 16 Mar 2005 11:33:39 +0600 From: Max Khon <fjoe@samodelkin.net> To: freebsd-current@freebsd.org Cc: sos@freebsd.org Subject: ATAng: reboot after panic, crashdumps [PATCH] Message-ID: <20050316053338.GA69911@samodelkin.net>
next in thread | raw e-mail | index | archive | help
--PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! Attached patch fixes reboot after panic for me on RELENG_5 and RELENG_5_3. Crashdumps work again for me as well. The problem was in ata_shutdown() -- ATA_FLUSHCACHE request issued from ata_shutdown() never completes (ata_queue_request() sleeps in sema_wait(&request->done)) because ata_interrupt() is never called (callouts do not work as well, so that if the controller is busy ATA_FLUSHCACHE was not retried). I am not sure if "if (panicstr == NULL)" check is required (for normal shutdown sequence). addump() does not check if we are shutting down cleanly (ata_flushcache() was copy-n-pasted from addump()) and always uses atadev->channel->hw.begin_transaction(&request)/end_transaction(&request) directly. /fjoe --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ata.diff" Index: ata-all.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-all.c,v retrieving revision 1.222.2.7 diff -u -p -r1.222.2.7 ata-all.c --- ata-all.c 2 Mar 2005 02:15:13 -0000 1.222.2.7 +++ ata-all.c 16 Mar 2005 05:09:04 -0000 @@ -66,6 +66,7 @@ static struct cdevsw ata_cdevsw = { }; /* prototypes */ +static void ata_flushcache(struct ata_device *); static void ata_shutdown(void *, int); static void ata_interrupt(void *); static int ata_getparam(struct ata_device *, u_int8_t); @@ -373,6 +374,29 @@ ata_resume(device_t dev) } static void +ata_flushcache(struct ata_device *atadev) +{ + struct ata_request request; + + if (panicstr == NULL) { + ata_controlcmd(atadev, ATA_FLUSHCACHE, 0, 0, 0); + return; + } + + bzero(&request, sizeof(struct ata_request)); + request.device = atadev; + request.u.ata.command = ATA_FLUSHCACHE; + request.flags = ATA_R_CONTROL; + + if (atadev->channel->hw.begin_transaction(&request) == ATA_OP_CONTINUES) { + do { + DELAY(20); + } while (atadev->channel->hw.end_transaction(&request) == ATA_OP_CONTINUES); + ata_finish(&request); + } +} + +static void ata_shutdown(void *arg, int howto) { struct ata_channel *ch; @@ -384,10 +408,10 @@ ata_shutdown(void *arg, int howto) continue; if (ch->device[MASTER].param && ch->device[MASTER].param->support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(&ch->device[MASTER], ATA_FLUSHCACHE, 0, 0, 0); + ata_flushcache(&ch->device[MASTER]); if (ch->device[SLAVE].param && ch->device[SLAVE].param->support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(&ch->device[SLAVE], ATA_FLUSHCACHE, 0, 0, 0); + ata_flushcache(&ch->device[SLAVE]); } } --PEIAKu/WMn1b1Hv9--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050316053338.GA69911>