|
@@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char *dest_desc,
|
|
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
|
|
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
|
|
void *buf, int bufflen)
|
|
void *buf, int bufflen)
|
|
{
|
|
{
|
|
|
|
+ int ret;
|
|
unsigned char cmd[] = {
|
|
unsigned char cmd[] = {
|
|
RECEIVE_DIAGNOSTIC,
|
|
RECEIVE_DIAGNOSTIC,
|
|
1, /* Set PCV bit */
|
|
1, /* Set PCV bit */
|
|
@@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
|
|
bufflen & 0xff,
|
|
bufflen & 0xff,
|
|
0
|
|
0
|
|
};
|
|
};
|
|
|
|
+ unsigned char recv_page_code;
|
|
|
|
|
|
- return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
|
|
|
|
|
|
+ ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
|
|
NULL, SES_TIMEOUT, SES_RETRIES, NULL);
|
|
NULL, SES_TIMEOUT, SES_RETRIES, NULL);
|
|
|
|
+ if (unlikely(!ret))
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ recv_page_code = ((unsigned char *)buf)[0];
|
|
|
|
+
|
|
|
|
+ if (likely(recv_page_code == page_code))
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ /* successful diagnostic but wrong page code. This happens to some
|
|
|
|
+ * USB devices, just print a message and pretend there was an error */
|
|
|
|
+
|
|
|
|
+ sdev_printk(KERN_ERR, sdev,
|
|
|
|
+ "Wrong diagnostic page; asked for %d got %u\n",
|
|
|
|
+ page_code, recv_page_code);
|
|
|
|
+
|
|
|
|
+ return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
static int ses_send_diag(struct scsi_device *sdev, int page_code,
|
|
static int ses_send_diag(struct scsi_device *sdev, int page_code,
|
|
@@ -541,7 +559,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
|
|
if (desc_ptr)
|
|
if (desc_ptr)
|
|
desc_ptr += len;
|
|
desc_ptr += len;
|
|
|
|
|
|
- if (addl_desc_ptr)
|
|
|
|
|
|
+ if (addl_desc_ptr &&
|
|
|
|
+ /* only find additional descriptions for specific devices */
|
|
|
|
+ (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
|
|
|
|
+ type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
|
|
|
|
+ type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
|
|
|
|
+ /* these elements are optional */
|
|
|
|
+ type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
|
|
|
|
+ type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
|
|
|
|
+ type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
|
|
addl_desc_ptr += addl_desc_ptr[1] + 2;
|
|
addl_desc_ptr += addl_desc_ptr[1] + 2;
|
|
|
|
|
|
}
|
|
}
|