aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-09-24 15:09:29 +0530
committerNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-10-04 12:01:21 +0530
commit2b14fb9a9eab6d6d34850bfb8c5cbd2bc3e94286 (patch)
tree0779c5edd5e98dda0adce54dce264af1e7ffbf10
parent2ddd78d4bea9fe2ed8ae84bf325453558b236317 (diff)
downloadSLOF-2b14fb9a9eab6d6d34850bfb8c5cbd2bc3e94286.zip
SLOF-2b14fb9a9eab6d6d34850bfb8c5cbd2bc3e94286.tar.gz
SLOF-2b14fb9a9eab6d6d34850bfb8c5cbd2bc3e94286.tar.bz2
usb-msc: handle stall and other fixes
* Add Reset Recovery procedure * Zero cbw and csw memory everytime * Add delays during cbw, data and csw stage * Increment tag after every command Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
-rw-r--r--lib/libusb/usb-core.c16
-rw-r--r--lib/libusb/usb-core.h2
-rw-r--r--slof/fs/usb/dev-storage.fs15
3 files changed, 29 insertions, 4 deletions
diff --git a/lib/libusb/usb-core.c b/lib/libusb/usb-core.c
index 6fad631..6c40913 100644
--- a/lib/libusb/usb-core.c
+++ b/lib/libusb/usb-core.c
@@ -435,6 +435,14 @@ static int usb_msc_reset(struct usb_dev *dev)
return usb_send_ctrl(dev->control, &req, NULL);
}
+void usb_msc_resetrecovery(struct usb_dev *dev)
+{
+ // usb_msc_reset(dev);
+ usb_clear_halt(dev->bulk_in);
+ usb_clear_halt(dev->bulk_out);
+ SLOF_msleep(2);
+}
+
static int usb_handle_device(struct usb_dev *dev, struct usb_dev_config_descr *cfg,
uint8_t *ptr, uint16_t len)
{
@@ -536,7 +544,13 @@ int setup_new_device(struct usb_dev *dev, unsigned int port)
slof_usb_handle(dev);
break;
case 8:
- dprintf("MASS STORAGE found %d\n", dev->intf_num);
+ dprintf("MASS STORAGE found %d %06X\n", dev->intf_num,
+ dev->class);
+ if ((dev->class & 0x50) != 0x50) { /* Bulk-only supported */
+ printf("Device not supported %06X\n", dev->class);
+ goto fail_mem_free;
+ }
+
if (!usb_msc_reset(dev)) {
printf("%s: bulk reset failed\n", __func__);
goto fail_mem_free;
diff --git a/lib/libusb/usb-core.h b/lib/libusb/usb-core.h
index 75aa0f9..fc9a0be 100644
--- a/lib/libusb/usb-core.h
+++ b/lib/libusb/usb-core.h
@@ -273,5 +273,5 @@ extern int usb_dev_populate_pipe(struct usb_dev *dev, struct usb_ep_descr *ep,
void *buf, size_t len);
extern int usb_hid_kbd_init(struct usb_dev *dev);
extern int usb_hid_kbd_exit(struct usb_dev *dev);
-
+extern void usb_msc_resetrecovery(struct usb_dev *dev);
#endif
diff --git a/slof/fs/usb/dev-storage.fs b/slof/fs/usb/dev-storage.fs
index f014114..cdf7a73 100644
--- a/slof/fs/usb/dev-storage.fs
+++ b/slof/fs/usb/dev-storage.fs
@@ -109,11 +109,16 @@ scsi-open
udev USB_PIPE_OUT td-buf td-buf-phys dma-buf-phys usb>cmd 1F
usb-transfer-bulk IF \ transfer CBW
resp-size IF
+ d# 125 us
udev USB_PIPE_IN td-buf td-buf-phys resp-buffer resp-size
usb-transfer-bulk 1 = not IF \ transfer data
- FALSE EXIT
+ usb-disk-debug? IF ." Data phase failed " cr THEN
+ \ FALSE EXIT
+ \ in case of a stall/halted endpoint we clear the halt
+ \ Fall through and try reading the CSW
THEN
THEN
+ d# 125 us
udev USB_PIPE_IN td-buf td-buf-phys dma-buf-phys usb>csw 0D
usb-transfer-bulk \ transfer CSW
ELSE
@@ -162,15 +167,20 @@ CONSTANT cbw-length
0 INSTANCE VALUE usb-dir
0 INSTANCE VALUE usb-cmd-addr
0 INSTANCE VALUE usb-cmd-len
+1 VALUE tag
: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... )
( ... [ sense-buf sense-len ] stat )
\ Cleanup virtio request and response
to usb-cmd-len to usb-cmd-addr to usb-dir to usb-buf-len to usb-buf-addr
- 1 usb-buf-len usb-dir lun usb-cmd-len dma-buf usb>cmd
+ dma-buf usb>cmd 40 0 fill
+ dma-buf usb>csw 20 0 fill
+
+ tag usb-buf-len usb-dir lun usb-cmd-len dma-buf usb>cmd
( tag transfer-len dir lun cmd-len addr )
build-cbw
+ 1 tag + to tag
usb-cmd-addr
dma-buf usb>cmd SCSI-COMMAND-OFFSET +
@@ -277,6 +287,7 @@ CONSTANT cbw-length
dup 20 >> FFFF and to lun
dup 30 >> FF and to port
to current-target
+ usb-disk-debug? IF ." USB-DISK: udev " udev . ." lun:" lun . ." port:" port . cr THEN
;
: dev-generate-srplun ( target lun-id -- srplun )