diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 06:23:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 06:23:15 -0400 |
commit | 1be025d3cb40cd295123af2c394f7229ef9b30ca (patch) | |
tree | 5dc14e1ea412cc7fdc3e563ad23187059fe8bfb5 /drivers/usb/storage | |
parent | 2d03423b2319cc854adeb28a03f65de5b5e0ab63 (diff) | |
parent | a2c76b83fdd763c826f38a55127ccf25708099ce (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (260 commits)
usb: renesas_usbhs: fixup inconsistent return from usbhs_pkt_push()
usb/isp1760: Allow to optionally trigger low-level chip reset via GPIOLIB.
USB: gadget: midi: memory leak in f_midi_bind_config()
USB: gadget: midi: fix range check in f_midi_out_open()
QE/FHCI: fixed the CONTROL bug
usb: renesas_usbhs: tidyup for smatch warnings
USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms
EHCI: workaround for MosChip controller bug
usb: gadget: file_storage: fix race on unloading
USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers
USB: ftdi_sio.c:Fill MSR fields of the ftdi async_icount structure
USB: ftdi_sio.c: Fill LSR fields of the ftdi async_icount structure
USB: ftdi_sio.c:Fill TX field of the ftdi async_icount structure
USB: ftdi_sio.c: Fill the RX field of the ftdi async_icount structure
USB: ftdi_sio.c: Basic icount infrastructure for ftdi_sio
usb/isp1760: Let OF bindings depend on general CONFIG_OF instead of PPC_OF .
USB: ftdi_sio: Support TI/Luminary Micro Stellaris BD-ICDI Board
USB: Fix runtime wakeup on OHCI
xHCI/USB: Make xHCI driver have a BOS descriptor.
usb: gadget: add new usb gadget for ACM and mass storage
...
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/storage/realtek_cr.c | 116 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 34 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 16 |
4 files changed, 140 insertions, 28 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index bedc4b9f2ac4..fe2d803a6347 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -42,7 +42,7 @@ config USB_STORAGE_REALTEK | |||
42 | 42 | ||
43 | config REALTEK_AUTOPM | 43 | config REALTEK_AUTOPM |
44 | bool "Realtek Card Reader autosuspend support" | 44 | bool "Realtek Card Reader autosuspend support" |
45 | depends on USB_STORAGE_REALTEK && CONFIG_PM_RUNTIME | 45 | depends on USB_STORAGE_REALTEK && PM_RUNTIME |
46 | default y | 46 | default y |
47 | 47 | ||
48 | config USB_STORAGE_DATAFAB | 48 | config USB_STORAGE_DATAFAB |
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 6fd13068481b..0ce5f79197e7 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c | |||
@@ -292,6 +292,52 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, | |||
292 | return USB_STOR_TRANSPORT_ERROR; | 292 | return USB_STOR_TRANSPORT_ERROR; |
293 | } | 293 | } |
294 | 294 | ||
295 | static int rts51x_bulk_transport_special(struct us_data *us, u8 lun, | ||
296 | u8 *cmd, int cmd_len, u8 *buf, int buf_len, | ||
297 | enum dma_data_direction dir, int *act_len) | ||
298 | { | ||
299 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; | ||
300 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; | ||
301 | int result; | ||
302 | unsigned int cswlen; | ||
303 | unsigned int cbwlen = US_BULK_CB_WRAP_LEN; | ||
304 | |||
305 | /* set up the command wrapper */ | ||
306 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); | ||
307 | bcb->DataTransferLength = cpu_to_le32(buf_len); | ||
308 | bcb->Flags = (dir == DMA_FROM_DEVICE) ? 1 << 7 : 0; | ||
309 | bcb->Tag = ++us->tag; | ||
310 | bcb->Lun = lun; | ||
311 | bcb->Length = cmd_len; | ||
312 | |||
313 | /* copy the command payload */ | ||
314 | memset(bcb->CDB, 0, sizeof(bcb->CDB)); | ||
315 | memcpy(bcb->CDB, cmd, bcb->Length); | ||
316 | |||
317 | /* send it to out endpoint */ | ||
318 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
319 | bcb, cbwlen, NULL); | ||
320 | if (result != USB_STOR_XFER_GOOD) | ||
321 | return USB_STOR_TRANSPORT_ERROR; | ||
322 | |||
323 | /* DATA STAGE */ | ||
324 | /* send/receive data payload, if there is any */ | ||
325 | |||
326 | if (buf && buf_len) { | ||
327 | unsigned int pipe = (dir == DMA_FROM_DEVICE) ? | ||
328 | us->recv_bulk_pipe : us->send_bulk_pipe; | ||
329 | result = usb_stor_bulk_transfer_buf(us, pipe, | ||
330 | buf, buf_len, NULL); | ||
331 | if (result == USB_STOR_XFER_ERROR) | ||
332 | return USB_STOR_TRANSPORT_ERROR; | ||
333 | } | ||
334 | |||
335 | /* get CSW for device status */ | ||
336 | result = usb_bulk_msg(us->pusb_dev, us->recv_bulk_pipe, bcs, | ||
337 | US_BULK_CS_WRAP_LEN, &cswlen, 250); | ||
338 | return result; | ||
339 | } | ||
340 | |||
295 | /* Determine what the maximum LUN supported is */ | 341 | /* Determine what the maximum LUN supported is */ |
296 | static int rts51x_get_max_lun(struct us_data *us) | 342 | static int rts51x_get_max_lun(struct us_data *us) |
297 | { | 343 | { |
@@ -319,6 +365,11 @@ static int rts51x_read_mem(struct us_data *us, u16 addr, u8 *data, u16 len) | |||
319 | { | 365 | { |
320 | int retval; | 366 | int retval; |
321 | u8 cmnd[12] = { 0 }; | 367 | u8 cmnd[12] = { 0 }; |
368 | u8 *buf; | ||
369 | |||
370 | buf = kmalloc(len, GFP_NOIO); | ||
371 | if (buf == NULL) | ||
372 | return USB_STOR_TRANSPORT_ERROR; | ||
322 | 373 | ||
323 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); | 374 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); |
324 | 375 | ||
@@ -330,10 +381,14 @@ static int rts51x_read_mem(struct us_data *us, u16 addr, u8 *data, u16 len) | |||
330 | cmnd[5] = (u8) len; | 381 | cmnd[5] = (u8) len; |
331 | 382 | ||
332 | retval = rts51x_bulk_transport(us, 0, cmnd, 12, | 383 | retval = rts51x_bulk_transport(us, 0, cmnd, 12, |
333 | data, len, DMA_FROM_DEVICE, NULL); | 384 | buf, len, DMA_FROM_DEVICE, NULL); |
334 | if (retval != USB_STOR_TRANSPORT_GOOD) | 385 | if (retval != USB_STOR_TRANSPORT_GOOD) { |
386 | kfree(buf); | ||
335 | return -EIO; | 387 | return -EIO; |
388 | } | ||
336 | 389 | ||
390 | memcpy(data, buf, len); | ||
391 | kfree(buf); | ||
337 | return 0; | 392 | return 0; |
338 | } | 393 | } |
339 | 394 | ||
@@ -341,6 +396,12 @@ static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len) | |||
341 | { | 396 | { |
342 | int retval; | 397 | int retval; |
343 | u8 cmnd[12] = { 0 }; | 398 | u8 cmnd[12] = { 0 }; |
399 | u8 *buf; | ||
400 | |||
401 | buf = kmalloc(len, GFP_NOIO); | ||
402 | if (buf == NULL) | ||
403 | return USB_STOR_TRANSPORT_ERROR; | ||
404 | memcpy(buf, data, len); | ||
344 | 405 | ||
345 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); | 406 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); |
346 | 407 | ||
@@ -352,7 +413,8 @@ static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len) | |||
352 | cmnd[5] = (u8) len; | 413 | cmnd[5] = (u8) len; |
353 | 414 | ||
354 | retval = rts51x_bulk_transport(us, 0, cmnd, 12, | 415 | retval = rts51x_bulk_transport(us, 0, cmnd, 12, |
355 | data, len, DMA_TO_DEVICE, NULL); | 416 | buf, len, DMA_TO_DEVICE, NULL); |
417 | kfree(buf); | ||
356 | if (retval != USB_STOR_TRANSPORT_GOOD) | 418 | if (retval != USB_STOR_TRANSPORT_GOOD) |
357 | return -EIO; | 419 | return -EIO; |
358 | 420 | ||
@@ -364,6 +426,11 @@ static int rts51x_read_status(struct us_data *us, | |||
364 | { | 426 | { |
365 | int retval; | 427 | int retval; |
366 | u8 cmnd[12] = { 0 }; | 428 | u8 cmnd[12] = { 0 }; |
429 | u8 *buf; | ||
430 | |||
431 | buf = kmalloc(len, GFP_NOIO); | ||
432 | if (buf == NULL) | ||
433 | return USB_STOR_TRANSPORT_ERROR; | ||
367 | 434 | ||
368 | US_DEBUGP("%s, lun = %d\n", __func__, lun); | 435 | US_DEBUGP("%s, lun = %d\n", __func__, lun); |
369 | 436 | ||
@@ -371,10 +438,14 @@ static int rts51x_read_status(struct us_data *us, | |||
371 | cmnd[1] = 0x09; | 438 | cmnd[1] = 0x09; |
372 | 439 | ||
373 | retval = rts51x_bulk_transport(us, lun, cmnd, 12, | 440 | retval = rts51x_bulk_transport(us, lun, cmnd, 12, |
374 | status, len, DMA_FROM_DEVICE, actlen); | 441 | buf, len, DMA_FROM_DEVICE, actlen); |
375 | if (retval != USB_STOR_TRANSPORT_GOOD) | 442 | if (retval != USB_STOR_TRANSPORT_GOOD) { |
443 | kfree(buf); | ||
376 | return -EIO; | 444 | return -EIO; |
445 | } | ||
377 | 446 | ||
447 | memcpy(status, buf, len); | ||
448 | kfree(buf); | ||
378 | return 0; | 449 | return 0; |
379 | } | 450 | } |
380 | 451 | ||
@@ -433,6 +504,29 @@ static int enable_oscillator(struct us_data *us) | |||
433 | return 0; | 504 | return 0; |
434 | } | 505 | } |
435 | 506 | ||
507 | static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len) | ||
508 | { | ||
509 | int retval; | ||
510 | u16 addr = 0xFE47; | ||
511 | u8 cmnd[12] = {0}; | ||
512 | |||
513 | US_DEBUGP("%s, addr = 0x%x, len = %d\n", __FUNCTION__, addr, len); | ||
514 | |||
515 | cmnd[0] = 0xF0; | ||
516 | cmnd[1] = 0x0E; | ||
517 | cmnd[2] = (u8)(addr >> 8); | ||
518 | cmnd[3] = (u8)addr; | ||
519 | cmnd[4] = (u8)(len >> 8); | ||
520 | cmnd[5] = (u8)len; | ||
521 | |||
522 | retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, data, len, DMA_TO_DEVICE, NULL); | ||
523 | if (retval != USB_STOR_TRANSPORT_GOOD) { | ||
524 | return -EIO; | ||
525 | } | ||
526 | |||
527 | return 0; | ||
528 | } | ||
529 | |||
436 | static int do_config_autodelink(struct us_data *us, int enable, int force) | 530 | static int do_config_autodelink(struct us_data *us, int enable, int force) |
437 | { | 531 | { |
438 | int retval; | 532 | int retval; |
@@ -453,7 +547,8 @@ static int do_config_autodelink(struct us_data *us, int enable, int force) | |||
453 | 547 | ||
454 | US_DEBUGP("In %s,set 0xfe47 to 0x%x\n", __func__, value); | 548 | US_DEBUGP("In %s,set 0xfe47 to 0x%x\n", __func__, value); |
455 | 549 | ||
456 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); | 550 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ |
551 | retval = __do_config_autodelink(us, &value, 1); | ||
457 | if (retval < 0) | 552 | if (retval < 0) |
458 | return -EIO; | 553 | return -EIO; |
459 | 554 | ||
@@ -485,7 +580,8 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
485 | 580 | ||
486 | SET_BIT(value, 7); | 581 | SET_BIT(value, 7); |
487 | 582 | ||
488 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); | 583 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ |
584 | retval = __do_config_autodelink(us, &value, 1); | ||
489 | if (retval < 0) | 585 | if (retval < 0) |
490 | return -EIO; | 586 | return -EIO; |
491 | 587 | ||
@@ -506,7 +602,8 @@ static int config_autodelink_after_power_on(struct us_data *us) | |||
506 | CLR_BIT(value, 7); | 602 | CLR_BIT(value, 7); |
507 | } | 603 | } |
508 | 604 | ||
509 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); | 605 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ |
606 | retval = __do_config_autodelink(us, &value, 1); | ||
510 | if (retval < 0) | 607 | if (retval < 0) |
511 | return -EIO; | 608 | return -EIO; |
512 | 609 | ||
@@ -583,7 +680,8 @@ static int config_autodelink_before_power_down(struct us_data *us) | |||
583 | if (CHECK_ID(chip, 0x0138, 0x3882)) | 680 | if (CHECK_ID(chip, 0x0138, 0x3882)) |
584 | SET_BIT(value, 2); | 681 | SET_BIT(value, 2); |
585 | 682 | ||
586 | retval = rts51x_write_mem(us, 0xFE47, &value, 1); | 683 | /* retval = rts51x_write_mem(us, 0xFE47, &value, 1); */ |
684 | retval = __do_config_autodelink(us, &value, 1); | ||
587 | if (retval < 0) | 685 | if (retval < 0) |
588 | return -EIO; | 686 | return -EIO; |
589 | } | 687 | } |
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index e8ae21b2d387..ff32390d61e5 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -691,6 +691,9 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
691 | int temp_result; | 691 | int temp_result; |
692 | struct scsi_eh_save ses; | 692 | struct scsi_eh_save ses; |
693 | int sense_size = US_SENSE_SIZE; | 693 | int sense_size = US_SENSE_SIZE; |
694 | struct scsi_sense_hdr sshdr; | ||
695 | const u8 *scdd; | ||
696 | u8 fm_ili; | ||
694 | 697 | ||
695 | /* device supports and needs bigger sense buffer */ | 698 | /* device supports and needs bigger sense buffer */ |
696 | if (us->fflags & US_FL_SANE_SENSE) | 699 | if (us->fflags & US_FL_SANE_SENSE) |
@@ -774,32 +777,30 @@ Retry_Sense: | |||
774 | srb->sense_buffer[7] = (US_SENSE_SIZE - 8); | 777 | srb->sense_buffer[7] = (US_SENSE_SIZE - 8); |
775 | } | 778 | } |
776 | 779 | ||
780 | scsi_normalize_sense(srb->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
781 | &sshdr); | ||
782 | |||
777 | US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); | 783 | US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); |
778 | US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", | 784 | US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", |
779 | srb->sense_buffer[0], | 785 | sshdr.response_code, sshdr.sense_key, |
780 | srb->sense_buffer[2] & 0xf, | 786 | sshdr.asc, sshdr.ascq); |
781 | srb->sense_buffer[12], | ||
782 | srb->sense_buffer[13]); | ||
783 | #ifdef CONFIG_USB_STORAGE_DEBUG | 787 | #ifdef CONFIG_USB_STORAGE_DEBUG |
784 | usb_stor_show_sense( | 788 | usb_stor_show_sense(sshdr.sense_key, sshdr.asc, sshdr.ascq); |
785 | srb->sense_buffer[2] & 0xf, | ||
786 | srb->sense_buffer[12], | ||
787 | srb->sense_buffer[13]); | ||
788 | #endif | 789 | #endif |
789 | 790 | ||
790 | /* set the result so the higher layers expect this data */ | 791 | /* set the result so the higher layers expect this data */ |
791 | srb->result = SAM_STAT_CHECK_CONDITION; | 792 | srb->result = SAM_STAT_CHECK_CONDITION; |
792 | 793 | ||
794 | scdd = scsi_sense_desc_find(srb->sense_buffer, | ||
795 | SCSI_SENSE_BUFFERSIZE, 4); | ||
796 | fm_ili = (scdd ? scdd[3] : srb->sense_buffer[2]) & 0xA0; | ||
797 | |||
793 | /* We often get empty sense data. This could indicate that | 798 | /* We often get empty sense data. This could indicate that |
794 | * everything worked or that there was an unspecified | 799 | * everything worked or that there was an unspecified |
795 | * problem. We have to decide which. | 800 | * problem. We have to decide which. |
796 | */ | 801 | */ |
797 | if ( /* Filemark 0, ignore EOM, ILI 0, no sense */ | 802 | if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 && |
798 | (srb->sense_buffer[2] & 0xaf) == 0 && | 803 | fm_ili == 0) { |
799 | /* No ASC or ASCQ */ | ||
800 | srb->sense_buffer[12] == 0 && | ||
801 | srb->sense_buffer[13] == 0) { | ||
802 | |||
803 | /* If things are really okay, then let's show that. | 804 | /* If things are really okay, then let's show that. |
804 | * Zero out the sense buffer so the higher layers | 805 | * Zero out the sense buffer so the higher layers |
805 | * won't realize we did an unsolicited auto-sense. | 806 | * won't realize we did an unsolicited auto-sense. |
@@ -814,7 +815,10 @@ Retry_Sense: | |||
814 | */ | 815 | */ |
815 | } else { | 816 | } else { |
816 | srb->result = DID_ERROR << 16; | 817 | srb->result = DID_ERROR << 16; |
817 | srb->sense_buffer[2] = HARDWARE_ERROR; | 818 | if ((sshdr.response_code & 0x72) == 0x72) |
819 | srb->sense_buffer[1] = HARDWARE_ERROR; | ||
820 | else | ||
821 | srb->sense_buffer[2] = HARDWARE_ERROR; | ||
818 | } | 822 | } |
819 | } | 823 | } |
820 | } | 824 | } |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 0ca095820f3e..c325e69415a1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -831,12 +831,22 @@ static int usb_stor_scan_thread(void * __us) | |||
831 | 831 | ||
832 | dev_dbg(dev, "device found\n"); | 832 | dev_dbg(dev, "device found\n"); |
833 | 833 | ||
834 | set_freezable(); | 834 | set_freezable_with_signal(); |
835 | /* Wait for the timeout to expire or for a disconnect */ | 835 | /* |
836 | * Wait for the timeout to expire or for a disconnect | ||
837 | * | ||
838 | * We can't freeze in this thread or we risk causing khubd to | ||
839 | * fail to freeze, but we can't be non-freezable either. Nor can | ||
840 | * khubd freeze while waiting for scanning to complete as it may | ||
841 | * hold the device lock, causing a hang when suspending devices. | ||
842 | * So we request a fake signal when freezing and use | ||
843 | * interruptible sleep to kick us out of our wait early when | ||
844 | * freezing happens. | ||
845 | */ | ||
836 | if (delay_use > 0) { | 846 | if (delay_use > 0) { |
837 | dev_dbg(dev, "waiting for device to settle " | 847 | dev_dbg(dev, "waiting for device to settle " |
838 | "before scanning\n"); | 848 | "before scanning\n"); |
839 | wait_event_freezable_timeout(us->delay_wait, | 849 | wait_event_interruptible_timeout(us->delay_wait, |
840 | test_bit(US_FLIDX_DONT_SCAN, &us->dflags), | 850 | test_bit(US_FLIDX_DONT_SCAN, &us->dflags), |
841 | delay_use * HZ); | 851 | delay_use * HZ); |
842 | } | 852 | } |