diff options
-rw-r--r-- | common/usb_storage.c | 39 | ||||
-rw-r--r-- | drivers/usb/gadget/ether.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_hcd.c | 23 |
4 files changed, 60 insertions, 25 deletions
diff --git a/common/usb_storage.c b/common/usb_storage.c index 76949b8..613c4f0 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -204,6 +204,22 @@ int usb_stor_info(void) return 1; } +static unsigned int usb_get_max_lun(struct us_data *us) +{ + int len; + unsigned char result; + len = usb_control_msg(us->pusb_dev, + usb_rcvctrlpipe(us->pusb_dev, 0), + US_BBB_GET_MAX_LUN, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + 0, us->ifnum, + &result, sizeof(result), + USB_CNTL_TIMEOUT * 5); + USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n", + len, (int) result); + return (len > 0) ? result : 0; +} + /******************************************************************************* * scan the usb and reports device info * to the user if mode = 1 @@ -241,13 +257,22 @@ int usb_stor_scan(int mode) break; /* no more devices avaiable */ if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) { - /* ok, it is a storage devices - * get info and fill it in + /* OK, it's a storage device. Iterate over its LUNs + * and populate `usb_dev_desc'. */ - if (usb_stor_get_info(dev, &usb_stor[usb_max_devs], - &usb_dev_desc[usb_max_devs]) == 1) + int lun, max_lun, start = usb_max_devs; + + max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]); + for (lun = 0; + lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; + lun++) { + usb_dev_desc[usb_max_devs].lun = lun; + if (usb_stor_get_info(dev, &usb_stor[start], + &usb_dev_desc[usb_max_devs]) == 1) { usb_max_devs++; } + } + } /* if storage device */ if (usb_max_devs == USB_MAX_STOR_DEV) { printf("max USB Storage Device reached: %d stopping\n", @@ -882,6 +907,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_INQUIRY; + srb->cmd[1] = srb->lun << 5; srb->cmd[4] = 36; srb->datalen = 36; srb->cmdlen = 12; @@ -905,6 +931,7 @@ static int usb_request_sense(ccb *srb, struct us_data *ss) ptr = (char *)srb->pdata; memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_REQ_SENSE; + srb->cmd[1] = srb->lun << 5; srb->cmd[4] = 18; srb->datalen = 18; srb->pdata = &srb->sense_buf[0]; @@ -924,6 +951,7 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_TST_U_RDY; + srb->cmd[1] = srb->lun << 5; srb->datalen = 0; srb->cmdlen = 12; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) @@ -943,6 +971,7 @@ static int usb_read_capacity(ccb *srb, struct us_data *ss) do { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_RD_CAPAC; + srb->cmd[1] = srb->lun << 5; srb->datalen = 8; srb->cmdlen = 12; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) @@ -957,6 +986,7 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start, { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_READ10; + srb->cmd[1] = srb->lun << 5; srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; @@ -973,6 +1003,7 @@ static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start, { memset(&srb->cmd[0], 0, 12); srb->cmd[0] = SCSI_WRITE10; + srb->cmd[1] = srb->lun << 5; srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index bc6480c..b22ca90 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1276,9 +1276,6 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) debug("%s: status %d\n", __func__, req->status); packet_received = 1; - - if (req) - dev->rx_req = req; } static int alloc_requests(struct eth_dev *dev, unsigned n, gfp_t gfp_flags) @@ -1287,16 +1284,18 @@ static int alloc_requests(struct eth_dev *dev, unsigned n, gfp_t gfp_flags) dev->tx_req = usb_ep_alloc_request(dev->in_ep, 0); if (!dev->tx_req) - goto fail; + goto fail1; dev->rx_req = usb_ep_alloc_request(dev->out_ep, 0); if (!dev->rx_req) - goto fail; + goto fail2; return 0; -fail: +fail2: + usb_ep_free_request(dev->in_ep, dev->tx_req); +fail1: error("can't alloc requests"); return -1; } @@ -1791,8 +1790,6 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd) } dev->network_started = 0; - dev->tx_req = NULL; - dev->rx_req = NULL; packet_received = 0; packet_sent = 0; @@ -1813,6 +1810,7 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd) usb_gadget_handle_interrupts(); } + packet_received = 0; rx_submit(dev, dev->rx_req, 0); return 0; fail: @@ -1823,15 +1821,13 @@ static int usb_eth_send(struct eth_device *netdev, volatile void *packet, int length) { int retval; - struct usb_request *req = NULL; struct eth_dev *dev = &l_ethdev; + struct usb_request *req = dev->tx_req; unsigned long ts; unsigned long timeout = USB_CONNECT_TIMEOUT; debug("%s:...\n", __func__); - req = dev->tx_req; - req->buf = (void *)packet; req->context = NULL; req->complete = tx_complete; @@ -1883,8 +1879,7 @@ static int usb_eth_recv(struct eth_device *netdev) NetReceive(NetRxPackets[0], dev->rx_req->length); packet_received = 0; - if (dev->rx_req) - rx_submit(dev, dev->rx_req, 0); + rx_submit(dev, dev->rx_req, 0); } else error("dev->rx_req invalid"); } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 3f76c4e..d246978 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1529,7 +1529,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, if (usb_pipebulk(pipe)) timeout = BULK_TO; else - timeout = 100; + timeout = 1000; /* wait for it to complete */ for (;;) { diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c index af989aa..f38b279 100644 --- a/drivers/usb/musb/musb_hcd.c +++ b/drivers/usb/musb/musb_hcd.c @@ -144,19 +144,28 @@ static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out) u16 csr; if (dir_out) { - if (!toggle) - writew(MUSB_TXCSR_CLRDATATOG, &musbr->txcsr); - else { - csr = readw(&musbr->txcsr); + csr = readw(&musbr->txcsr); + if (!toggle) { + if (csr & MUSB_TXCSR_MODE) + csr = MUSB_TXCSR_CLRDATATOG; + else + csr = 0; + writew(csr, &musbr->txcsr); + } else { csr |= MUSB_TXCSR_H_WR_DATATOGGLE; writew(csr, &musbr->txcsr); csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT); writew(csr, &musbr->txcsr); } } else { - if (!toggle) - writew(MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr); - else { + if (!toggle) { + csr = readw(&musbr->txcsr); + if (csr & MUSB_TXCSR_MODE) + csr = MUSB_RXCSR_CLRDATATOG; + else + csr = 0; + writew(csr, &musbr->rxcsr); + } else { csr = readw(&musbr->rxcsr); csr |= MUSB_RXCSR_H_WR_DATATOGGLE; writew(csr, &musbr->rxcsr); |