diff options
author | Jack Hammer <jack_hammer@adaptec.com> | 2006-01-31 13:17:55 -0500 |
---|---|---|
committer | James Bottomley <jejb@titanic.(none)> | 2006-01-31 15:43:18 -0500 |
commit | a5b3c86e4bfb5689d68932105d3fdd1477c9c281 (patch) | |
tree | b6de20e32d8bd79399ccb849b88968c16970d880 /drivers | |
parent | 2254c86db124a37057116ad20a8de7b8483b6f44 (diff) |
[SCSI] ServeRAID: prevent seeing DADSI devices
A critical thing the ServeRAID driver MUST do is hide the physical DASDI
devices from the OS. It does this by intercepting the INQUIRY commands.
In recent 2.6.15 testing, I discovered this to be failing.
The cause was the driver assuming that the INQUIRY response data was in a
simple single buffer, when it was actually a 1 element scatter gather list.
This patch makes ips always look at the correct data when examining an
INQUIRY response.
Signed-off-by: Jack Hammer <jack_hammer@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/ips.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 32d592befca6..86c546164da9 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -3499,6 +3499,7 @@ ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) | |||
3499 | int device_error; | 3499 | int device_error; |
3500 | uint32_t transfer_len; | 3500 | uint32_t transfer_len; |
3501 | IPS_DCDB_TABLE_TAPE *tapeDCDB; | 3501 | IPS_DCDB_TABLE_TAPE *tapeDCDB; |
3502 | IPS_SCSI_INQ_DATA inquiryData; | ||
3502 | 3503 | ||
3503 | METHOD_TRACE("ips_map_status", 1); | 3504 | METHOD_TRACE("ips_map_status", 1); |
3504 | 3505 | ||
@@ -3557,13 +3558,13 @@ ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp) | |||
3557 | errcode = DID_OK; | 3558 | errcode = DID_OK; |
3558 | 3559 | ||
3559 | /* Restrict access to physical DASD */ | 3560 | /* Restrict access to physical DASD */ |
3560 | if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && | 3561 | if (scb->scsi_cmd->cmnd[0] == INQUIRY) { |
3561 | ((((char *) scb->scsi_cmd-> | 3562 | ips_scmd_buf_read(scb->scsi_cmd, |
3562 | buffer)[0] & 0x1f) == TYPE_DISK)) { | 3563 | &inquiryData, sizeof (inquiryData)); |
3563 | /* underflow -- no error */ | 3564 | if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) { |
3564 | /* restrict access to physical DASD */ | 3565 | errcode = DID_TIME_OUT; |
3565 | errcode = DID_TIME_OUT; | 3566 | break; |
3566 | break; | 3567 | } |
3567 | } | 3568 | } |
3568 | } else | 3569 | } else |
3569 | errcode = DID_ERROR; | 3570 | errcode = DID_ERROR; |
@@ -4135,6 +4136,7 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) | |||
4135 | uint8_t basic_status; | 4136 | uint8_t basic_status; |
4136 | uint8_t ext_status; | 4137 | uint8_t ext_status; |
4137 | int errcode; | 4138 | int errcode; |
4139 | IPS_SCSI_INQ_DATA inquiryData; | ||
4138 | 4140 | ||
4139 | METHOD_TRACE("ips_chkstatus", 1); | 4141 | METHOD_TRACE("ips_chkstatus", 1); |
4140 | 4142 | ||
@@ -4255,11 +4257,11 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus) | |||
4255 | scb->scsi_cmd->result = errcode << 16; | 4257 | scb->scsi_cmd->result = errcode << 16; |
4256 | } else { /* bus == 0 */ | 4258 | } else { /* bus == 0 */ |
4257 | /* restrict access to physical drives */ | 4259 | /* restrict access to physical drives */ |
4258 | if ((scb->scsi_cmd->cmnd[0] == INQUIRY) && | 4260 | if (scb->scsi_cmd->cmnd[0] == INQUIRY) { |
4259 | ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == | 4261 | ips_scmd_buf_read(scb->scsi_cmd, |
4260 | TYPE_DISK)) { | 4262 | &inquiryData, sizeof (inquiryData)); |
4261 | 4263 | if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) | |
4262 | scb->scsi_cmd->result = DID_TIME_OUT << 16; | 4264 | scb->scsi_cmd->result = DID_TIME_OUT << 16; |
4263 | } | 4265 | } |
4264 | } /* else */ | 4266 | } /* else */ |
4265 | } else { /* recovered error / success */ | 4267 | } else { /* recovered error / success */ |