From 2ddd78d4bea9fe2ed8ae84bf325453558b236317 Mon Sep 17 00:00:00 2001 From: Nikunj A Dadhania Date: Tue, 24 Sep 2013 15:09:29 +0530 Subject: [PATCH] scsi: make probe more error resilient * Some usb devices do not like report-luns, assume it as single lun device and move further. * Make inquiry of the device first for 36bytes and then determine what is the additional size to read. Signed-off-by: Nikunj A Dadhania --- slof/fs/scsi-disk.fs | 20 ++++++++++++-------- slof/fs/scsi-host-helpers.fs | 15 ++++++++++----- slof/fs/scsi-probe-helpers.fs | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/slof/fs/scsi-disk.fs b/slof/fs/scsi-disk.fs index 1d1539f..1978471 100644 --- a/slof/fs/scsi-disk.fs +++ b/slof/fs/scsi-disk.fs @@ -90,19 +90,23 @@ CREATE cdb 10 allot dup 0<> IF " read-blocks" dump-scsi-error -65 throw ELSE drop THEN ; -: inquiry ( -- buffer | NULL ) - scsi-disk-debug? IF - ." SCSI-DISK: inquiry " .s cr - THEN - \ WARNING: ATAPI devices with libata seem to ignore the MSB of - \ the allocation length... let's only ask for ff bytes - ff cdb scsi-build-inquiry +: (inquiry) ( size -- buffer | NULL ) + dup cdb scsi-build-inquiry \ 16 retries for inquiry to flush out any UAs - scratch ff scsi-dir-read cdb scsi-param-size 10 retry-scsi-command + scratch swap scsi-dir-read cdb scsi-param-size 10 retry-scsi-command \ Success ? 0= IF scratch ELSE 2drop 0 THEN ; +: inquiry ( -- buffer | NULL ) + scsi-disk-debug? IF + ." SCSI-DISK: inquiry " .s cr + THEN + d# 36 (inquiry) 0= IF 0 EXIT THEN + scratch inquiry-data>add-length c@ 5 + + (inquiry) +; + : read-capacity ( -- blocksize #blocks ) \ Now issue the read-capacity command scsi-disk-debug? IF diff --git a/slof/fs/scsi-host-helpers.fs b/slof/fs/scsi-host-helpers.fs index 9ff3613..579ce37 100644 --- a/slof/fs/scsi-host-helpers.fs +++ b/slof/fs/scsi-host-helpers.fs @@ -92,16 +92,21 @@ CREATE sector d# 512 allot CREATE cdb 10 allot -: inquiry ( -- buffer | NULL ) - \ WARNING: ATAPI devices with libata seem to ignore the MSB of - \ the allocation length... let's only ask for ff bytes - ff cdb scsi-build-inquiry +: (inquiry) ( size -- buffer | NULL ) + dup cdb scsi-build-inquiry \ 16 retries for inquiry to flush out any UAs - sector ff scsi-dir-read cdb scsi-param-size 10 retry-scsi-command + sector swap scsi-dir-read cdb scsi-param-size 10 retry-scsi-command \ Success ? 0= IF sector ELSE 2drop 0 THEN ; +\ Read the initial 36bytes and then decide how much more is to be read +: inquiry ( -- buffer | NULL ) + d# 36 (inquiry) 0= IF 0 EXIT THEN + sector inquiry-data>add-length c@ 5 + + (inquiry) +; + : report-luns ( -- [ sector ] true | false ) 200 cdb scsi-build-report-luns \ 16 retries to flush out any UAs diff --git a/slof/fs/scsi-probe-helpers.fs b/slof/fs/scsi-probe-helpers.fs index 7cb40c2..307838f 100644 --- a/slof/fs/scsi-probe-helpers.fs +++ b/slof/fs/scsi-probe-helpers.fs @@ -37,6 +37,20 @@ rot ( devarray ndev mem devcur ) dup >r x! r> 8 + ( devarray ndev devcur ) swap 1 + + ELSE + dev-max-target 1 = IF + \ Some USB MSC devices do not implement report + \ luns. That will stall the bulk pipe. These devices are + \ single lun devices, report it accordingly + + ( devarray devcur ndev ) + 16 alloc-mem ( devarray devcur ndev mem ) + dup 16 0 fill ( devarray devcur ndev mem ) + dup 0 0 dev-generate-srplun swap x! ( devarray devcur ndev mem ) + rot x! ( devarray ndev ) + 1 + + UNLOOP EXIT + THEN THEN LOOP nip