[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Hard drive RPM not reported correctly
>Submitter-Id: net
>Originator: Marco Peereboom
>Organization:
net
>Confidential: no
>Synopsis: OpenBSD uses default value of 3600 RPM for hard drives.
>Severity: non-critical
>Priority: low
>Category: kernel
>Class: sw-bug
>Release: N/A
>Environment:
System : OpenBSD 3.1
Architecture: OpenBSD.i386
Machine : i386
>Description:
Issue a "disklabel -d sd0c" and the RPM field will report a hard coded value of 3600 RPM.
Besides this there is also a hard coded value of 0x20 in scsi/sd_scsi.c which prevents the
mode sense command to return all the mode page data. Most mode pages will work but the
bigger ones won't (for example the "Rigid Disk Drive Geometry Page").
>How-To-Repeat:
disklabel -d sd0c does the trick.
>Fix:
- Added the rpm field to the flex geometry for completion sake in sys/scsi/scsi_disk.h
- Removed hard coded 3600 RPM value from sys/scsi/sd.c
- Changed the mode sense data length from 0x20 to 0xff in sys/scsi/sd_scsi.c
- Removed hard coded 3600 RPM value from sys/scsi/sd_scsi.c
- Added dynamic rpm values instead of hard coded ones.
Diffs:
======================================================
[root@odin scsi]# diff -u scsi_disk.h.old scsi_disk.h
--- scsi_disk.h.old Mon Jun 17 21:10:03 2002
+++ scsi_disk.h Mon Jun 17 21:18:06 2002
@@ -320,10 +320,9 @@
u_int8_t head_unload; /* head unload delay */
u_int8_t pin_34_2; /* pin 34 (6) pin 2 (7/11) definition */
u_int8_t pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */
+ u_int8_t rpm[2]; /* media rotation speed */
u_int8_t reserved1;
u_int8_t reserved2;
- u_int8_t reserved3;
- u_int8_t reserved4;
} flex_geometry;
};
======================================================
[root@odin scsi]# diff -u sd.c.old sd.c
--- sd.c.old Mon Jun 17 21:40:58 2002
+++ sd.c Wed Jul 10 21:09:00 2002
@@ -1000,7 +1000,7 @@
sizeof(lp->d_packname) - 1);
lp->d_secperunit = sd->params.disksize;
- lp->d_rpm = 3600;
+ lp->d_rpm = sd->params.rot_rate;
lp->d_interleave = 1;
lp->d_flags = 0;
======================================================
[root@odin scsi]# diff -u sd_scsi.c.old sd_scsi.c
--- sd_scsi.c.old Mon Jun 17 21:32:49 2002
+++ sd_scsi.c Wed Jul 10 21:06:48 2002
@@ -107,7 +107,7 @@
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.opcode = MODE_SENSE;
scsi_cmd.page = page;
- scsi_cmd.length = 0x20;
+ scsi_cmd.length = 0xff; /* 0x20 was not enough */
/*
* If the command worked, use the results to fill out
* the parameter structure
@@ -181,8 +181,6 @@
int page;
int error;
- dp->rot_rate = 3600; /* XXX any way of getting this? */
-
/*
* If offline, the SDEV_MEDIA_LOADED flag will be
* cleared by the caller if necessary.
@@ -209,6 +207,7 @@
dp->heads = scsi_sense.pages.rigid_geometry.nheads;
dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl);
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
+ dp->rot_rate = _2btol(scsi_sense.pages.rigid_geometry.rpm);
if (dp->heads == 0 || dp->cyls == 0)
goto fake_it;
@@ -231,6 +230,7 @@
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr;
dp->disksize = dp->heads * dp->cyls * dp->sectors;
+ dp->rot_rate = _2btol(scsi_sense.pages.flex_geometry.rpm);
if (dp->disksize == 0)
goto fake_it;