Commit af968e29 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (21 commits)
  usb: ftdi_sio: add PID for Propox ISPcable III
  Revert "xHCI: reset-on-resume quirk for NEC uPD720200"
  xHCI: fix bug in xhci_clear_command_ring()
  usb: gadget: fsl_udc: fix dequeuing a request in progress
  usb: fsl_mxc_udc.c: Remove compile-time dependency of MX35 SoC type
  usb: fsl_mxc_udc.c: Fix build issue by including missing header file
  USB: fsl_udc_core: use usb_endpoint_xfer_isoc to judge ISO XFER
  usb: udc: Fix gadget driver's speed check in various UDC drivers
  usb: gadget: fix g_serial regression
  usb: renesas_usbhs: fixup driver speed
  usb: renesas_usbhs: fixup gadget.dev.driver when udc_stop.
  usb: renesas_usbhs: fixup signal the driver that cable was disconnected
  usb: renesas_usbhs: fixup device_register timing
  usb: musb: PM: fix context save/restore in suspend/resume path
  USB: linux-cdc-acm.inf: add support for the acm_ms gadget
  EHCI : Fix a regression in the ISO scheduler
  xHCI: reset-on-resume quirk for NEC uPD720200
  USB: whci-hcd: fix endian conversion in qset_clear()
  USB: usb-storage: unusual_devs entry for Kingston DT 101 G2
  usb: option: add SIMCom SIM5218
  ...
parents f9143eae 8593b6f6
...@@ -90,10 +90,10 @@ ServiceBinary=%12%\USBSER.sys ...@@ -90,10 +90,10 @@ ServiceBinary=%12%\USBSER.sys
[SourceDisksFiles] [SourceDisksFiles]
[SourceDisksNames] [SourceDisksNames]
[DeviceList] [DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02 %DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
[DeviceList.NTamd64] [DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02 %DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
......
...@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver, ...@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,
u32 tmp; u32 tmp;
if (!driver || !bind || !driver->setup if (!driver || !bind || !driver->setup
|| driver->speed != USB_SPEED_HIGH) || driver->speed < USB_SPEED_HIGH)
return -EINVAL; return -EINVAL;
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
......
...@@ -131,8 +131,8 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ...@@ -131,8 +131,8 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
} }
if (!gser->port.in->desc || !gser->port.out->desc) { if (!gser->port.in->desc || !gser->port.out->desc) {
DBG(cdev, "activate generic ttyGS%d\n", gser->port_num); DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
if (!config_ep_by_speed(cdev->gadget, f, gser->port.in) || if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
!config_ep_by_speed(cdev->gadget, f, gser->port.out)) { config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
gser->port.in->desc = NULL; gser->port.in->desc = NULL;
gser->port.out->desc = NULL; gser->port.out->desc = NULL;
return -EINVAL; return -EINVAL;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/fsl_devices.h> #include <linux/fsl_devices.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -88,7 +89,6 @@ int fsl_udc_clk_init(struct platform_device *pdev) ...@@ -88,7 +89,6 @@ int fsl_udc_clk_init(struct platform_device *pdev)
void fsl_udc_clk_finalize(struct platform_device *pdev) void fsl_udc_clk_finalize(struct platform_device *pdev)
{ {
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
#if defined(CONFIG_SOC_IMX35)
if (cpu_is_mx35()) { if (cpu_is_mx35()) {
unsigned int v; unsigned int v;
...@@ -101,7 +101,6 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) ...@@ -101,7 +101,6 @@ void fsl_udc_clk_finalize(struct platform_device *pdev)
USBPHYCTRL_OTGBASE_OFFSET)); USBPHYCTRL_OTGBASE_OFFSET));
} }
} }
#endif
/* ULPI transceivers don't need usbpll */ /* ULPI transceivers don't need usbpll */
if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
......
...@@ -2336,8 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, ...@@ -2336,8 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver,
if (!udc_controller) if (!udc_controller)
return -ENODEV; return -ENODEV;
if (!driver || (driver->speed != USB_SPEED_FULL if (!driver || driver->speed < USB_SPEED_FULL
&& driver->speed != USB_SPEED_HIGH)
|| !bind || !driver->disconnect || !driver->setup) || !bind || !driver->disconnect || !driver->setup)
return -EINVAL; return -EINVAL;
......
...@@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) ...@@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
kfree(req); kfree(req);
} }
/*-------------------------------------------------------------------------*/ /* Actually add a dTD chain to an empty dQH and let go */
static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td)
{
struct ep_queue_head *qh = get_qh_by_ep(ep);
/* Write dQH next pointer and terminate bit to 0 */
qh->next_dtd_ptr = cpu_to_hc32(td->td_dma
& EP_QUEUE_HEAD_NEXT_POINTER_MASK);
/* Clear active and halt bit */
qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
| EP_QUEUE_HEAD_STATUS_HALT));
/* Ensure that updates to the QH will occur before priming. */
wmb();
/* Prime endpoint by writing correct bit to ENDPTPRIME */
fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16))
: (1 << (ep_index(ep))), &dr_regs->endpointprime);
}
/* Add dTD chain to the dQH of an EP */
static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
{ {
int i = ep_index(ep) * 2 + ep_is_in(ep);
u32 temp, bitmask, tmp_stat; u32 temp, bitmask, tmp_stat;
struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
/* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr); /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */ VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
...@@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) ...@@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
/* Read prime bit, if 1 goto done */ /* Read prime bit, if 1 goto done */
if (fsl_readl(&dr_regs->endpointprime) & bitmask) if (fsl_readl(&dr_regs->endpointprime) & bitmask)
goto out; return;
do { do {
/* Set ATDTW bit in USBCMD */ /* Set ATDTW bit in USBCMD */
...@@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) ...@@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd); fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
if (tmp_stat) if (tmp_stat)
goto out; return;
} }
/* Write dQH next pointer and terminate bit to 0 */ fsl_prime_ep(ep, req->head);
temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
dQH->next_dtd_ptr = cpu_to_hc32(temp);
/* Clear active and halt bit */
temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
| EP_QUEUE_HEAD_STATUS_HALT));
dQH->size_ioc_int_sts &= temp;
/* Ensure that updates to the QH will occur before priming. */
wmb();
/* Prime endpoint by writing 1 to ENDPTPRIME */
temp = ep_is_in(ep)
? (1 << (ep_index(ep) + 16))
: (1 << (ep_index(ep)));
fsl_writel(temp, &dr_regs->endpointprime);
out:
return;
} }
/* Fill in the dTD structure /* Fill in the dTD structure
...@@ -877,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) ...@@ -877,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
VDBG("%s, bad ep", __func__); VDBG("%s, bad ep", __func__);
return -EINVAL; return -EINVAL;
} }
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { if (usb_endpoint_xfer_isoc(ep->desc)) {
if (req->req.length > ep->ep.maxpacket) if (req->req.length > ep->ep.maxpacket)
return -EMSGSIZE; return -EMSGSIZE;
} }
...@@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) ...@@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
/* The request isn't the last request in this ep queue */ /* The request isn't the last request in this ep queue */
if (req->queue.next != &ep->queue) { if (req->queue.next != &ep->queue) {
struct ep_queue_head *qh;
struct fsl_req *next_req; struct fsl_req *next_req;
qh = ep->qh;
next_req = list_entry(req->queue.next, struct fsl_req, next_req = list_entry(req->queue.next, struct fsl_req,
queue); queue);
/* Point the QH to the first TD of next request */ /* prime with dTD of next request */
fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr); fsl_prime_ep(ep, next_req->head);
} }
/* The request hasn't been processed, patch up the TD chain */ /* The request hasn't been processed, patch up the TD chain */
} else { } else {
struct fsl_req *prev_req; struct fsl_req *prev_req;
prev_req = list_entry(req->queue.prev, struct fsl_req, queue); prev_req = list_entry(req->queue.prev, struct fsl_req, queue);
fsl_writel(fsl_readl(&req->tail->next_td_ptr), prev_req->tail->next_td_ptr = req->tail->next_td_ptr;
&prev_req->tail->next_td_ptr);
} }
done(ep, req, -ECONNRESET); done(ep, req, -ECONNRESET);
...@@ -1032,7 +1028,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value) ...@@ -1032,7 +1028,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
goto out; goto out;
} }
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { if (usb_endpoint_xfer_isoc(ep->desc)) {
status = -EOPNOTSUPP; status = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep) ...@@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
struct fsl_udc *udc; struct fsl_udc *udc;
int size = 0; int size = 0;
u32 bitmask; u32 bitmask;
struct ep_queue_head *d_qh; struct ep_queue_head *qh;
ep = container_of(_ep, struct fsl_ep, ep); ep = container_of(_ep, struct fsl_ep, ep);
if (!_ep || (!ep->desc && ep_index(ep) != 0)) if (!_ep || (!ep->desc && ep_index(ep) != 0))
...@@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep) ...@@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
return -ESHUTDOWN; return -ESHUTDOWN;
d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)]; qh = get_qh_by_ep(ep);
bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) : bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
(1 << (ep_index(ep))); (1 << (ep_index(ep)));
if (fsl_readl(&dr_regs->endptstatus) & bitmask) if (fsl_readl(&dr_regs->endptstatus) & bitmask)
size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE) size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE)
>> DTD_LENGTH_BIT_POS; >> DTD_LENGTH_BIT_POS;
pr_debug("%s %u\n", __func__, size); pr_debug("%s %u\n", __func__, size);
...@@ -1938,8 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver, ...@@ -1938,8 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver,
if (!udc_controller) if (!udc_controller)
return -ENODEV; return -ENODEV;
if (!driver || (driver->speed != USB_SPEED_FULL if (!driver || driver->speed < USB_SPEED_FULL
&& driver->speed != USB_SPEED_HIGH)
|| !bind || !driver->disconnect || !driver->setup) || !bind || !driver->disconnect || !driver->setup)
return -EINVAL; return -EINVAL;
......
...@@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) ...@@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
* 2 + ((windex & USB_DIR_IN) ? 1 : 0)) * 2 + ((windex & USB_DIR_IN) ? 1 : 0))
#define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP))
static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
{
/* we only have one ep0 structure but two queue heads */
if (ep_index(ep) != 0)
return ep->qh;
else
return &ep->udc->ep_qh[(ep->udc->ep0_dir ==
USB_DIR_IN) ? 1 : 0];
}
struct platform_device; struct platform_device;
#ifdef CONFIG_ARCH_MXC #ifdef CONFIG_ARCH_MXC
int fsl_udc_clk_init(struct platform_device *pdev); int fsl_udc_clk_init(struct platform_device *pdev);
......
...@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver, ...@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver,
int retval; int retval;
if (!driver if (!driver
|| driver->speed != USB_SPEED_HIGH || driver->speed < USB_SPEED_HIGH
|| !bind || !bind
|| !driver->setup) || !driver->setup)
return -EINVAL; return -EINVAL;
......
...@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget, ...@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget,
* (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
* "must not be used in normal operation" * "must not be used in normal operation"
*/ */
if (!driver || driver->speed != USB_SPEED_HIGH if (!driver || driver->speed < USB_SPEED_HIGH
|| !driver->setup) || !driver->setup)
return -EINVAL; return -EINVAL;
......
...@@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget, ...@@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget,
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
if (!driver if (!driver
|| driver->speed != USB_SPEED_HIGH || driver->speed < USB_SPEED_HIGH
|| !driver->setup) || !driver->setup)
return -EINVAL; return -EINVAL;
if (!r8a66597) if (!r8a66597)
......
...@@ -2586,10 +2586,8 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver, ...@@ -2586,10 +2586,8 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver,
return -EINVAL; return -EINVAL;
} }
if (driver->speed != USB_SPEED_HIGH && if (driver->speed < USB_SPEED_FULL)
driver->speed != USB_SPEED_FULL) {
dev_err(hsotg->dev, "%s: bad speed\n", __func__); dev_err(hsotg->dev, "%s: bad speed\n", __func__);
}
if (!bind || !driver->setup) { if (!bind || !driver->setup) {
dev_err(hsotg->dev, "%s: missing entry points\n", __func__); dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
......
...@@ -1142,8 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, ...@@ -1142,8 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver,
int ret; int ret;
if (!driver if (!driver
|| (driver->speed != USB_SPEED_FULL && || driver->speed < USB_SPEED_FULL
driver->speed != USB_SPEED_HIGH)
|| !bind || !bind
|| !driver->unbind || !driver->disconnect || !driver->setup) || !driver->unbind || !driver->disconnect || !driver->setup)
return -EINVAL; return -EINVAL;
......
...@@ -1475,6 +1475,7 @@ iso_stream_schedule ( ...@@ -1475,6 +1475,7 @@ iso_stream_schedule (
* jump until after the queue is primed. * jump until after the queue is primed.
*/ */
else { else {
int done = 0;
start = SCHEDULE_SLOP + (now & ~0x07); start = SCHEDULE_SLOP + (now & ~0x07);
/* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
...@@ -1492,18 +1493,18 @@ iso_stream_schedule ( ...@@ -1492,18 +1493,18 @@ iso_stream_schedule (
if (stream->highspeed) { if (stream->highspeed) {
if (itd_slot_ok(ehci, mod, start, if (itd_slot_ok(ehci, mod, start,
stream->usecs, period)) stream->usecs, period))
break; done = 1;
} else { } else {
if ((start % 8) >= 6) if ((start % 8) >= 6)
continue; continue;
if (sitd_slot_ok(ehci, mod, stream, if (sitd_slot_ok(ehci, mod, stream,
start, sched, period)) start, sched, period))
break; done = 1;
} }
} while (start > next); } while (start > next && !done);
/* no room in the schedule */ /* no room in the schedule */
if (start == next) { if (!done) {
ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
urb, now, now + mod); urb, now, now + mod);
status = -ENOSPC; status = -ENOSPC;
......
...@@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) ...@@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
{ {
qset->td_start = qset->td_end = qset->ntds = 0; qset->td_start = qset->td_end = qset->ntds = 0;
qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
qset->qh.err_count = 0; qset->qh.err_count = 0;
qset->qh.scratch[0] = 0; qset->qh.scratch[0] = 0;
......
...@@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) ...@@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
ring = xhci->cmd_ring; ring = xhci->cmd_ring;
seg = ring->deq_seg; seg = ring->deq_seg;
do { do {
memset(seg->trbs, 0, SEGMENT_SIZE); memset(seg->trbs, 0,
sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
cpu_to_le32(~TRB_CYCLE);
seg = seg->next; seg = seg->next;
} while (seg != ring->deq_seg); } while (seg != ring->deq_seg);
......
...@@ -2301,18 +2301,12 @@ static int musb_suspend(struct device *dev) ...@@ -2301,18 +2301,12 @@ static int musb_suspend(struct device *dev)
*/ */
} }
musb_save_context(musb);
spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags);
return 0; return 0;
} }
static int musb_resume_noirq(struct device *dev) static int musb_resume_noirq(struct device *dev)
{ {
struct musb *musb = dev_to_musb(dev);
musb_restore_context(musb);
/* for static cmos like DaVinci, register values were preserved /* for static cmos like DaVinci, register values were preserved
* unless for some reason the whole soc powered down or the USB * unless for some reason the whole soc powered down or the USB
* module got reset through the PSC (vs just being disabled). * module got reset through the PSC (vs just being disabled).
......
...@@ -1903,7 +1903,7 @@ static int musb_gadget_start(struct usb_gadget *g, ...@@ -1903,7 +1903,7 @@ static int musb_gadget_start(struct usb_gadget *g,
unsigned long flags; unsigned long flags;
int retval = -EINVAL; int retval = -EINVAL;
if (driver->speed != USB_SPEED_HIGH) if (driver->speed < USB_SPEED_HIGH)
goto err0; goto err0;
pm_runtime_get_sync(musb->controller); pm_runtime_get_sync(musb->controller);
......
...@@ -751,53 +751,32 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, ...@@ -751,53 +751,32 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver) struct usb_gadget_driver *driver)
{ {
struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
struct usbhs_priv *priv; struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
struct device *dev;
int ret;
if (!driver || if (!driver ||
!driver->setup || !driver->setup ||
driver->speed != USB_SPEED_HIGH) driver->speed < USB_SPEED_FULL)
return -EINVAL; return -EINVAL;
dev = usbhsg_gpriv_to_dev(gpriv);
priv = usbhsg_gpriv_to_priv(gpriv);
/* first hook up the driver ... */ /* first hook up the driver ... */
gpriv->driver = driver; gpriv->driver = driver;
gpriv->gadget.dev.driver = &driver->driver; gpriv->gadget.dev.driver = &driver->driver;
ret = device_add(&gpriv->gadget.dev);
if (ret) {
dev_err(dev, "device_add error %d\n", ret);
goto add_fail;
}
return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD);
add_fail:
gpriv->driver = NULL;
gpriv->gadget.dev.driver = NULL;
return ret;
} }
static int usbhsg_gadget_stop(struct usb_gadget *gadget, static int usbhsg_gadget_stop(struct usb_gadget *gadget,
struct usb_gadget_driver *driver) struct usb_gadget_driver *driver)
{ {
struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
struct usbhs_priv *priv; struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
struct device *dev;
if (!driver || if (!driver ||
!driver->unbind) !driver->unbind)
return -EINVAL; return -EINVAL;
dev = usbhsg_gpriv_to_dev(gpriv);
priv = usbhsg_gpriv_to_priv(gpriv);
usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD);
device_del(&gpriv->gadget.dev); gpriv->gadget.dev.driver = NULL;
gpriv->driver = NULL; gpriv->driver = NULL;
return 0; return 0;
...@@ -827,6 +806,13 @@ static int usbhsg_start(struct usbhs_priv *priv) ...@@ -827,6 +806,13 @@ static int usbhsg_start(struct usbhs_priv *priv)
static int usbhsg_stop(struct usbhs_priv *priv) static int usbhsg_stop(struct usbhs_priv *priv)
{ {
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
/* cable disconnect */
if (gpriv->driver &&
gpriv->driver->disconnect)
gpriv->driver->disconnect(&gpriv->gadget);
return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
} }
...@@ -876,12 +862,14 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ...@@ -876,12 +862,14 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
/* /*
* init gadget * init gadget
*/ */
device_initialize(&gpriv->gadget.dev);
dev_set_name(&gpriv->gadget.dev, "gadget"); dev_set_name(&gpriv->gadget.dev, "gadget");
gpriv->gadget.dev.parent = dev; gpriv->gadget.dev.parent = dev;
gpriv->gadget.name = "renesas_usbhs_udc"; gpriv->gadget.name = "renesas_usbhs_udc";
gpriv->gadget.ops = &usbhsg_gadget_ops; gpriv->gadget.ops = &usbhsg_gadget_ops;
gpriv->gadget.is_dualspeed = 1; gpriv->gadget.is_dualspeed = 1;
ret = device_register(&gpriv->gadget.dev);
if (ret < 0)
goto err_add_udc;
INIT_LIST_HEAD(&gpriv->gadget.ep_list); INIT_LIST_HEAD(&gpriv->gadget.ep_list);
...@@ -912,12 +900,15 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ...@@ -912,12 +900,15 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
ret = usb_add_gadget_udc(dev, &gpriv->gadget); ret = usb_add_gadget_udc(dev, &gpriv->gadget);
if (ret) if (ret)
goto err_add_udc; goto err_register;
dev_info(dev, "gadget probed\n"); dev_info(dev, "gadget probed\n");
return 0; return 0;
err_register:
device_unregister(&gpriv->gadget.dev);
err_add_udc: err_add_udc:
kfree(gpriv->uep); kfree(gpriv->uep);
...@@ -933,6 +924,8 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv) ...@@ -933,6 +924,8 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
usb_del_gadget_udc(&gpriv->gadget); usb_del_gadget_udc(&gpriv->gadget);
device_unregister(&gpriv->gadget.dev);
usbhsg_controller_unregister(gpriv); usbhsg_controller_unregister(gpriv);
kfree(gpriv->uep); kfree(gpriv->uep);
......
...@@ -736,6 +736,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -736,6 +736,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
......
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
/* Propox devices */ /* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739
/* Lenz LI-USB Computer Interface. */ /* Lenz LI-USB Computer Interface. */
#define FTDI_LENZ_LIUSB_PID 0xD780 #define FTDI_LENZ_LIUSB_PID 0xD780
......
...@@ -661,6 +661,9 @@ static const struct usb_device_id option_ids[] = { ...@@ -661,6 +661,9 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
...@@ -747,6 +750,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -747,6 +750,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
......
...@@ -1854,6 +1854,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, ...@@ -1854,6 +1854,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ), US_FL_IGNORE_RESIDUE ),
/* Reported by Qinglin Ye <yestyle@gmail.com> */
UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100,
"Kingston",
"DT 101 G2",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BULK_IGNORE_TAG ),
/* Reported by Francesco Foresti <frafore@tiscali.it> */ /* Reported by Francesco Foresti <frafore@tiscali.it> */
UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201,
"Super Top", "Super Top",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment