Skip to content

Commit

Permalink
Merge tag 'usb-3.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/usb

Pull USB patches from Greg Kroah-Hartman:
 "Here are a number of USB patches, a bit more than I normally like this
  late in the -rc series, but given people's vacations (myself
  included), and the kernel summit, it seems to have happened this way.

  All are tiny, but they add up.  A number of gadget and xhci fixes, and
  a few new device ids.  All have been tested in linux-next.

  Signed-off-by: Greg Kroah-Hartman <[email protected]>"

* tag 'usb-3.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (33 commits)
  usb: chipidea: udc: don't stall endpoint if request list is empty in isr_tr_complete_low
  usb: chipidea: cleanup dma_pool if udc_start() fails
  usb: chipidea: udc: fix error path in udc_start()
  usb: chipidea: udc: add pullup fuction, needed by the uvc gadget
  usb: chipidea: udc: fix setup of endpoint maxpacket size
  USB: option: replace ZTE K5006-Z entry with vendor class rule
  EHCI: Update qTD next pointer in QH overlay region during unlink
  USB: cdc-wdm: fix wdm_find_device* return value
  USB: ftdi_sio: do not claim CDC ACM function
  usb: dwc3: gadget: fix pending isoc handling
  usb: renesas_usbhs: fixup DMA transport data alignment
  usb: gadget: at91udc: Don't check for ep->ep.desc
  usb: gadget: at91udc: don't overwrite driver data
  usb: dwc3: core: fix incorrect usage of resource pointer
  usb: musb: musbhsdma: fix IRQ check
  usb: musb: tusb6010: fix error path in tusb_probe()
  usb: musb: host: fix for musb_start_urb Oops
  usb: gadget: dummy_hcd: add support for USB_DT_BOS on rh
  usb: gadget: dummy_hcd: fixup error probe path
  usb: gadget: s3c-hsotg.c: fix error return code
  ...
  • Loading branch information
torvalds committed Sep 14, 2012
2 parents fe59d29 + 38bb2ca commit 4bca55d
Show file tree
Hide file tree
Showing 26 changed files with 410 additions and 57 deletions.
59 changes: 41 additions & 18 deletions drivers/usb/chipidea/udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n)
}

/**
* hw_device_state: enables/disables interrupts & starts/stops device (execute
* without interruption)
* hw_device_state: enables/disables interrupts (execute without interruption)
* @dma: 0 => disable, !0 => enable and set dma engine
*
* This function returns an error code
Expand All @@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma)
/* interrupt, error, port change, reset, sleep/suspend */
hw_write(ci, OP_USBINTR, ~0,
USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
} else {
hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
hw_write(ci, OP_USBINTR, ~0, 0);
}
return 0;
Expand Down Expand Up @@ -774,10 +771,7 @@ __acquires(mEp->lock)
{
struct ci13xxx_req *mReq, *mReqTemp;
struct ci13xxx_ep *mEpTemp = mEp;
int uninitialized_var(retval);

if (list_empty(&mEp->qh.queue))
return -EINVAL;
int retval = 0;

list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
queue) {
Expand Down Expand Up @@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
return -ENOTSUPP;
}

/* Change Data+ pullup status
* this func is used by usb_gadget_connect/disconnet
*/
static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on)
{
struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget);

if (is_on)
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
else
hw_write(ci, OP_USBCMD, USBCMD_RS, 0);

return 0;
}

static int ci13xxx_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver);
static int ci13xxx_stop(struct usb_gadget *gadget,
Expand All @@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget,
static const struct usb_gadget_ops usb_gadget_ops = {
.vbus_session = ci13xxx_vbus_session,
.wakeup = ci13xxx_wakeup,
.pullup = ci13xxx_pullup,
.vbus_draw = ci13xxx_vbus_draw,
.udc_start = ci13xxx_start,
.udc_stop = ci13xxx_stop,
Expand All @@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci)

mEp->ep.name = mEp->name;
mEp->ep.ops = &usb_ep_ops;
mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
/*
* for ep0: maxP defined in desc, for other
* eps, maxP is set by epautoconfig() called
* by gadget layer
*/
mEp->ep.maxpacket = (unsigned short)~0;

INIT_LIST_HEAD(&mEp->qh.queue);
mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL,
Expand All @@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci)
else
ci->ep0in = mEp;

mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
continue;
}

Expand All @@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci)
return retval;
}

static void destroy_eps(struct ci13xxx *ci)
{
int i;

for (i = 0; i < ci->hw_ep_max; i++) {
struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i];

dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma);
}
}

