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>
