diff options
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/storage/uas.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 9ff9404f99d7..44b096c1737b 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
| @@ -246,6 +246,29 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
| 246 | } | 246 | } |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | static bool uas_evaluate_response_iu(struct response_iu *riu, struct scsi_cmnd *cmnd) | ||
| 250 | { | ||
| 251 | u8 response_code = riu->response_code; | ||
| 252 | |||
| 253 | switch (response_code) { | ||
| 254 | case RC_INCORRECT_LUN: | ||
| 255 | cmnd->result = DID_BAD_TARGET << 16; | ||
| 256 | break; | ||
| 257 | case RC_TMF_SUCCEEDED: | ||
| 258 | cmnd->result = DID_OK << 16; | ||
| 259 | break; | ||
| 260 | case RC_TMF_NOT_SUPPORTED: | ||
| 261 | cmnd->result = DID_TARGET_FAILURE << 16; | ||
| 262 | break; | ||
| 263 | default: | ||
| 264 | uas_log_cmd_state(cmnd, "response iu", response_code); | ||
| 265 | cmnd->result = DID_ERROR << 16; | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | |||
| 269 | return response_code == RC_TMF_SUCCEEDED; | ||
| 270 | } | ||
| 271 | |||
| 249 | static void uas_stat_cmplt(struct urb *urb) | 272 | static void uas_stat_cmplt(struct urb *urb) |
| 250 | { | 273 | { |
| 251 | struct iu *iu = urb->transfer_buffer; | 274 | struct iu *iu = urb->transfer_buffer; |
| @@ -258,6 +281,7 @@ static void uas_stat_cmplt(struct urb *urb) | |||
| 258 | unsigned long flags; | 281 | unsigned long flags; |
| 259 | unsigned int idx; | 282 | unsigned int idx; |
| 260 | int status = urb->status; | 283 | int status = urb->status; |
| 284 | bool success; | ||
| 261 | 285 | ||
| 262 | spin_lock_irqsave(&devinfo->lock, flags); | 286 | spin_lock_irqsave(&devinfo->lock, flags); |
| 263 | 287 | ||
| @@ -313,13 +337,13 @@ static void uas_stat_cmplt(struct urb *urb) | |||
| 313 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); | 337 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); |
| 314 | break; | 338 | break; |
| 315 | case IU_ID_RESPONSE: | 339 | case IU_ID_RESPONSE: |
| 316 | uas_log_cmd_state(cmnd, "unexpected response iu", | ||
| 317 | ((struct response_iu *)iu)->response_code); | ||
| 318 | /* Error, cancel data transfers */ | ||
| 319 | data_in_urb = usb_get_urb(cmdinfo->data_in_urb); | ||
| 320 | data_out_urb = usb_get_urb(cmdinfo->data_out_urb); | ||
| 321 | cmdinfo->state &= ~COMMAND_INFLIGHT; | 340 | cmdinfo->state &= ~COMMAND_INFLIGHT; |
| 322 | cmnd->result = DID_ERROR << 16; | 341 | success = uas_evaluate_response_iu((struct response_iu *)iu, cmnd); |
| 342 | if (!success) { | ||
| 343 | /* Error, cancel data transfers */ | ||
| 344 | data_in_urb = usb_get_urb(cmdinfo->data_in_urb); | ||
| 345 | data_out_urb = usb_get_urb(cmdinfo->data_out_urb); | ||
| 346 | } | ||
| 323 | uas_try_complete(cmnd, __func__); | 347 | uas_try_complete(cmnd, __func__); |
| 324 | break; | 348 | break; |
| 325 | default: | 349 | default: |