/**
* ci13xxx_start: register a gadget driver
* @gadget: our gadget
Expand Down Expand Up @@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci)
if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
if (ci->transceiver == NULL) {
retval = -ENODEV;
goto free_pools;
goto destroy_eps;
}
}

Expand Down Expand Up @@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci)

remove_trans:
if (!IS_ERR_OR_NULL(ci->transceiver)) {
otg_set_peripheral(ci->transceiver->otg, &ci->gadget);
otg_set_peripheral(ci->transceiver->otg, NULL);
if (ci->global_phy)
usb_put_phy(ci->transceiver);
}
Expand All @@ -1742,6 +1769,8 @@ static int udc_start(struct ci13xxx *ci)
put_transceiver:
if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy)
usb_put_phy(ci->transceiver);
destroy_eps:
destroy_eps(ci);
free_pools:
dma_pool_destroy(ci->td_pool);
free_qh_pool:
Expand All @@ -1756,18 +1785,12 @@ static int udc_start(struct ci13xxx *ci)
*/
static void udc_stop(struct ci13xxx *ci)
{
int i;

if (ci == NULL)
return;

usb_del_gadget_udc(&ci->gadget);

for (i = 0; i < ci->hw_ep_max; i++) {
struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i];

dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma);
}
destroy_eps(ci);

dma_pool_destroy(ci->td_pool);
dma_pool_destroy(ci->qh_pool);
Expand Down
12 changes: 8 additions & 4 deletions drivers/usb/class/cdc-wdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,29 @@ static struct usb_driver wdm_driver;
/* return intfdata if we own the interface, else look up intf in the list */
static struct wdm_device *wdm_find_device(struct usb_interface *intf)
{
struct wdm_device *desc = NULL;
struct wdm_device *desc;

spin_lock(&wdm_device_list_lock);
list_for_each_entry(desc, &wdm_device_list, device_list)
if (desc->intf == intf)
break;
goto found;
desc = NULL;
found:
spin_unlock(&wdm_device_list_lock);

return desc;
}

static struct wdm_device *wdm_find_device_by_minor(int minor)
{
struct wdm_device *desc = NULL;
struct wdm_device *desc;

spin_lock(&wdm_device_list_lock);
list_for_each_entry(desc, &wdm_device_list, device_list)
if (desc->intf->minor == minor)
break;
goto found;
desc = NULL;
found:
spin_unlock(&wdm_device_list_lock);

return desc;
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x04b4, 0x0526), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },

/* Microchip Joss Optical infrared touchboard device */
{ USB_DEVICE(0x04d8, 0x000c), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },

/* Samsung Android phone modem - ID conflict with SPH-I500 */
{ USB_DEVICE(0x04e8, 0x6601), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
Expand Down
9 changes: 7 additions & 2 deletions drivers/usb/dwc3/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
dev_err(dev, "missing IRQ\n");
return -ENODEV;
}
dwc->xhci_resources[1] = *res;
dwc->xhci_resources[1].start = res->start;
dwc->xhci_resources[1].end = res->end;
dwc->xhci_resources[1].flags = res->flags;
dwc->xhci_resources[1].name = res->name;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "missing memory resource\n");
return -ENODEV;
}
dwc->xhci_resources[0] = *res;
dwc->xhci_resources[0].start = res->start;
dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
DWC3_XHCI_REGS_END;
dwc->xhci_resources[0].flags = res->flags;
dwc->xhci_resources[0].name = res->name;

/*
* Request memory region but exclude xHCI regs,
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
transferred = min_t(u32, ur->length,
transfer_size - length);
memcpy(ur->buf, dwc->ep0_bounce, transferred);
dwc->ep0_bounced = false;
} else {
transferred = ur->length - length;
}
Expand Down
19 changes: 17 additions & 2 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
if (req->request.status == -EINPROGRESS)
req->request.status = status;

usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);
if (dwc->ep0_bounced && dep->number == 0)
dwc->ep0_bounced = false;
else
usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);

dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
req, dep->name, req->request.actual,
Expand Down Expand Up @@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,
if (list_empty(&dep->request_list)) {
dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",
dep->name);
dep->flags |= DWC3_EP_PENDING_REQUEST;
return;
}

Expand Down Expand Up @@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
if (dep->flags & DWC3_EP_PENDING_REQUEST) {
int ret;

/*
* If xfernotready is already elapsed and it is a case
* of isoc transfer, then issue END TRANSFER, so that
* you can receive xfernotready again and can have
* notion of current microframe.
*/
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
dwc3_stop_active_transfer(dwc, dep->number);
return 0;
}

ret = __dwc3_gadget_kick_transfer(dep, 0, true);
if (ret && ret != -EBUSY) {
struct dwc3 *dwc = dep->dwc;
Expand Down
6 changes: 1 addition & 5 deletions drivers/usb/gadget/at91_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
unsigned long flags;

if (!_ep || !ep
|| !desc || ep->ep.desc
|| _ep->name == ep0name
|| !desc || _ep->name == ep0name
|| desc->bDescriptorType != USB_DT_ENDPOINT
|| (maxpacket = usb_endpoint_maxp(desc)) == 0
|| maxpacket > ep->maxpacket) {
Expand Down Expand Up @@ -530,7 +529,6 @@ static int at91_ep_enable(struct usb_ep *_ep,
tmp |= AT91_UDP_EPEDS;
__raw_writel(tmp, ep->creg);

ep->ep.desc = desc;
ep->ep.maxpacket = maxpacket;

/*
Expand Down Expand Up @@ -1635,7 +1633,6 @@ static int at91_start(struct usb_gadget *gadget,
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
udc->gadget.dev.of_node = udc->pdev->dev.of_node;
dev_set_drvdata(&udc->gadget.dev, &driver->driver);
udc->enabled = 1;
udc->selfpowered = 1;

Expand All @@ -1656,7 +1653,6 @@ static int at91_stop(struct usb_gadget *gadget,
spin_unlock_irqrestore(&udc->lock, flags);

udc->gadget.dev.driver = NULL;
dev_set_drvdata(&udc->gadget.dev, NULL);
udc->driver = NULL;

DBG("unbound from %s\n", driver->driver.name);
Expand Down
41 changes: 37 additions & 4 deletions drivers/usb/gadget/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,27 @@ static int dummy_hub_status(struct usb_hcd *hcd, char *buf)
return retval;
}

/* usb 3.0 root hub device descriptor */
struct {
struct usb_bos_descriptor bos;
struct usb_ss_cap_descriptor ss_cap;
} __packed usb3_bos_desc = {

.bos = {
.bLength = USB_DT_BOS_SIZE,
.bDescriptorType = USB_DT_BOS,
.wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)),
.bNumDeviceCaps = 1,
},
.ss_cap = {
.bLength = USB_DT_USB_SS_CAP_SIZE,
.bDescriptorType = USB_DT_DEVICE_CAPABILITY,
.bDevCapabilityType = USB_SS_CAP_TYPE,
.wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION),
.bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION),
},
};

static inline void
ss_hub_descriptor(struct usb_hub_descriptor *desc)
{
Expand Down Expand Up @@ -2006,6 +2027,18 @@ static int dummy_hub_control(
else
hub_descriptor((struct usb_hub_descriptor *) buf);
break;

case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
if (hcd->speed != HCD_USB3)
goto error;

if ((wValue >> 8) != USB_DT_BOS)
goto error;

memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc));
retval = sizeof(usb3_bos_desc);
break;

case GetHubStatus:
*(__le32 *) buf = cpu_to_le32(0);
break;
Expand Down Expand Up @@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)
hs_hcd->has_tt = 1;

retval = usb_add_hcd(hs_hcd, 0, 0);
if (retval != 0) {
usb_put_hcd(hs_hcd);
return retval;
}
if (retval)
goto put_usb2_hcd;

if (mod_data.is_super_speed) {
ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev,
Expand All @@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)
put_usb3_hcd:
usb_put_hcd(ss_hcd);
dealloc_usb2_hcd:
usb_remove_hcd(hs_hcd);
put_usb2_hcd:
usb_put_hcd(hs_hcd);
the_controller.hs_hcd = the_controller.ss_hcd = NULL;
return retval;
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/gadget/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@
/* Debugging ****************************************************************/

#ifdef VERBOSE_DEBUG
#ifndef pr_vdebug
# define pr_vdebug pr_debug
#endif /* pr_vdebug */
# define ffs_dump_mem(prefix, ptr, len) \
print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
#else
#ifndef pr_vdebug
# define pr_vdebug(...) do { } while (0)
#endif /* pr_vdebug */
# define ffs_dump_mem(prefix, ptr, len) do { } while (0)
#endif /* VERBOSE_DEBUG */

Expand Down
Loading

0 comments on commit 4bca55d

Please sign in to comment.