diff options
Diffstat (limited to 'drivers/scsi/ses.c')
-rw-r--r-- | drivers/scsi/ses.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index dcb0d76d7312..044d06410d4c 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char *dest_desc, | |||
84 | static int ses_recv_diag(struct scsi_device *sdev, int page_code, | 84 | static int ses_recv_diag(struct scsi_device *sdev, int page_code, |
85 | void *buf, int bufflen) | 85 | void *buf, int bufflen) |
86 | { | 86 | { |
87 | int ret; | ||
87 | unsigned char cmd[] = { | 88 | unsigned char cmd[] = { |
88 | RECEIVE_DIAGNOSTIC, | 89 | RECEIVE_DIAGNOSTIC, |
89 | 1, /* Set PCV bit */ | 90 | 1, /* Set PCV bit */ |
@@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code, | |||
92 | bufflen & 0xff, | 93 | bufflen & 0xff, |
93 | 0 | 94 | 0 |
94 | }; | 95 | }; |
96 | unsigned char recv_page_code; | ||
95 | 97 | ||
96 | return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, | 98 | ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, |
97 | NULL, SES_TIMEOUT, SES_RETRIES, NULL); | 99 | NULL, SES_TIMEOUT, SES_RETRIES, NULL); |
100 | if (unlikely(!ret)) | ||
101 | return ret; | ||
102 | |||
103 | recv_page_code = ((unsigned char *)buf)[0]; | ||
104 | |||
105 | if (likely(recv_page_code == page_code)) | ||
106 | return ret; | ||
107 | |||
108 | /* successful diagnostic but wrong page code. This happens to some | ||
109 | * USB devices, just print a message and pretend there was an error */ | ||
110 | |||
111 | sdev_printk(KERN_ERR, sdev, | ||
112 | "Wrong diagnostic page; asked for %d got %u\n", | ||
113 | page_code, recv_page_code); | ||
114 | |||
115 | return -EINVAL; | ||
98 | } | 116 | } |
99 | 117 | ||
100 | static int ses_send_diag(struct scsi_device *sdev, int page_code, | 118 | 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, | |||
541 | if (desc_ptr) | 559 | if (desc_ptr) |
542 | desc_ptr += len; | 560 | desc_ptr += len; |
543 | 561 | ||
544 | if (addl_desc_ptr) | 562 | if (addl_desc_ptr && |
563 | /* only find additional descriptions for specific devices */ | ||
564 | (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || | ||
565 | type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE || | ||
566 | type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER || | ||
567 | /* these elements are optional */ | ||
568 | type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT || | ||
569 | type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT || | ||
570 | type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) | ||
545 | addl_desc_ptr += addl_desc_ptr[1] + 2; | 571 | addl_desc_ptr += addl_desc_ptr[1] + 2; |
546 | 572 | ||
547 | } | 573 | } |