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: