Subject: kern/21475: [rkb] SCSI disk driver handles "big" MODE SENSE/SELECT incorrectly
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rafal@netbsd.org>
List: netbsd-bugs
Date: 05/05/2003 23:40:03
>Number: 21475
>Category: kern
>Synopsis: SCSI disk driver handles "big" MODE SENSE/SELECT incorrectly
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue May 06 01:41:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Rafal
>Release: NetBSD 1.6R
>Organization:
lacking
>Environment:
System: NetBSD groo-the-wanderer 1.6R NetBSD 1.6R (STINKPAD) #0: Sun May 4 03:49:18 EDT 2003 rafal@groo-the-wanderer:/usr/rafal/netbsd-src/sys/arch/i386/compile/STINKPAD i386
Architecture: i386
Machine: i386
>Description:
The sd_scsibus_mode_sense() can use either the the 6-byte MODE_
{SENSE,SELECT} commands or the 10-byte MODE_{SENSE,SELECT}_BIG
commands to actually set/retrieve mode data (depending on the
quirks of the drive and/or bus). However, the return data of
these two commands is not in the same format -- the BIG flavors
have a bigger header...
Unfortunately, the code which calls sd_scsibus_mode_sense() all
uses data from the returned buffer with the assumption that only
a "small" header was used, and therefore fails (or appears as if the device is returning garbage) when the BIG commands are used.
The disk data returned with the "big" command is the following:
sd0: 3751 MB, 131076 cyl, 22 head, 0 sec, 62720 bytes/sect x 62720 sectors
The mode sense command and returned data are as follows:
sd0(umass0:0:1:0): command: 0x5a,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x2c,0x0-[44 bytes]
------------------------------
000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
032: 00 00 00 00 00 00 00 00 00 00 00 00
------------------------------
sd0(umass0:0:1:0): scsipi_done
sd0(umass0:0:1:0): command: 0x5a,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x2c,0x0-[44 bytes]
------------------------------
000: 00 27 00 00 00 00 00 08 00 00 f5 00 00 00 02 00
016: 04 16 00 01 ea 04 00 00 00 00 00 00 00 00 00 00
032: 00 00 00 00 00 00 00 00 00 00 00 00
------------------------------
Interpreting the above data by hand shows it *does* contain the
correct bits, only the SCSIPI code does not expect them to be in
the spots where they end up, and thus reads garbage out of the
mode page.
Forcing the PQUIRK_NOBIGMODESENSE for the device instead produces
the following (correct) data:
sd0: 31360 KB, 490 cyl, 4 head, 32 sec, 512 bytes/sect x 62720 sectors
The mode sense command and returned data are as follows:
sd0(umass0:0:1:0): command: 0x1a,0x0,0x4,0x0,0x2c,0x0-[44 bytes]
------------------------------
000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
032: 00 00 00 00 00 00 00 00 00 00 00 00
------------------------------
sd0(umass0:0:1:0): scsipi_done
sd0(umass0:0:1:0): command: 0x1a,0x0,0x4,0x0,0x2c,0x0-[44 bytes]
------------------------------
000: 23 00 00 08 00 00 f5 00 00 00 02 00 04 16 00 01
016: ea 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00
032: 00 00 00 00 00 00 00 00 00 00 00 00
------------------------------
Here, we can see the mode page data is shifted up four bytes, and
the SCSIPI code gets the parameters correct, as the data aligns
with the locations the SCSIPI code is using due to the small mode
header used here.
>How-To-Repeat:
Attach the following USB CF reader to your NetBSD system, or for
that matter any umass device that doesn't appear as a "simplified
direct" (ie, RBC) device (since the umass interface forces the
"use BIG commands" quirk for all SCSI devices). RBC devices are
safe since the sd_scsi.c code forces the PQUIRK_NOBIGMODESENSE
quirk for all RBC devices.
The device I used was a:
eUSB CompactFlash Adapter (0x000a),
SCM Microsystems Inc.(0x04e6), rev 2.18
Which is sold as a "Unity Digital" CF reader. Shuttle also
makes a USB CF reader based on the same chipset, as do others.
>Fix:
The correct fix is to have the sd_scsi.c code be passed back the
start of the page data (or the size of the header) so that it can
adjust the positions where it looks for data in the reply buffer.
A workaround is to simply add PQUIRK_NOBIGMODESENSE quirks for
all disk devices which also use PQUIRK_ONLYBIG commands until
the SCSIPI code is fixed; another workaround is to add specific
quirks for devices which would otherwise use MODE_SENSE_BIG and
thus cause the SCSIPI code to spit up and force them to use the
small variant (this is what I'm doing for my CF frob for now...
it works quite allright after that).
>Release-Note:
>Audit-Trail:
>Unformatted: