Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[scsi] Cope with targets that send multiple CHECK CONDITIONS at power-on
Some targets send a spurious CHECK CONDITION message in response to
the first SCSI command.  We issue (and ignore the status of) an
arbitary harmless SCSI command (a READ CAPACITY (10)) in order to draw
out this response.

The Solaris Comstar target seems to send more than one spurious CHECK
CONDITION response.  Attempt up to SCSI_MAX_DUMMY_READ_CAP dummy READ
CAPACITY (10) commands before assuming that error responses are
meaningful.

Problem reported by Kristof Van Doorsselaere <kvandoor@aserver.com>
and Shiva Shankar <802.11e@gmail.com>.
  • Loading branch information
Michael Brown committed Jan 30, 2009
1 parent 52c596b commit b111bdf
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions src/drivers/block/scsi.c
Expand Up @@ -29,6 +29,13 @@
*
*/

/** Maximum number of dummy "read capacity (10)" operations
*
* These are issued at connection setup to draw out various useless
* power-on messages.
*/
#define SCSI_MAX_DUMMY_READ_CAP 10

static inline __attribute__ (( always_inline )) struct scsi_device *
block_to_scsi ( struct block_device *blockdev ) {
return container_of ( blockdev, struct scsi_device, blockdev );
Expand Down Expand Up @@ -250,14 +257,21 @@ static struct block_device_operations scsi_operations_10 = {
* CAPACITY call to determine the block size and total device size.
*/
int init_scsidev ( struct scsi_device *scsi ) {
unsigned int i;
int rc;

/* Issue a theoretically extraneous READ CAPACITY (10)
* command, solely in order to draw out the "CHECK CONDITION
* (power-on occurred)" that some dumb targets insist on
* sending as an error at start of day.
/* Issue some theoretically extraneous READ CAPACITY (10)
* commands, solely in order to draw out the "CHECK CONDITION
* (power-on occurred)", "CHECK CONDITION (reported LUNs data
* has changed)" etc. that some dumb targets insist on sending
* as an error at start of day. The precise command that we
* use is unimportant; we just need to provide the target with
* an opportunity to send its responses.
*/
scsi_read_capacity_10 ( &scsi->blockdev );
for ( i = 0 ; i < SCSI_MAX_DUMMY_READ_CAP ; i++ ) {
if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) == 0 )
break;
}

/* Try READ CAPACITY (10), which is a mandatory command, first. */
scsi->blockdev.op = &scsi_operations_10;
Expand Down

0 comments on commit b111bdf

Please sign in to comment.