Subject: scsi disks with "Medium Format Corrupted"
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 05/19/2004 17:15:47
--mP3DRpeJDSE+ciuQ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
as part of tests with esiop I managed to damage a scsi disk with the format
command. It's now in this state:
java:/root#scsictl /dev/rsd1c format 516
scsictl: /dev/rsd1c: Device not configured
And on console:
sd1(esiop0:0:3:0): Check Condition on CDB: 0x23 00 00 00 00 00 00 00 0c 00
SENSE KEY: Media Error
ASC/ASCQ: Medium Format Corrupted
FRU CODE: 0xc
The problem is that we allow opening disks which are not formatted at all,
or with a format we can't handle, but we don't handle the case where
READ_FORMAT_CAPACITIES fails.
The attached patch cause sd_interpret_sense() to return EFTYPE instead of
EIO for the "Medium Format Corrupted" ASC/ASQ, so that we can check for
this kind of event in sd_get_capacity().
We also should not try to build a disklabel if the media is not formatted
(in my case this caused a panic: buf mem pool index 54, because sd->params
is not initialised properly).
Any comments ?
--
Manuel Bouyer <bouyer@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
--mP3DRpeJDSE+ciuQ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
Index: sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.216
diff -u -r1.216 sd.c
--- sd.c 14 Mar 2004 00:17:37 -0000 1.216
+++ sd.c 19 May 2004 15:12:42 -0000
@@ -532,6 +532,7 @@
}
if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
+ int param_error;
periph->periph_flags |= PERIPH_MEDIA_LOADED;
/*
@@ -542,15 +543,16 @@
* The drive should refuse real I/O, if the media is
* unformatted.
*/
- if (sd_get_parms(sd, &sd->params,
- 0) == SDGP_RESULT_OFFLINE) {
+ if ((param_error = sd_get_parms(sd, &sd->params, 0))
+ == SDGP_RESULT_OFFLINE) {
error = ENXIO;
goto bad2;
}
SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
/* Load the partition info if not already loaded. */
- sdgetdisklabel(sd);
+ if (param_error == 0)
+ sdgetdisklabel(sd);
SC_DEBUG(periph, SCSIPI_DB3, ("Disklabel loaded "));
}
}
@@ -1393,6 +1395,12 @@
splx(s);
}
}
+ if ((sense->flags & SSD_KEY) == SKEY_MEDIUM_ERROR &&
+ sense->add_sense_code == 0x31 &&
+ sense->add_sense_code_qual == 0x00) { /* maybe for any asq ? */
+ /* Medium Format Corrupted */
+ retval = EFTYPE;
+ }
return (retval);
}
@@ -1701,6 +1709,10 @@
sizeof(scsipi_result), SDRETRIES, 20000,
NULL, flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK /*|
XS_CTL_IGNORE_ILLEGAL_REQUEST*/);
+ if (error == EFTYPE) {
+ /* Medium Format Corrupted, handle as not formatted */
+ return (SDGP_RESULT_UNFORMATTED);
+ }
if (error || scsipi_result.header.length == 0)
return (SDGP_RESULT_OFFLINE);
--mP3DRpeJDSE+ciuQ--