Re: PATCH; make sr.c respect use_10_for_ms

Douglas Gilbert
2003-06-22T04:52:01Z

Matthew Dharm wrote:
> On Sat, Jun 21, 2003 at 09:54:46PM -0500, James Bottomley wrote:
>
>>@@ -702,7 +692,7 @@
>> printk("%s: scsi-1 drive\n", cd->cdi.name);
>> return;
>> }
>>- n = buffer[3] + 4;
>>+ n = rc;
>> cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
>> cd->readcd_known = 1;
>> cd->readcd_cdda = buffer[n + 5] & 0x01;
>
>
> This bit isn't right. n is supposed to point to the start of the page
> data, not the page header. The header is a different size if the command
> is 6-byte or 10-byte.
>
> If you look at my patch, you can see the correct offsets you need.

Matt,
Here is a small function to calculate the mode sense reponse
offset to the first page (borrowed from smartmontools, GPL-ed
code):

/* Offset into mode sense (6 or 10 byte) response that actual mode page
* starts at (relative to resp[0]). Returns -1 if problem */
int scsiModePageOffset(const UINT8 * resp, int len, int modese_10)
{
int resp_len, bd_len;
int offset = -1;

if (resp) {
if (modese_10) {
resp_len = (resp[0] << 8) + resp[1] + 2;
bd_len = (resp[6] << 8) + resp[7];
offset = bd_len + 8;
} else {
resp_len = resp[0] + 1;
bd_len = resp[3];
offset = bd_len + 4;
}
if ((offset + 2) > len) {
pout("scsiModePageOffset: page too small, offset=%d "
"resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
offset = -1;
} else if ((offset + 2) > resp_len) {
pout("scsiModePageOffset: response length too short,
resp_len=%d"
" offset=%d bd_len=%d\n", resp_len, offset, bd_len);
offset = -1;
}
}
return offset;
}

BTW The sanity checks can be useful, Recently, I have been
trying to solve problems with the aacraid which returns
garbage to MODE SENSE commands (and locks up when given
LOG SENSE commands).
My USB mass storage enclosure is quirky as well: when
it gets a MODE_SENSE_10 it swaps the response_length bytes
(bytes 0 and 1) producing an exaggerated length. The mode
page is still readable and valid.

Doug Gilbert