Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb...
[deliverable/linux.git] / drivers / staging / keucr / transport.c
CommitLineData
871f8477
CYC
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
126bb03b
AC
3#include <linux/sched.h>
4#include <linux/errno.h>
5#include <linux/slab.h>
6
7#include <scsi/scsi.h>
8#include <scsi/scsi_eh.h>
9#include <scsi/scsi_device.h>
10
11#include "usb.h"
12#include "scsiglue.h"
13#include "transport.h"
14
15/***********************************************************************
16 * Data transfer routines
17 ***********************************************************************/
3aa4fc58
CYC
18/*
19 * usb_stor_blocking_completion()
20 */
126bb03b
AC
21static void usb_stor_blocking_completion(struct urb *urb)
22{
23 struct completion *urb_done_ptr = urb->context;
24
871f8477 25 /* pr_info("transport --- usb_stor_blocking_completion\n"); */
126bb03b
AC
26 complete(urb_done_ptr);
27}
28
3aa4fc58
CYC
29/*
30 * usb_stor_msg_common()
31 */
126bb03b
AC
32static int usb_stor_msg_common(struct us_data *us, int timeout)
33{
34 struct completion urb_done;
35 long timeleft;
36 int status;
37
871f8477 38 /* pr_info("transport --- usb_stor_msg_common\n"); */
126bb03b
AC
39 if (test_bit(US_FLIDX_ABORTING, &us->dflags))
40 return -EIO;
41
42 init_completion(&urb_done);
43
44 us->current_urb->context = &urb_done;
45 us->current_urb->actual_length = 0;
46 us->current_urb->error_count = 0;
47 us->current_urb->status = 0;
48
307ae1d3 49 us->current_urb->transfer_flags = 0;
126bb03b
AC
50 if (us->current_urb->transfer_buffer == us->iobuf)
51 us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
52 us->current_urb->transfer_dma = us->iobuf_dma;
53 us->current_urb->setup_dma = us->cr_dma;
54
55 status = usb_submit_urb(us->current_urb, GFP_NOIO);
56 if (status)
57 return status;
58
59 set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
60
3aa4fc58
CYC
61 if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
62 if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
871f8477 63 /* pr_info("-- cancelling URB\n"); */
126bb03b
AC
64 usb_unlink_urb(us->current_urb);
65 }
66 }
67
3aa4fc58
CYC
68 timeleft = wait_for_completion_interruptible_timeout(&urb_done,
69 timeout ? : MAX_SCHEDULE_TIMEOUT);
126bb03b
AC
70 clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
71
3aa4fc58 72 if (timeleft <= 0) {
871f8477
CYC
73 /* pr_info("%s -- cancelling URB\n",
74 timeleft == 0 ? "Timeout" : "Signal"); */
126bb03b
AC
75 usb_kill_urb(us->current_urb);
76 }
77
78 return us->current_urb->status;
79}
80
eecb3c07
LL
81/*
82 * usb_stor_print_cmd():
83 */
84static void usb_stor_print_cmd(struct us_data *us, struct scsi_cmnd *srb)
85{
432f8574
HS
86 u8 *Cdb = srb->cmnd;
87 u32 cmd = Cdb[0];
eecb3c07
LL
88
89 switch (cmd) {
90 case TEST_UNIT_READY:
eecb3c07
LL
91 break;
92 case INQUIRY:
0ea8a165
JS
93 dev_dbg(&us->pusb_dev->dev,
94 "scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
eecb3c07
LL
95 break;
96 case MODE_SENSE:
0ea8a165
JS
97 dev_dbg(&us->pusb_dev->dev,
98 "scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
eecb3c07
LL
99 break;
100 case START_STOP:
0ea8a165
JS
101 dev_dbg(&us->pusb_dev->dev,
102 "scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
eecb3c07
LL
103 break;
104 case READ_CAPACITY:
0ea8a165
JS
105 dev_dbg(&us->pusb_dev->dev,
106 "scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
eecb3c07
LL
107 break;
108 case READ_10:
eecb3c07
LL
109 break;
110 case WRITE_10:
eecb3c07
LL
111 break;
112 case ALLOW_MEDIUM_REMOVAL:
0ea8a165
JS
113 dev_dbg(&us->pusb_dev->dev,
114 "scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
eecb3c07
LL
115 break;
116 default:
117 dev_dbg(&us->pusb_dev->dev, "scsi cmd %X --- Other cmd\n", cmd);
118 break;
119 }
eecb3c07
LL
120}
121
3aa4fc58
CYC
122/*
123 * usb_stor_control_msg()
124 */
126bb03b
AC
125int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
126 u8 request, u8 requesttype, u16 value, u16 index,
127 void *data, u16 size, int timeout)
128{
129 int status;
130
871f8477 131 /* pr_info("transport --- usb_stor_control_msg\n"); */
126bb03b
AC
132
133 /* fill in the devrequest structure */
134 us->cr->bRequestType = requesttype;
135 us->cr->bRequest = request;
136 us->cr->wValue = cpu_to_le16(value);
137 us->cr->wIndex = cpu_to_le16(index);
138 us->cr->wLength = cpu_to_le16(size);
139
140 /* fill and submit the URB */
141 usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
3aa4fc58 142 (unsigned char *) us->cr, data, size,
126bb03b
AC
143 usb_stor_blocking_completion, NULL);
144 status = usb_stor_msg_common(us, timeout);
145
146 /* return the actual length of the data transferred if no error */
147 if (status == 0)
148 status = us->current_urb->actual_length;
149 return status;
150}
151
3aa4fc58
CYC
152/*
153 * usb_stor_clear_halt()
154 */
126bb03b
AC
155int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
156{
157 int result;
158 int endp = usb_pipeendpoint(pipe);
159
871f8477 160 /* pr_info("transport --- usb_stor_clear_halt\n"); */
3aa4fc58 161 if (usb_pipein(pipe))
126bb03b
AC
162 endp |= USB_DIR_IN;
163
164 result = usb_stor_control_msg(us, us->send_ctrl_pipe,
165 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
166 USB_ENDPOINT_HALT, endp,
167 NULL, 0, 3*HZ);
168
169 /* reset the endpoint toggle */
170 if (result >= 0)
3aa4fc58
CYC
171 /* usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
172 usb_pipeout(pipe), 0); */
173 usb_reset_endpoint(us->pusb_dev, endp);
126bb03b
AC
174
175 return result;
176}
177
3aa4fc58
CYC
178/*
179 * interpret_urb_result()
180 */
126bb03b
AC
181static int interpret_urb_result(struct us_data *us, unsigned int pipe,
182 unsigned int length, int result, unsigned int partial)
183{
871f8477 184 /* pr_info("transport --- interpret_urb_result\n"); */
126bb03b
AC
185 switch (result) {
186 /* no error code; did we send all the data? */
187 case 0:
3aa4fc58 188 if (partial != length) {
871f8477 189 /* pr_info("-- short transfer\n"); */
126bb03b
AC
190 return USB_STOR_XFER_SHORT;
191 }
871f8477 192 /* pr_info("-- transfer complete\n"); */
126bb03b
AC
193 return USB_STOR_XFER_GOOD;
194 case -EPIPE:
3aa4fc58 195 if (usb_pipecontrol(pipe)) {
871f8477 196 /* pr_info("-- stall on control pipe\n"); */
126bb03b
AC
197 return USB_STOR_XFER_STALLED;
198 }
871f8477 199 /* pr_info("clearing endpoint halt for pipe 0x%x\n", pipe); */
126bb03b
AC
200 if (usb_stor_clear_halt(us, pipe) < 0)
201 return USB_STOR_XFER_ERROR;
202 return USB_STOR_XFER_STALLED;
203 case -EOVERFLOW:
871f8477 204 /* pr_info("-- babble\n"); */
126bb03b
AC
205 return USB_STOR_XFER_LONG;
206 case -ECONNRESET:
871f8477 207 /* pr_info("-- transfer cancelled\n"); */
126bb03b
AC
208 return USB_STOR_XFER_ERROR;
209 case -EREMOTEIO:
871f8477 210 /* pr_info("-- short read transfer\n"); */
126bb03b
AC
211 return USB_STOR_XFER_SHORT;
212 case -EIO:
871f8477 213 /* pr_info("-- abort or disconnect in progress\n"); */
126bb03b
AC
214 return USB_STOR_XFER_ERROR;
215 default:
871f8477 216 /* pr_info("-- unknown error\n"); */
126bb03b
AC
217 return USB_STOR_XFER_ERROR;
218 }
219}
220
3aa4fc58
CYC
221/*
222 * usb_stor_bulk_transfer_buf()
223 */
126bb03b
AC
224int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
225 void *buf, unsigned int length, unsigned int *act_len)
226{
227 int result;
228
871f8477 229 /* pr_info("transport --- usb_stor_bulk_transfer_buf\n"); */
126bb03b
AC
230
231 /* fill and submit the URB */
3aa4fc58
CYC
232 usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf,
233 length, usb_stor_blocking_completion, NULL);
126bb03b
AC
234 result = usb_stor_msg_common(us, 0);
235
236 /* store the actual length of the data transferred */
237 if (act_len)
238 *act_len = us->current_urb->actual_length;
239
3aa4fc58
CYC
240 return interpret_urb_result(us, pipe, length, result,
241 us->current_urb->actual_length);
126bb03b
AC
242}
243
3aa4fc58
CYC
244/*
245 * usb_stor_bulk_transfer_sglist()
246 */
126bb03b
AC
247static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
248 struct scatterlist *sg, int num_sg, unsigned int length,
249 unsigned int *act_len)
250{
251 int result;
252
871f8477 253 /* pr_info("transport --- usb_stor_bulk_transfer_sglist\n"); */
126bb03b
AC
254 if (test_bit(US_FLIDX_ABORTING, &us->dflags))
255 return USB_STOR_XFER_ERROR;
256
257 /* initialize the scatter-gather request block */
3aa4fc58
CYC
258 result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
259 sg, num_sg, length, GFP_NOIO);
260 if (result) {
871f8477 261 /* pr_info("usb_sg_init returned %d\n", result); */
126bb03b
AC
262 return USB_STOR_XFER_ERROR;
263 }
264
3aa4fc58
CYC
265 /* since the block has been initialized successfully,
266 it's now okay to cancel it */
126bb03b
AC
267 set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
268
269 /* did an abort/disconnect occur during the submission? */
3aa4fc58 270 if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
126bb03b 271 /* cancel the request, if it hasn't been cancelled already */
3aa4fc58 272 if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
871f8477 273 /* pr_info("-- cancelling sg request\n"); */
126bb03b
AC
274 usb_sg_cancel(&us->current_sg);
275 }
276 }
277
278 /* wait for the completion of the transfer */
279 usb_sg_wait(&us->current_sg);
280 clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
281
282 result = us->current_sg.status;
283 if (act_len)
284 *act_len = us->current_sg.bytes;
285
3aa4fc58
CYC
286 return interpret_urb_result(us, pipe, length,
287 result, us->current_sg.bytes);
126bb03b
AC
288}
289
3aa4fc58
CYC
290/*
291 * usb_stor_bulk_srb()
292 */
293int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
294 struct scsi_cmnd *srb)
126bb03b
AC
295{
296 unsigned int partial;
297 int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
298 scsi_sg_count(srb), scsi_bufflen(srb),
299 &partial);
300
301 scsi_set_resid(srb, scsi_bufflen(srb) - partial);
302 return result;
303}
304
3aa4fc58
CYC
305/*
306 * usb_stor_bulk_transfer_sg()
307 */
308int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
126bb03b
AC
309 void *buf, unsigned int length_left, int use_sg, int *residual)
310{
311 int result;
312 unsigned int partial;
313
871f8477 314 /* pr_info("transport --- usb_stor_bulk_transfer_sg\n"); */
126bb03b 315 /* are we scatter-gathering? */
3aa4fc58 316 if (use_sg) {
126bb03b
AC
317 /* use the usb core scatter-gather primitives */
318 result = usb_stor_bulk_transfer_sglist(us, pipe,
319 (struct scatterlist *) buf, use_sg,
320 length_left, &partial);
321 length_left -= partial;
3aa4fc58 322 } else {
126bb03b 323 /* no scatter-gather, just make the request */
3aa4fc58
CYC
324 result = usb_stor_bulk_transfer_buf(us, pipe, buf,
325 length_left, &partial);
126bb03b
AC
326 length_left -= partial;
327 }
328
329 /* store the residual and return the error code */
330 if (residual)
331 *residual = length_left;
332 return result;
333}
334
335/***********************************************************************
336 * Transport routines
337 ***********************************************************************/
3aa4fc58
CYC
338/*
339 * usb_stor_invoke_transport()
340 */
126bb03b
AC
341void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
342{
343 int need_auto_sense;
344 int result;
345
871f8477 346 /* pr_info("transport --- usb_stor_invoke_transport\n"); */
29b31420 347 usb_stor_print_cmd(us, srb);
126bb03b
AC
348 /* send the command to the transport layer */
349 scsi_set_resid(srb, 0);
3aa4fc58
CYC
350 result = us->transport(srb, us); /* usb_stor_Bulk_transport; */
351
352 /* if the command gets aborted by the higher layers,
353 we need to short-circuit all other processing */
354 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
871f8477 355 /* pr_info("-- command was aborted\n"); */
126bb03b
AC
356 srb->result = DID_ABORT << 16;
357 goto Handle_Errors;
358 }
359
360 /* if there is a transport error, reset and don't auto-sense */
3aa4fc58 361 if (result == USB_STOR_TRANSPORT_ERROR) {
871f8477 362 /* pr_info("-- transport indicates error, resetting\n"); */
126bb03b
AC
363 srb->result = DID_ERROR << 16;
364 goto Handle_Errors;
365 }
366
367 /* if the transport provided its own sense data, don't auto-sense */
3aa4fc58 368 if (result == USB_STOR_TRANSPORT_NO_SENSE) {
126bb03b
AC
369 srb->result = SAM_STAT_CHECK_CONDITION;
370 return;
371 }
372
373 srb->result = SAM_STAT_GOOD;
374
375 /* Determine if we need to auto-sense */
376 need_auto_sense = 0;
377
3aa4fc58
CYC
378 if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
379 srb->sc_data_direction != DMA_FROM_DEVICE) {
871f8477 380 /* pr_info("-- CB transport device requiring auto-sense\n"); */
126bb03b
AC
381 need_auto_sense = 1;
382 }
383
3aa4fc58 384 if (result == USB_STOR_TRANSPORT_FAILED) {
871f8477 385 /* pr_info("-- transport indicates command failure\n"); */
126bb03b
AC
386 need_auto_sense = 1;
387 }
388
389 /* Now, if we need to do the auto-sense, let's do it */
3aa4fc58 390 if (need_auto_sense) {
126bb03b
AC
391 int temp_result;
392 struct scsi_eh_save ses;
393
871f8477 394 pr_info("Issuing auto-REQUEST_SENSE\n");
126bb03b
AC
395
396 scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
397
398 /* we must do the protocol translation here */
3aa4fc58
CYC
399 if (us->subclass == USB_SC_RBC ||
400 us->subclass == USB_SC_SCSI ||
401 us->subclass == USB_SC_CYP_ATACB) {
126bb03b 402 srb->cmd_len = 6;
3aa4fc58 403 } else {
126bb03b 404 srb->cmd_len = 12;
3aa4fc58 405 }
126bb03b
AC
406 /* issue the auto-sense command */
407 scsi_set_resid(srb, 0);
408 temp_result = us->transport(us->srb, us);
409
410 /* let's clean up right away */
411 scsi_eh_restore_cmnd(srb, &ses);
412
3aa4fc58 413 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
871f8477 414 /* pr_info("-- auto-sense aborted\n"); */
126bb03b
AC
415 srb->result = DID_ABORT << 16;
416 goto Handle_Errors;
417 }
3aa4fc58 418 if (temp_result != USB_STOR_TRANSPORT_GOOD) {
871f8477 419 /* pr_info("-- auto-sense failure\n"); */
126bb03b
AC
420 srb->result = DID_ERROR << 16;
421 if (!(us->fflags & US_FL_SCM_MULT_TARG))
422 goto Handle_Errors;
423 return;
424 }
425
426 /* set the result so the higher layers expect this data */
427 srb->result = SAM_STAT_CHECK_CONDITION;
428
429 if (result == USB_STOR_TRANSPORT_GOOD &&
430 (srb->sense_buffer[2] & 0xaf) == 0 &&
431 srb->sense_buffer[12] == 0 &&
3aa4fc58 432 srb->sense_buffer[13] == 0) {
126bb03b
AC
433 srb->result = SAM_STAT_GOOD;
434 srb->sense_buffer[0] = 0x0;
435 }
436 }
437
438 /* Did we transfer less than the minimum amount required? */
3aa4fc58
CYC
439 if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
440 scsi_get_resid(srb) < srb->underflow)
441 srb->result = (DID_ERROR << 16);
442 /* v02 | (SUGGEST_RETRY << 24); */
126bb03b
AC
443
444 return;
445
446Handle_Errors:
447 scsi_lock(us_to_host(us));
448 set_bit(US_FLIDX_RESETTING, &us->dflags);
449 clear_bit(US_FLIDX_ABORTING, &us->dflags);
450 scsi_unlock(us_to_host(us));
451
452 mutex_unlock(&us->dev_mutex);
453 result = usb_stor_port_reset(us);
454 mutex_lock(&us->dev_mutex);
455
3aa4fc58 456 if (result < 0) {
126bb03b
AC
457 scsi_lock(us_to_host(us));
458 usb_stor_report_device_reset(us);
459 scsi_unlock(us_to_host(us));
460 us->transport_reset(us);
461 }
462 clear_bit(US_FLIDX_RESETTING, &us->dflags);
463}
464
3aa4fc58
CYC
465/*
466 * ENE_stor_invoke_transport()
467 */
126bb03b
AC
468void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
469{
3aa4fc58 470 int result = 0;
126bb03b 471
871f8477 472 /* pr_info("transport --- ENE_stor_invoke_transport\n"); */
29b31420 473 usb_stor_print_cmd(us, srb);
126bb03b
AC
474 /* send the command to the transport layer */
475 scsi_set_resid(srb, 0);
20c3d7f7 476 if (!(us->SM_Status.Ready))
126bb03b 477 result = ENE_InitMedia(us);
3aa4fc58 478
126bb03b
AC
479 if (us->Power_IsResum == true) {
480 result = ENE_InitMedia(us);
3aa4fc58
CYC
481 us->Power_IsResum = false;
482 }
483
3aa4fc58
CYC
484 if (us->SM_Status.Ready)
485 result = SM_SCSIIrp(us, srb);
486
487 /* if the command gets aborted by the higher layers,
488 we need to short-circuit all other processing */
489 if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
871f8477 490 /* pr_info("-- command was aborted\n"); */
126bb03b
AC
491 srb->result = DID_ABORT << 16;
492 goto Handle_Errors;
493 }
494
495 /* if there is a transport error, reset and don't auto-sense */
3aa4fc58 496 if (result == USB_STOR_TRANSPORT_ERROR) {
871f8477 497 /* pr_info("-- transport indicates error, resetting\n"); */
126bb03b
AC
498 srb->result = DID_ERROR << 16;
499 goto Handle_Errors;
500 }
501
502 /* if the transport provided its own sense data, don't auto-sense */
3aa4fc58 503 if (result == USB_STOR_TRANSPORT_NO_SENSE) {
126bb03b
AC
504 srb->result = SAM_STAT_CHECK_CONDITION;
505 return;
506 }
507
508 srb->result = SAM_STAT_GOOD;
3aa4fc58 509 if (result == USB_STOR_TRANSPORT_FAILED) {
871f8477 510 /* pr_info("-- transport indicates command failure\n"); */
3aa4fc58 511 /* need_auto_sense = 1; */
126bb03b
AC
512 BuildSenseBuffer(srb, us->SrbStatus);
513 srb->result = SAM_STAT_CHECK_CONDITION;
514 }
515
516 /* Did we transfer less than the minimum amount required? */
3aa4fc58
CYC
517 if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
518 scsi_get_resid(srb) < srb->underflow)
519 srb->result = (DID_ERROR << 16);
520 /* v02 | (SUGGEST_RETRY << 24); */
126bb03b
AC
521
522 return;
523
524Handle_Errors:
525 scsi_lock(us_to_host(us));
526 set_bit(US_FLIDX_RESETTING, &us->dflags);
527 clear_bit(US_FLIDX_ABORTING, &us->dflags);
528 scsi_unlock(us_to_host(us));
529
530 mutex_unlock(&us->dev_mutex);
531 result = usb_stor_port_reset(us);
532 mutex_lock(&us->dev_mutex);
533
3aa4fc58 534 if (result < 0) {
126bb03b
AC
535 scsi_lock(us_to_host(us));
536 usb_stor_report_device_reset(us);
537 scsi_unlock(us_to_host(us));
538 us->transport_reset(us);
539 }
540 clear_bit(US_FLIDX_RESETTING, &us->dflags);
541}
542
3aa4fc58
CYC
543/*
544 * BuildSenseBuffer()
545 */
126bb03b
AC
546void BuildSenseBuffer(struct scsi_cmnd *srb, int SrbStatus)
547{
432f8574
HS
548 u8 *buf = srb->sense_buffer;
549 u8 asc;
126bb03b 550
871f8477 551 pr_info("transport --- BuildSenseBuffer\n");
3aa4fc58
CYC
552 switch (SrbStatus) {
553 case SS_NOT_READY:
554 asc = 0x3a;
555 break; /* sense key = 0x02 */
556 case SS_MEDIUM_ERR:
557 asc = 0x0c;
558 break; /* sense key = 0x03 */
559 case SS_ILLEGAL_REQUEST:
560 asc = 0x20;
561 break; /* sense key = 0x05 */
562 default:
563 asc = 0x00;
564 break; /* ?? */
565 }
566
567 memset(buf, 0, 18);
568 buf[0x00] = 0xf0;
569 buf[0x02] = SrbStatus;
570 buf[0x07] = 0x0b;
571 buf[0x0c] = asc;
126bb03b
AC
572}
573
3aa4fc58
CYC
574/*
575 * usb_stor_stop_transport()
576 */
126bb03b
AC
577void usb_stor_stop_transport(struct us_data *us)
578{
871f8477 579 /* pr_info("transport --- usb_stor_stop_transport\n"); */
126bb03b 580
3aa4fc58 581 if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
871f8477 582 /* pr_info("-- cancelling URB\n"); */
126bb03b
AC
583 usb_unlink_urb(us->current_urb);
584 }
585
3aa4fc58 586 if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
871f8477 587 /* pr_info("-- cancelling sg request\n"); */
126bb03b
AC
588 usb_sg_cancel(&us->current_sg);
589 }
590}
591
3aa4fc58
CYC
592/*
593 * usb_stor_Bulk_max_lun()
594 */
126bb03b
AC
595int usb_stor_Bulk_max_lun(struct us_data *us)
596{
597 int result;
598
871f8477 599 /* pr_info("transport --- usb_stor_Bulk_max_lun\n"); */
126bb03b
AC
600 /* issue the command */
601 us->iobuf[0] = 0;
602 result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
603 US_BULK_GET_MAX_LUN,
604 USB_DIR_IN | USB_TYPE_CLASS |
605 USB_RECIP_INTERFACE,
606 0, us->ifnum, us->iobuf, 1, HZ);
607
871f8477
CYC
608 /* pr_info("GetMaxLUN command result is %d, data is %d\n",
609 result, us->iobuf[0]); */
126bb03b
AC
610
611 /* if we have a successful request, return the result */
612 if (result > 0)
613 return us->iobuf[0];
614
615 return 0;
616}
617
3aa4fc58
CYC
618/*
619 * usb_stor_Bulk_transport()
620 */
126bb03b
AC
621int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
622{
623 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
624 struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
625 unsigned int transfer_length = scsi_bufflen(srb);
626 unsigned int residue;
627 int result;
628 int fake_sense = 0;
629 unsigned int cswlen;
630 unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
631
871f8477 632 /* pr_info("transport --- usb_stor_Bulk_transport\n"); */
126bb03b 633 /* Take care of BULK32 devices; set extra byte to 0 */
3aa4fc58 634 if (unlikely(us->fflags & US_FL_BULK32)) {
126bb03b
AC
635 cbwlen = 32;
636 us->iobuf[31] = 0;
637 }
638
639 /* set up the command wrapper */
640 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
641 bcb->DataTransferLength = cpu_to_le32(transfer_length);
642 bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
643 bcb->Tag = ++us->tag;
644 bcb->Lun = srb->device->lun;
645 if (us->fflags & US_FL_SCM_MULT_TARG)
646 bcb->Lun |= srb->device->id << 4;
647 bcb->Length = srb->cmd_len;
648
649 /* copy the command payload */
650 memset(bcb->CDB, 0, sizeof(bcb->CDB));
651 memcpy(bcb->CDB, srb->cmnd, bcb->Length);
652
3aa4fc58 653 /* send command */
126bb03b 654 /* send it to out endpoint */
871f8477 655 /* pr_info("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
126bb03b
AC
656 le32_to_cpu(bcb->Signature), bcb->Tag,
657 le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
658 (bcb->Lun >> 4), (bcb->Lun & 0x0F),
871f8477 659 bcb->Length); */
3aa4fc58
CYC
660 result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
661 bcb, cbwlen, NULL);
871f8477 662 /* pr_info("Bulk command transfer result=%d\n", result); */
126bb03b
AC
663 if (result != USB_STOR_XFER_GOOD)
664 return USB_STOR_TRANSPORT_ERROR;
665
666 if (unlikely(us->fflags & US_FL_GO_SLOW))
667 udelay(125);
668
3aa4fc58
CYC
669 /* R/W data */
670 if (transfer_length) {
d48e5cff 671 unsigned int pipe;
8c4842d6 672
d48e5cff
CYC
673 if (srb->sc_data_direction == DMA_FROM_DEVICE)
674 pipe = us->recv_bulk_pipe;
675 else
676 pipe = us->send_bulk_pipe;
677
126bb03b 678 result = usb_stor_bulk_srb(us, pipe, srb);
871f8477 679 /* pr_info("Bulk data transfer result 0x%x\n", result); */
126bb03b
AC
680 if (result == USB_STOR_XFER_ERROR)
681 return USB_STOR_TRANSPORT_ERROR;
682
683 if (result == USB_STOR_XFER_LONG)
684 fake_sense = 1;
685 }
686
687 /* get CSW for device status */
871f8477 688 /* pr_info("Attempting to get CSW...\n"); */
3aa4fc58
CYC
689 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
690 US_BULK_CS_WRAP_LEN, &cswlen);
126bb03b 691
3aa4fc58 692 if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
871f8477 693 /* pr_info("Received 0-length CSW; retrying...\n"); */
3aa4fc58
CYC
694 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
695 US_BULK_CS_WRAP_LEN, &cswlen);
126bb03b
AC
696 }
697
698 /* did the attempt to read the CSW fail? */
3aa4fc58 699 if (result == USB_STOR_XFER_STALLED) {
126bb03b 700 /* get the status again */
871f8477 701 /* pr_info("Attempting to get CSW (2nd try)...\n"); */
3aa4fc58
CYC
702 result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
703 US_BULK_CS_WRAP_LEN, NULL);
126bb03b
AC
704 }
705
706 /* if we still have a failure at this point, we're in trouble */
871f8477 707 /* pr_info("Bulk status result = %d\n", result); */
126bb03b
AC
708 if (result != USB_STOR_XFER_GOOD)
709 return USB_STOR_TRANSPORT_ERROR;
710
711 /* check bulk status */
712 residue = le32_to_cpu(bcs->Residue);
871f8477
CYC
713 /* pr_info("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
714 le32_to_cpu(bcs->Signature),
715 bcs->Tag, residue, bcs->Status); */
3aa4fc58
CYC
716 if (!(bcs->Tag == us->tag ||
717 (us->fflags & US_FL_BULK_IGNORE_TAG)) ||
718 bcs->Status > US_BULK_STAT_PHASE) {
871f8477 719 /* pr_info("Bulk logical error\n"); */
126bb03b
AC
720 return USB_STOR_TRANSPORT_ERROR;
721 }
722
3aa4fc58 723 if (!us->bcs_signature) {
126bb03b 724 us->bcs_signature = bcs->Signature;
3aa4fc58 725 /* if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) */
871f8477
CYC
726 /* pr_info("Learnt BCS signature 0x%08X\n",
727 le32_to_cpu(us->bcs_signature)); */
3aa4fc58 728 } else if (bcs->Signature != us->bcs_signature) {
871f8477 729 /* pr_info("Signature mismatch: got %08X, expecting %08X\n",
126bb03b 730 le32_to_cpu(bcs->Signature),
871f8477 731 le32_to_cpu(us->bcs_signature)); */
126bb03b
AC
732 return USB_STOR_TRANSPORT_ERROR;
733 }
734
735 /* try to compute the actual residue, based on how much data
736 * was really transferred and what the device tells us */
3aa4fc58 737 if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
126bb03b
AC
738
739 /* Heuristically detect devices that generate bogus residues
740 * by seeing what happens with INQUIRY and READ CAPACITY
741 * commands.
742 */
743 if (bcs->Status == US_BULK_STAT_OK &&
744 scsi_get_resid(srb) == 0 &&
745 ((srb->cmnd[0] == INQUIRY &&
746 transfer_length == 36) ||
747 (srb->cmnd[0] == READ_CAPACITY &&
3aa4fc58 748 transfer_length == 8))) {
126bb03b
AC
749 us->fflags |= US_FL_IGNORE_RESIDUE;
750
3aa4fc58 751 } else {
126bb03b 752 residue = min(residue, transfer_length);
3fb91d11
JS
753 scsi_set_resid(srb, max_t(int, scsi_get_resid(srb),
754 residue));
126bb03b
AC
755 }
756 }
757
758 /* based on the status code, we report good or bad */
3aa4fc58
CYC
759 switch (bcs->Status) {
760 case US_BULK_STAT_OK:
761 if (fake_sense) {
762 memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
763 sizeof(usb_stor_sense_invalidCDB));
764 return USB_STOR_TRANSPORT_NO_SENSE;
765 }
766 return USB_STOR_TRANSPORT_GOOD;
767
768 case US_BULK_STAT_FAIL:
769 return USB_STOR_TRANSPORT_FAILED;
770
771 case US_BULK_STAT_PHASE:
772 return USB_STOR_TRANSPORT_ERROR;
126bb03b
AC
773 }
774 return USB_STOR_TRANSPORT_ERROR;
775}
776
777/***********************************************************************
778 * Reset routines
779 ***********************************************************************/
3aa4fc58
CYC
780/*
781 * usb_stor_reset_common()
782 */
126bb03b
AC
783static int usb_stor_reset_common(struct us_data *us,
784 u8 request, u8 requesttype,
785 u16 value, u16 index, void *data, u16 size)
786{
787 int result;
788 int result2;
789
871f8477 790 /* pr_info("transport --- usb_stor_reset_common\n"); */
3aa4fc58 791 if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
871f8477 792 /* pr_info("No reset during disconnect\n"); */
126bb03b
AC
793 return -EIO;
794 }
795
3aa4fc58
CYC
796 result = usb_stor_control_msg(us, us->send_ctrl_pipe,
797 request, requesttype, value, index, data, size, 5*HZ);
798
799 if (result < 0) {
871f8477 800 /* pr_info("Soft reset failed: %d\n", result); */
126bb03b
AC
801 return result;
802 }
803
3aa4fc58
CYC
804 wait_event_interruptible_timeout(us->delay_wait,
805 test_bit(US_FLIDX_DISCONNECTING, &us->dflags), HZ*6);
806
807 if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
871f8477 808 /* pr_info("Reset interrupted by disconnect\n"); */
126bb03b
AC
809 return -EIO;
810 }
811
871f8477 812 /* pr_info("Soft reset: clearing bulk-in endpoint halt\n"); */
126bb03b
AC
813 result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
814
871f8477 815 /* pr_info("Soft reset: clearing bulk-out endpoint halt\n"); */
126bb03b
AC
816 result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);
817
818 /* return a result code based on the result of the clear-halts */
819 if (result >= 0)
820 result = result2;
3aa4fc58 821 /* if (result < 0) */
871f8477 822 /* pr_info("Soft reset failed\n"); */
3aa4fc58 823 /* else */
871f8477 824 /* pr_info("Soft reset done\n"); */
126bb03b
AC
825 return result;
826}
827
3aa4fc58
CYC
828/*
829 * usb_stor_Bulk_reset()
830 */
126bb03b
AC
831int usb_stor_Bulk_reset(struct us_data *us)
832{
871f8477 833 /* pr_info("transport --- usb_stor_Bulk_reset\n"); */
126bb03b
AC
834 return usb_stor_reset_common(us, US_BULK_RESET_REQUEST,
835 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
836 0, us->ifnum, NULL, 0);
837}
838
3aa4fc58
CYC
839/*
840 * usb_stor_port_reset()
841 */
126bb03b
AC
842int usb_stor_port_reset(struct us_data *us)
843{
a200adb1 844 int result;
126bb03b 845
871f8477 846 /* pr_info("transport --- usb_stor_port_reset\n"); */
e1049604 847 result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
126bb03b 848 if (result < 0)
871f8477 849 pr_info("unable to lock device for reset: %d\n", result);
e1049604 850 else {
126bb03b 851 /* Were we disconnected while waiting for the lock? */
e1049604 852 if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
126bb03b 853 result = -EIO;
871f8477 854 /* pr_info("No reset during disconnect\n"); */
e1049604 855 } else {
126bb03b 856 result = usb_reset_device(us->pusb_dev);
871f8477
CYC
857 /* pr_info("usb_reset_composite_device returns %d\n",
858 result); */
126bb03b 859 }
e1049604 860 usb_unlock_device(us->pusb_dev);
126bb03b
AC
861 }
862 return result;
863}
864
865
This page took 0.374704 seconds and 5 git commands to generate.