From 4e2c4ad3604ba6f5053090749d64ed3ce5914805 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:22 +0200 Subject: usb: ehci: Properly set hub devnum and portnr with usb-1 hubs in the chain For full / low speed devices we need to get the devnum and portnr of the tt, so of the first upstream usb-2 hub, not of the parent device (which may be a usb-1 hub). Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index eaf59134cb..41af302e03 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -273,6 +273,29 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed) return QH_FULL_SPEED; } +static void ehci_update_endpt2_dev_n_port(struct usb_device *dev, + struct QH *qh) +{ + struct usb_device *ttdev; + + if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL) + return; + + /* + * For full / low speed devices we need to get the devnum and portnr of + * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs + * in the tree before that one! + */ + ttdev = dev; + while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH) + ttdev = ttdev->parent; + if (!ttdev->parent) + return; + + qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) | + QH_ENDPT2_HUBADDR(ttdev->parent->devnum)); +} + static int ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) @@ -390,10 +413,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); qh->qh_endpt1 = cpu_to_hc32(endpt); - endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) | - QH_ENDPT2_HUBADDR(dev->parent->devnum) | - QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); + endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); qh->qh_endpt2 = cpu_to_hc32(endpt); + ehci_update_endpt2_dev_n_port(dev, qh); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); @@ -1201,12 +1223,10 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, (1 << 0)); /* S-mask: microframe 0 */ if (dev->speed == USB_SPEED_LOW || dev->speed == USB_SPEED_FULL) { - debug("TT: port: %d, hub address: %d\n", - dev->portnr, dev->parent->devnum); - qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) | - (dev->parent->devnum << 16) | - (0x1c << 8)); /* C-mask: microframes 2-4 */ + /* C-mask: microframes 2-4 */ + qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8)); } + ehci_update_endpt2_dev_n_port(dev, qh); td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); -- cgit v1.2.1 From ea7b30c58973d59396c71d5880a652639d479a68 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:23 +0200 Subject: usb: ehci: Add missing cache flush to destroy_int_queue Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 41af302e03..1a0ddc3d51 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1342,6 +1342,8 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) if (NEXT_QH(cur) == queue->first) { debug("found candidate. removing from chain\n"); cur->qh_link = queue->last->qh_link; + flush_dcache_range((uint32_t)cur, + ALIGN_END_ADDR(struct QH, cur, 1)); result = 0; break; } -- cgit v1.2.1 From 415548d88446134549917aae026f53dbbee36fd2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:24 +0200 Subject: usb: ehci: poll_int_queue check real qtd, not the overlay When we first start an int queue, the qh's overlay area is all zeros. This gets filled by the hc with the actual qtd values as soon as it advances the queue, but we may call poll_int_queue before then, in which case we would think the transfer has completed as the hc has not yet copied the qt_token to the overlay, so the active flag is not set. This fixes this by checking the actual qtd token, rather then the overlay. This also fixes a (theoretical) race where we see the completion in the overlay and free and re-use the qtd before the hc has completed writing back the overlay to the actual qtd. Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1a0ddc3d51..635a3b4511 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1297,6 +1297,7 @@ fail1: void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) { struct QH *cur = queue->current; + struct qTD *cur_td; /* depleted queue */ if (cur == NULL) { @@ -1304,20 +1305,21 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) return NULL; } /* still active */ - invalidate_dcache_range((uint32_t)cur, - ALIGN_END_ADDR(struct QH, cur, 1)); - if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) { - debug("Exit poll_int_queue with no completed intr transfer. " - "token is %x\n", cur->qh_overlay.qt_token); + cur_td = &queue->tds[queue->current - queue->first]; + invalidate_dcache_range((uint32_t)cur_td, + ALIGN_END_ADDR(struct qTD, cur_td, 1)); + if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) & + QT_TOKEN_STATUS_ACTIVE) { + debug("Exit poll_int_queue with no completed intr transfer. token is %x\n", + hc32_to_cpu(cur_td->qt_token)); return NULL; } if (!(cur->qh_link & QH_LINK_TERMINATE)) queue->current++; else queue->current = NULL; - debug("Exit poll_int_queue with completed intr transfer. " - "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token, - &cur->qh_overlay.qt_token, queue->first); + debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n", + hc32_to_cpu(cur_td->qt_token), cur, queue->first); return cur->buffer; } -- cgit v1.2.1 From 36b73109c49c1359a5fcc790c00717cb27468c12 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:25 +0200 Subject: usb: ehci: Make periodic_schedules a per controller variable Periodic schedules tracks how many int_queue-s are active, and decides whether or not to en/disable the periodic schedule based on this. This is clearly a per controller thing. Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 9 ++++----- drivers/usb/host/ehci.h | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 635a3b4511..6323c50837 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -996,6 +996,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) * Set up periodic list * Step 1: Parent QH for all periodic transfers. */ + ehcic[index].periodic_schedules = 0; periodic = &ehcic[index].periodic_queue; memset(periodic, 0, sizeof(*periodic)); periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE); @@ -1154,8 +1155,6 @@ disable_periodic(struct ehci_ctrl *ctrl) return 0; } -static int periodic_schedules; - struct int_queue * create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, int elementsize, void *buffer) @@ -1278,7 +1277,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, debug("FATAL: periodic should never fail, but did"); goto fail3; } - periodic_schedules++; + ctrl->periodic_schedules++; debug("Exit create_int_queue\n"); return result; @@ -1335,7 +1334,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) debug("FATAL: periodic should never fail, but did"); goto out; } - periodic_schedules--; + ctrl->periodic_schedules--; struct QH *cur = &ctrl->periodic_queue; timeout = get_timer(0) + 500; /* abort after 500ms */ @@ -1357,7 +1356,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) } } - if (periodic_schedules > 0) { + if (ctrl->periodic_schedules > 0) { result = enable_periodic(ctrl); if (result < 0) debug("FATAL: periodic should never fail, but did"); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 093eb4b832..433e703da8 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -246,6 +246,7 @@ struct ehci_ctrl { struct QH qh_list __aligned(USB_DMA_MINALIGN); struct QH periodic_queue __aligned(USB_DMA_MINALIGN); uint32_t *periodic_list; + int periodic_schedules; int ntds; }; -- cgit v1.2.1 From 32d019265d1f0c334f2f86407abf295d46bd2f4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:54:37 +0200 Subject: stdio: Add force parameter to stdio_deregister In some cases we really want to move forward with a deregister, add a force parameter to allow this, and replace the dev with a nulldev in this case. Signed-off-by: Hans de Goede --- drivers/serial/serial-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1ac943f692..fd010cac42 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -198,7 +198,7 @@ static int serial_pre_remove(struct udevice *dev) #ifdef CONFIG_SYS_STDIO_DEREGISTER struct serial_dev_priv *upriv = dev->uclass_priv; - if (stdio_deregister_dev(upriv->sdev)) + if (stdio_deregister_dev(upriv->sdev), 0) return -EPERM; #endif -- cgit v1.2.1 From b9c99d32466b90aa2269eca99545f045a23266ab Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 11 Sep 2014 15:26:10 +0200 Subject: usb: dfu: thor: gadget: Remove dead code This code is not used anymore in the current DFU implementation and can be safely removed. Signed-off-by: Lukasz Majewski --- drivers/usb/gadget/f_dfu.c | 8 -------- drivers/usb/gadget/f_thor.c | 10 ---------- 2 files changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 3e4f02932b..d040606e6f 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -81,14 +81,6 @@ static struct usb_descriptor_header *dfu_runtime_descs[] = { NULL, }; -static const struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof dev_qualifier, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_VENDOR_SPEC, - .bNumConfigurations = 1, -}; - static const char dfu_name[] = "Device Firmware Upgrade"; /* diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c index c85b0fbd3c..78519fa41f 100644 --- a/drivers/usb/gadget/f_thor.c +++ b/drivers/usb/gadget/f_thor.c @@ -458,16 +458,6 @@ static struct usb_endpoint_descriptor hs_int_desc = { .bInterval = 0x9, }; -static struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof(dev_qualifier), - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_VENDOR_SPEC, - - .bNumConfigurations = 2, -}; - /* * This attribute vendor descriptor is necessary for correct operation with * Windows version of THOR download program -- cgit v1.2.1 From 9f3b8ed14cef1e277f1362f121e16975bba2026f Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 10 Sep 2014 08:55:00 +0200 Subject: usb: dfu: add fullspeed support for DFU DFU now can use also fullspeed. Signed-off-by: Heiko Schocher Cc: Tom Rini Cc: Lukasz Majewski Cc: Marek Vasut Cc: Liu Bin Cc: Lukas Stockmann --- drivers/usb/gadget/f_dfu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index d040606e6f..16fc9ddf82 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -229,6 +229,7 @@ static inline void to_dfu_mode(struct f_dfu *f_dfu) { f_dfu->usb_function.strings = dfu_strings; f_dfu->usb_function.hs_descriptors = f_dfu->function; + f_dfu->usb_function.descriptors = f_dfu->function; f_dfu->dfu_state = DFU_STATE_dfuIDLE; } @@ -236,6 +237,7 @@ static inline void to_runtime_mode(struct f_dfu *f_dfu) { f_dfu->usb_function.strings = NULL; f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.descriptors = dfu_runtime_descs; } static int handle_upload(struct usb_request *req, u16 len) @@ -800,6 +802,7 @@ static int dfu_bind_config(struct usb_configuration *c) return -ENOMEM; f_dfu->usb_function.name = "dfu"; f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.descriptors = dfu_runtime_descs; f_dfu->usb_function.bind = dfu_bind; f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; -- cgit v1.2.1 From f9935c87b6c8e81ef8d621bd06d24a78eec8a821 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Fri, 19 Sep 2014 17:06:46 -0700 Subject: usb: f_mass_storage: set removable flag in do_inquiry based on LUN Without this flag, tools like Alex Page's USB Image Tool won't see drives exposed over USB Gadget as removable, and won't allow access to them. http://www.alexpage.de/usb-image-tool/ The code was pulled from the main-line kernel: drivers/usb/gadget/function/f_mass_storage.c Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_mass_storage.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index f274d9679f..e045957d07 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -1110,6 +1110,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) memset(buf, 0, 8); buf[0] = TYPE_DISK; + buf[1] = curlun->removable ? 0x80 : 0; buf[2] = 2; /* ANSI SCSI level 2 */ buf[3] = 2; /* SCSI-2 INQUIRY data format */ buf[4] = 31; /* Additional length */ -- cgit v1.2.1 From 23d1d10c4248f1b9f838e512e7f18e600f06b348 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 19 Sep 2014 14:15:12 +0800 Subject: usb: gadget: fastboot: improve download progress bar When download is ongoing, if the actual size of one transfer is not the same as BYTES_PER_DOT, which will cause the dot won't print anymore. Then it will let the user thinking it is stuck, actually it is transfering without dot printed. So, improve the method to show the progress bar (print dot). Signed-off-by: Bo Shen Acked-by: Marek Vasut --- drivers/usb/gadget/f_fastboot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 38c09658cc..9d15f6352e 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -386,6 +386,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) unsigned int transfer_size = download_size - download_bytes; const unsigned char *buffer = req->buf; unsigned int buffer_size = req->actual; + unsigned int pre_dot_num, now_dot_num; if (req->status != 0) { printf("Bad status: %d\n", req->status); @@ -398,7 +399,15 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes, buffer, transfer_size); + pre_dot_num = download_bytes / BYTES_PER_DOT; download_bytes += transfer_size; + now_dot_num = download_bytes / BYTES_PER_DOT; + + if (pre_dot_num != now_dot_num) { + putc('.'); + if (!(now_dot_num % 74)) + putc('\n'); + } /* Check if transfer is done */ if (download_bytes >= download_size) { @@ -420,11 +429,6 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) req->length = ep->maxpacket; } - if (download_bytes && !(download_bytes % BYTES_PER_DOT)) { - putc('.'); - if (!(download_bytes % (74 * BYTES_PER_DOT))) - putc('\n'); - } req->actual = 0; usb_ep_queue(ep, req, 0); } -- cgit v1.2.1 From e206799370f77097a29577599960b7f123f61b8c Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 28 Sep 2014 18:35:14 -0700 Subject: usb: ci_udc: respect CONFIG_USB_GADGET_DUALSPEED Force full-speed (12 Mbit/s) operation if CONFIG_USB_GADGET_DUALSPEED is not defined. The controller is capable of high-speed (480 Mbit/s) operation, but some designs may require the use of lower-speed operation. Signed-off-by: Eric Nelson --- drivers/usb/gadget/ci_udc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 2572b346eb..b0ef35e745 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -777,6 +777,11 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on) /* select DEVICE mode */ writel(USBMODE_DEVICE, &udc->usbmode); +#if !defined(CONFIG_USB_GADGET_DUALSPEED) + /* Port force Full-Speed Connect */ + setbits_le32(&udc->portsc, PFSC); +#endif + writel(0xffffffff, &udc->epflush); /* Turn on the USB connection by enabling the pullup resistor */ -- cgit v1.2.1 From c674a6660e9934cf332bb007726997b1c3686bf1 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Tue, 30 Sep 2014 12:05:40 -0700 Subject: usb: gadget: fastboot: add max-download-size variable Current Android Fastboot seems to use 'max-download-size' instead of 'downloadsize' variable to indicate the maximum size of sparse segments. See function get_target_sparse_limit() in file fastboot/fastboot.c in the AOSP: https://android.googlesource.com/platform/system/core/+/master Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 9d15f6352e..3e1c0a9faf 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -351,7 +351,8 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) strncat(response, FASTBOOT_VERSION, chars_left); } else if (!strcmp_l1("bootloader-version", cmd)) { strncat(response, U_BOOT_VERSION, chars_left); - } else if (!strcmp_l1("downloadsize", cmd)) { + } else if (!strcmp_l1("downloadsize", cmd) || + !strcmp_l1("max-download-size", cmd)) { char str_num[12]; sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); -- cgit v1.2.1 From 84c24f66c2971f2a4149f60228bfc08f29ba9d30 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Tue, 30 Sep 2014 12:05:41 -0700 Subject: usb: gadget: fastboot: explicitly set radix of maximum download size The processing of the max-download-size variable requires a radix specifier, or the fastboot host tool will interpret it as an octal number. See function get_target_sparse_limit() in file fastboot/fastboot.c in the AOSP: https://android.googlesource.com/platform/system/core/+/master Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 3e1c0a9faf..392379dce4 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -355,7 +355,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) !strcmp_l1("max-download-size", cmd)) { char str_num[12]; - sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); + sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); strncat(response, str_num, chars_left); } else if (!strcmp_l1("serialno", cmd)) { s = getenv("serial#"); -- cgit v1.2.1 From d1fcbae1173f00917f5a71e4c074a61120605021 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sat, 4 Oct 2014 01:46:10 +0200 Subject: usb: tegra: ULPI regression on tegra20 Trying to enumerate USB devices connected via ULPI to T20 failed as follows: USB2: ULPI integrity check failed Git bisecting revealed the following commit being at odds: commit 2d34151f7501ddaa599897f0d89ad576126b03eb usb: tegra: refactor PHY type selection Looking at above commit one quickly identifies a copy paste error which this patch fixes. Happy ULPIing again (;-p). Signed-off-by: Marcel Ziswiler --- drivers/usb/host/ehci-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 33e5ea9ebd..5f0a98e8b8 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -305,11 +305,11 @@ static void init_phy_mux(struct fdt_usb *config, uint pts, #if defined(CONFIG_TEGRA20) if (config->periph_id == PERIPH_ID_USBD) { clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK, - PTS_UTMI << PTS1_SHIFT); + pts << PTS1_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS1); } else { clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, - PTS_UTMI << PTS_SHIFT); + pts << PTS_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS); } #else -- cgit v1.2.1 From 16b61d13bab361853564da401b15fc34ae1dfea7 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 22 Jul 2014 12:47:02 +0200 Subject: usb: musb-new: core: set MUSB_POWER_HSENAB in MUSB_POWER for host mode This bit allows the MUSB controller to negotiate for high-speed mode when the device is reset by the hub. If unset, Babble errors occur with high-speed mass storage devices right after the first packet. This condition is not caught by the interrupt handles in U-Boot, so no recovery is done, and the USB communication is stuck. To fix this, set the bit unconditionally, not only for CONFIG_USB_GADGET_DUALSPEED but also for host-only modes. Signed-off-by: Daniel Mack --- drivers/usb/musb-new/musb_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c index 4edd6d729d..242cc30b1c 100644 --- a/drivers/usb/musb-new/musb_core.c +++ b/drivers/usb/musb-new/musb_core.c @@ -942,9 +942,7 @@ void musb_start(struct musb *musb) /* put into basic highspeed mode and start session */ musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE -#ifdef CONFIG_USB_GADGET_DUALSPEED | MUSB_POWER_HSENAB -#endif /* ENSUSPEND wedges tusb */ /* | MUSB_POWER_ENSUSPEND */ ); -- cgit v1.2.1 From e2140588dd2f3e619f21d9575281b7c7ea771c09 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Wed, 1 Oct 2014 14:30:56 -0700 Subject: usb: gadget: fastboot: terminate commands with NULL Without NULL termination, various commands will read past the end of input. In particular, this was noticed with error() calls in cb_getvar and simple_strtoul() in cb_download. Since the download callback happens elsewhere, the 4k buffer should always be sufficient to handle command arguments. Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 392379dce4..71b62e5005 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -546,7 +546,14 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) error("unknown command: %s\n", cmdbuf); fastboot_tx_write_str("FAILunknown command"); } else { - func_cb(ep, req); + if (req->actual < req->length) { + u8 *buf = (u8 *)req->buf; + buf[req->actual] = 0; + func_cb(ep, req); + } else { + error("buffer overflow\n"); + fastboot_tx_write_str("FAILbuffer overflow"); + } } if (req->status == 0) { -- cgit v1.2.1