savecore: first and last dump headers disagree on /dev/ad0b

Tor Egge Tor.Egge at cvsup.no.freebsd.org
Tue Oct 7 12:01:45 PDT 2003


> Hello.
> -CURRENT as of yesterday can't save kernel dump:
> 
>   savecore: first and last dump headers disagree on /dev/ad0b
>   savecore: unsaved dumps found but not saved
> 
> Is this a known issue? 

Yes.

I had the same problem on my development machine at the end of August and
ended up using the enclosed patch to get working dumps.

- Tor Egge
-------------- next part --------------
Index: sys/dev/ata/ata-all.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.187
diff -u -r1.187 ata-all.c
--- sys/dev/ata/ata-all.c	27 Aug 2003 15:27:56 -0000	1.187
+++ sys/dev/ata/ata-all.c	31 Aug 2003 22:31:33 -0000
@@ -109,9 +109,11 @@
     ch->device[MASTER].channel = ch;
     ch->device[MASTER].unit = ATA_MASTER;
     ch->device[MASTER].mode = ATA_PIO;
+    ch->device[MASTER].dumping = 0;
     ch->device[SLAVE].channel = ch;
     ch->device[SLAVE].unit = ATA_SLAVE;
     ch->device[SLAVE].mode = ATA_PIO;
+    ch->device[SLAVE].dumping = 0;
     ch->dev = dev;
     ch->state = ATA_IDLE;
     bzero(&ch->queue_mtx, sizeof(struct mtx));
Index: sys/dev/ata/ata-all.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-all.h,v
retrieving revision 1.65
diff -u -r1.65 ata-all.h
--- sys/dev/ata/ata-all.h	25 Aug 2003 11:13:04 -0000	1.65
+++ sys/dev/ata/ata-all.h	31 Aug 2003 22:56:14 -0000
@@ -227,6 +227,7 @@
 
     int				cmd;		/* last cmd executed */
     int				mode;		/* transfermode */
+    int				dumping;	/* panic dump in progress */
     void			(*setmode)(struct ata_device *atadev, int mode);
 };
 
Index: sys/dev/ata/ata-disk.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-disk.c,v
retrieving revision 1.159
diff -u -r1.159 ata-disk.c
--- sys/dev/ata/ata-disk.c	25 Aug 2003 09:01:49 -0000	1.159
+++ sys/dev/ata/ata-disk.c	31 Aug 2003 23:18:40 -0000
@@ -336,6 +336,26 @@
     if (!adp)
 	return ENXIO;
 
+    /* Some chipsets must be configured for PIO before dump starts. */
+    if (adp->device->dumping == 0) {
+	adp->device->dumping = 1;
+	adp->device->setmode(adp->device, ATA_PIO_MAX);
+    }
+    if (length == 0) {
+	int error = 0;
+	/* Commit dump to media */
+	if (adp->device->param != NULL &&
+	    adp->device->param->support.command2 & ATA_SUPPORT_FLUSHCACHE) {
+	    error = ata_controlcmd(adp->device, ATA_FLUSHCACHE, 0, 0, 0);
+	    if (error != 0)
+		ata_prtdev(adp->device, "Flush cache failed\n");
+	    else
+		ata_prtdev(adp->device, "Flush cache succeeded\n");
+	} else
+	    ata_prtdev(adp->device, "Flush cache skipped\n");
+	return error;
+    }
+
     bzero(&request, sizeof(struct ata_request));
     request.device = adp->device;
     request.data = virtual;
@@ -352,13 +372,15 @@
 
     if (adp->device->channel->hw.transaction(&request) == ATA_OP_FINISHED)
 	return EIO;
-    while (request.bytecount > request.donecount) {
+    while (adp->device->channel->running == &request) {
 	DELAY(20);
-	adp->device->channel->running = &request;
 	adp->device->channel->hw.interrupt(adp->device->channel);
-	adp->device->channel->running = NULL;
 	if (request.status & ATA_S_ERROR)
 	    return EIO;
+    }
+    if (request.bytecount > request.donecount) {
+	printf("Short write?");
+	return EIO;
     }
     return 0;
 }
Index: sys/dev/ata/ata-queue.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-queue.c,v
retrieving revision 1.4
diff -u -r1.4 ata-queue.c
--- sys/dev/ata/ata-queue.c	28 Aug 2003 08:22:53 -0000	1.4
+++ sys/dev/ata/ata-queue.c	31 Aug 2003 22:35:30 -0000
@@ -106,9 +106,36 @@
 ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t feature,
 	       u_int64_t lba, u_int16_t count)
 {
-    struct ata_request *request = ata_alloc_request();
+    struct ata_request *request;
     int error = ENOMEM;
 
+    /* Handle calls from addump */
+    if (atadev->dumping) {
+	struct ata_request request2;
+	request = &request2;
+	bzero(request, sizeof(struct ata_request));
+	request->device = atadev;
+	request->u.ata.command = command;
+	request->u.ata.lba = lba;
+	request->u.ata.count = count;
+	request->u.ata.feature = feature;
+	request->flags = ATA_R_CONTROL;
+	request->timeout = 5;
+	if (atadev->channel->hw.transaction(request) ==
+	    ATA_OP_CONTINUES) {
+	    while (atadev->channel->running == request &&
+		   (request->status & ATA_S_ERROR) == 0) {
+		DELAY(20);
+		atadev->channel->hw.interrupt(atadev->channel);
+	    }
+	}
+	error = request->result;
+	if ((request->status & ATA_S_ERROR) != 0 && error == 0)
+	    error = EIO;
+	return error;
+    }
+    request = ata_alloc_request();
+	
     if (request) {
 	request->device = atadev;
 	request->u.ata.command = command;


More information about the freebsd-current mailing list