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