diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 15:33:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 15:33:02 -0400 |
commit | c44dead70a841d90ddc01968012f323c33217c9e (patch) | |
tree | 85489ebe9b9a3413cd8ee197ffb40c8aa8d97e63 /drivers/usb/gadget | |
parent | 99dff5856220a02b8711f2e8746413ea6e53ccf6 (diff) | |
parent | d5f6db9e1aff6ccf1876224f152c0268b0c8a992 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (205 commits)
USB: EHCI: Remove SPARC_LEON {read,write}_be definitions from ehci.h
USB: UHCI: Support big endian GRUSBHC HC
sparc: add {read,write}*_be routines
USB: UHCI: Add support for big endian descriptors
USB: UHCI: Use ACCESS_ONCE rather than using a full compiler barrier
USB: UHCI: Add support for big endian mmio
usb-storage: Correct adjust_quirks to include latest flags
usb/isp1760: Fix possible unlink problems
usb/isp1760: Move function isp1760_endpoint_disable() within file.
USB: remove remaining usages of hcd->state from usbcore and fix regression
usb: musb: ux500: add configuration and build options for ux500 dma
usb: musb: ux500: add dma glue layer for ux500
usb: musb: ux500: add dma name for ux500
usb: musb: ux500: add ux500 specific code for gadget side
usb: musb: fix compile error
usb-storage: fix up the unusual_realtek device list
USB: gadget: f_audio: Fix invalid dereference of initdata
EHCI: don't rescan interrupt QHs needlessly
OHCI: fix regression caused by nVidia shutdown workaround
USB: OTG: msm: Free VCCCX regulator even if we can't set the voltage
...
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 35 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 75 | ||||
-rw-r--r-- | drivers/usb/gadget/composite.c | 62 | ||||
-rw-r--r-- | drivers/usb/gadget/dbgp.c | 14 | ||||
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 21 | ||||
-rw-r--r-- | drivers/usb/gadget/f_audio.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 68 | ||||
-rw-r--r-- | drivers/usb/gadget/f_rndis.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 55 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_qe_udc.h | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 438 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/gadget_chips.h | 17 | ||||
-rw-r--r-- | drivers/usb/gadget/printer.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 235 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c-hsudc.c | 1349 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 18 |
19 files changed, 2107 insertions, 298 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bc5123cf41c2..58456d1aec21 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -260,6 +260,24 @@ config USB_R8A66597 | |||
260 | default USB_GADGET | 260 | default USB_GADGET |
261 | select USB_GADGET_SELECTED | 261 | select USB_GADGET_SELECTED |
262 | 262 | ||
263 | config USB_GADGET_RENESAS_USBHS | ||
264 | boolean "Renesas USBHS" | ||
265 | depends on USB_RENESAS_USBHS | ||
266 | select USB_GADGET_DUALSPEED | ||
267 | help | ||
268 | Renesas USBHS is a discrete USB host and peripheral controller | ||
269 | chip that supports both full and high speed USB 2.0 data transfers. | ||
270 | platform is able to configure endpoint (pipe) style | ||
271 | |||
272 | Say "y" to enable the gadget specific portion of the USBHS driver. | ||
273 | |||
274 | |||
275 | config USB_RENESAS_USBHS_UDC | ||
276 | tristate | ||
277 | depends on USB_GADGET_RENESAS_USBHS | ||
278 | default USB_GADGET | ||
279 | select USB_GADGET_SELECTED | ||
280 | |||
263 | config USB_GADGET_PXA27X | 281 | config USB_GADGET_PXA27X |
264 | boolean "PXA 27x" | 282 | boolean "PXA 27x" |
265 | depends on ARCH_PXA && (PXA27x || PXA3xx) | 283 | depends on ARCH_PXA && (PXA27x || PXA3xx) |
@@ -338,6 +356,23 @@ config USB_S3C2410_DEBUG | |||
338 | boolean "S3C2410 udc debug messages" | 356 | boolean "S3C2410 udc debug messages" |
339 | depends on USB_GADGET_S3C2410 | 357 | depends on USB_GADGET_S3C2410 |
340 | 358 | ||
359 | config USB_GADGET_S3C_HSUDC | ||
360 | boolean "S3C2416, S3C2443 and S3C2450 USB Device Controller" | ||
361 | depends on ARCH_S3C2410 | ||
362 | select USB_GADGET_DUALSPEED | ||
363 | help | ||
364 | Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC | ||
365 | integrated with dual speed USB 2.0 device controller. It has | ||
366 | 8 endpoints, as well as endpoint zero. | ||
367 | |||
368 | This driver has been tested on S3C2416 and S3C2450 processors. | ||
369 | |||
370 | config USB_S3C_HSUDC | ||
371 | tristate | ||
372 | depends on USB_GADGET_S3C_HSUDC | ||
373 | default USB_GADGET | ||
374 | select USB_GADGET_SELECTED | ||
375 | |||
341 | config USB_GADGET_PXA_U2O | 376 | config USB_GADGET_PXA_U2O |
342 | boolean "PXA9xx Processor USB2.0 controller" | 377 | boolean "PXA9xx Processor USB2.0 controller" |
343 | select USB_GADGET_DUALSPEED | 378 | select USB_GADGET_DUALSPEED |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1ea15ee74fd3..4fe92b18a055 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | |||
22 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | 22 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o |
23 | obj-$(CONFIG_USB_CI13XXX_PCI) += ci13xxx_pci.o | 23 | obj-$(CONFIG_USB_CI13XXX_PCI) += ci13xxx_pci.o |
24 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o | 24 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o |
25 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | ||
25 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o | 26 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o |
26 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | 27 | obj-$(CONFIG_USB_EG20T) += pch_udc.o |
27 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o | 28 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 9b7cdb16f26b..41dc093c0a1b 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1767,7 +1767,7 @@ static int __init at91udc_probe(struct platform_device *pdev) | |||
1767 | } | 1767 | } |
1768 | 1768 | ||
1769 | /* newer chips have more FIFO memory than rm9200 */ | 1769 | /* newer chips have more FIFO memory than rm9200 */ |
1770 | if (cpu_is_at91sam9260()) { | 1770 | if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) { |
1771 | udc->ep[0].maxpacket = 64; | 1771 | udc->ep[0].maxpacket = 64; |
1772 | udc->ep[3].maxpacket = 64; | 1772 | udc->ep[3].maxpacket = 64; |
1773 | udc->ep[4].maxpacket = 512; | 1773 | udc->ep[4].maxpacket = 512; |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index e09178bc1450..baaf87ed7685 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -310,7 +310,7 @@ static int hw_device_reset(struct ci13xxx *udc) | |||
310 | udc->udc_driver->notify_event(udc, | 310 | udc->udc_driver->notify_event(udc, |
311 | CI13XXX_CONTROLLER_RESET_EVENT); | 311 | CI13XXX_CONTROLLER_RESET_EVENT); |
312 | 312 | ||
313 | if (udc->udc_driver->flags && CI13XXX_DISABLE_STREAMING) | 313 | if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING) |
314 | hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS); | 314 | hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS); |
315 | 315 | ||
316 | /* USBMODE should be configured step by step */ | 316 | /* USBMODE should be configured step by step */ |
@@ -1634,8 +1634,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) | |||
1634 | gadget_for_each_ep(ep, gadget) { | 1634 | gadget_for_each_ep(ep, gadget) { |
1635 | usb_ep_disable(ep); | 1635 | usb_ep_disable(ep); |
1636 | } | 1636 | } |
1637 | usb_ep_disable(&udc->ep0out.ep); | ||
1638 | usb_ep_disable(&udc->ep0in.ep); | ||
1639 | 1637 | ||
1640 | if (udc->status != NULL) { | 1638 | if (udc->status != NULL) { |
1641 | usb_ep_free_request(&udc->ep0in.ep, udc->status); | 1639 | usb_ep_free_request(&udc->ep0in.ep, udc->status); |
@@ -1678,18 +1676,10 @@ __acquires(udc->lock) | |||
1678 | if (retval) | 1676 | if (retval) |
1679 | goto done; | 1677 | goto done; |
1680 | 1678 | ||
1681 | retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc); | 1679 | udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC); |
1682 | if (retval) | 1680 | if (udc->status == NULL) |
1683 | goto done; | 1681 | retval = -ENOMEM; |
1684 | 1682 | ||
1685 | retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc); | ||
1686 | if (!retval) { | ||
1687 | udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC); | ||
1688 | if (udc->status == NULL) { | ||
1689 | usb_ep_disable(&udc->ep0out.ep); | ||
1690 | retval = -ENOMEM; | ||
1691 | } | ||
1692 | } | ||
1693 | spin_lock(udc->lock); | 1683 | spin_lock(udc->lock); |
1694 | 1684 | ||
1695 | done: | 1685 | done: |
@@ -1843,7 +1833,8 @@ __releases(mEp->lock) | |||
1843 | __acquires(mEp->lock) | 1833 | __acquires(mEp->lock) |
1844 | { | 1834 | { |
1845 | struct ci13xxx_req *mReq, *mReqTemp; | 1835 | struct ci13xxx_req *mReq, *mReqTemp; |
1846 | int retval; | 1836 | struct ci13xxx_ep *mEpTemp = mEp; |
1837 | int uninitialized_var(retval); | ||
1847 | 1838 | ||
1848 | trace("%p", mEp); | 1839 | trace("%p", mEp); |
1849 | 1840 | ||
@@ -1859,12 +1850,15 @@ __acquires(mEp->lock) | |||
1859 | dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); | 1850 | dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); |
1860 | if (mReq->req.complete != NULL) { | 1851 | if (mReq->req.complete != NULL) { |
1861 | spin_unlock(mEp->lock); | 1852 | spin_unlock(mEp->lock); |
1862 | mReq->req.complete(&mEp->ep, &mReq->req); | 1853 | if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) && |
1854 | mReq->req.length) | ||
1855 | mEpTemp = &_udc->ep0in; | ||
1856 | mReq->req.complete(&mEpTemp->ep, &mReq->req); | ||
1863 | spin_lock(mEp->lock); | 1857 | spin_lock(mEp->lock); |
1864 | } | 1858 | } |
1865 | } | 1859 | } |
1866 | 1860 | ||
1867 | if (retval == EBUSY) | 1861 | if (retval == -EBUSY) |
1868 | retval = 0; | 1862 | retval = 0; |
1869 | if (retval < 0) | 1863 | if (retval < 0) |
1870 | dbg_event(_usb_addr(mEp), "DONE", retval); | 1864 | dbg_event(_usb_addr(mEp), "DONE", retval); |
@@ -1894,7 +1888,7 @@ __acquires(udc->lock) | |||
1894 | 1888 | ||
1895 | for (i = 0; i < hw_ep_max; i++) { | 1889 | for (i = 0; i < hw_ep_max; i++) { |
1896 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; | 1890 | struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; |
1897 | int type, num, err = -EINVAL; | 1891 | int type, num, dir, err = -EINVAL; |
1898 | struct usb_ctrlrequest req; | 1892 | struct usb_ctrlrequest req; |
1899 | 1893 | ||
1900 | if (mEp->desc == NULL) | 1894 | if (mEp->desc == NULL) |
@@ -1952,7 +1946,10 @@ __acquires(udc->lock) | |||
1952 | if (req.wLength != 0) | 1946 | if (req.wLength != 0) |
1953 | break; | 1947 | break; |
1954 | num = le16_to_cpu(req.wIndex); | 1948 | num = le16_to_cpu(req.wIndex); |
1949 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
1955 | num &= USB_ENDPOINT_NUMBER_MASK; | 1950 | num &= USB_ENDPOINT_NUMBER_MASK; |
1951 | if (dir) /* TX */ | ||
1952 | num += hw_ep_max/2; | ||
1956 | if (!udc->ci13xxx_ep[num].wedge) { | 1953 | if (!udc->ci13xxx_ep[num].wedge) { |
1957 | spin_unlock(udc->lock); | 1954 | spin_unlock(udc->lock); |
1958 | err = usb_ep_clear_halt( | 1955 | err = usb_ep_clear_halt( |
@@ -2001,7 +1998,10 @@ __acquires(udc->lock) | |||
2001 | if (req.wLength != 0) | 1998 | if (req.wLength != 0) |
2002 | break; | 1999 | break; |
2003 | num = le16_to_cpu(req.wIndex); | 2000 | num = le16_to_cpu(req.wIndex); |
2001 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
2004 | num &= USB_ENDPOINT_NUMBER_MASK; | 2002 | num &= USB_ENDPOINT_NUMBER_MASK; |
2003 | if (dir) /* TX */ | ||
2004 | num += hw_ep_max/2; | ||
2005 | 2005 | ||
2006 | spin_unlock(udc->lock); | 2006 | spin_unlock(udc->lock); |
2007 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); | 2007 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); |
@@ -2110,7 +2110,12 @@ static int ep_enable(struct usb_ep *ep, | |||
2110 | (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; | 2110 | (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; |
2111 | mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */ | 2111 | mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */ |
2112 | 2112 | ||
2113 | retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); | 2113 | /* |
2114 | * Enable endpoints in the HW other than ep0 as ep0 | ||
2115 | * is always enabled | ||
2116 | */ | ||
2117 | if (mEp->num) | ||
2118 | retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); | ||
2114 | 2119 | ||
2115 | spin_unlock_irqrestore(mEp->lock, flags); | 2120 | spin_unlock_irqrestore(mEp->lock, flags); |
2116 | return retval; | 2121 | return retval; |
@@ -2242,11 +2247,15 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
2242 | 2247 | ||
2243 | spin_lock_irqsave(mEp->lock, flags); | 2248 | spin_lock_irqsave(mEp->lock, flags); |
2244 | 2249 | ||
2245 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL && | 2250 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { |
2246 | !list_empty(&mEp->qh.queue)) { | 2251 | if (req->length) |
2247 | _ep_nuke(mEp); | 2252 | mEp = (_udc->ep0_dir == RX) ? |
2248 | retval = -EOVERFLOW; | 2253 | &_udc->ep0out : &_udc->ep0in; |
2249 | warn("endpoint ctrl %X nuked", _usb_addr(mEp)); | 2254 | if (!list_empty(&mEp->qh.queue)) { |
2255 | _ep_nuke(mEp); | ||
2256 | retval = -EOVERFLOW; | ||
2257 | warn("endpoint ctrl %X nuked", _usb_addr(mEp)); | ||
2258 | } | ||
2250 | } | 2259 | } |
2251 | 2260 | ||
2252 | /* first nuke then test link, e.g. previous status has not sent */ | 2261 | /* first nuke then test link, e.g. previous status has not sent */ |
@@ -2497,6 +2506,15 @@ out: | |||
2497 | return ret; | 2506 | return ret; |
2498 | } | 2507 | } |
2499 | 2508 | ||
2509 | static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
2510 | { | ||
2511 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
2512 | |||
2513 | if (udc->transceiver) | ||
2514 | return otg_set_power(udc->transceiver, mA); | ||
2515 | return -ENOTSUPP; | ||
2516 | } | ||
2517 | |||
2500 | /** | 2518 | /** |
2501 | * Device operations part of the API to the USB controller hardware, | 2519 | * Device operations part of the API to the USB controller hardware, |
2502 | * which don't involve endpoints (or i/o) | 2520 | * which don't involve endpoints (or i/o) |
@@ -2505,6 +2523,7 @@ out: | |||
2505 | static const struct usb_gadget_ops usb_gadget_ops = { | 2523 | static const struct usb_gadget_ops usb_gadget_ops = { |
2506 | .vbus_session = ci13xxx_vbus_session, | 2524 | .vbus_session = ci13xxx_vbus_session, |
2507 | .wakeup = ci13xxx_wakeup, | 2525 | .wakeup = ci13xxx_wakeup, |
2526 | .vbus_draw = ci13xxx_vbus_draw, | ||
2508 | }; | 2527 | }; |
2509 | 2528 | ||
2510 | /** | 2529 | /** |
@@ -2595,6 +2614,14 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2595 | } | 2614 | } |
2596 | if (retval) | 2615 | if (retval) |
2597 | goto done; | 2616 | goto done; |
2617 | spin_unlock_irqrestore(udc->lock, flags); | ||
2618 | retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc); | ||
2619 | if (retval) | ||
2620 | return retval; | ||
2621 | retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc); | ||
2622 | if (retval) | ||
2623 | return retval; | ||
2624 | spin_lock_irqsave(udc->lock, flags); | ||
2598 | 2625 | ||
2599 | udc->gadget.ep0 = &udc->ep0in.ep; | 2626 | udc->gadget.ep0 = &udc->ep0in.ep; |
2600 | /* bind gadget */ | 2627 | /* bind gadget */ |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 82314ed22506..5cbb1a41c223 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -461,12 +461,23 @@ static int set_config(struct usb_composite_dev *cdev, | |||
461 | reset_config(cdev); | 461 | reset_config(cdev); |
462 | goto done; | 462 | goto done; |
463 | } | 463 | } |
464 | |||
465 | if (result == USB_GADGET_DELAYED_STATUS) { | ||
466 | DBG(cdev, | ||
467 | "%s: interface %d (%s) requested delayed status\n", | ||
468 | __func__, tmp, f->name); | ||
469 | cdev->delayed_status++; | ||
470 | DBG(cdev, "delayed_status count %d\n", | ||
471 | cdev->delayed_status); | ||
472 | } | ||
464 | } | 473 | } |
465 | 474 | ||
466 | /* when we return, be sure our power usage is valid */ | 475 | /* when we return, be sure our power usage is valid */ |
467 | power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; | 476 | power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; |
468 | done: | 477 | done: |
469 | usb_gadget_vbus_draw(gadget, power); | 478 | usb_gadget_vbus_draw(gadget, power); |
479 | if (result >= 0 && cdev->delayed_status) | ||
480 | result = USB_GADGET_DELAYED_STATUS; | ||
470 | return result; | 481 | return result; |
471 | } | 482 | } |
472 | 483 | ||
@@ -895,6 +906,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
895 | if (w_value && !f->set_alt) | 906 | if (w_value && !f->set_alt) |
896 | break; | 907 | break; |
897 | value = f->set_alt(f, w_index, w_value); | 908 | value = f->set_alt(f, w_index, w_value); |
909 | if (value == USB_GADGET_DELAYED_STATUS) { | ||
910 | DBG(cdev, | ||
911 | "%s: interface %d (%s) requested delayed status\n", | ||
912 | __func__, intf, f->name); | ||
913 | cdev->delayed_status++; | ||
914 | DBG(cdev, "delayed_status count %d\n", | ||
915 | cdev->delayed_status); | ||
916 | } | ||
898 | break; | 917 | break; |
899 | case USB_REQ_GET_INTERFACE: | 918 | case USB_REQ_GET_INTERFACE: |
900 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) | 919 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) |
@@ -958,7 +977,7 @@ unknown: | |||
958 | } | 977 | } |
959 | 978 | ||
960 | /* respond with data transfer before status phase? */ | 979 | /* respond with data transfer before status phase? */ |
961 | if (value >= 0) { | 980 | if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { |
962 | req->length = value; | 981 | req->length = value; |
963 | req->zero = value < w_length; | 982 | req->zero = value < w_length; |
964 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | 983 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); |
@@ -967,6 +986,10 @@ unknown: | |||
967 | req->status = 0; | 986 | req->status = 0; |
968 | composite_setup_complete(gadget->ep0, req); | 987 | composite_setup_complete(gadget->ep0, req); |
969 | } | 988 | } |
989 | } else if (value == USB_GADGET_DELAYED_STATUS && w_length != 0) { | ||
990 | WARN(cdev, | ||
991 | "%s: Delayed status not supported for w_length != 0", | ||
992 | __func__); | ||
970 | } | 993 | } |
971 | 994 | ||
972 | done: | 995 | done: |
@@ -1289,3 +1312,40 @@ void usb_composite_unregister(struct usb_composite_driver *driver) | |||
1289 | return; | 1312 | return; |
1290 | usb_gadget_unregister_driver(&composite_driver); | 1313 | usb_gadget_unregister_driver(&composite_driver); |
1291 | } | 1314 | } |
1315 | |||
1316 | /** | ||
1317 | * usb_composite_setup_continue() - Continue with the control transfer | ||
1318 | * @cdev: the composite device who's control transfer was kept waiting | ||
1319 | * | ||
1320 | * This function must be called by the USB function driver to continue | ||
1321 | * with the control transfer's data/status stage in case it had requested to | ||
1322 | * delay the data/status stages. A USB function's setup handler (e.g. set_alt()) | ||
1323 | * can request the composite framework to delay the setup request's data/status | ||
1324 | * stages by returning USB_GADGET_DELAYED_STATUS. | ||
1325 | */ | ||
1326 | void usb_composite_setup_continue(struct usb_composite_dev *cdev) | ||
1327 | { | ||
1328 | int value; | ||
1329 | struct usb_request *req = cdev->req; | ||
1330 | unsigned long flags; | ||
1331 | |||
1332 | DBG(cdev, "%s\n", __func__); | ||
1333 | spin_lock_irqsave(&cdev->lock, flags); | ||
1334 | |||
1335 | if (cdev->delayed_status == 0) { | ||
1336 | WARN(cdev, "%s: Unexpected call\n", __func__); | ||
1337 | |||
1338 | } else if (--cdev->delayed_status == 0) { | ||
1339 | DBG(cdev, "%s: Completing delayed status\n", __func__); | ||
1340 | req->length = 0; | ||
1341 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | ||
1342 | if (value < 0) { | ||
1343 | DBG(cdev, "ep_queue --> %d\n", value); | ||
1344 | req->status = 0; | ||
1345 | composite_setup_complete(cdev->gadget->ep0, req); | ||
1346 | } | ||
1347 | } | ||
1348 | |||
1349 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
1350 | } | ||
1351 | |||
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index e5ac8a316fec..dbe92ee88477 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c | |||
@@ -261,8 +261,8 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) | |||
261 | o_desc.wMaxPacketSize = | 261 | o_desc.wMaxPacketSize = |
262 | __constant_cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); | 262 | __constant_cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); |
263 | 263 | ||
264 | dbg_desc.bDebugInEndpoint = i_desc.bEndpointAddress & 0x7f; | 264 | dbg_desc.bDebugInEndpoint = i_desc.bEndpointAddress; |
265 | dbg_desc.bDebugOutEndpoint = o_desc.bEndpointAddress & 0x7f; | 265 | dbg_desc.bDebugOutEndpoint = o_desc.bEndpointAddress; |
266 | 266 | ||
267 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 267 | #ifdef CONFIG_USB_G_DBGP_SERIAL |
268 | dbgp.serial->in = dbgp.i_ep; | 268 | dbgp.serial->in = dbgp.i_ep; |
@@ -312,6 +312,7 @@ static int __init dbgp_bind(struct usb_gadget *gadget) | |||
312 | 312 | ||
313 | dbgp.req->length = DBGP_REQ_EP0_LEN; | 313 | dbgp.req->length = DBGP_REQ_EP0_LEN; |
314 | gadget->ep0->driver_data = gadget; | 314 | gadget->ep0->driver_data = gadget; |
315 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
315 | 316 | ||
316 | #ifdef CONFIG_USB_G_DBGP_SERIAL | 317 | #ifdef CONFIG_USB_G_DBGP_SERIAL |
317 | dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); | 318 | dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); |
@@ -350,9 +351,9 @@ static int dbgp_setup(struct usb_gadget *gadget, | |||
350 | u8 request = ctrl->bRequest; | 351 | u8 request = ctrl->bRequest; |
351 | u16 value = le16_to_cpu(ctrl->wValue); | 352 | u16 value = le16_to_cpu(ctrl->wValue); |
352 | u16 length = le16_to_cpu(ctrl->wLength); | 353 | u16 length = le16_to_cpu(ctrl->wLength); |
353 | int err = 0; | 354 | int err = -EOPNOTSUPP; |
354 | void *data; | 355 | void *data = NULL; |
355 | u16 len; | 356 | u16 len = 0; |
356 | 357 | ||
357 | gadget->ep0->driver_data = gadget; | 358 | gadget->ep0->driver_data = gadget; |
358 | 359 | ||
@@ -371,10 +372,9 @@ static int dbgp_setup(struct usb_gadget *gadget, | |||
371 | default: | 372 | default: |
372 | goto fail; | 373 | goto fail; |
373 | } | 374 | } |
375 | err = 0; | ||
374 | } else if (request == USB_REQ_SET_FEATURE && | 376 | } else if (request == USB_REQ_SET_FEATURE && |
375 | value == USB_DEVICE_DEBUG_MODE) { | 377 | value == USB_DEVICE_DEBUG_MODE) { |
376 | len = 0; | ||
377 | data = NULL; | ||
378 | dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); | 378 | dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); |
379 | #ifdef CONFIG_USB_G_DBGP_PRINTK | 379 | #ifdef CONFIG_USB_G_DBGP_PRINTK |
380 | err = dbgp_enable_ep(); | 380 | err = dbgp_enable_ep(); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 3214ca375d64..61ff927928ab 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -892,10 +892,11 @@ static int dummy_udc_probe (struct platform_device *pdev) | |||
892 | return rc; | 892 | return rc; |
893 | } | 893 | } |
894 | 894 | ||
895 | platform_set_drvdata (pdev, dum); | ||
896 | rc = device_create_file (&dum->gadget.dev, &dev_attr_function); | 895 | rc = device_create_file (&dum->gadget.dev, &dev_attr_function); |
897 | if (rc < 0) | 896 | if (rc < 0) |
898 | device_unregister (&dum->gadget.dev); | 897 | device_unregister (&dum->gadget.dev); |
898 | else | ||
899 | platform_set_drvdata(pdev, dum); | ||
899 | return rc; | 900 | return rc; |
900 | } | 901 | } |
901 | 902 | ||
@@ -1995,11 +1996,29 @@ static int __init init (void) | |||
1995 | retval = platform_device_add(the_hcd_pdev); | 1996 | retval = platform_device_add(the_hcd_pdev); |
1996 | if (retval < 0) | 1997 | if (retval < 0) |
1997 | goto err_add_hcd; | 1998 | goto err_add_hcd; |
1999 | if (!the_controller) { | ||
2000 | /* | ||
2001 | * The hcd was added successfully but its probe function failed | ||
2002 | * for some reason. | ||
2003 | */ | ||
2004 | retval = -EINVAL; | ||
2005 | goto err_add_udc; | ||
2006 | } | ||
1998 | retval = platform_device_add(the_udc_pdev); | 2007 | retval = platform_device_add(the_udc_pdev); |
1999 | if (retval < 0) | 2008 | if (retval < 0) |
2000 | goto err_add_udc; | 2009 | goto err_add_udc; |
2010 | if (!platform_get_drvdata(the_udc_pdev)) { | ||
2011 | /* | ||
2012 | * The udc was added successfully but its probe function failed | ||
2013 | * for some reason. | ||
2014 | */ | ||
2015 | retval = -EINVAL; | ||
2016 | goto err_probe_udc; | ||
2017 | } | ||
2001 | return retval; | 2018 | return retval; |
2002 | 2019 | ||
2020 | err_probe_udc: | ||
2021 | platform_device_del(the_udc_pdev); | ||
2003 | err_add_udc: | 2022 | err_add_udc: |
2004 | platform_device_del(the_hcd_pdev); | 2023 | platform_device_del(the_hcd_pdev); |
2005 | err_add_hcd: | 2024 | err_add_hcd: |
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 0111f8a9cf7f..8ee330a2ab58 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
@@ -177,7 +177,7 @@ static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { | |||
177 | }; | 177 | }; |
178 | 178 | ||
179 | /* Standard ISO OUT Endpoint Descriptor */ | 179 | /* Standard ISO OUT Endpoint Descriptor */ |
180 | static struct usb_endpoint_descriptor as_out_ep_desc __initdata = { | 180 | static struct usb_endpoint_descriptor as_out_ep_desc = { |
181 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | 181 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, |
182 | .bDescriptorType = USB_DT_ENDPOINT, | 182 | .bDescriptorType = USB_DT_ENDPOINT, |
183 | .bEndpointAddress = USB_DIR_OUT, | 183 | .bEndpointAddress = USB_DIR_OUT, |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6d8e533949eb..efb58f9f5aa9 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -347,6 +347,7 @@ struct fsg_operations { | |||
347 | /* Data shared by all the FSG instances. */ | 347 | /* Data shared by all the FSG instances. */ |
348 | struct fsg_common { | 348 | struct fsg_common { |
349 | struct usb_gadget *gadget; | 349 | struct usb_gadget *gadget; |
350 | struct usb_composite_dev *cdev; | ||
350 | struct fsg_dev *fsg, *new_fsg; | 351 | struct fsg_dev *fsg, *new_fsg; |
351 | wait_queue_head_t fsg_wait; | 352 | wait_queue_head_t fsg_wait; |
352 | 353 | ||
@@ -613,6 +614,11 @@ static int fsg_setup(struct usb_function *f, | |||
613 | if (!fsg_is_set(fsg->common)) | 614 | if (!fsg_is_set(fsg->common)) |
614 | return -EOPNOTSUPP; | 615 | return -EOPNOTSUPP; |
615 | 616 | ||
617 | ++fsg->common->ep0_req_tag; /* Record arrival of a new request */ | ||
618 | req->context = NULL; | ||
619 | req->length = 0; | ||
620 | dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); | ||
621 | |||
616 | switch (ctrl->bRequest) { | 622 | switch (ctrl->bRequest) { |
617 | 623 | ||
618 | case USB_BULK_RESET_REQUEST: | 624 | case USB_BULK_RESET_REQUEST: |
@@ -1584,37 +1590,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) | |||
1584 | return rc; | 1590 | return rc; |
1585 | } | 1591 | } |
1586 | 1592 | ||
1587 | static int pad_with_zeros(struct fsg_dev *fsg) | ||
1588 | { | ||
1589 | struct fsg_buffhd *bh = fsg->common->next_buffhd_to_fill; | ||
1590 | u32 nkeep = bh->inreq->length; | ||
1591 | u32 nsend; | ||
1592 | int rc; | ||
1593 | |||
1594 | bh->state = BUF_STATE_EMPTY; /* For the first iteration */ | ||
1595 | fsg->common->usb_amount_left = nkeep + fsg->common->residue; | ||
1596 | while (fsg->common->usb_amount_left > 0) { | ||
1597 | |||
1598 | /* Wait for the next buffer to be free */ | ||
1599 | while (bh->state != BUF_STATE_EMPTY) { | ||
1600 | rc = sleep_thread(fsg->common); | ||
1601 | if (rc) | ||
1602 | return rc; | ||
1603 | } | ||
1604 | |||
1605 | nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN); | ||
1606 | memset(bh->buf + nkeep, 0, nsend - nkeep); | ||
1607 | bh->inreq->length = nsend; | ||
1608 | bh->inreq->zero = 0; | ||
1609 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
1610 | &bh->inreq_busy, &bh->state); | ||
1611 | bh = fsg->common->next_buffhd_to_fill = bh->next; | ||
1612 | fsg->common->usb_amount_left -= nsend; | ||
1613 | nkeep = 0; | ||
1614 | } | ||
1615 | return 0; | ||
1616 | } | ||
1617 | |||
1618 | static int throw_away_data(struct fsg_common *common) | 1593 | static int throw_away_data(struct fsg_common *common) |
1619 | { | 1594 | { |
1620 | struct fsg_buffhd *bh; | 1595 | struct fsg_buffhd *bh; |
@@ -1702,6 +1677,10 @@ static int finish_reply(struct fsg_common *common) | |||
1702 | if (common->data_size == 0) { | 1677 | if (common->data_size == 0) { |
1703 | /* Nothing to send */ | 1678 | /* Nothing to send */ |
1704 | 1679 | ||
1680 | /* Don't know what to do if common->fsg is NULL */ | ||
1681 | } else if (!fsg_is_set(common)) { | ||
1682 | rc = -EIO; | ||
1683 | |||
1705 | /* If there's no residue, simply send the last buffer */ | 1684 | /* If there's no residue, simply send the last buffer */ |
1706 | } else if (common->residue == 0) { | 1685 | } else if (common->residue == 0) { |
1707 | bh->inreq->zero = 0; | 1686 | bh->inreq->zero = 0; |
@@ -1710,24 +1689,19 @@ static int finish_reply(struct fsg_common *common) | |||
1710 | common->next_buffhd_to_fill = bh->next; | 1689 | common->next_buffhd_to_fill = bh->next; |
1711 | 1690 | ||
1712 | /* | 1691 | /* |
1713 | * For Bulk-only, if we're allowed to stall then send the | 1692 | * For Bulk-only, mark the end of the data with a short |
1714 | * short packet and halt the bulk-in endpoint. If we can't | 1693 | * packet. If we are allowed to stall, halt the bulk-in |
1715 | * stall, pad out the remaining data with 0's. | 1694 | * endpoint. (Note: This violates the Bulk-Only Transport |
1695 | * specification, which requires us to pad the data if we | ||
1696 | * don't halt the endpoint. Presumably nobody will mind.) | ||
1716 | */ | 1697 | */ |
1717 | } else if (common->can_stall) { | 1698 | } else { |
1718 | bh->inreq->zero = 1; | 1699 | bh->inreq->zero = 1; |
1719 | if (!start_in_transfer(common, bh)) | 1700 | if (!start_in_transfer(common, bh)) |
1720 | /* Don't know what to do if | ||
1721 | * common->fsg is NULL */ | ||
1722 | rc = -EIO; | 1701 | rc = -EIO; |
1723 | common->next_buffhd_to_fill = bh->next; | 1702 | common->next_buffhd_to_fill = bh->next; |
1724 | if (common->fsg) | 1703 | if (common->can_stall) |
1725 | rc = halt_bulk_in_endpoint(common->fsg); | 1704 | rc = halt_bulk_in_endpoint(common->fsg); |
1726 | } else if (fsg_is_set(common)) { | ||
1727 | rc = pad_with_zeros(common->fsg); | ||
1728 | } else { | ||
1729 | /* Don't know what to do if common->fsg is NULL */ | ||
1730 | rc = -EIO; | ||
1731 | } | 1705 | } |
1732 | break; | 1706 | break; |
1733 | 1707 | ||
@@ -1910,7 +1884,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1910 | common->lun, lun); | 1884 | common->lun, lun); |
1911 | 1885 | ||
1912 | /* Check the LUN */ | 1886 | /* Check the LUN */ |
1913 | if (common->lun >= 0 && common->lun < common->nluns) { | 1887 | if (common->lun < common->nluns) { |
1914 | curlun = &common->luns[common->lun]; | 1888 | curlun = &common->luns[common->lun]; |
1915 | common->curlun = curlun; | 1889 | common->curlun = curlun; |
1916 | if (common->cmnd[0] != REQUEST_SENSE) { | 1890 | if (common->cmnd[0] != REQUEST_SENSE) { |
@@ -2468,7 +2442,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
2468 | struct fsg_dev *fsg = fsg_from_func(f); | 2442 | struct fsg_dev *fsg = fsg_from_func(f); |
2469 | fsg->common->new_fsg = fsg; | 2443 | fsg->common->new_fsg = fsg; |
2470 | raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); | 2444 | raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); |
2471 | return 0; | 2445 | return USB_GADGET_DELAYED_STATUS; |
2472 | } | 2446 | } |
2473 | 2447 | ||
2474 | static void fsg_disable(struct usb_function *f) | 2448 | static void fsg_disable(struct usb_function *f) |
@@ -2604,6 +2578,8 @@ static void handle_exception(struct fsg_common *common) | |||
2604 | 2578 | ||
2605 | case FSG_STATE_CONFIG_CHANGE: | 2579 | case FSG_STATE_CONFIG_CHANGE: |
2606 | do_set_interface(common, common->new_fsg); | 2580 | do_set_interface(common, common->new_fsg); |
2581 | if (common->new_fsg) | ||
2582 | usb_composite_setup_continue(common->cdev); | ||
2607 | break; | 2583 | break; |
2608 | 2584 | ||
2609 | case FSG_STATE_EXIT: | 2585 | case FSG_STATE_EXIT: |
@@ -2774,6 +2750,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2774 | common->gadget = gadget; | 2750 | common->gadget = gadget; |
2775 | common->ep0 = gadget->ep0; | 2751 | common->ep0 = gadget->ep0; |
2776 | common->ep0req = cdev->req; | 2752 | common->ep0req = cdev->req; |
2753 | common->cdev = cdev; | ||
2777 | 2754 | ||
2778 | /* Maybe allocate device-global string IDs, and patch descriptors */ | 2755 | /* Maybe allocate device-global string IDs, and patch descriptors */ |
2779 | if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { | 2756 | if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { |
@@ -2800,6 +2777,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2800 | for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { | 2777 | for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { |
2801 | curlun->cdrom = !!lcfg->cdrom; | 2778 | curlun->cdrom = !!lcfg->cdrom; |
2802 | curlun->ro = lcfg->cdrom || lcfg->ro; | 2779 | curlun->ro = lcfg->cdrom || lcfg->ro; |
2780 | curlun->initially_ro = curlun->ro; | ||
2803 | curlun->removable = lcfg->removable; | 2781 | curlun->removable = lcfg->removable; |
2804 | curlun->dev.release = fsg_lun_release; | 2782 | curlun->dev.release = fsg_lun_release; |
2805 | curlun->dev.parent = &gadget->dev; | 2783 | curlun->dev.parent = &gadget->dev; |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 882484a40398..fa12ec8364ef 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -420,8 +420,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
420 | */ | 420 | */ |
421 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | 421 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) |
422 | | USB_CDC_SEND_ENCAPSULATED_COMMAND: | 422 | | USB_CDC_SEND_ENCAPSULATED_COMMAND: |
423 | if (w_length > req->length || w_value | 423 | if (w_value || w_index != rndis->ctrl_id) |
424 | || w_index != rndis->ctrl_id) | ||
425 | goto invalid; | 424 | goto invalid; |
426 | /* read the request; process it later */ | 425 | /* read the request; process it later */ |
427 | value = w_length; | 426 | value = w_length; |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a6eacb59571b..0360f56221ea 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -1947,37 +1947,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) | |||
1947 | return rc; | 1947 | return rc; |
1948 | } | 1948 | } |
1949 | 1949 | ||
1950 | static int pad_with_zeros(struct fsg_dev *fsg) | ||
1951 | { | ||
1952 | struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; | ||
1953 | u32 nkeep = bh->inreq->length; | ||
1954 | u32 nsend; | ||
1955 | int rc; | ||
1956 | |||
1957 | bh->state = BUF_STATE_EMPTY; // For the first iteration | ||
1958 | fsg->usb_amount_left = nkeep + fsg->residue; | ||
1959 | while (fsg->usb_amount_left > 0) { | ||
1960 | |||
1961 | /* Wait for the next buffer to be free */ | ||
1962 | while (bh->state != BUF_STATE_EMPTY) { | ||
1963 | rc = sleep_thread(fsg); | ||
1964 | if (rc) | ||
1965 | return rc; | ||
1966 | } | ||
1967 | |||
1968 | nsend = min(fsg->usb_amount_left, (u32) mod_data.buflen); | ||
1969 | memset(bh->buf + nkeep, 0, nsend - nkeep); | ||
1970 | bh->inreq->length = nsend; | ||
1971 | bh->inreq->zero = 0; | ||
1972 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | ||
1973 | &bh->inreq_busy, &bh->state); | ||
1974 | bh = fsg->next_buffhd_to_fill = bh->next; | ||
1975 | fsg->usb_amount_left -= nsend; | ||
1976 | nkeep = 0; | ||
1977 | } | ||
1978 | return 0; | ||
1979 | } | ||
1980 | |||
1981 | static int throw_away_data(struct fsg_dev *fsg) | 1950 | static int throw_away_data(struct fsg_dev *fsg) |
1982 | { | 1951 | { |
1983 | struct fsg_buffhd *bh; | 1952 | struct fsg_buffhd *bh; |
@@ -2082,18 +2051,20 @@ static int finish_reply(struct fsg_dev *fsg) | |||
2082 | } | 2051 | } |
2083 | } | 2052 | } |
2084 | 2053 | ||
2085 | /* For Bulk-only, if we're allowed to stall then send the | 2054 | /* |
2086 | * short packet and halt the bulk-in endpoint. If we can't | 2055 | * For Bulk-only, mark the end of the data with a short |
2087 | * stall, pad out the remaining data with 0's. */ | 2056 | * packet. If we are allowed to stall, halt the bulk-in |
2057 | * endpoint. (Note: This violates the Bulk-Only Transport | ||
2058 | * specification, which requires us to pad the data if we | ||
2059 | * don't halt the endpoint. Presumably nobody will mind.) | ||
2060 | */ | ||
2088 | else { | 2061 | else { |
2089 | if (mod_data.can_stall) { | 2062 | bh->inreq->zero = 1; |
2090 | bh->inreq->zero = 1; | 2063 | start_transfer(fsg, fsg->bulk_in, bh->inreq, |
2091 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | 2064 | &bh->inreq_busy, &bh->state); |
2092 | &bh->inreq_busy, &bh->state); | 2065 | fsg->next_buffhd_to_fill = bh->next; |
2093 | fsg->next_buffhd_to_fill = bh->next; | 2066 | if (mod_data.can_stall) |
2094 | rc = halt_bulk_in_endpoint(fsg); | 2067 | rc = halt_bulk_in_endpoint(fsg); |
2095 | } else | ||
2096 | rc = pad_with_zeros(fsg); | ||
2097 | } | 2068 | } |
2098 | break; | 2069 | break; |
2099 | 2070 | ||
@@ -2314,7 +2285,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2314 | fsg->lun = lun; // Use LUN from the command | 2285 | fsg->lun = lun; // Use LUN from the command |
2315 | 2286 | ||
2316 | /* Check the LUN */ | 2287 | /* Check the LUN */ |
2317 | if (fsg->lun >= 0 && fsg->lun < fsg->nluns) { | 2288 | if (fsg->lun < fsg->nluns) { |
2318 | fsg->curlun = curlun = &fsg->luns[fsg->lun]; | 2289 | fsg->curlun = curlun = &fsg->luns[fsg->lun]; |
2319 | if (fsg->cmnd[0] != REQUEST_SENSE) { | 2290 | if (fsg->cmnd[0] != REQUEST_SENSE) { |
2320 | curlun->sense_data = SS_NO_SENSE; | 2291 | curlun->sense_data = SS_NO_SENSE; |
diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index e35e24fd64bb..1da5fb03d218 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h | |||
@@ -207,7 +207,7 @@ struct qe_frame{ | |||
207 | 207 | ||
208 | /* Frame status field */ | 208 | /* Frame status field */ |
209 | /* Receive side */ | 209 | /* Receive side */ |
210 | #define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */ | 210 | #define FRAME_OK 0x00000000 /* Frame transmitted or received OK */ |
211 | #define FRAME_ERROR 0x80000000 /* Error occurred on frame */ | 211 | #define FRAME_ERROR 0x80000000 /* Error occurred on frame */ |
212 | #define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */ | 212 | #define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */ |
213 | #define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */ | 213 | #define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */ |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 07499c1cdcc4..2cd9a60c7f3a 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -1,12 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004-2007 Freescale Semicondutor, Inc. All rights reserved. | 2 | * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc. |
3 | * All rights reserved. | ||
3 | * | 4 | * |
4 | * Author: Li Yang <leoli@freescale.com> | 5 | * Author: Li Yang <leoli@freescale.com> |
5 | * Jiang Bo <tanya.jiang@freescale.com> | 6 | * Jiang Bo <tanya.jiang@freescale.com> |
6 | * | 7 | * |
7 | * Description: | 8 | * Description: |
8 | * Freescale high-speed USB SOC DR module device controller driver. | 9 | * Freescale high-speed USB SOC DR module device controller driver. |
9 | * This can be found on MPC8349E/MPC8313E cpus. | 10 | * This can be found on MPC8349E/MPC8313E/MPC5121E cpus. |
10 | * The driver is previously named as mpc_udc. Based on bare board | 11 | * The driver is previously named as mpc_udc. Based on bare board |
11 | * code from Dave Liu and Shlomi Gridish. | 12 | * code from Dave Liu and Shlomi Gridish. |
12 | * | 13 | * |
@@ -45,6 +46,7 @@ | |||
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/unaligned.h> | 47 | #include <asm/unaligned.h> |
47 | #include <asm/dma.h> | 48 | #include <asm/dma.h> |
49 | #include <asm/cacheflush.h> | ||
48 | 50 | ||
49 | #include "fsl_usb2_udc.h" | 51 | #include "fsl_usb2_udc.h" |
50 | 52 | ||
@@ -77,12 +79,64 @@ fsl_ep0_desc = { | |||
77 | static void fsl_ep_fifo_flush(struct usb_ep *_ep); | 79 | static void fsl_ep_fifo_flush(struct usb_ep *_ep); |
78 | 80 | ||
79 | #ifdef CONFIG_PPC32 | 81 | #ifdef CONFIG_PPC32 |
80 | #define fsl_readl(addr) in_le32(addr) | 82 | /* |
81 | #define fsl_writel(val32, addr) out_le32(addr, val32) | 83 | * On some SoCs, the USB controller registers can be big or little endian, |
82 | #else | 84 | * depending on the version of the chip. In order to be able to run the |
85 | * same kernel binary on 2 different versions of an SoC, the BE/LE decision | ||
86 | * must be made at run time. _fsl_readl and fsl_writel are pointers to the | ||
87 | * BE or LE readl() and writel() functions, and fsl_readl() and fsl_writel() | ||
88 | * call through those pointers. Platform code for SoCs that have BE USB | ||
89 | * registers should set pdata->big_endian_mmio flag. | ||
90 | * | ||
91 | * This also applies to controller-to-cpu accessors for the USB descriptors, | ||
92 | * since their endianness is also SoC dependant. Platform code for SoCs that | ||
93 | * have BE USB descriptors should set pdata->big_endian_desc flag. | ||
94 | */ | ||
95 | static u32 _fsl_readl_be(const unsigned __iomem *p) | ||
96 | { | ||
97 | return in_be32(p); | ||
98 | } | ||
99 | |||
100 | static u32 _fsl_readl_le(const unsigned __iomem *p) | ||
101 | { | ||
102 | return in_le32(p); | ||
103 | } | ||
104 | |||
105 | static void _fsl_writel_be(u32 v, unsigned __iomem *p) | ||
106 | { | ||
107 | out_be32(p, v); | ||
108 | } | ||
109 | |||
110 | static void _fsl_writel_le(u32 v, unsigned __iomem *p) | ||
111 | { | ||
112 | out_le32(p, v); | ||
113 | } | ||
114 | |||
115 | static u32 (*_fsl_readl)(const unsigned __iomem *p); | ||
116 | static void (*_fsl_writel)(u32 v, unsigned __iomem *p); | ||
117 | |||
118 | #define fsl_readl(p) (*_fsl_readl)((p)) | ||
119 | #define fsl_writel(v, p) (*_fsl_writel)((v), (p)) | ||
120 | |||
121 | static inline u32 cpu_to_hc32(const u32 x) | ||
122 | { | ||
123 | return udc_controller->pdata->big_endian_desc | ||
124 | ? (__force u32)cpu_to_be32(x) | ||
125 | : (__force u32)cpu_to_le32(x); | ||
126 | } | ||
127 | |||
128 | static inline u32 hc32_to_cpu(const u32 x) | ||
129 | { | ||
130 | return udc_controller->pdata->big_endian_desc | ||
131 | ? be32_to_cpu((__force __be32)x) | ||
132 | : le32_to_cpu((__force __le32)x); | ||
133 | } | ||
134 | #else /* !CONFIG_PPC32 */ | ||
83 | #define fsl_readl(addr) readl(addr) | 135 | #define fsl_readl(addr) readl(addr) |
84 | #define fsl_writel(val32, addr) writel(val32, addr) | 136 | #define fsl_writel(val32, addr) writel(val32, addr) |
85 | #endif | 137 | #define cpu_to_hc32(x) cpu_to_le32(x) |
138 | #define hc32_to_cpu(x) le32_to_cpu(x) | ||
139 | #endif /* CONFIG_PPC32 */ | ||
86 | 140 | ||
87 | /******************************************************************** | 141 | /******************************************************************** |
88 | * Internal Used Function | 142 | * Internal Used Function |
@@ -177,7 +231,8 @@ static void nuke(struct fsl_ep *ep, int status) | |||
177 | 231 | ||
178 | static int dr_controller_setup(struct fsl_udc *udc) | 232 | static int dr_controller_setup(struct fsl_udc *udc) |
179 | { | 233 | { |
180 | unsigned int tmp, portctrl; | 234 | unsigned int tmp, portctrl, ep_num; |
235 | unsigned int max_no_of_ep; | ||
181 | #ifndef CONFIG_ARCH_MXC | 236 | #ifndef CONFIG_ARCH_MXC |
182 | unsigned int ctrl; | 237 | unsigned int ctrl; |
183 | #endif | 238 | #endif |
@@ -226,9 +281,12 @@ static int dr_controller_setup(struct fsl_udc *udc) | |||
226 | 281 | ||
227 | /* Set the controller as device mode */ | 282 | /* Set the controller as device mode */ |
228 | tmp = fsl_readl(&dr_regs->usbmode); | 283 | tmp = fsl_readl(&dr_regs->usbmode); |
284 | tmp &= ~USB_MODE_CTRL_MODE_MASK; /* clear mode bits */ | ||
229 | tmp |= USB_MODE_CTRL_MODE_DEVICE; | 285 | tmp |= USB_MODE_CTRL_MODE_DEVICE; |
230 | /* Disable Setup Lockout */ | 286 | /* Disable Setup Lockout */ |
231 | tmp |= USB_MODE_SETUP_LOCK_OFF; | 287 | tmp |= USB_MODE_SETUP_LOCK_OFF; |
288 | if (udc->pdata->es) | ||
289 | tmp |= USB_MODE_ES; | ||
232 | fsl_writel(tmp, &dr_regs->usbmode); | 290 | fsl_writel(tmp, &dr_regs->usbmode); |
233 | 291 | ||
234 | /* Clear the setup status */ | 292 | /* Clear the setup status */ |
@@ -242,22 +300,34 @@ static int dr_controller_setup(struct fsl_udc *udc) | |||
242 | udc->ep_qh, (int)tmp, | 300 | udc->ep_qh, (int)tmp, |
243 | fsl_readl(&dr_regs->endpointlistaddr)); | 301 | fsl_readl(&dr_regs->endpointlistaddr)); |
244 | 302 | ||
303 | max_no_of_ep = (0x0000001F & fsl_readl(&dr_regs->dccparams)); | ||
304 | for (ep_num = 1; ep_num < max_no_of_ep; ep_num++) { | ||
305 | tmp = fsl_readl(&dr_regs->endptctrl[ep_num]); | ||
306 | tmp &= ~(EPCTRL_TX_TYPE | EPCTRL_RX_TYPE); | ||
307 | tmp |= (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT) | ||
308 | | (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT); | ||
309 | fsl_writel(tmp, &dr_regs->endptctrl[ep_num]); | ||
310 | } | ||
245 | /* Config control enable i/o output, cpu endian register */ | 311 | /* Config control enable i/o output, cpu endian register */ |
246 | #ifndef CONFIG_ARCH_MXC | 312 | #ifndef CONFIG_ARCH_MXC |
247 | ctrl = __raw_readl(&usb_sys_regs->control); | 313 | if (udc->pdata->have_sysif_regs) { |
248 | ctrl |= USB_CTRL_IOENB; | 314 | ctrl = __raw_readl(&usb_sys_regs->control); |
249 | __raw_writel(ctrl, &usb_sys_regs->control); | 315 | ctrl |= USB_CTRL_IOENB; |
316 | __raw_writel(ctrl, &usb_sys_regs->control); | ||
317 | } | ||
250 | #endif | 318 | #endif |
251 | 319 | ||
252 | #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) | 320 | #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) |
253 | /* Turn on cache snooping hardware, since some PowerPC platforms | 321 | /* Turn on cache snooping hardware, since some PowerPC platforms |
254 | * wholly rely on hardware to deal with cache coherent. */ | 322 | * wholly rely on hardware to deal with cache coherent. */ |
255 | 323 | ||
256 | /* Setup Snooping for all the 4GB space */ | 324 | if (udc->pdata->have_sysif_regs) { |
257 | tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */ | 325 | /* Setup Snooping for all the 4GB space */ |
258 | __raw_writel(tmp, &usb_sys_regs->snoop1); | 326 | tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */ |
259 | tmp |= 0x80000000; /* starts from 0x8000000, size 2G */ | 327 | __raw_writel(tmp, &usb_sys_regs->snoop1); |
260 | __raw_writel(tmp, &usb_sys_regs->snoop2); | 328 | tmp |= 0x80000000; /* starts from 0x8000000, size 2G */ |
329 | __raw_writel(tmp, &usb_sys_regs->snoop2); | ||
330 | } | ||
261 | #endif | 331 | #endif |
262 | 332 | ||
263 | return 0; | 333 | return 0; |
@@ -293,6 +363,19 @@ static void dr_controller_stop(struct fsl_udc *udc) | |||
293 | { | 363 | { |
294 | unsigned int tmp; | 364 | unsigned int tmp; |
295 | 365 | ||
366 | pr_debug("%s\n", __func__); | ||
367 | |||
368 | /* if we're in OTG mode, and the Host is currently using the port, | ||
369 | * stop now and don't rip the controller out from under the | ||
370 | * ehci driver | ||
371 | */ | ||
372 | if (udc->gadget.is_otg) { | ||
373 | if (!(fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) { | ||
374 | pr_debug("udc: Leaving early\n"); | ||
375 | return; | ||
376 | } | ||
377 | } | ||
378 | |||
296 | /* disable all INTR */ | 379 | /* disable all INTR */ |
297 | fsl_writel(0, &dr_regs->usbintr); | 380 | fsl_writel(0, &dr_regs->usbintr); |
298 | 381 | ||
@@ -318,12 +401,14 @@ static void dr_ep_setup(unsigned char ep_num, unsigned char dir, | |||
318 | if (ep_num) | 401 | if (ep_num) |
319 | tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; | 402 | tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; |
320 | tmp_epctrl |= EPCTRL_TX_ENABLE; | 403 | tmp_epctrl |= EPCTRL_TX_ENABLE; |
404 | tmp_epctrl &= ~EPCTRL_TX_TYPE; | ||
321 | tmp_epctrl |= ((unsigned int)(ep_type) | 405 | tmp_epctrl |= ((unsigned int)(ep_type) |
322 | << EPCTRL_TX_EP_TYPE_SHIFT); | 406 | << EPCTRL_TX_EP_TYPE_SHIFT); |
323 | } else { | 407 | } else { |
324 | if (ep_num) | 408 | if (ep_num) |
325 | tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; | 409 | tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; |
326 | tmp_epctrl |= EPCTRL_RX_ENABLE; | 410 | tmp_epctrl |= EPCTRL_RX_ENABLE; |
411 | tmp_epctrl &= ~EPCTRL_RX_TYPE; | ||
327 | tmp_epctrl |= ((unsigned int)(ep_type) | 412 | tmp_epctrl |= ((unsigned int)(ep_type) |
328 | << EPCTRL_RX_EP_TYPE_SHIFT); | 413 | << EPCTRL_RX_EP_TYPE_SHIFT); |
329 | } | 414 | } |
@@ -409,7 +494,7 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, | |||
409 | if (zlt) | 494 | if (zlt) |
410 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; | 495 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; |
411 | 496 | ||
412 | p_QH->max_pkt_length = cpu_to_le32(tmp); | 497 | p_QH->max_pkt_length = cpu_to_hc32(tmp); |
413 | p_QH->next_dtd_ptr = 1; | 498 | p_QH->next_dtd_ptr = 1; |
414 | p_QH->size_ioc_int_sts = 0; | 499 | p_QH->size_ioc_int_sts = 0; |
415 | } | 500 | } |
@@ -546,10 +631,13 @@ static int fsl_ep_disable(struct usb_ep *_ep) | |||
546 | /* disable ep on controller */ | 631 | /* disable ep on controller */ |
547 | ep_num = ep_index(ep); | 632 | ep_num = ep_index(ep); |
548 | epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); | 633 | epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); |
549 | if (ep_is_in(ep)) | 634 | if (ep_is_in(ep)) { |
550 | epctrl &= ~EPCTRL_TX_ENABLE; | 635 | epctrl &= ~(EPCTRL_TX_ENABLE | EPCTRL_TX_TYPE); |
551 | else | 636 | epctrl |= EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT; |
552 | epctrl &= ~EPCTRL_RX_ENABLE; | 637 | } else { |
638 | epctrl &= ~(EPCTRL_RX_ENABLE | EPCTRL_TX_TYPE); | ||
639 | epctrl |= EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT; | ||
640 | } | ||
553 | fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); | 641 | fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); |
554 | 642 | ||
555 | udc = (struct fsl_udc *)ep->udc; | 643 | udc = (struct fsl_udc *)ep->udc; |
@@ -616,7 +704,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | |||
616 | struct fsl_req *lastreq; | 704 | struct fsl_req *lastreq; |
617 | lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); | 705 | lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); |
618 | lastreq->tail->next_td_ptr = | 706 | lastreq->tail->next_td_ptr = |
619 | cpu_to_le32(req->head->td_dma & DTD_ADDR_MASK); | 707 | cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); |
620 | /* Read prime bit, if 1 goto done */ | 708 | /* Read prime bit, if 1 goto done */ |
621 | if (fsl_readl(&dr_regs->endpointprime) & bitmask) | 709 | if (fsl_readl(&dr_regs->endpointprime) & bitmask) |
622 | goto out; | 710 | goto out; |
@@ -641,10 +729,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | |||
641 | 729 | ||
642 | /* Write dQH next pointer and terminate bit to 0 */ | 730 | /* Write dQH next pointer and terminate bit to 0 */ |
643 | temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | 731 | temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; |
644 | dQH->next_dtd_ptr = cpu_to_le32(temp); | 732 | dQH->next_dtd_ptr = cpu_to_hc32(temp); |
645 | 733 | ||
646 | /* Clear active and halt bit */ | 734 | /* Clear active and halt bit */ |
647 | temp = cpu_to_le32(~(EP_QUEUE_HEAD_STATUS_ACTIVE | 735 | temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE |
648 | | EP_QUEUE_HEAD_STATUS_HALT)); | 736 | | EP_QUEUE_HEAD_STATUS_HALT)); |
649 | dQH->size_ioc_int_sts &= temp; | 737 | dQH->size_ioc_int_sts &= temp; |
650 | 738 | ||
@@ -682,17 +770,17 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, | |||
682 | 770 | ||
683 | dtd->td_dma = *dma; | 771 | dtd->td_dma = *dma; |
684 | /* Clear reserved field */ | 772 | /* Clear reserved field */ |
685 | swap_temp = cpu_to_le32(dtd->size_ioc_sts); | 773 | swap_temp = hc32_to_cpu(dtd->size_ioc_sts); |
686 | swap_temp &= ~DTD_RESERVED_FIELDS; | 774 | swap_temp &= ~DTD_RESERVED_FIELDS; |
687 | dtd->size_ioc_sts = cpu_to_le32(swap_temp); | 775 | dtd->size_ioc_sts = cpu_to_hc32(swap_temp); |
688 | 776 | ||
689 | /* Init all of buffer page pointers */ | 777 | /* Init all of buffer page pointers */ |
690 | swap_temp = (u32) (req->req.dma + req->req.actual); | 778 | swap_temp = (u32) (req->req.dma + req->req.actual); |
691 | dtd->buff_ptr0 = cpu_to_le32(swap_temp); | 779 | dtd->buff_ptr0 = cpu_to_hc32(swap_temp); |
692 | dtd->buff_ptr1 = cpu_to_le32(swap_temp + 0x1000); | 780 | dtd->buff_ptr1 = cpu_to_hc32(swap_temp + 0x1000); |
693 | dtd->buff_ptr2 = cpu_to_le32(swap_temp + 0x2000); | 781 | dtd->buff_ptr2 = cpu_to_hc32(swap_temp + 0x2000); |
694 | dtd->buff_ptr3 = cpu_to_le32(swap_temp + 0x3000); | 782 | dtd->buff_ptr3 = cpu_to_hc32(swap_temp + 0x3000); |
695 | dtd->buff_ptr4 = cpu_to_le32(swap_temp + 0x4000); | 783 | dtd->buff_ptr4 = cpu_to_hc32(swap_temp + 0x4000); |
696 | 784 | ||
697 | req->req.actual += *length; | 785 | req->req.actual += *length; |
698 | 786 | ||
@@ -716,7 +804,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, | |||
716 | if (*is_last && !req->req.no_interrupt) | 804 | if (*is_last && !req->req.no_interrupt) |
717 | swap_temp |= DTD_IOC; | 805 | swap_temp |= DTD_IOC; |
718 | 806 | ||
719 | dtd->size_ioc_sts = cpu_to_le32(swap_temp); | 807 | dtd->size_ioc_sts = cpu_to_hc32(swap_temp); |
720 | 808 | ||
721 | mb(); | 809 | mb(); |
722 | 810 | ||
@@ -743,7 +831,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) | |||
743 | is_first = 0; | 831 | is_first = 0; |
744 | req->head = dtd; | 832 | req->head = dtd; |
745 | } else { | 833 | } else { |
746 | last_dtd->next_td_ptr = cpu_to_le32(dma); | 834 | last_dtd->next_td_ptr = cpu_to_hc32(dma); |
747 | last_dtd->next_td_virt = dtd; | 835 | last_dtd->next_td_virt = dtd; |
748 | } | 836 | } |
749 | last_dtd = dtd; | 837 | last_dtd = dtd; |
@@ -751,7 +839,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) | |||
751 | req->dtd_count++; | 839 | req->dtd_count++; |
752 | } while (!is_last); | 840 | } while (!is_last); |
753 | 841 | ||
754 | dtd->next_td_ptr = cpu_to_le32(DTD_NEXT_TERMINATE); | 842 | dtd->next_td_ptr = cpu_to_hc32(DTD_NEXT_TERMINATE); |
755 | 843 | ||
756 | req->tail = dtd; | 844 | req->tail = dtd; |
757 | 845 | ||
@@ -962,6 +1050,36 @@ out: | |||
962 | return status; | 1050 | return status; |
963 | } | 1051 | } |
964 | 1052 | ||
1053 | static int fsl_ep_fifo_status(struct usb_ep *_ep) | ||
1054 | { | ||
1055 | struct fsl_ep *ep; | ||
1056 | struct fsl_udc *udc; | ||
1057 | int size = 0; | ||
1058 | u32 bitmask; | ||
1059 | struct ep_queue_head *d_qh; | ||
1060 | |||
1061 | ep = container_of(_ep, struct fsl_ep, ep); | ||
1062 | if (!_ep || (!ep->desc && ep_index(ep) != 0)) | ||
1063 | return -ENODEV; | ||
1064 | |||
1065 | udc = (struct fsl_udc *)ep->udc; | ||
1066 | |||
1067 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) | ||
1068 | return -ESHUTDOWN; | ||
1069 | |||
1070 | d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)]; | ||
1071 | |||
1072 | bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) : | ||
1073 | (1 << (ep_index(ep))); | ||
1074 | |||
1075 | if (fsl_readl(&dr_regs->endptstatus) & bitmask) | ||
1076 | size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE) | ||
1077 | >> DTD_LENGTH_BIT_POS; | ||
1078 | |||
1079 | pr_debug("%s %u\n", __func__, size); | ||
1080 | return size; | ||
1081 | } | ||
1082 | |||
965 | static void fsl_ep_fifo_flush(struct usb_ep *_ep) | 1083 | static void fsl_ep_fifo_flush(struct usb_ep *_ep) |
966 | { | 1084 | { |
967 | struct fsl_ep *ep; | 1085 | struct fsl_ep *ep; |
@@ -1014,6 +1132,7 @@ static struct usb_ep_ops fsl_ep_ops = { | |||
1014 | .dequeue = fsl_ep_dequeue, | 1132 | .dequeue = fsl_ep_dequeue, |
1015 | 1133 | ||
1016 | .set_halt = fsl_ep_set_halt, | 1134 | .set_halt = fsl_ep_set_halt, |
1135 | .fifo_status = fsl_ep_fifo_status, | ||
1017 | .fifo_flush = fsl_ep_fifo_flush, /* flush fifo */ | 1136 | .fifo_flush = fsl_ep_fifo_flush, /* flush fifo */ |
1018 | }; | 1137 | }; |
1019 | 1138 | ||
@@ -1228,6 +1347,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, | |||
1228 | req = udc->status_req; | 1347 | req = udc->status_req; |
1229 | /* Fill in the reqest structure */ | 1348 | /* Fill in the reqest structure */ |
1230 | *((u16 *) req->req.buf) = cpu_to_le16(tmp); | 1349 | *((u16 *) req->req.buf) = cpu_to_le16(tmp); |
1350 | |||
1351 | /* flush cache for the req buffer */ | ||
1352 | flush_dcache_range((u32)req->req.buf, (u32)req->req.buf + 8); | ||
1353 | |||
1231 | req->ep = ep; | 1354 | req->ep = ep; |
1232 | req->req.length = 2; | 1355 | req->req.length = 2; |
1233 | req->req.status = -EINPROGRESS; | 1356 | req->req.status = -EINPROGRESS; |
@@ -1280,6 +1403,7 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1280 | /* Status phase from udc */ | 1403 | /* Status phase from udc */ |
1281 | { | 1404 | { |
1282 | int rc = -EOPNOTSUPP; | 1405 | int rc = -EOPNOTSUPP; |
1406 | u16 ptc = 0; | ||
1283 | 1407 | ||
1284 | if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) | 1408 | if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) |
1285 | == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { | 1409 | == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { |
@@ -1301,17 +1425,19 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1301 | | USB_TYPE_STANDARD)) { | 1425 | | USB_TYPE_STANDARD)) { |
1302 | /* Note: The driver has not include OTG support yet. | 1426 | /* Note: The driver has not include OTG support yet. |
1303 | * This will be set when OTG support is added */ | 1427 | * This will be set when OTG support is added */ |
1304 | if (!gadget_is_otg(&udc->gadget)) | 1428 | if (wValue == USB_DEVICE_TEST_MODE) |
1305 | break; | 1429 | ptc = wIndex >> 8; |
1306 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) | 1430 | else if (gadget_is_otg(&udc->gadget)) { |
1307 | udc->gadget.b_hnp_enable = 1; | 1431 | if (setup->bRequest == |
1308 | else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) | 1432 | USB_DEVICE_B_HNP_ENABLE) |
1309 | udc->gadget.a_hnp_support = 1; | 1433 | udc->gadget.b_hnp_enable = 1; |
1310 | else if (setup->bRequest == | 1434 | else if (setup->bRequest == |
1311 | USB_DEVICE_A_ALT_HNP_SUPPORT) | 1435 | USB_DEVICE_A_HNP_SUPPORT) |
1312 | udc->gadget.a_alt_hnp_support = 1; | 1436 | udc->gadget.a_hnp_support = 1; |
1313 | else | 1437 | else if (setup->bRequest == |
1314 | break; | 1438 | USB_DEVICE_A_ALT_HNP_SUPPORT) |
1439 | udc->gadget.a_alt_hnp_support = 1; | ||
1440 | } | ||
1315 | rc = 0; | 1441 | rc = 0; |
1316 | } else | 1442 | } else |
1317 | break; | 1443 | break; |
@@ -1320,6 +1446,15 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1320 | if (ep0_prime_status(udc, EP_DIR_IN)) | 1446 | if (ep0_prime_status(udc, EP_DIR_IN)) |
1321 | ep0stall(udc); | 1447 | ep0stall(udc); |
1322 | } | 1448 | } |
1449 | if (ptc) { | ||
1450 | u32 tmp; | ||
1451 | |||
1452 | mdelay(10); | ||
1453 | tmp = fsl_readl(&dr_regs->portsc1) | (ptc << 16); | ||
1454 | fsl_writel(tmp, &dr_regs->portsc1); | ||
1455 | printk(KERN_INFO "udc: switch to test mode %d.\n", ptc); | ||
1456 | } | ||
1457 | |||
1323 | return; | 1458 | return; |
1324 | } | 1459 | } |
1325 | 1460 | ||
@@ -1394,6 +1529,7 @@ static void tripwire_handler(struct fsl_udc *udc, u8 ep_num, u8 *buffer_ptr) | |||
1394 | { | 1529 | { |
1395 | u32 temp; | 1530 | u32 temp; |
1396 | struct ep_queue_head *qh; | 1531 | struct ep_queue_head *qh; |
1532 | struct fsl_usb2_platform_data *pdata = udc->pdata; | ||
1397 | 1533 | ||
1398 | qh = &udc->ep_qh[ep_num * 2 + EP_DIR_OUT]; | 1534 | qh = &udc->ep_qh[ep_num * 2 + EP_DIR_OUT]; |
1399 | 1535 | ||
@@ -1408,7 +1544,16 @@ static void tripwire_handler(struct fsl_udc *udc, u8 ep_num, u8 *buffer_ptr) | |||
1408 | fsl_writel(temp | USB_CMD_SUTW, &dr_regs->usbcmd); | 1544 | fsl_writel(temp | USB_CMD_SUTW, &dr_regs->usbcmd); |
1409 | 1545 | ||
1410 | /* Copy the setup packet to local buffer */ | 1546 | /* Copy the setup packet to local buffer */ |
1411 | memcpy(buffer_ptr, (u8 *) qh->setup_buffer, 8); | 1547 | if (pdata->le_setup_buf) { |
1548 | u32 *p = (u32 *)buffer_ptr; | ||
1549 | u32 *s = (u32 *)qh->setup_buffer; | ||
1550 | |||
1551 | /* Convert little endian setup buffer to CPU endian */ | ||
1552 | *p++ = le32_to_cpu(*s++); | ||
1553 | *p = le32_to_cpu(*s); | ||
1554 | } else { | ||
1555 | memcpy(buffer_ptr, (u8 *) qh->setup_buffer, 8); | ||
1556 | } | ||
1412 | } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_SUTW)); | 1557 | } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_SUTW)); |
1413 | 1558 | ||
1414 | /* Clear Setup Tripwire */ | 1559 | /* Clear Setup Tripwire */ |
@@ -1432,19 +1577,19 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, | |||
1432 | actual = curr_req->req.length; | 1577 | actual = curr_req->req.length; |
1433 | 1578 | ||
1434 | for (j = 0; j < curr_req->dtd_count; j++) { | 1579 | for (j = 0; j < curr_req->dtd_count; j++) { |
1435 | remaining_length = (le32_to_cpu(curr_td->size_ioc_sts) | 1580 | remaining_length = (hc32_to_cpu(curr_td->size_ioc_sts) |
1436 | & DTD_PACKET_SIZE) | 1581 | & DTD_PACKET_SIZE) |
1437 | >> DTD_LENGTH_BIT_POS; | 1582 | >> DTD_LENGTH_BIT_POS; |
1438 | actual -= remaining_length; | 1583 | actual -= remaining_length; |
1439 | 1584 | ||
1440 | if ((errors = le32_to_cpu(curr_td->size_ioc_sts) & | 1585 | errors = hc32_to_cpu(curr_td->size_ioc_sts); |
1441 | DTD_ERROR_MASK)) { | 1586 | if (errors & DTD_ERROR_MASK) { |
1442 | if (errors & DTD_STATUS_HALTED) { | 1587 | if (errors & DTD_STATUS_HALTED) { |
1443 | ERR("dTD error %08x QH=%d\n", errors, pipe); | 1588 | ERR("dTD error %08x QH=%d\n", errors, pipe); |
1444 | /* Clear the errors and Halt condition */ | 1589 | /* Clear the errors and Halt condition */ |
1445 | tmp = le32_to_cpu(curr_qh->size_ioc_int_sts); | 1590 | tmp = hc32_to_cpu(curr_qh->size_ioc_int_sts); |
1446 | tmp &= ~errors; | 1591 | tmp &= ~errors; |
1447 | curr_qh->size_ioc_int_sts = cpu_to_le32(tmp); | 1592 | curr_qh->size_ioc_int_sts = cpu_to_hc32(tmp); |
1448 | status = -EPIPE; | 1593 | status = -EPIPE; |
1449 | /* FIXME: continue with next queued TD? */ | 1594 | /* FIXME: continue with next queued TD? */ |
1450 | 1595 | ||
@@ -1462,7 +1607,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, | |||
1462 | ERR("Unknown error has occurred (0x%x)!\n", | 1607 | ERR("Unknown error has occurred (0x%x)!\n", |
1463 | errors); | 1608 | errors); |
1464 | 1609 | ||
1465 | } else if (le32_to_cpu(curr_td->size_ioc_sts) | 1610 | } else if (hc32_to_cpu(curr_td->size_ioc_sts) |
1466 | & DTD_STATUS_ACTIVE) { | 1611 | & DTD_STATUS_ACTIVE) { |
1467 | VDBG("Request not complete"); | 1612 | VDBG("Request not complete"); |
1468 | status = REQ_UNCOMPLETE; | 1613 | status = REQ_UNCOMPLETE; |
@@ -1551,6 +1696,9 @@ static void port_change_irq(struct fsl_udc *udc) | |||
1551 | { | 1696 | { |
1552 | u32 speed; | 1697 | u32 speed; |
1553 | 1698 | ||
1699 | if (udc->bus_reset) | ||
1700 | udc->bus_reset = 0; | ||
1701 | |||
1554 | /* Bus resetting is finished */ | 1702 | /* Bus resetting is finished */ |
1555 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { | 1703 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { |
1556 | /* Get the speed */ | 1704 | /* Get the speed */ |
@@ -1658,6 +1806,8 @@ static void reset_irq(struct fsl_udc *udc) | |||
1658 | 1806 | ||
1659 | if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { | 1807 | if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { |
1660 | VDBG("Bus reset"); | 1808 | VDBG("Bus reset"); |
1809 | /* Bus is reseting */ | ||
1810 | udc->bus_reset = 1; | ||
1661 | /* Reset all the queues, include XD, dTD, EP queue | 1811 | /* Reset all the queues, include XD, dTD, EP queue |
1662 | * head and TR Queue */ | 1812 | * head and TR Queue */ |
1663 | reset_queues(udc); | 1813 | reset_queues(udc); |
@@ -1735,6 +1885,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) | |||
1735 | 1885 | ||
1736 | /* Reset Received */ | 1886 | /* Reset Received */ |
1737 | if (irq_src & USB_STS_RESET) { | 1887 | if (irq_src & USB_STS_RESET) { |
1888 | VDBG("reset int"); | ||
1738 | reset_irq(udc); | 1889 | reset_irq(udc); |
1739 | status = IRQ_HANDLED; | 1890 | status = IRQ_HANDLED; |
1740 | } | 1891 | } |
@@ -1792,11 +1943,30 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1792 | goto out; | 1943 | goto out; |
1793 | } | 1944 | } |
1794 | 1945 | ||
1795 | /* Enable DR IRQ reg and Set usbcmd reg Run bit */ | 1946 | if (udc_controller->transceiver) { |
1796 | dr_controller_run(udc_controller); | 1947 | /* Suspend the controller until OTG enable it */ |
1797 | udc_controller->usb_state = USB_STATE_ATTACHED; | 1948 | udc_controller->stopped = 1; |
1798 | udc_controller->ep0_state = WAIT_FOR_SETUP; | 1949 | printk(KERN_INFO "Suspend udc for OTG auto detect\n"); |
1799 | udc_controller->ep0_dir = 0; | 1950 | |
1951 | /* connect to bus through transceiver */ | ||
1952 | if (udc_controller->transceiver) { | ||
1953 | retval = otg_set_peripheral(udc_controller->transceiver, | ||
1954 | &udc_controller->gadget); | ||
1955 | if (retval < 0) { | ||
1956 | ERR("can't bind to transceiver\n"); | ||
1957 | driver->unbind(&udc_controller->gadget); | ||
1958 | udc_controller->gadget.dev.driver = 0; | ||
1959 | udc_controller->driver = 0; | ||
1960 | return retval; | ||
1961 | } | ||
1962 | } | ||
1963 | } else { | ||
1964 | /* Enable DR IRQ reg and set USBCMD reg Run bit */ | ||
1965 | dr_controller_run(udc_controller); | ||
1966 | udc_controller->usb_state = USB_STATE_ATTACHED; | ||
1967 | udc_controller->ep0_state = WAIT_FOR_SETUP; | ||
1968 | udc_controller->ep0_dir = 0; | ||
1969 | } | ||
1800 | printk(KERN_INFO "%s: bind to driver %s\n", | 1970 | printk(KERN_INFO "%s: bind to driver %s\n", |
1801 | udc_controller->gadget.name, driver->driver.name); | 1971 | udc_controller->gadget.name, driver->driver.name); |
1802 | 1972 | ||
@@ -2044,16 +2214,18 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, | |||
2044 | next += t; | 2214 | next += t; |
2045 | 2215 | ||
2046 | #ifndef CONFIG_ARCH_MXC | 2216 | #ifndef CONFIG_ARCH_MXC |
2047 | tmp_reg = usb_sys_regs->snoop1; | 2217 | if (udc->pdata->have_sysif_regs) { |
2048 | t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); | 2218 | tmp_reg = usb_sys_regs->snoop1; |
2049 | size -= t; | 2219 | t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg); |
2050 | next += t; | 2220 | size -= t; |
2221 | next += t; | ||
2051 | 2222 | ||
2052 | tmp_reg = usb_sys_regs->control; | 2223 | tmp_reg = usb_sys_regs->control; |
2053 | t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n", | 2224 | t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n", |
2054 | tmp_reg); | 2225 | tmp_reg); |
2055 | size -= t; | 2226 | size -= t; |
2056 | next += t; | 2227 | next += t; |
2228 | } | ||
2057 | #endif | 2229 | #endif |
2058 | 2230 | ||
2059 | /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ | 2231 | /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ |
@@ -2233,6 +2405,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | |||
2233 | */ | 2405 | */ |
2234 | static int __init fsl_udc_probe(struct platform_device *pdev) | 2406 | static int __init fsl_udc_probe(struct platform_device *pdev) |
2235 | { | 2407 | { |
2408 | struct fsl_usb2_platform_data *pdata; | ||
2236 | struct resource *res; | 2409 | struct resource *res; |
2237 | int ret = -ENODEV; | 2410 | int ret = -ENODEV; |
2238 | unsigned int i; | 2411 | unsigned int i; |
@@ -2249,20 +2422,35 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2249 | return -ENOMEM; | 2422 | return -ENOMEM; |
2250 | } | 2423 | } |
2251 | 2424 | ||
2425 | pdata = pdev->dev.platform_data; | ||
2426 | udc_controller->pdata = pdata; | ||
2252 | spin_lock_init(&udc_controller->lock); | 2427 | spin_lock_init(&udc_controller->lock); |
2253 | udc_controller->stopped = 1; | 2428 | udc_controller->stopped = 1; |
2254 | 2429 | ||
2430 | #ifdef CONFIG_USB_OTG | ||
2431 | if (pdata->operating_mode == FSL_USB2_DR_OTG) { | ||
2432 | udc_controller->transceiver = otg_get_transceiver(); | ||
2433 | if (!udc_controller->transceiver) { | ||
2434 | ERR("Can't find OTG driver!\n"); | ||
2435 | ret = -ENODEV; | ||
2436 | goto err_kfree; | ||
2437 | } | ||
2438 | } | ||
2439 | #endif | ||
2440 | |||
2255 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2441 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2256 | if (!res) { | 2442 | if (!res) { |
2257 | ret = -ENXIO; | 2443 | ret = -ENXIO; |
2258 | goto err_kfree; | 2444 | goto err_kfree; |
2259 | } | 2445 | } |
2260 | 2446 | ||
2261 | if (!request_mem_region(res->start, res->end - res->start + 1, | 2447 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) { |
2262 | driver_name)) { | 2448 | if (!request_mem_region(res->start, res->end - res->start + 1, |
2263 | ERR("request mem region for %s failed\n", pdev->name); | 2449 | driver_name)) { |
2264 | ret = -EBUSY; | 2450 | ERR("request mem region for %s failed\n", pdev->name); |
2265 | goto err_kfree; | 2451 | ret = -EBUSY; |
2452 | goto err_kfree; | ||
2453 | } | ||
2266 | } | 2454 | } |
2267 | 2455 | ||
2268 | dr_regs = ioremap(res->start, resource_size(res)); | 2456 | dr_regs = ioremap(res->start, resource_size(res)); |
@@ -2271,9 +2459,29 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2271 | goto err_release_mem_region; | 2459 | goto err_release_mem_region; |
2272 | } | 2460 | } |
2273 | 2461 | ||
2462 | pdata->regs = (void *)dr_regs; | ||
2463 | |||
2464 | /* | ||
2465 | * do platform specific init: check the clock, grab/config pins, etc. | ||
2466 | */ | ||
2467 | if (pdata->init && pdata->init(pdev)) { | ||
2468 | ret = -ENODEV; | ||
2469 | goto err_iounmap_noclk; | ||
2470 | } | ||
2471 | |||
2472 | /* Set accessors only after pdata->init() ! */ | ||
2473 | if (pdata->big_endian_mmio) { | ||
2474 | _fsl_readl = _fsl_readl_be; | ||
2475 | _fsl_writel = _fsl_writel_be; | ||
2476 | } else { | ||
2477 | _fsl_readl = _fsl_readl_le; | ||
2478 | _fsl_writel = _fsl_writel_le; | ||
2479 | } | ||
2480 | |||
2274 | #ifndef CONFIG_ARCH_MXC | 2481 | #ifndef CONFIG_ARCH_MXC |
2275 | usb_sys_regs = (struct usb_sys_interface *) | 2482 | if (pdata->have_sysif_regs) |
2276 | ((u32)dr_regs + USB_DR_SYS_OFFSET); | 2483 | usb_sys_regs = (struct usb_sys_interface *) |
2484 | ((u32)dr_regs + USB_DR_SYS_OFFSET); | ||
2277 | #endif | 2485 | #endif |
2278 | 2486 | ||
2279 | /* Initialize USB clocks */ | 2487 | /* Initialize USB clocks */ |
@@ -2313,9 +2521,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2313 | goto err_free_irq; | 2521 | goto err_free_irq; |
2314 | } | 2522 | } |
2315 | 2523 | ||
2316 | /* initialize usb hw reg except for regs for EP, | 2524 | if (!udc_controller->transceiver) { |
2317 | * leave usbintr reg untouched */ | 2525 | /* initialize usb hw reg except for regs for EP, |
2318 | dr_controller_setup(udc_controller); | 2526 | * leave usbintr reg untouched */ |
2527 | dr_controller_setup(udc_controller); | ||
2528 | } | ||
2319 | 2529 | ||
2320 | fsl_udc_clk_finalize(pdev); | 2530 | fsl_udc_clk_finalize(pdev); |
2321 | 2531 | ||
@@ -2335,6 +2545,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2335 | if (ret < 0) | 2545 | if (ret < 0) |
2336 | goto err_free_irq; | 2546 | goto err_free_irq; |
2337 | 2547 | ||
2548 | if (udc_controller->transceiver) | ||
2549 | udc_controller->gadget.is_otg = 1; | ||
2550 | |||
2338 | /* setup QH and epctrl for ep0 */ | 2551 | /* setup QH and epctrl for ep0 */ |
2339 | ep0_setup(udc_controller); | 2552 | ep0_setup(udc_controller); |
2340 | 2553 | ||
@@ -2373,11 +2586,14 @@ err_unregister: | |||
2373 | err_free_irq: | 2586 | err_free_irq: |
2374 | free_irq(udc_controller->irq, udc_controller); | 2587 | free_irq(udc_controller->irq, udc_controller); |
2375 | err_iounmap: | 2588 | err_iounmap: |
2589 | if (pdata->exit) | ||
2590 | pdata->exit(pdev); | ||
2376 | fsl_udc_clk_release(); | 2591 | fsl_udc_clk_release(); |
2377 | err_iounmap_noclk: | 2592 | err_iounmap_noclk: |
2378 | iounmap(dr_regs); | 2593 | iounmap(dr_regs); |
2379 | err_release_mem_region: | 2594 | err_release_mem_region: |
2380 | release_mem_region(res->start, res->end - res->start + 1); | 2595 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) |
2596 | release_mem_region(res->start, res->end - res->start + 1); | ||
2381 | err_kfree: | 2597 | err_kfree: |
2382 | kfree(udc_controller); | 2598 | kfree(udc_controller); |
2383 | udc_controller = NULL; | 2599 | udc_controller = NULL; |
@@ -2390,6 +2606,7 @@ err_kfree: | |||
2390 | static int __exit fsl_udc_remove(struct platform_device *pdev) | 2606 | static int __exit fsl_udc_remove(struct platform_device *pdev) |
2391 | { | 2607 | { |
2392 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2608 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2609 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | ||
2393 | 2610 | ||
2394 | DECLARE_COMPLETION(done); | 2611 | DECLARE_COMPLETION(done); |
2395 | 2612 | ||
@@ -2410,12 +2627,20 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) | |||
2410 | dma_pool_destroy(udc_controller->td_pool); | 2627 | dma_pool_destroy(udc_controller->td_pool); |
2411 | free_irq(udc_controller->irq, udc_controller); | 2628 | free_irq(udc_controller->irq, udc_controller); |
2412 | iounmap(dr_regs); | 2629 | iounmap(dr_regs); |
2413 | release_mem_region(res->start, res->end - res->start + 1); | 2630 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) |
2631 | release_mem_region(res->start, res->end - res->start + 1); | ||
2414 | 2632 | ||
2415 | device_unregister(&udc_controller->gadget.dev); | 2633 | device_unregister(&udc_controller->gadget.dev); |
2416 | /* free udc --wait for the release() finished */ | 2634 | /* free udc --wait for the release() finished */ |
2417 | wait_for_completion(&done); | 2635 | wait_for_completion(&done); |
2418 | 2636 | ||
2637 | /* | ||
2638 | * do platform specific un-initialization: | ||
2639 | * release iomux pins, etc. | ||
2640 | */ | ||
2641 | if (pdata->exit) | ||
2642 | pdata->exit(pdev); | ||
2643 | |||
2419 | return 0; | 2644 | return 0; |
2420 | } | 2645 | } |
2421 | 2646 | ||
@@ -2446,6 +2671,62 @@ static int fsl_udc_resume(struct platform_device *pdev) | |||
2446 | return 0; | 2671 | return 0; |
2447 | } | 2672 | } |
2448 | 2673 | ||
2674 | static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) | ||
2675 | { | ||
2676 | struct fsl_udc *udc = udc_controller; | ||
2677 | u32 mode, usbcmd; | ||
2678 | |||
2679 | mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; | ||
2680 | |||
2681 | pr_debug("%s(): mode 0x%x stopped %d\n", __func__, mode, udc->stopped); | ||
2682 | |||
2683 | /* | ||
2684 | * If the controller is already stopped, then this must be a | ||
2685 | * PM suspend. Remember this fact, so that we will leave the | ||
2686 | * controller stopped at PM resume time. | ||
2687 | */ | ||
2688 | if (udc->stopped) { | ||
2689 | pr_debug("gadget already stopped, leaving early\n"); | ||
2690 | udc->already_stopped = 1; | ||
2691 | return 0; | ||
2692 | } | ||
2693 | |||
2694 | if (mode != USB_MODE_CTRL_MODE_DEVICE) { | ||
2695 | pr_debug("gadget not in device mode, leaving early\n"); | ||
2696 | return 0; | ||
2697 | } | ||
2698 | |||
2699 | /* stop the controller */ | ||
2700 | usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP; | ||
2701 | fsl_writel(usbcmd, &dr_regs->usbcmd); | ||
2702 | |||
2703 | udc->stopped = 1; | ||
2704 | |||
2705 | pr_info("USB Gadget suspended\n"); | ||
2706 | |||
2707 | return 0; | ||
2708 | } | ||
2709 | |||
2710 | static int fsl_udc_otg_resume(struct device *dev) | ||
2711 | { | ||
2712 | pr_debug("%s(): stopped %d already_stopped %d\n", __func__, | ||
2713 | udc_controller->stopped, udc_controller->already_stopped); | ||
2714 | |||
2715 | /* | ||
2716 | * If the controller was stopped at suspend time, then | ||
2717 | * don't resume it now. | ||
2718 | */ | ||
2719 | if (udc_controller->already_stopped) { | ||
2720 | udc_controller->already_stopped = 0; | ||
2721 | pr_debug("gadget was already stopped, leaving early\n"); | ||
2722 | return 0; | ||
2723 | } | ||
2724 | |||
2725 | pr_info("USB Gadget resume\n"); | ||
2726 | |||
2727 | return fsl_udc_resume(NULL); | ||
2728 | } | ||
2729 | |||
2449 | /*------------------------------------------------------------------------- | 2730 | /*------------------------------------------------------------------------- |
2450 | Register entry point for the peripheral controller driver | 2731 | Register entry point for the peripheral controller driver |
2451 | --------------------------------------------------------------------------*/ | 2732 | --------------------------------------------------------------------------*/ |
@@ -2458,6 +2739,9 @@ static struct platform_driver udc_driver = { | |||
2458 | .driver = { | 2739 | .driver = { |
2459 | .name = (char *)driver_name, | 2740 | .name = (char *)driver_name, |
2460 | .owner = THIS_MODULE, | 2741 | .owner = THIS_MODULE, |
2742 | /* udc suspend/resume called from OTG driver */ | ||
2743 | .suspend = fsl_udc_otg_suspend, | ||
2744 | .resume = fsl_udc_otg_resume, | ||
2461 | }, | 2745 | }, |
2462 | }; | 2746 | }; |
2463 | 2747 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index e88cce5c2c0d..1d51be83fda8 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -275,7 +275,9 @@ struct usb_sys_interface { | |||
275 | #define USB_MODE_CTRL_MODE_IDLE 0x00000000 | 275 | #define USB_MODE_CTRL_MODE_IDLE 0x00000000 |
276 | #define USB_MODE_CTRL_MODE_DEVICE 0x00000002 | 276 | #define USB_MODE_CTRL_MODE_DEVICE 0x00000002 |
277 | #define USB_MODE_CTRL_MODE_HOST 0x00000003 | 277 | #define USB_MODE_CTRL_MODE_HOST 0x00000003 |
278 | #define USB_MODE_CTRL_MODE_MASK 0x00000003 | ||
278 | #define USB_MODE_CTRL_MODE_RSV 0x00000001 | 279 | #define USB_MODE_CTRL_MODE_RSV 0x00000001 |
280 | #define USB_MODE_ES 0x00000004 /* Endian Select */ | ||
279 | #define USB_MODE_SETUP_LOCK_OFF 0x00000008 | 281 | #define USB_MODE_SETUP_LOCK_OFF 0x00000008 |
280 | #define USB_MODE_STREAM_DISABLE 0x00000010 | 282 | #define USB_MODE_STREAM_DISABLE 0x00000010 |
281 | /* Endpoint Flush Register */ | 283 | /* Endpoint Flush Register */ |
@@ -461,6 +463,7 @@ struct fsl_ep { | |||
461 | struct fsl_udc { | 463 | struct fsl_udc { |
462 | struct usb_gadget gadget; | 464 | struct usb_gadget gadget; |
463 | struct usb_gadget_driver *driver; | 465 | struct usb_gadget_driver *driver; |
466 | struct fsl_usb2_platform_data *pdata; | ||
464 | struct completion *done; /* to make sure release() is done */ | 467 | struct completion *done; /* to make sure release() is done */ |
465 | struct fsl_ep *eps; | 468 | struct fsl_ep *eps; |
466 | unsigned int max_ep; | 469 | unsigned int max_ep; |
@@ -473,6 +476,8 @@ struct fsl_udc { | |||
473 | unsigned vbus_active:1; | 476 | unsigned vbus_active:1; |
474 | unsigned stopped:1; | 477 | unsigned stopped:1; |
475 | unsigned remote_wakeup:1; | 478 | unsigned remote_wakeup:1; |
479 | unsigned already_stopped:1; | ||
480 | unsigned big_endian_desc:1; | ||
476 | 481 | ||
477 | struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ | 482 | struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ |
478 | struct fsl_req *status_req; /* ep0 status request */ | 483 | struct fsl_req *status_req; /* ep0 status request */ |
@@ -483,6 +488,7 @@ struct fsl_udc { | |||
483 | dma_addr_t ep_qh_dma; /* dma address of QH */ | 488 | dma_addr_t ep_qh_dma; /* dma address of QH */ |
484 | 489 | ||
485 | u32 max_pipes; /* Device max pipes */ | 490 | u32 max_pipes; /* Device max pipes */ |
491 | u32 bus_reset; /* Device is bus resetting */ | ||
486 | u32 resume_state; /* USB state to resume */ | 492 | u32 resume_state; /* USB state to resume */ |
487 | u32 usb_state; /* USB current state */ | 493 | u32 usb_state; /* USB current state */ |
488 | u32 ep0_state; /* Endpoint zero state */ | 494 | u32 ep0_state; /* Endpoint zero state */ |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index e896f6359dfe..bcdac7c73e89 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -136,6 +136,12 @@ | |||
136 | #define gadget_is_s3c_hsotg(g) 0 | 136 | #define gadget_is_s3c_hsotg(g) 0 |
137 | #endif | 137 | #endif |
138 | 138 | ||
139 | #ifdef CONFIG_USB_S3C_HSUDC | ||
140 | #define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name)) | ||
141 | #else | ||
142 | #define gadget_is_s3c_hsudc(g) 0 | ||
143 | #endif | ||
144 | |||
139 | #ifdef CONFIG_USB_GADGET_EG20T | 145 | #ifdef CONFIG_USB_GADGET_EG20T |
140 | #define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name)) | 146 | #define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name)) |
141 | #else | 147 | #else |
@@ -148,6 +154,12 @@ | |||
148 | #define gadget_is_ci13xxx_msm(g) 0 | 154 | #define gadget_is_ci13xxx_msm(g) 0 |
149 | #endif | 155 | #endif |
150 | 156 | ||
157 | #ifdef CONFIG_USB_GADGET_RENESAS_USBHS | ||
158 | #define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name)) | ||
159 | #else | ||
160 | #define gadget_is_renesas_usbhs(g) 0 | ||
161 | #endif | ||
162 | |||
151 | /** | 163 | /** |
152 | * usb_gadget_controller_number - support bcdDevice id convention | 164 | * usb_gadget_controller_number - support bcdDevice id convention |
153 | * @gadget: the controller being driven | 165 | * @gadget: the controller being driven |
@@ -207,6 +219,11 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
207 | return 0x27; | 219 | return 0x27; |
208 | else if (gadget_is_ci13xxx_msm(gadget)) | 220 | else if (gadget_is_ci13xxx_msm(gadget)) |
209 | return 0x28; | 221 | return 0x28; |
222 | else if (gadget_is_renesas_usbhs(gadget)) | ||
223 | return 0x29; | ||
224 | else if (gadget_is_s3c_hsudc(gadget)) | ||
225 | return 0x30; | ||
226 | |||
210 | return -ENOENT; | 227 | return -ENOENT; |
211 | } | 228 | } |
212 | 229 | ||
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index c3f2bd42bd5a..271ef94668e7 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -1189,6 +1189,8 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1189 | else if (gadget->a_alt_hnp_support) | 1189 | else if (gadget->a_alt_hnp_support) |
1190 | DBG(dev, "HNP needs a different root port\n"); | 1190 | DBG(dev, "HNP needs a different root port\n"); |
1191 | value = printer_set_config(dev, wValue); | 1191 | value = printer_set_config(dev, wValue); |
1192 | if (!value) | ||
1193 | value = set_interface(dev, PRINTER_INTERFACE); | ||
1192 | break; | 1194 | break; |
1193 | case USB_REQ_GET_CONFIGURATION: | 1195 | case USB_REQ_GET_CONFIGURATION: |
1194 | if (ctrl->bRequestType != USB_DIR_IN) | 1196 | if (ctrl->bRequestType != USB_DIR_IN) |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 0912679de99a..acb9cc418df9 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -1,5 +1,8 @@ | |||
1 | /* linux/drivers/usb/gadget/s3c-hsotg.c | 1 | /* linux/drivers/usb/gadget/s3c-hsotg.c |
2 | * | 2 | * |
3 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | 6 | * Copyright 2008 Openmoko, Inc. |
4 | * Copyright 2008 Simtec Electronics | 7 | * Copyright 2008 Simtec Electronics |
5 | * Ben Dooks <ben@simtec.co.uk> | 8 | * Ben Dooks <ben@simtec.co.uk> |
@@ -613,11 +616,10 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) | |||
613 | maxpkt = S3C_DxEPTSIZ_PktCnt_LIMIT + 1; | 616 | maxpkt = S3C_DxEPTSIZ_PktCnt_LIMIT + 1; |
614 | } else { | 617 | } else { |
615 | maxsize = 64+64; | 618 | maxsize = 64+64; |
616 | if (hs_ep->dir_in) { | 619 | if (hs_ep->dir_in) |
617 | maxpkt = S3C_DIEPTSIZ0_PktCnt_LIMIT + 1; | 620 | maxpkt = S3C_DIEPTSIZ0_PktCnt_LIMIT + 1; |
618 | } else { | 621 | else |
619 | maxpkt = 2; | 622 | maxpkt = 2; |
620 | } | ||
621 | } | 623 | } |
622 | 624 | ||
623 | /* we made the constant loading easier above by using +1 */ | 625 | /* we made the constant loading easier above by using +1 */ |
@@ -679,6 +681,14 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | |||
679 | __func__, readl(hsotg->regs + epctrl_reg), index, | 681 | __func__, readl(hsotg->regs + epctrl_reg), index, |
680 | hs_ep->dir_in ? "in" : "out"); | 682 | hs_ep->dir_in ? "in" : "out"); |
681 | 683 | ||
684 | /* If endpoint is stalled, we will restart request later */ | ||
685 | ctrl = readl(hsotg->regs + epctrl_reg); | ||
686 | |||
687 | if (ctrl & S3C_DxEPCTL_Stall) { | ||
688 | dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index); | ||
689 | return; | ||
690 | } | ||
691 | |||
682 | length = ureq->length - ureq->actual; | 692 | length = ureq->length - ureq->actual; |
683 | 693 | ||
684 | if (0) | 694 | if (0) |
@@ -731,18 +741,6 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | |||
731 | /* write size / packets */ | 741 | /* write size / packets */ |
732 | writel(epsize, hsotg->regs + epsize_reg); | 742 | writel(epsize, hsotg->regs + epsize_reg); |
733 | 743 | ||
734 | ctrl = readl(hsotg->regs + epctrl_reg); | ||
735 | |||
736 | if (ctrl & S3C_DxEPCTL_Stall) { | ||
737 | dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index); | ||
738 | |||
739 | /* not sure what we can do here, if it is EP0 then we should | ||
740 | * get this cleared once the endpoint has transmitted the | ||
741 | * STALL packet, otherwise it needs to be cleared by the | ||
742 | * host. | ||
743 | */ | ||
744 | } | ||
745 | |||
746 | if (using_dma(hsotg)) { | 744 | if (using_dma(hsotg)) { |
747 | unsigned int dma_reg; | 745 | unsigned int dma_reg; |
748 | 746 | ||
@@ -1048,6 +1046,20 @@ static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg, | |||
1048 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); | 1046 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); |
1049 | 1047 | ||
1050 | /** | 1048 | /** |
1049 | * get_ep_head - return the first request on the endpoint | ||
1050 | * @hs_ep: The controller endpoint to get | ||
1051 | * | ||
1052 | * Get the first request on the endpoint. | ||
1053 | */ | ||
1054 | static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) | ||
1055 | { | ||
1056 | if (list_empty(&hs_ep->queue)) | ||
1057 | return NULL; | ||
1058 | |||
1059 | return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue); | ||
1060 | } | ||
1061 | |||
1062 | /** | ||
1051 | * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE | 1063 | * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE |
1052 | * @hsotg: The device state | 1064 | * @hsotg: The device state |
1053 | * @ctrl: USB control request | 1065 | * @ctrl: USB control request |
@@ -1055,8 +1067,12 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); | |||
1055 | static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, | 1067 | static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, |
1056 | struct usb_ctrlrequest *ctrl) | 1068 | struct usb_ctrlrequest *ctrl) |
1057 | { | 1069 | { |
1070 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | ||
1071 | struct s3c_hsotg_req *hs_req; | ||
1072 | bool restart; | ||
1058 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); | 1073 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); |
1059 | struct s3c_hsotg_ep *ep; | 1074 | struct s3c_hsotg_ep *ep; |
1075 | int ret; | ||
1060 | 1076 | ||
1061 | dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", | 1077 | dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", |
1062 | __func__, set ? "SET" : "CLEAR"); | 1078 | __func__, set ? "SET" : "CLEAR"); |
@@ -1072,6 +1088,36 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, | |||
1072 | switch (le16_to_cpu(ctrl->wValue)) { | 1088 | switch (le16_to_cpu(ctrl->wValue)) { |
1073 | case USB_ENDPOINT_HALT: | 1089 | case USB_ENDPOINT_HALT: |
1074 | s3c_hsotg_ep_sethalt(&ep->ep, set); | 1090 | s3c_hsotg_ep_sethalt(&ep->ep, set); |
1091 | |||
1092 | ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); | ||
1093 | if (ret) { | ||
1094 | dev_err(hsotg->dev, | ||
1095 | "%s: failed to send reply\n", __func__); | ||
1096 | return ret; | ||
1097 | } | ||
1098 | |||
1099 | if (!set) { | ||
1100 | /* | ||
1101 | * If we have request in progress, | ||
1102 | * then complete it | ||
1103 | */ | ||
1104 | if (ep->req) { | ||
1105 | hs_req = ep->req; | ||
1106 | ep->req = NULL; | ||
1107 | list_del_init(&hs_req->queue); | ||
1108 | hs_req->req.complete(&ep->ep, | ||
1109 | &hs_req->req); | ||
1110 | } | ||
1111 | |||
1112 | /* If we have pending request, then start it */ | ||
1113 | restart = !list_empty(&ep->queue); | ||
1114 | if (restart) { | ||
1115 | hs_req = get_ep_head(ep); | ||
1116 | s3c_hsotg_start_req(hsotg, ep, | ||
1117 | hs_req, false); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1075 | break; | 1121 | break; |
1076 | 1122 | ||
1077 | default: | 1123 | default: |
@@ -1148,14 +1194,6 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | |||
1148 | dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret); | 1194 | dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret); |
1149 | } | 1195 | } |
1150 | 1196 | ||
1151 | if (ret > 0) { | ||
1152 | if (!ep0->dir_in) { | ||
1153 | /* need to generate zlp in reply or take data */ | ||
1154 | /* todo - deal with any data we might be sent? */ | ||
1155 | ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); | ||
1156 | } | ||
1157 | } | ||
1158 | |||
1159 | /* the request is either unhandlable, or is not formatted correctly | 1197 | /* the request is either unhandlable, or is not formatted correctly |
1160 | * so respond with a STALL for the status stage to indicate failure. | 1198 | * so respond with a STALL for the status stage to indicate failure. |
1161 | */ | 1199 | */ |
@@ -1247,20 +1285,6 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) | |||
1247 | } | 1285 | } |
1248 | 1286 | ||
1249 | /** | 1287 | /** |
1250 | * get_ep_head - return the first request on the endpoint | ||
1251 | * @hs_ep: The controller endpoint to get | ||
1252 | * | ||
1253 | * Get the first request on the endpoint. | ||
1254 | */ | ||
1255 | static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) | ||
1256 | { | ||
1257 | if (list_empty(&hs_ep->queue)) | ||
1258 | return NULL; | ||
1259 | |||
1260 | return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue); | ||
1261 | } | ||
1262 | |||
1263 | /** | ||
1264 | * s3c_hsotg_complete_request - complete a request given to us | 1288 | * s3c_hsotg_complete_request - complete a request given to us |
1265 | * @hsotg: The device state. | 1289 | * @hsotg: The device state. |
1266 | * @hs_ep: The endpoint the request was on. | 1290 | * @hs_ep: The endpoint the request was on. |
@@ -1683,6 +1707,37 @@ bad_mps: | |||
1683 | dev_err(hsotg->dev, "ep%d: bad mps of %d\n", ep, mps); | 1707 | dev_err(hsotg->dev, "ep%d: bad mps of %d\n", ep, mps); |
1684 | } | 1708 | } |
1685 | 1709 | ||
1710 | /** | ||
1711 | * s3c_hsotg_txfifo_flush - flush Tx FIFO | ||
1712 | * @hsotg: The driver state | ||
1713 | * @idx: The index for the endpoint (0..15) | ||
1714 | */ | ||
1715 | static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) | ||
1716 | { | ||
1717 | int timeout; | ||
1718 | int val; | ||
1719 | |||
1720 | writel(S3C_GRSTCTL_TxFNum(idx) | S3C_GRSTCTL_TxFFlsh, | ||
1721 | hsotg->regs + S3C_GRSTCTL); | ||
1722 | |||
1723 | /* wait until the fifo is flushed */ | ||
1724 | timeout = 100; | ||
1725 | |||
1726 | while (1) { | ||
1727 | val = readl(hsotg->regs + S3C_GRSTCTL); | ||
1728 | |||
1729 | if ((val & (S3C_GRSTCTL_TxFFlsh)) == 0) | ||
1730 | break; | ||
1731 | |||
1732 | if (--timeout == 0) { | ||
1733 | dev_err(hsotg->dev, | ||
1734 | "%s: timeout flushing fifo (GRSTCTL=%08x)\n", | ||
1735 | __func__, val); | ||
1736 | } | ||
1737 | |||
1738 | udelay(1); | ||
1739 | } | ||
1740 | } | ||
1686 | 1741 | ||
1687 | /** | 1742 | /** |
1688 | * s3c_hsotg_trytx - check to see if anything needs transmitting | 1743 | * s3c_hsotg_trytx - check to see if anything needs transmitting |
@@ -1775,10 +1830,12 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1775 | u32 epctl_reg = dir_in ? S3C_DIEPCTL(idx) : S3C_DOEPCTL(idx); | 1830 | u32 epctl_reg = dir_in ? S3C_DIEPCTL(idx) : S3C_DOEPCTL(idx); |
1776 | u32 epsiz_reg = dir_in ? S3C_DIEPTSIZ(idx) : S3C_DOEPTSIZ(idx); | 1831 | u32 epsiz_reg = dir_in ? S3C_DIEPTSIZ(idx) : S3C_DOEPTSIZ(idx); |
1777 | u32 ints; | 1832 | u32 ints; |
1778 | u32 clear = 0; | ||
1779 | 1833 | ||
1780 | ints = readl(hsotg->regs + epint_reg); | 1834 | ints = readl(hsotg->regs + epint_reg); |
1781 | 1835 | ||
1836 | /* Clear endpoint interrupts */ | ||
1837 | writel(ints, hsotg->regs + epint_reg); | ||
1838 | |||
1782 | dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", | 1839 | dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", |
1783 | __func__, idx, dir_in ? "in" : "out", ints); | 1840 | __func__, idx, dir_in ? "in" : "out", ints); |
1784 | 1841 | ||
@@ -1801,19 +1858,28 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1801 | 1858 | ||
1802 | s3c_hsotg_handle_outdone(hsotg, idx, false); | 1859 | s3c_hsotg_handle_outdone(hsotg, idx, false); |
1803 | } | 1860 | } |
1804 | |||
1805 | clear |= S3C_DxEPINT_XferCompl; | ||
1806 | } | 1861 | } |
1807 | 1862 | ||
1808 | if (ints & S3C_DxEPINT_EPDisbld) { | 1863 | if (ints & S3C_DxEPINT_EPDisbld) { |
1809 | dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); | 1864 | dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); |
1810 | clear |= S3C_DxEPINT_EPDisbld; | 1865 | |
1866 | if (dir_in) { | ||
1867 | int epctl = readl(hsotg->regs + epctl_reg); | ||
1868 | |||
1869 | s3c_hsotg_txfifo_flush(hsotg, idx); | ||
1870 | |||
1871 | if ((epctl & S3C_DxEPCTL_Stall) && | ||
1872 | (epctl & S3C_DxEPCTL_EPType_Bulk)) { | ||
1873 | int dctl = readl(hsotg->regs + S3C_DCTL); | ||
1874 | |||
1875 | dctl |= S3C_DCTL_CGNPInNAK; | ||
1876 | writel(dctl, hsotg->regs + S3C_DCTL); | ||
1877 | } | ||
1878 | } | ||
1811 | } | 1879 | } |
1812 | 1880 | ||
1813 | if (ints & S3C_DxEPINT_AHBErr) { | 1881 | if (ints & S3C_DxEPINT_AHBErr) |
1814 | dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); | 1882 | dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); |
1815 | clear |= S3C_DxEPINT_AHBErr; | ||
1816 | } | ||
1817 | 1883 | ||
1818 | if (ints & S3C_DxEPINT_Setup) { /* Setup or Timeout */ | 1884 | if (ints & S3C_DxEPINT_Setup) { /* Setup or Timeout */ |
1819 | dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); | 1885 | dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); |
@@ -1829,14 +1895,10 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1829 | else | 1895 | else |
1830 | s3c_hsotg_handle_outdone(hsotg, 0, true); | 1896 | s3c_hsotg_handle_outdone(hsotg, 0, true); |
1831 | } | 1897 | } |
1832 | |||
1833 | clear |= S3C_DxEPINT_Setup; | ||
1834 | } | 1898 | } |
1835 | 1899 | ||
1836 | if (ints & S3C_DxEPINT_Back2BackSetup) { | 1900 | if (ints & S3C_DxEPINT_Back2BackSetup) |
1837 | dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); | 1901 | dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); |
1838 | clear |= S3C_DxEPINT_Back2BackSetup; | ||
1839 | } | ||
1840 | 1902 | ||
1841 | if (dir_in) { | 1903 | if (dir_in) { |
1842 | /* not sure if this is important, but we'll clear it anyway | 1904 | /* not sure if this is important, but we'll clear it anyway |
@@ -1844,14 +1906,12 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1844 | if (ints & S3C_DIEPMSK_INTknTXFEmpMsk) { | 1906 | if (ints & S3C_DIEPMSK_INTknTXFEmpMsk) { |
1845 | dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n", | 1907 | dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n", |
1846 | __func__, idx); | 1908 | __func__, idx); |
1847 | clear |= S3C_DIEPMSK_INTknTXFEmpMsk; | ||
1848 | } | 1909 | } |
1849 | 1910 | ||
1850 | /* this probably means something bad is happening */ | 1911 | /* this probably means something bad is happening */ |
1851 | if (ints & S3C_DIEPMSK_INTknEPMisMsk) { | 1912 | if (ints & S3C_DIEPMSK_INTknEPMisMsk) { |
1852 | dev_warn(hsotg->dev, "%s: ep%d: INTknEP\n", | 1913 | dev_warn(hsotg->dev, "%s: ep%d: INTknEP\n", |
1853 | __func__, idx); | 1914 | __func__, idx); |
1854 | clear |= S3C_DIEPMSK_INTknEPMisMsk; | ||
1855 | } | 1915 | } |
1856 | 1916 | ||
1857 | /* FIFO has space or is empty (see GAHBCFG) */ | 1917 | /* FIFO has space or is empty (see GAHBCFG) */ |
@@ -1860,11 +1920,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1860 | dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", | 1920 | dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", |
1861 | __func__, idx); | 1921 | __func__, idx); |
1862 | s3c_hsotg_trytx(hsotg, hs_ep); | 1922 | s3c_hsotg_trytx(hsotg, hs_ep); |
1863 | clear |= S3C_DIEPMSK_TxFIFOEmpty; | ||
1864 | } | 1923 | } |
1865 | } | 1924 | } |
1866 | |||
1867 | writel(clear, hsotg->regs + epint_reg); | ||
1868 | } | 1925 | } |
1869 | 1926 | ||
1870 | /** | 1927 | /** |
@@ -2056,7 +2113,6 @@ irq_retry: | |||
2056 | dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); | 2113 | dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); |
2057 | 2114 | ||
2058 | writel(otgint, hsotg->regs + S3C_GOTGINT); | 2115 | writel(otgint, hsotg->regs + S3C_GOTGINT); |
2059 | writel(S3C_GINTSTS_OTGInt, hsotg->regs + S3C_GINTSTS); | ||
2060 | } | 2116 | } |
2061 | 2117 | ||
2062 | if (gintsts & S3C_GINTSTS_DisconnInt) { | 2118 | if (gintsts & S3C_GINTSTS_DisconnInt) { |
@@ -2072,8 +2128,9 @@ irq_retry: | |||
2072 | } | 2128 | } |
2073 | 2129 | ||
2074 | if (gintsts & S3C_GINTSTS_EnumDone) { | 2130 | if (gintsts & S3C_GINTSTS_EnumDone) { |
2075 | s3c_hsotg_irq_enumdone(hsotg); | ||
2076 | writel(S3C_GINTSTS_EnumDone, hsotg->regs + S3C_GINTSTS); | 2131 | writel(S3C_GINTSTS_EnumDone, hsotg->regs + S3C_GINTSTS); |
2132 | |||
2133 | s3c_hsotg_irq_enumdone(hsotg); | ||
2077 | } | 2134 | } |
2078 | 2135 | ||
2079 | if (gintsts & S3C_GINTSTS_ConIDStsChng) { | 2136 | if (gintsts & S3C_GINTSTS_ConIDStsChng) { |
@@ -2101,10 +2158,6 @@ irq_retry: | |||
2101 | if (daint_in & 1) | 2158 | if (daint_in & 1) |
2102 | s3c_hsotg_epint(hsotg, ep, 1); | 2159 | s3c_hsotg_epint(hsotg, ep, 1); |
2103 | } | 2160 | } |
2104 | |||
2105 | writel(daint, hsotg->regs + S3C_DAINT); | ||
2106 | writel(gintsts & (S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt), | ||
2107 | hsotg->regs + S3C_GINTSTS); | ||
2108 | } | 2161 | } |
2109 | 2162 | ||
2110 | if (gintsts & S3C_GINTSTS_USBRst) { | 2163 | if (gintsts & S3C_GINTSTS_USBRst) { |
@@ -2112,6 +2165,8 @@ irq_retry: | |||
2112 | dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", | 2165 | dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", |
2113 | readl(hsotg->regs + S3C_GNPTXSTS)); | 2166 | readl(hsotg->regs + S3C_GNPTXSTS)); |
2114 | 2167 | ||
2168 | writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS); | ||
2169 | |||
2115 | kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); | 2170 | kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); |
2116 | 2171 | ||
2117 | /* it seems after a reset we can end up with a situation | 2172 | /* it seems after a reset we can end up with a situation |
@@ -2123,8 +2178,6 @@ irq_retry: | |||
2123 | s3c_hsotg_init_fifo(hsotg); | 2178 | s3c_hsotg_init_fifo(hsotg); |
2124 | 2179 | ||
2125 | s3c_hsotg_enqueue_setup(hsotg); | 2180 | s3c_hsotg_enqueue_setup(hsotg); |
2126 | |||
2127 | writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS); | ||
2128 | } | 2181 | } |
2129 | 2182 | ||
2130 | /* check both FIFOs */ | 2183 | /* check both FIFOs */ |
@@ -2138,8 +2191,6 @@ irq_retry: | |||
2138 | 2191 | ||
2139 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_NPTxFEmp); | 2192 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_NPTxFEmp); |
2140 | s3c_hsotg_irq_fifoempty(hsotg, false); | 2193 | s3c_hsotg_irq_fifoempty(hsotg, false); |
2141 | |||
2142 | writel(S3C_GINTSTS_NPTxFEmp, hsotg->regs + S3C_GINTSTS); | ||
2143 | } | 2194 | } |
2144 | 2195 | ||
2145 | if (gintsts & S3C_GINTSTS_PTxFEmp) { | 2196 | if (gintsts & S3C_GINTSTS_PTxFEmp) { |
@@ -2149,8 +2200,6 @@ irq_retry: | |||
2149 | 2200 | ||
2150 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_PTxFEmp); | 2201 | s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_PTxFEmp); |
2151 | s3c_hsotg_irq_fifoempty(hsotg, true); | 2202 | s3c_hsotg_irq_fifoempty(hsotg, true); |
2152 | |||
2153 | writel(S3C_GINTSTS_PTxFEmp, hsotg->regs + S3C_GINTSTS); | ||
2154 | } | 2203 | } |
2155 | 2204 | ||
2156 | if (gintsts & S3C_GINTSTS_RxFLvl) { | 2205 | if (gintsts & S3C_GINTSTS_RxFLvl) { |
@@ -2159,7 +2208,6 @@ irq_retry: | |||
2159 | * set. */ | 2208 | * set. */ |
2160 | 2209 | ||
2161 | s3c_hsotg_handle_rx(hsotg); | 2210 | s3c_hsotg_handle_rx(hsotg); |
2162 | writel(S3C_GINTSTS_RxFLvl, hsotg->regs + S3C_GINTSTS); | ||
2163 | } | 2211 | } |
2164 | 2212 | ||
2165 | if (gintsts & S3C_GINTSTS_ModeMis) { | 2213 | if (gintsts & S3C_GINTSTS_ModeMis) { |
@@ -2193,19 +2241,17 @@ irq_retry: | |||
2193 | if (gintsts & S3C_GINTSTS_GOUTNakEff) { | 2241 | if (gintsts & S3C_GINTSTS_GOUTNakEff) { |
2194 | dev_info(hsotg->dev, "GOUTNakEff triggered\n"); | 2242 | dev_info(hsotg->dev, "GOUTNakEff triggered\n"); |
2195 | 2243 | ||
2196 | s3c_hsotg_dump(hsotg); | ||
2197 | |||
2198 | writel(S3C_DCTL_CGOUTNak, hsotg->regs + S3C_DCTL); | 2244 | writel(S3C_DCTL_CGOUTNak, hsotg->regs + S3C_DCTL); |
2199 | writel(S3C_GINTSTS_GOUTNakEff, hsotg->regs + S3C_GINTSTS); | 2245 | |
2246 | s3c_hsotg_dump(hsotg); | ||
2200 | } | 2247 | } |
2201 | 2248 | ||
2202 | if (gintsts & S3C_GINTSTS_GINNakEff) { | 2249 | if (gintsts & S3C_GINTSTS_GINNakEff) { |
2203 | dev_info(hsotg->dev, "GINNakEff triggered\n"); | 2250 | dev_info(hsotg->dev, "GINNakEff triggered\n"); |
2204 | 2251 | ||
2205 | s3c_hsotg_dump(hsotg); | ||
2206 | |||
2207 | writel(S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); | 2252 | writel(S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); |
2208 | writel(S3C_GINTSTS_GINNakEff, hsotg->regs + S3C_GINTSTS); | 2253 | |
2254 | s3c_hsotg_dump(hsotg); | ||
2209 | } | 2255 | } |
2210 | 2256 | ||
2211 | /* if we've had fifo events, we should try and go around the | 2257 | /* if we've had fifo events, we should try and go around the |
@@ -2403,11 +2449,6 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2403 | 2449 | ||
2404 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | 2450 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); |
2405 | 2451 | ||
2406 | if (hs_req == hs_ep->req) { | ||
2407 | dev_dbg(hs->dev, "%s: already in progress\n", __func__); | ||
2408 | return -EINPROGRESS; | ||
2409 | } | ||
2410 | |||
2411 | spin_lock_irqsave(&hs_ep->lock, flags); | 2452 | spin_lock_irqsave(&hs_ep->lock, flags); |
2412 | 2453 | ||
2413 | if (!on_list(hs_ep, hs_req)) { | 2454 | if (!on_list(hs_ep, hs_req)) { |
@@ -2429,6 +2470,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2429 | unsigned long irqflags; | 2470 | unsigned long irqflags; |
2430 | u32 epreg; | 2471 | u32 epreg; |
2431 | u32 epctl; | 2472 | u32 epctl; |
2473 | u32 xfertype; | ||
2432 | 2474 | ||
2433 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2475 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2434 | 2476 | ||
@@ -2439,10 +2481,17 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2439 | epreg = S3C_DIEPCTL(index); | 2481 | epreg = S3C_DIEPCTL(index); |
2440 | epctl = readl(hs->regs + epreg); | 2482 | epctl = readl(hs->regs + epreg); |
2441 | 2483 | ||
2442 | if (value) | 2484 | if (value) { |
2443 | epctl |= S3C_DxEPCTL_Stall; | 2485 | epctl |= S3C_DxEPCTL_Stall + S3C_DxEPCTL_SNAK; |
2444 | else | 2486 | if (epctl & S3C_DxEPCTL_EPEna) |
2487 | epctl |= S3C_DxEPCTL_EPDis; | ||
2488 | } else { | ||
2445 | epctl &= ~S3C_DxEPCTL_Stall; | 2489 | epctl &= ~S3C_DxEPCTL_Stall; |
2490 | xfertype = epctl & S3C_DxEPCTL_EPType_MASK; | ||
2491 | if (xfertype == S3C_DxEPCTL_EPType_Bulk || | ||
2492 | xfertype == S3C_DxEPCTL_EPType_Intterupt) | ||
2493 | epctl |= S3C_DxEPCTL_SetD0PID; | ||
2494 | } | ||
2446 | 2495 | ||
2447 | writel(epctl, hs->regs + epreg); | 2496 | writel(epctl, hs->regs + epreg); |
2448 | 2497 | ||
@@ -2451,8 +2500,13 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2451 | 2500 | ||
2452 | if (value) | 2501 | if (value) |
2453 | epctl |= S3C_DxEPCTL_Stall; | 2502 | epctl |= S3C_DxEPCTL_Stall; |
2454 | else | 2503 | else { |
2455 | epctl &= ~S3C_DxEPCTL_Stall; | 2504 | epctl &= ~S3C_DxEPCTL_Stall; |
2505 | xfertype = epctl & S3C_DxEPCTL_EPType_MASK; | ||
2506 | if (xfertype == S3C_DxEPCTL_EPType_Bulk || | ||
2507 | xfertype == S3C_DxEPCTL_EPType_Intterupt) | ||
2508 | epctl |= S3C_DxEPCTL_SetD0PID; | ||
2509 | } | ||
2456 | 2510 | ||
2457 | writel(epctl, hs->regs + epreg); | 2511 | writel(epctl, hs->regs + epreg); |
2458 | 2512 | ||
@@ -2491,9 +2545,9 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | |||
2491 | timeout = 1000; | 2545 | timeout = 1000; |
2492 | do { | 2546 | do { |
2493 | grstctl = readl(hsotg->regs + S3C_GRSTCTL); | 2547 | grstctl = readl(hsotg->regs + S3C_GRSTCTL); |
2494 | } while (!(grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); | 2548 | } while ((grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); |
2495 | 2549 | ||
2496 | if (!(grstctl & S3C_GRSTCTL_CSftRst)) { | 2550 | if (grstctl & S3C_GRSTCTL_CSftRst) { |
2497 | dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); | 2551 | dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); |
2498 | return -EINVAL; | 2552 | return -EINVAL; |
2499 | } | 2553 | } |
@@ -2510,13 +2564,10 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | |||
2510 | return -ETIMEDOUT; | 2564 | return -ETIMEDOUT; |
2511 | } | 2565 | } |
2512 | 2566 | ||
2513 | if (grstctl & S3C_GRSTCTL_CSftRst) | ||
2514 | continue; | ||
2515 | |||
2516 | if (!(grstctl & S3C_GRSTCTL_AHBIdle)) | 2567 | if (!(grstctl & S3C_GRSTCTL_AHBIdle)) |
2517 | continue; | 2568 | continue; |
2518 | 2569 | ||
2519 | break; /* reset done */ | 2570 | break; /* reset done */ |
2520 | } | 2571 | } |
2521 | 2572 | ||
2522 | dev_dbg(hsotg->dev, "reset successful\n"); | 2573 | dev_dbg(hsotg->dev, "reset successful\n"); |
@@ -2588,6 +2639,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2588 | 2639 | ||
2589 | writel(1 << 18 | S3C_DCFG_DevSpd_HS, hsotg->regs + S3C_DCFG); | 2640 | writel(1 << 18 | S3C_DCFG_DevSpd_HS, hsotg->regs + S3C_DCFG); |
2590 | 2641 | ||
2642 | /* Clear any pending OTG interrupts */ | ||
2643 | writel(0xffffffff, hsotg->regs + S3C_GOTGINT); | ||
2644 | |||
2645 | /* Clear any pending interrupts */ | ||
2646 | writel(0xffffffff, hsotg->regs + S3C_GINTSTS); | ||
2647 | |||
2591 | writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt | | 2648 | writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt | |
2592 | S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst | | 2649 | S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst | |
2593 | S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt | | 2650 | S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt | |
@@ -3261,7 +3318,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3261 | hsotg->clk = clk_get(&pdev->dev, "otg"); | 3318 | hsotg->clk = clk_get(&pdev->dev, "otg"); |
3262 | if (IS_ERR(hsotg->clk)) { | 3319 | if (IS_ERR(hsotg->clk)) { |
3263 | dev_err(dev, "cannot get otg clock\n"); | 3320 | dev_err(dev, "cannot get otg clock\n"); |
3264 | ret = -EINVAL; | 3321 | ret = PTR_ERR(hsotg->clk); |
3265 | goto err_mem; | 3322 | goto err_mem; |
3266 | } | 3323 | } |
3267 | 3324 | ||
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c new file mode 100644 index 000000000000..cfe3cf56d6bd --- /dev/null +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -0,0 +1,1349 @@ | |||
1 | /* linux/drivers/usb/gadget/s3c-hsudc.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S3C24XX USB 2.0 High-speed USB controller gadget driver | ||
7 | * | ||
8 | * The S3C24XX USB 2.0 high-speed USB controller supports upto 9 endpoints. | ||
9 | * Each endpoint can be configured as either in or out endpoint. Endpoints | ||
10 | * can be configured for Bulk or Interrupt transfer mode. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/usb/ch9.h> | ||
28 | #include <linux/usb/gadget.h> | ||
29 | |||
30 | #include <mach/regs-s3c2443-clock.h> | ||
31 | #include <plat/udc.h> | ||
32 | |||
33 | #define S3C_HSUDC_REG(x) (x) | ||
34 | |||
35 | /* Non-Indexed Registers */ | ||
36 | #define S3C_IR S3C_HSUDC_REG(0x00) /* Index Register */ | ||
37 | #define S3C_EIR S3C_HSUDC_REG(0x04) /* EP Intr Status */ | ||
38 | #define S3C_EIR_EP0 (1<<0) | ||
39 | #define S3C_EIER S3C_HSUDC_REG(0x08) /* EP Intr Enable */ | ||
40 | #define S3C_FAR S3C_HSUDC_REG(0x0c) /* Gadget Address */ | ||
41 | #define S3C_FNR S3C_HSUDC_REG(0x10) /* Frame Number */ | ||
42 | #define S3C_EDR S3C_HSUDC_REG(0x14) /* EP Direction */ | ||
43 | #define S3C_TR S3C_HSUDC_REG(0x18) /* Test Register */ | ||
44 | #define S3C_SSR S3C_HSUDC_REG(0x1c) /* System Status */ | ||
45 | #define S3C_SSR_DTZIEN_EN (0xff8f) | ||
46 | #define S3C_SSR_ERR (0xff80) | ||
47 | #define S3C_SSR_VBUSON (1 << 8) | ||
48 | #define S3C_SSR_HSP (1 << 4) | ||
49 | #define S3C_SSR_SDE (1 << 3) | ||
50 | #define S3C_SSR_RESUME (1 << 2) | ||
51 | #define S3C_SSR_SUSPEND (1 << 1) | ||
52 | #define S3C_SSR_RESET (1 << 0) | ||
53 | #define S3C_SCR S3C_HSUDC_REG(0x20) /* System Control */ | ||
54 | #define S3C_SCR_DTZIEN_EN (1 << 14) | ||
55 | #define S3C_SCR_RRD_EN (1 << 5) | ||
56 | #define S3C_SCR_SUS_EN (1 << 1) | ||
57 | #define S3C_SCR_RST_EN (1 << 0) | ||
58 | #define S3C_EP0SR S3C_HSUDC_REG(0x24) /* EP0 Status */ | ||
59 | #define S3C_EP0SR_EP0_LWO (1 << 6) | ||
60 | #define S3C_EP0SR_STALL (1 << 4) | ||
61 | #define S3C_EP0SR_TX_SUCCESS (1 << 1) | ||
62 | #define S3C_EP0SR_RX_SUCCESS (1 << 0) | ||
63 | #define S3C_EP0CR S3C_HSUDC_REG(0x28) /* EP0 Control */ | ||
64 | #define S3C_BR(_x) S3C_HSUDC_REG(0x60 + (_x * 4)) | ||
65 | |||
66 | /* Indexed Registers */ | ||
67 | #define S3C_ESR S3C_HSUDC_REG(0x2c) /* EPn Status */ | ||
68 | #define S3C_ESR_FLUSH (1 << 6) | ||
69 | #define S3C_ESR_STALL (1 << 5) | ||
70 | #define S3C_ESR_LWO (1 << 4) | ||
71 | #define S3C_ESR_PSIF_ONE (1 << 2) | ||
72 | #define S3C_ESR_PSIF_TWO (2 << 2) | ||
73 | #define S3C_ESR_TX_SUCCESS (1 << 1) | ||
74 | #define S3C_ESR_RX_SUCCESS (1 << 0) | ||
75 | #define S3C_ECR S3C_HSUDC_REG(0x30) /* EPn Control */ | ||
76 | #define S3C_ECR_DUEN (1 << 7) | ||
77 | #define S3C_ECR_FLUSH (1 << 6) | ||
78 | #define S3C_ECR_STALL (1 << 1) | ||
79 | #define S3C_ECR_IEMS (1 << 0) | ||
80 | #define S3C_BRCR S3C_HSUDC_REG(0x34) /* Read Count */ | ||
81 | #define S3C_BWCR S3C_HSUDC_REG(0x38) /* Write Count */ | ||
82 | #define S3C_MPR S3C_HSUDC_REG(0x3c) /* Max Pkt Size */ | ||
83 | |||
84 | #define WAIT_FOR_SETUP (0) | ||
85 | #define DATA_STATE_XMIT (1) | ||
86 | #define DATA_STATE_RECV (2) | ||
87 | |||
88 | /** | ||
89 | * struct s3c_hsudc_ep - Endpoint representation used by driver. | ||
90 | * @ep: USB gadget layer representation of device endpoint. | ||
91 | * @name: Endpoint name (as required by ep autoconfiguration). | ||
92 | * @dev: Reference to the device controller to which this EP belongs. | ||
93 | * @desc: Endpoint descriptor obtained from the gadget driver. | ||
94 | * @queue: Transfer request queue for the endpoint. | ||
95 | * @stopped: Maintains state of endpoint, set if EP is halted. | ||
96 | * @bEndpointAddress: EP address (including direction bit). | ||
97 | * @fifo: Base address of EP FIFO. | ||
98 | */ | ||
99 | struct s3c_hsudc_ep { | ||
100 | struct usb_ep ep; | ||
101 | char name[20]; | ||
102 | struct s3c_hsudc *dev; | ||
103 | const struct usb_endpoint_descriptor *desc; | ||
104 | struct list_head queue; | ||
105 | u8 stopped; | ||
106 | u8 wedge; | ||
107 | u8 bEndpointAddress; | ||
108 | void __iomem *fifo; | ||
109 | }; | ||
110 | |||
111 | /** | ||
112 | * struct s3c_hsudc_req - Driver encapsulation of USB gadget transfer request. | ||
113 | * @req: Reference to USB gadget transfer request. | ||
114 | * @queue: Used for inserting this request to the endpoint request queue. | ||
115 | */ | ||
116 | struct s3c_hsudc_req { | ||
117 | struct usb_request req; | ||
118 | struct list_head queue; | ||
119 | }; | ||
120 | |||
121 | /** | ||
122 | * struct s3c_hsudc - Driver's abstraction of the device controller. | ||
123 | * @gadget: Instance of usb_gadget which is referenced by gadget driver. | ||
124 | * @driver: Reference to currenty active gadget driver. | ||
125 | * @dev: The device reference used by probe function. | ||
126 | * @lock: Lock to synchronize the usage of Endpoints (EP's are indexed). | ||
127 | * @regs: Remapped base address of controller's register space. | ||
128 | * @mem_rsrc: Device memory resource used for remapping device register space. | ||
129 | * irq: IRQ number used by the controller. | ||
130 | * uclk: Reference to the controller clock. | ||
131 | * ep0state: Current state of EP0. | ||
132 | * ep: List of endpoints supported by the controller. | ||
133 | */ | ||
134 | struct s3c_hsudc { | ||
135 | struct usb_gadget gadget; | ||
136 | struct usb_gadget_driver *driver; | ||
137 | struct device *dev; | ||
138 | struct s3c24xx_hsudc_platdata *pd; | ||
139 | spinlock_t lock; | ||
140 | void __iomem *regs; | ||
141 | struct resource *mem_rsrc; | ||
142 | int irq; | ||
143 | struct clk *uclk; | ||
144 | int ep0state; | ||
145 | struct s3c_hsudc_ep ep[]; | ||
146 | }; | ||
147 | |||
148 | #define ep_maxpacket(_ep) ((_ep)->ep.maxpacket) | ||
149 | #define ep_is_in(_ep) ((_ep)->bEndpointAddress & USB_DIR_IN) | ||
150 | #define ep_index(_ep) ((_ep)->bEndpointAddress & \ | ||
151 | USB_ENDPOINT_NUMBER_MASK) | ||
152 | |||
153 | static struct s3c_hsudc *the_controller; | ||
154 | static const char driver_name[] = "s3c-udc"; | ||
155 | static const char ep0name[] = "ep0-control"; | ||
156 | |||
157 | static inline struct s3c_hsudc_req *our_req(struct usb_request *req) | ||
158 | { | ||
159 | return container_of(req, struct s3c_hsudc_req, req); | ||
160 | } | ||
161 | |||
162 | static inline struct s3c_hsudc_ep *our_ep(struct usb_ep *ep) | ||
163 | { | ||
164 | return container_of(ep, struct s3c_hsudc_ep, ep); | ||
165 | } | ||
166 | |||
167 | static inline struct s3c_hsudc *to_hsudc(struct usb_gadget *gadget) | ||
168 | { | ||
169 | return container_of(gadget, struct s3c_hsudc, gadget); | ||
170 | } | ||
171 | |||
172 | static inline void set_index(struct s3c_hsudc *hsudc, int ep_addr) | ||
173 | { | ||
174 | ep_addr &= USB_ENDPOINT_NUMBER_MASK; | ||
175 | writel(ep_addr, hsudc->regs + S3C_IR); | ||
176 | } | ||
177 | |||
178 | static inline void __orr32(void __iomem *ptr, u32 val) | ||
179 | { | ||
180 | writel(readl(ptr) | val, ptr); | ||
181 | } | ||
182 | |||
183 | static void s3c_hsudc_init_phy(void) | ||
184 | { | ||
185 | u32 cfg; | ||
186 | |||
187 | cfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY; | ||
188 | writel(cfg, S3C2443_PWRCFG); | ||
189 | |||
190 | cfg = readl(S3C2443_URSTCON); | ||
191 | cfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); | ||
192 | writel(cfg, S3C2443_URSTCON); | ||
193 | mdelay(1); | ||
194 | |||
195 | cfg = readl(S3C2443_URSTCON); | ||
196 | cfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); | ||
197 | writel(cfg, S3C2443_URSTCON); | ||
198 | |||
199 | cfg = readl(S3C2443_PHYCTRL); | ||
200 | cfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT); | ||
201 | cfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL); | ||
202 | writel(cfg, S3C2443_PHYCTRL); | ||
203 | |||
204 | cfg = readl(S3C2443_PHYPWR); | ||
205 | cfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN | | ||
206 | S3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK | | ||
207 | S3C2443_PHYPWR_ANALOG_PD); | ||
208 | cfg |= S3C2443_PHYPWR_COMMON_ON; | ||
209 | writel(cfg, S3C2443_PHYPWR); | ||
210 | |||
211 | cfg = readl(S3C2443_UCLKCON); | ||
212 | cfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN | | ||
213 | S3C2443_UCLKCON_TCLKEN); | ||
214 | writel(cfg, S3C2443_UCLKCON); | ||
215 | } | ||
216 | |||
217 | static void s3c_hsudc_uninit_phy(void) | ||
218 | { | ||
219 | u32 cfg; | ||
220 | |||
221 | cfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY; | ||
222 | writel(cfg, S3C2443_PWRCFG); | ||
223 | |||
224 | writel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR); | ||
225 | |||
226 | cfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN; | ||
227 | writel(cfg, S3C2443_UCLKCON); | ||
228 | } | ||
229 | |||
230 | /** | ||
231 | * s3c_hsudc_complete_request - Complete a transfer request. | ||
232 | * @hsep: Endpoint to which the request belongs. | ||
233 | * @hsreq: Transfer request to be completed. | ||
234 | * @status: Transfer completion status for the transfer request. | ||
235 | */ | ||
236 | static void s3c_hsudc_complete_request(struct s3c_hsudc_ep *hsep, | ||
237 | struct s3c_hsudc_req *hsreq, int status) | ||
238 | { | ||
239 | unsigned int stopped = hsep->stopped; | ||
240 | struct s3c_hsudc *hsudc = hsep->dev; | ||
241 | |||
242 | list_del_init(&hsreq->queue); | ||
243 | hsreq->req.status = status; | ||
244 | |||
245 | if (!ep_index(hsep)) { | ||
246 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
247 | hsep->bEndpointAddress &= ~USB_DIR_IN; | ||
248 | } | ||
249 | |||
250 | hsep->stopped = 1; | ||
251 | spin_unlock(&hsudc->lock); | ||
252 | if (hsreq->req.complete != NULL) | ||
253 | hsreq->req.complete(&hsep->ep, &hsreq->req); | ||
254 | spin_lock(&hsudc->lock); | ||
255 | hsep->stopped = stopped; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * s3c_hsudc_nuke_ep - Terminate all requests queued for a endpoint. | ||
260 | * @hsep: Endpoint for which queued requests have to be terminated. | ||
261 | * @status: Transfer completion status for the transfer request. | ||
262 | */ | ||
263 | static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status) | ||
264 | { | ||
265 | struct s3c_hsudc_req *hsreq; | ||
266 | |||
267 | while (!list_empty(&hsep->queue)) { | ||
268 | hsreq = list_entry(hsep->queue.next, | ||
269 | struct s3c_hsudc_req, queue); | ||
270 | s3c_hsudc_complete_request(hsep, hsreq, status); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * s3c_hsudc_stop_activity - Stop activity on all endpoints. | ||
276 | * @hsudc: Device controller for which EP activity is to be stopped. | ||
277 | * @driver: Reference to the gadget driver which is currently active. | ||
278 | * | ||
279 | * All the endpoints are stopped and any pending transfer requests if any on | ||
280 | * the endpoint are terminated. | ||
281 | */ | ||
282 | static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc, | ||
283 | struct usb_gadget_driver *driver) | ||
284 | { | ||
285 | struct s3c_hsudc_ep *hsep; | ||
286 | int epnum; | ||
287 | |||
288 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | ||
289 | |||
290 | for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) { | ||
291 | hsep = &hsudc->ep[epnum]; | ||
292 | hsep->stopped = 1; | ||
293 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); | ||
294 | } | ||
295 | |||
296 | spin_unlock(&hsudc->lock); | ||
297 | driver->disconnect(&hsudc->gadget); | ||
298 | spin_lock(&hsudc->lock); | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * s3c_hsudc_read_setup_pkt - Read the received setup packet from EP0 fifo. | ||
303 | * @hsudc: Device controller from which setup packet is to be read. | ||
304 | * @buf: The buffer into which the setup packet is read. | ||
305 | * | ||
306 | * The setup packet received in the EP0 fifo is read and stored into a | ||
307 | * given buffer address. | ||
308 | */ | ||
309 | |||
310 | static void s3c_hsudc_read_setup_pkt(struct s3c_hsudc *hsudc, u16 *buf) | ||
311 | { | ||
312 | int count; | ||
313 | |||
314 | count = readl(hsudc->regs + S3C_BRCR); | ||
315 | while (count--) | ||
316 | *buf++ = (u16)readl(hsudc->regs + S3C_BR(0)); | ||
317 | |||
318 | writel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR); | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * s3c_hsudc_write_fifo - Write next chunk of transfer data to EP fifo. | ||
323 | * @hsep: Endpoint to which the data is to be written. | ||
324 | * @hsreq: Transfer request from which the next chunk of data is written. | ||
325 | * | ||
326 | * Write the next chunk of data from a transfer request to the endpoint FIFO. | ||
327 | * If the transfer request completes, 1 is returned, otherwise 0 is returned. | ||
328 | */ | ||
329 | static int s3c_hsudc_write_fifo(struct s3c_hsudc_ep *hsep, | ||
330 | struct s3c_hsudc_req *hsreq) | ||
331 | { | ||
332 | u16 *buf; | ||
333 | u32 max = ep_maxpacket(hsep); | ||
334 | u32 count, length; | ||
335 | bool is_last; | ||
336 | void __iomem *fifo = hsep->fifo; | ||
337 | |||
338 | buf = hsreq->req.buf + hsreq->req.actual; | ||
339 | prefetch(buf); | ||
340 | |||
341 | length = hsreq->req.length - hsreq->req.actual; | ||
342 | length = min(length, max); | ||
343 | hsreq->req.actual += length; | ||
344 | |||
345 | writel(length, hsep->dev->regs + S3C_BWCR); | ||
346 | for (count = 0; count < length; count += 2) | ||
347 | writel(*buf++, fifo); | ||
348 | |||
349 | if (count != max) { | ||
350 | is_last = true; | ||
351 | } else { | ||
352 | if (hsreq->req.length != hsreq->req.actual || hsreq->req.zero) | ||
353 | is_last = false; | ||
354 | else | ||
355 | is_last = true; | ||
356 | } | ||
357 | |||
358 | if (is_last) { | ||
359 | s3c_hsudc_complete_request(hsep, hsreq, 0); | ||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * s3c_hsudc_read_fifo - Read the next chunk of data from EP fifo. | ||
368 | * @hsep: Endpoint from which the data is to be read. | ||
369 | * @hsreq: Transfer request to which the next chunk of data read is written. | ||
370 | * | ||
371 | * Read the next chunk of data from the endpoint FIFO and a write it to the | ||
372 | * transfer request buffer. If the transfer request completes, 1 is returned, | ||
373 | * otherwise 0 is returned. | ||
374 | */ | ||
375 | static int s3c_hsudc_read_fifo(struct s3c_hsudc_ep *hsep, | ||
376 | struct s3c_hsudc_req *hsreq) | ||
377 | { | ||
378 | struct s3c_hsudc *hsudc = hsep->dev; | ||
379 | u32 csr, offset; | ||
380 | u16 *buf, word; | ||
381 | u32 buflen, rcnt, rlen; | ||
382 | void __iomem *fifo = hsep->fifo; | ||
383 | u32 is_short = 0; | ||
384 | |||
385 | offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR; | ||
386 | csr = readl(hsudc->regs + offset); | ||
387 | if (!(csr & S3C_ESR_RX_SUCCESS)) | ||
388 | return -EINVAL; | ||
389 | |||
390 | buf = hsreq->req.buf + hsreq->req.actual; | ||
391 | prefetchw(buf); | ||
392 | buflen = hsreq->req.length - hsreq->req.actual; | ||
393 | |||
394 | rcnt = readl(hsudc->regs + S3C_BRCR); | ||
395 | rlen = (csr & S3C_ESR_LWO) ? (rcnt * 2 - 1) : (rcnt * 2); | ||
396 | |||
397 | hsreq->req.actual += min(rlen, buflen); | ||
398 | is_short = (rlen < hsep->ep.maxpacket); | ||
399 | |||
400 | while (rcnt-- != 0) { | ||
401 | word = (u16)readl(fifo); | ||
402 | if (buflen) { | ||
403 | *buf++ = word; | ||
404 | buflen--; | ||
405 | } else { | ||
406 | hsreq->req.status = -EOVERFLOW; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | writel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset); | ||
411 | |||
412 | if (is_short || hsreq->req.actual == hsreq->req.length) { | ||
413 | s3c_hsudc_complete_request(hsep, hsreq, 0); | ||
414 | return 1; | ||
415 | } | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * s3c_hsudc_epin_intr - Handle in-endpoint interrupt. | ||
422 | * @hsudc - Device controller for which the interrupt is to be handled. | ||
423 | * @ep_idx - Endpoint number on which an interrupt is pending. | ||
424 | * | ||
425 | * Handles interrupt for a in-endpoint. The interrupts that are handled are | ||
426 | * stall and data transmit complete interrupt. | ||
427 | */ | ||
428 | static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx) | ||
429 | { | ||
430 | struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; | ||
431 | struct s3c_hsudc_req *hsreq; | ||
432 | u32 csr; | ||
433 | |||
434 | csr = readl((u32)hsudc->regs + S3C_ESR); | ||
435 | if (csr & S3C_ESR_STALL) { | ||
436 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | if (csr & S3C_ESR_TX_SUCCESS) { | ||
441 | writel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR); | ||
442 | if (list_empty(&hsep->queue)) | ||
443 | return; | ||
444 | |||
445 | hsreq = list_entry(hsep->queue.next, | ||
446 | struct s3c_hsudc_req, queue); | ||
447 | if ((s3c_hsudc_write_fifo(hsep, hsreq) == 0) && | ||
448 | (csr & S3C_ESR_PSIF_TWO)) | ||
449 | s3c_hsudc_write_fifo(hsep, hsreq); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * s3c_hsudc_epout_intr - Handle out-endpoint interrupt. | ||
455 | * @hsudc - Device controller for which the interrupt is to be handled. | ||
456 | * @ep_idx - Endpoint number on which an interrupt is pending. | ||
457 | * | ||
458 | * Handles interrupt for a out-endpoint. The interrupts that are handled are | ||
459 | * stall, flush and data ready interrupt. | ||
460 | */ | ||
461 | static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx) | ||
462 | { | ||
463 | struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; | ||
464 | struct s3c_hsudc_req *hsreq; | ||
465 | u32 csr; | ||
466 | |||
467 | csr = readl((u32)hsudc->regs + S3C_ESR); | ||
468 | if (csr & S3C_ESR_STALL) { | ||
469 | writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | if (csr & S3C_ESR_FLUSH) { | ||
474 | __orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH); | ||
475 | return; | ||
476 | } | ||
477 | |||
478 | if (csr & S3C_ESR_RX_SUCCESS) { | ||
479 | if (list_empty(&hsep->queue)) | ||
480 | return; | ||
481 | |||
482 | hsreq = list_entry(hsep->queue.next, | ||
483 | struct s3c_hsudc_req, queue); | ||
484 | if (((s3c_hsudc_read_fifo(hsep, hsreq)) == 0) && | ||
485 | (csr & S3C_ESR_PSIF_TWO)) | ||
486 | s3c_hsudc_read_fifo(hsep, hsreq); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | /** s3c_hsudc_set_halt - Set or clear a endpoint halt. | ||
491 | * @_ep: Endpoint on which halt has to be set or cleared. | ||
492 | * @value: 1 for setting halt on endpoint, 0 to clear halt. | ||
493 | * | ||
494 | * Set or clear endpoint halt. If halt is set, the endpoint is stopped. | ||
495 | * If halt is cleared, for in-endpoints, if there are any pending | ||
496 | * transfer requests, transfers are started. | ||
497 | */ | ||
498 | static int s3c_hsudc_set_halt(struct usb_ep *_ep, int value) | ||
499 | { | ||
500 | struct s3c_hsudc_ep *hsep = our_ep(_ep); | ||
501 | struct s3c_hsudc *hsudc = hsep->dev; | ||
502 | struct s3c_hsudc_req *hsreq; | ||
503 | unsigned long irqflags; | ||
504 | u32 ecr; | ||
505 | u32 offset; | ||
506 | |||
507 | if (value && ep_is_in(hsep) && !list_empty(&hsep->queue)) | ||
508 | return -EAGAIN; | ||
509 | |||
510 | spin_lock_irqsave(&hsudc->lock, irqflags); | ||
511 | set_index(hsudc, ep_index(hsep)); | ||
512 | offset = (ep_index(hsep)) ? S3C_ECR : S3C_EP0CR; | ||
513 | ecr = readl(hsudc->regs + offset); | ||
514 | |||
515 | if (value) { | ||
516 | ecr |= S3C_ECR_STALL; | ||
517 | if (ep_index(hsep)) | ||
518 | ecr |= S3C_ECR_FLUSH; | ||
519 | hsep->stopped = 1; | ||
520 | } else { | ||
521 | ecr &= ~S3C_ECR_STALL; | ||
522 | hsep->stopped = hsep->wedge = 0; | ||
523 | } | ||
524 | writel(ecr, hsudc->regs + offset); | ||
525 | |||
526 | if (ep_is_in(hsep) && !list_empty(&hsep->queue) && !value) { | ||
527 | hsreq = list_entry(hsep->queue.next, | ||
528 | struct s3c_hsudc_req, queue); | ||
529 | if (hsreq) | ||
530 | s3c_hsudc_write_fifo(hsep, hsreq); | ||
531 | } | ||
532 | |||
533 | spin_unlock_irqrestore(&hsudc->lock, irqflags); | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | /** s3c_hsudc_set_wedge - Sets the halt feature with the clear requests ignored | ||
538 | * @_ep: Endpoint on which wedge has to be set. | ||
539 | * | ||
540 | * Sets the halt feature with the clear requests ignored. | ||
541 | */ | ||
542 | static int s3c_hsudc_set_wedge(struct usb_ep *_ep) | ||
543 | { | ||
544 | struct s3c_hsudc_ep *hsep = our_ep(_ep); | ||
545 | |||
546 | if (!hsep) | ||
547 | return -EINVAL; | ||
548 | |||
549 | hsep->wedge = 1; | ||
550 | return usb_ep_set_halt(_ep); | ||
551 | } | ||
552 | |||
553 | /** s3c_hsudc_handle_reqfeat - Handle set feature or clear feature requests. | ||
554 | * @_ep: Device controller on which the set/clear feature needs to be handled. | ||
555 | * @ctrl: Control request as received on the endpoint 0. | ||
556 | * | ||
557 | * Handle set feature or clear feature control requests on the control endpoint. | ||
558 | */ | ||
559 | static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc, | ||
560 | struct usb_ctrlrequest *ctrl) | ||
561 | { | ||
562 | struct s3c_hsudc_ep *hsep; | ||
563 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); | ||
564 | u8 ep_num = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
565 | |||
566 | if (ctrl->bRequestType == USB_RECIP_ENDPOINT) { | ||
567 | hsep = &hsudc->ep[ep_num]; | ||
568 | switch (le16_to_cpu(ctrl->wValue)) { | ||
569 | case USB_ENDPOINT_HALT: | ||
570 | if (set || (!set && !hsep->wedge)) | ||
571 | s3c_hsudc_set_halt(&hsep->ep, set); | ||
572 | return 0; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | return -ENOENT; | ||
577 | } | ||
578 | |||
579 | /** | ||
580 | * s3c_hsudc_process_req_status - Handle get status control request. | ||
581 | * @hsudc: Device controller on which get status request has be handled. | ||
582 | * @ctrl: Control request as received on the endpoint 0. | ||
583 | * | ||
584 | * Handle get status control request received on control endpoint. | ||
585 | */ | ||
586 | static void s3c_hsudc_process_req_status(struct s3c_hsudc *hsudc, | ||
587 | struct usb_ctrlrequest *ctrl) | ||
588 | { | ||
589 | struct s3c_hsudc_ep *hsep0 = &hsudc->ep[0]; | ||
590 | struct s3c_hsudc_req hsreq; | ||
591 | struct s3c_hsudc_ep *hsep; | ||
592 | __le16 reply; | ||
593 | u8 epnum; | ||
594 | |||
595 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
596 | case USB_RECIP_DEVICE: | ||
597 | reply = cpu_to_le16(0); | ||
598 | break; | ||
599 | |||
600 | case USB_RECIP_INTERFACE: | ||
601 | reply = cpu_to_le16(0); | ||
602 | break; | ||
603 | |||
604 | case USB_RECIP_ENDPOINT: | ||
605 | epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; | ||
606 | hsep = &hsudc->ep[epnum]; | ||
607 | reply = cpu_to_le16(hsep->stopped ? 1 : 0); | ||
608 | break; | ||
609 | } | ||
610 | |||
611 | INIT_LIST_HEAD(&hsreq.queue); | ||
612 | hsreq.req.length = 2; | ||
613 | hsreq.req.buf = &reply; | ||
614 | hsreq.req.actual = 0; | ||
615 | hsreq.req.complete = NULL; | ||
616 | s3c_hsudc_write_fifo(hsep0, &hsreq); | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * s3c_hsudc_process_setup - Process control request received on endpoint 0. | ||
621 | * @hsudc: Device controller on which control request has been received. | ||
622 | * | ||
623 | * Read the control request received on endpoint 0, decode it and handle | ||
624 | * the request. | ||
625 | */ | ||
626 | static void s3c_hsudc_process_setup(struct s3c_hsudc *hsudc) | ||
627 | { | ||
628 | struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; | ||
629 | struct usb_ctrlrequest ctrl = {0}; | ||
630 | int ret; | ||
631 | |||
632 | s3c_hsudc_nuke_ep(hsep, -EPROTO); | ||
633 | s3c_hsudc_read_setup_pkt(hsudc, (u16 *)&ctrl); | ||
634 | |||
635 | if (ctrl.bRequestType & USB_DIR_IN) { | ||
636 | hsep->bEndpointAddress |= USB_DIR_IN; | ||
637 | hsudc->ep0state = DATA_STATE_XMIT; | ||
638 | } else { | ||
639 | hsep->bEndpointAddress &= ~USB_DIR_IN; | ||
640 | hsudc->ep0state = DATA_STATE_RECV; | ||
641 | } | ||
642 | |||
643 | switch (ctrl.bRequest) { | ||
644 | case USB_REQ_SET_ADDRESS: | ||
645 | if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) | ||
646 | break; | ||
647 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
648 | return; | ||
649 | |||
650 | case USB_REQ_GET_STATUS: | ||
651 | if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) | ||
652 | break; | ||
653 | s3c_hsudc_process_req_status(hsudc, &ctrl); | ||
654 | return; | ||
655 | |||
656 | case USB_REQ_SET_FEATURE: | ||
657 | case USB_REQ_CLEAR_FEATURE: | ||
658 | if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) | ||
659 | break; | ||
660 | s3c_hsudc_handle_reqfeat(hsudc, &ctrl); | ||
661 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
662 | return; | ||
663 | } | ||
664 | |||
665 | if (hsudc->driver) { | ||
666 | spin_unlock(&hsudc->lock); | ||
667 | ret = hsudc->driver->setup(&hsudc->gadget, &ctrl); | ||
668 | spin_lock(&hsudc->lock); | ||
669 | |||
670 | if (ctrl.bRequest == USB_REQ_SET_CONFIGURATION) { | ||
671 | hsep->bEndpointAddress &= ~USB_DIR_IN; | ||
672 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
673 | } | ||
674 | |||
675 | if (ret < 0) { | ||
676 | dev_err(hsudc->dev, "setup failed, returned %d\n", | ||
677 | ret); | ||
678 | s3c_hsudc_set_halt(&hsep->ep, 1); | ||
679 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
680 | hsep->bEndpointAddress &= ~USB_DIR_IN; | ||
681 | } | ||
682 | } | ||
683 | } | ||
684 | |||
685 | /** s3c_hsudc_handle_ep0_intr - Handle endpoint 0 interrupt. | ||
686 | * @hsudc: Device controller on which endpoint 0 interrupt has occured. | ||
687 | * | ||
688 | * Handle endpoint 0 interrupt when it occurs. EP0 interrupt could occur | ||
689 | * when a stall handshake is sent to host or data is sent/received on | ||
690 | * endpoint 0. | ||
691 | */ | ||
692 | static void s3c_hsudc_handle_ep0_intr(struct s3c_hsudc *hsudc) | ||
693 | { | ||
694 | struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; | ||
695 | struct s3c_hsudc_req *hsreq; | ||
696 | u32 csr = readl(hsudc->regs + S3C_EP0SR); | ||
697 | u32 ecr; | ||
698 | |||
699 | if (csr & S3C_EP0SR_STALL) { | ||
700 | ecr = readl(hsudc->regs + S3C_EP0CR); | ||
701 | ecr &= ~(S3C_ECR_STALL | S3C_ECR_FLUSH); | ||
702 | writel(ecr, hsudc->regs + S3C_EP0CR); | ||
703 | |||
704 | writel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR); | ||
705 | hsep->stopped = 0; | ||
706 | |||
707 | s3c_hsudc_nuke_ep(hsep, -ECONNABORTED); | ||
708 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
709 | hsep->bEndpointAddress &= ~USB_DIR_IN; | ||
710 | return; | ||
711 | } | ||
712 | |||
713 | if (csr & S3C_EP0SR_TX_SUCCESS) { | ||
714 | writel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR); | ||
715 | if (ep_is_in(hsep)) { | ||
716 | if (list_empty(&hsep->queue)) | ||
717 | return; | ||
718 | |||
719 | hsreq = list_entry(hsep->queue.next, | ||
720 | struct s3c_hsudc_req, queue); | ||
721 | s3c_hsudc_write_fifo(hsep, hsreq); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | if (csr & S3C_EP0SR_RX_SUCCESS) { | ||
726 | if (hsudc->ep0state == WAIT_FOR_SETUP) | ||
727 | s3c_hsudc_process_setup(hsudc); | ||
728 | else { | ||
729 | if (!ep_is_in(hsep)) { | ||
730 | if (list_empty(&hsep->queue)) | ||
731 | return; | ||
732 | hsreq = list_entry(hsep->queue.next, | ||
733 | struct s3c_hsudc_req, queue); | ||
734 | s3c_hsudc_read_fifo(hsep, hsreq); | ||
735 | } | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | |||
740 | /** | ||
741 | * s3c_hsudc_ep_enable - Enable a endpoint. | ||
742 | * @_ep: The endpoint to be enabled. | ||
743 | * @desc: Endpoint descriptor. | ||
744 | * | ||
745 | * Enables a endpoint when called from the gadget driver. Endpoint stall if | ||
746 | * any is cleared, transfer type is configured and endpoint interrupt is | ||
747 | * enabled. | ||
748 | */ | ||
749 | static int s3c_hsudc_ep_enable(struct usb_ep *_ep, | ||
750 | const struct usb_endpoint_descriptor *desc) | ||
751 | { | ||
752 | struct s3c_hsudc_ep *hsep; | ||
753 | struct s3c_hsudc *hsudc; | ||
754 | unsigned long flags; | ||
755 | u32 ecr = 0; | ||
756 | |||
757 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | ||
758 | if (!_ep || !desc || hsep->desc || _ep->name == ep0name | ||
759 | || desc->bDescriptorType != USB_DT_ENDPOINT | ||
760 | || hsep->bEndpointAddress != desc->bEndpointAddress | ||
761 | || ep_maxpacket(hsep) < le16_to_cpu(desc->wMaxPacketSize)) | ||
762 | return -EINVAL; | ||
763 | |||
764 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK | ||
765 | && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(hsep)) | ||
766 | || !desc->wMaxPacketSize) | ||
767 | return -ERANGE; | ||
768 | |||
769 | hsudc = hsep->dev; | ||
770 | if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) | ||
771 | return -ESHUTDOWN; | ||
772 | |||
773 | spin_lock_irqsave(&hsudc->lock, flags); | ||
774 | |||
775 | set_index(hsudc, hsep->bEndpointAddress); | ||
776 | ecr |= ((usb_endpoint_xfer_int(desc)) ? S3C_ECR_IEMS : S3C_ECR_DUEN); | ||
777 | writel(ecr, hsudc->regs + S3C_ECR); | ||
778 | |||
779 | hsep->stopped = hsep->wedge = 0; | ||
780 | hsep->desc = desc; | ||
781 | hsep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | ||
782 | |||
783 | s3c_hsudc_set_halt(_ep, 0); | ||
784 | __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER); | ||
785 | |||
786 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | /** | ||
791 | * s3c_hsudc_ep_disable - Disable a endpoint. | ||
792 | * @_ep: The endpoint to be disabled. | ||
793 | * @desc: Endpoint descriptor. | ||
794 | * | ||
795 | * Disables a endpoint when called from the gadget driver. | ||
796 | */ | ||
797 | static int s3c_hsudc_ep_disable(struct usb_ep *_ep) | ||
798 | { | ||
799 | struct s3c_hsudc_ep *hsep = our_ep(_ep); | ||
800 | struct s3c_hsudc *hsudc = hsep->dev; | ||
801 | unsigned long flags; | ||
802 | |||
803 | if (!_ep || !hsep->desc) | ||
804 | return -EINVAL; | ||
805 | |||
806 | spin_lock_irqsave(&hsudc->lock, flags); | ||
807 | |||
808 | set_index(hsudc, hsep->bEndpointAddress); | ||
809 | __clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER); | ||
810 | |||
811 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); | ||
812 | |||
813 | hsep->desc = 0; | ||
814 | hsep->stopped = 1; | ||
815 | |||
816 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * s3c_hsudc_alloc_request - Allocate a new request. | ||
822 | * @_ep: Endpoint for which request is allocated (not used). | ||
823 | * @gfp_flags: Flags used for the allocation. | ||
824 | * | ||
825 | * Allocates a single transfer request structure when called from gadget driver. | ||
826 | */ | ||
827 | static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep, | ||
828 | gfp_t gfp_flags) | ||
829 | { | ||
830 | struct s3c_hsudc_req *hsreq; | ||
831 | |||
832 | hsreq = kzalloc(sizeof *hsreq, gfp_flags); | ||
833 | if (!hsreq) | ||
834 | return 0; | ||
835 | |||
836 | INIT_LIST_HEAD(&hsreq->queue); | ||
837 | return &hsreq->req; | ||
838 | } | ||
839 | |||
840 | /** | ||
841 | * s3c_hsudc_free_request - Deallocate a request. | ||
842 | * @ep: Endpoint for which request is deallocated (not used). | ||
843 | * @_req: Request to be deallocated. | ||
844 | * | ||
845 | * Allocates a single transfer request structure when called from gadget driver. | ||
846 | */ | ||
847 | static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req) | ||
848 | { | ||
849 | struct s3c_hsudc_req *hsreq; | ||
850 | |||
851 | hsreq = container_of(_req, struct s3c_hsudc_req, req); | ||
852 | WARN_ON(!list_empty(&hsreq->queue)); | ||
853 | kfree(hsreq); | ||
854 | } | ||
855 | |||
856 | /** | ||
857 | * s3c_hsudc_queue - Queue a transfer request for the endpoint. | ||
858 | * @_ep: Endpoint for which the request is queued. | ||
859 | * @_req: Request to be queued. | ||
860 | * @gfp_flags: Not used. | ||
861 | * | ||
862 | * Start or enqueue a request for a endpoint when called from gadget driver. | ||
863 | */ | ||
864 | static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
865 | gfp_t gfp_flags) | ||
866 | { | ||
867 | struct s3c_hsudc_req *hsreq; | ||
868 | struct s3c_hsudc_ep *hsep; | ||
869 | struct s3c_hsudc *hsudc; | ||
870 | unsigned long flags; | ||
871 | u32 offset; | ||
872 | u32 csr; | ||
873 | |||
874 | hsreq = container_of(_req, struct s3c_hsudc_req, req); | ||
875 | if ((!_req || !_req->complete || !_req->buf || | ||
876 | !list_empty(&hsreq->queue))) | ||
877 | return -EINVAL; | ||
878 | |||
879 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | ||
880 | hsudc = hsep->dev; | ||
881 | if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) | ||
882 | return -ESHUTDOWN; | ||
883 | |||
884 | spin_lock_irqsave(&hsudc->lock, flags); | ||
885 | set_index(hsudc, hsep->bEndpointAddress); | ||
886 | |||
887 | _req->status = -EINPROGRESS; | ||
888 | _req->actual = 0; | ||
889 | |||
890 | if (!ep_index(hsep) && _req->length == 0) { | ||
891 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
892 | s3c_hsudc_complete_request(hsep, hsreq, 0); | ||
893 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | if (list_empty(&hsep->queue) && !hsep->stopped) { | ||
898 | offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR; | ||
899 | if (ep_is_in(hsep)) { | ||
900 | csr = readl((u32)hsudc->regs + offset); | ||
901 | if (!(csr & S3C_ESR_TX_SUCCESS) && | ||
902 | (s3c_hsudc_write_fifo(hsep, hsreq) == 1)) | ||
903 | hsreq = 0; | ||
904 | } else { | ||
905 | csr = readl((u32)hsudc->regs + offset); | ||
906 | if ((csr & S3C_ESR_RX_SUCCESS) | ||
907 | && (s3c_hsudc_read_fifo(hsep, hsreq) == 1)) | ||
908 | hsreq = 0; | ||
909 | } | ||
910 | } | ||
911 | |||
912 | if (hsreq != 0) | ||
913 | list_add_tail(&hsreq->queue, &hsep->queue); | ||
914 | |||
915 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | /** | ||
920 | * s3c_hsudc_dequeue - Dequeue a transfer request from an endpoint. | ||
921 | * @_ep: Endpoint from which the request is dequeued. | ||
922 | * @_req: Request to be dequeued. | ||
923 | * | ||
924 | * Dequeue a request from a endpoint when called from gadget driver. | ||
925 | */ | ||
926 | static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
927 | { | ||
928 | struct s3c_hsudc_ep *hsep = our_ep(_ep); | ||
929 | struct s3c_hsudc *hsudc = hsep->dev; | ||
930 | struct s3c_hsudc_req *hsreq; | ||
931 | unsigned long flags; | ||
932 | |||
933 | hsep = container_of(_ep, struct s3c_hsudc_ep, ep); | ||
934 | if (!_ep || hsep->ep.name == ep0name) | ||
935 | return -EINVAL; | ||
936 | |||
937 | spin_lock_irqsave(&hsudc->lock, flags); | ||
938 | |||
939 | list_for_each_entry(hsreq, &hsep->queue, queue) { | ||
940 | if (&hsreq->req == _req) | ||
941 | break; | ||
942 | } | ||
943 | if (&hsreq->req != _req) { | ||
944 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
945 | return -EINVAL; | ||
946 | } | ||
947 | |||
948 | set_index(hsudc, hsep->bEndpointAddress); | ||
949 | s3c_hsudc_complete_request(hsep, hsreq, -ECONNRESET); | ||
950 | |||
951 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | static struct usb_ep_ops s3c_hsudc_ep_ops = { | ||
956 | .enable = s3c_hsudc_ep_enable, | ||
957 | .disable = s3c_hsudc_ep_disable, | ||
958 | .alloc_request = s3c_hsudc_alloc_request, | ||
959 | .free_request = s3c_hsudc_free_request, | ||
960 | .queue = s3c_hsudc_queue, | ||
961 | .dequeue = s3c_hsudc_dequeue, | ||
962 | .set_halt = s3c_hsudc_set_halt, | ||
963 | .set_wedge = s3c_hsudc_set_wedge, | ||
964 | }; | ||
965 | |||
966 | /** | ||
967 | * s3c_hsudc_initep - Initialize a endpoint to default state. | ||
968 | * @hsudc - Reference to the device controller. | ||
969 | * @hsep - Endpoint to be initialized. | ||
970 | * @epnum - Address to be assigned to the endpoint. | ||
971 | * | ||
972 | * Initialize a endpoint with default configuration. | ||
973 | */ | ||
974 | static void s3c_hsudc_initep(struct s3c_hsudc *hsudc, | ||
975 | struct s3c_hsudc_ep *hsep, int epnum) | ||
976 | { | ||
977 | char *dir; | ||
978 | |||
979 | if ((epnum % 2) == 0) { | ||
980 | dir = "out"; | ||
981 | } else { | ||
982 | dir = "in"; | ||
983 | hsep->bEndpointAddress = USB_DIR_IN; | ||
984 | } | ||
985 | |||
986 | hsep->bEndpointAddress |= epnum; | ||
987 | if (epnum) | ||
988 | snprintf(hsep->name, sizeof(hsep->name), "ep%d%s", epnum, dir); | ||
989 | else | ||
990 | snprintf(hsep->name, sizeof(hsep->name), "%s", ep0name); | ||
991 | |||
992 | INIT_LIST_HEAD(&hsep->queue); | ||
993 | INIT_LIST_HEAD(&hsep->ep.ep_list); | ||
994 | if (epnum) | ||
995 | list_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list); | ||
996 | |||
997 | hsep->dev = hsudc; | ||
998 | hsep->ep.name = hsep->name; | ||
999 | hsep->ep.maxpacket = epnum ? 512 : 64; | ||
1000 | hsep->ep.ops = &s3c_hsudc_ep_ops; | ||
1001 | hsep->fifo = hsudc->regs + S3C_BR(epnum); | ||
1002 | hsep->desc = 0; | ||
1003 | hsep->stopped = 0; | ||
1004 | hsep->wedge = 0; | ||
1005 | |||
1006 | set_index(hsudc, epnum); | ||
1007 | writel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR); | ||
1008 | } | ||
1009 | |||
1010 | /** | ||
1011 | * s3c_hsudc_setup_ep - Configure all endpoints to default state. | ||
1012 | * @hsudc: Reference to device controller. | ||
1013 | * | ||
1014 | * Configures all endpoints to default state. | ||
1015 | */ | ||
1016 | static void s3c_hsudc_setup_ep(struct s3c_hsudc *hsudc) | ||
1017 | { | ||
1018 | int epnum; | ||
1019 | |||
1020 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
1021 | INIT_LIST_HEAD(&hsudc->gadget.ep_list); | ||
1022 | for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) | ||
1023 | s3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum); | ||
1024 | } | ||
1025 | |||
1026 | /** | ||
1027 | * s3c_hsudc_reconfig - Reconfigure the device controller to default state. | ||
1028 | * @hsudc: Reference to device controller. | ||
1029 | * | ||
1030 | * Reconfigures the device controller registers to a default state. | ||
1031 | */ | ||
1032 | static void s3c_hsudc_reconfig(struct s3c_hsudc *hsudc) | ||
1033 | { | ||
1034 | writel(0xAA, hsudc->regs + S3C_EDR); | ||
1035 | writel(1, hsudc->regs + S3C_EIER); | ||
1036 | writel(0, hsudc->regs + S3C_TR); | ||
1037 | writel(S3C_SCR_DTZIEN_EN | S3C_SCR_RRD_EN | S3C_SCR_SUS_EN | | ||
1038 | S3C_SCR_RST_EN, hsudc->regs + S3C_SCR); | ||
1039 | writel(0, hsudc->regs + S3C_EP0CR); | ||
1040 | |||
1041 | s3c_hsudc_setup_ep(hsudc); | ||
1042 | } | ||
1043 | |||
1044 | /** | ||
1045 | * s3c_hsudc_irq - Interrupt handler for device controller. | ||
1046 | * @irq: Not used. | ||
1047 | * @_dev: Reference to the device controller. | ||
1048 | * | ||
1049 | * Interrupt handler for the device controller. This handler handles controller | ||
1050 | * interrupts and endpoint interrupts. | ||
1051 | */ | ||
1052 | static irqreturn_t s3c_hsudc_irq(int irq, void *_dev) | ||
1053 | { | ||
1054 | struct s3c_hsudc *hsudc = _dev; | ||
1055 | struct s3c_hsudc_ep *hsep; | ||
1056 | u32 ep_intr; | ||
1057 | u32 sys_status; | ||
1058 | u32 ep_idx; | ||
1059 | |||
1060 | spin_lock(&hsudc->lock); | ||
1061 | |||
1062 | sys_status = readl(hsudc->regs + S3C_SSR); | ||
1063 | ep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF; | ||
1064 | |||
1065 | if (!ep_intr && !(sys_status & S3C_SSR_DTZIEN_EN)) { | ||
1066 | spin_unlock(&hsudc->lock); | ||
1067 | return IRQ_HANDLED; | ||
1068 | } | ||
1069 | |||
1070 | if (sys_status) { | ||
1071 | if (sys_status & S3C_SSR_VBUSON) | ||
1072 | writel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR); | ||
1073 | |||
1074 | if (sys_status & S3C_SSR_ERR) | ||
1075 | writel(S3C_SSR_ERR, hsudc->regs + S3C_SSR); | ||
1076 | |||
1077 | if (sys_status & S3C_SSR_SDE) { | ||
1078 | writel(S3C_SSR_SDE, hsudc->regs + S3C_SSR); | ||
1079 | hsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ? | ||
1080 | USB_SPEED_HIGH : USB_SPEED_FULL; | ||
1081 | } | ||
1082 | |||
1083 | if (sys_status & S3C_SSR_SUSPEND) { | ||
1084 | writel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR); | ||
1085 | if (hsudc->gadget.speed != USB_SPEED_UNKNOWN | ||
1086 | && hsudc->driver && hsudc->driver->suspend) | ||
1087 | hsudc->driver->suspend(&hsudc->gadget); | ||
1088 | } | ||
1089 | |||
1090 | if (sys_status & S3C_SSR_RESUME) { | ||
1091 | writel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR); | ||
1092 | if (hsudc->gadget.speed != USB_SPEED_UNKNOWN | ||
1093 | && hsudc->driver && hsudc->driver->resume) | ||
1094 | hsudc->driver->resume(&hsudc->gadget); | ||
1095 | } | ||
1096 | |||
1097 | if (sys_status & S3C_SSR_RESET) { | ||
1098 | writel(S3C_SSR_RESET, hsudc->regs + S3C_SSR); | ||
1099 | for (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) { | ||
1100 | hsep = &hsudc->ep[ep_idx]; | ||
1101 | hsep->stopped = 1; | ||
1102 | s3c_hsudc_nuke_ep(hsep, -ECONNRESET); | ||
1103 | } | ||
1104 | s3c_hsudc_reconfig(hsudc); | ||
1105 | hsudc->ep0state = WAIT_FOR_SETUP; | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | if (ep_intr & S3C_EIR_EP0) { | ||
1110 | writel(S3C_EIR_EP0, hsudc->regs + S3C_EIR); | ||
1111 | set_index(hsudc, 0); | ||
1112 | s3c_hsudc_handle_ep0_intr(hsudc); | ||
1113 | } | ||
1114 | |||
1115 | ep_intr >>= 1; | ||
1116 | ep_idx = 1; | ||
1117 | while (ep_intr) { | ||
1118 | if (ep_intr & 1) { | ||
1119 | hsep = &hsudc->ep[ep_idx]; | ||
1120 | set_index(hsudc, ep_idx); | ||
1121 | writel(1 << ep_idx, hsudc->regs + S3C_EIR); | ||
1122 | if (ep_is_in(hsep)) | ||
1123 | s3c_hsudc_epin_intr(hsudc, ep_idx); | ||
1124 | else | ||
1125 | s3c_hsudc_epout_intr(hsudc, ep_idx); | ||
1126 | } | ||
1127 | ep_intr >>= 1; | ||
1128 | ep_idx++; | ||
1129 | } | ||
1130 | |||
1131 | spin_unlock(&hsudc->lock); | ||
1132 | return IRQ_HANDLED; | ||
1133 | } | ||
1134 | |||
1135 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | ||
1136 | int (*bind)(struct usb_gadget *)) | ||
1137 | { | ||
1138 | struct s3c_hsudc *hsudc = the_controller; | ||
1139 | int ret; | ||
1140 | |||
1141 | if (!driver | ||
1142 | || (driver->speed != USB_SPEED_FULL && | ||
1143 | driver->speed != USB_SPEED_HIGH) | ||
1144 | || !bind | ||
1145 | || !driver->unbind || !driver->disconnect || !driver->setup) | ||
1146 | return -EINVAL; | ||
1147 | |||
1148 | if (!hsudc) | ||
1149 | return -ENODEV; | ||
1150 | |||
1151 | if (hsudc->driver) | ||
1152 | return -EBUSY; | ||
1153 | |||
1154 | hsudc->driver = driver; | ||
1155 | hsudc->gadget.dev.driver = &driver->driver; | ||
1156 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1157 | ret = device_add(&hsudc->gadget.dev); | ||
1158 | if (ret) { | ||
1159 | dev_err(hsudc->dev, "failed to probe gadget device"); | ||
1160 | return ret; | ||
1161 | } | ||
1162 | |||
1163 | ret = bind(&hsudc->gadget); | ||
1164 | if (ret) { | ||
1165 | dev_err(hsudc->dev, "%s: bind failed\n", hsudc->gadget.name); | ||
1166 | device_del(&hsudc->gadget.dev); | ||
1167 | |||
1168 | hsudc->driver = NULL; | ||
1169 | hsudc->gadget.dev.driver = NULL; | ||
1170 | return ret; | ||
1171 | } | ||
1172 | |||
1173 | enable_irq(hsudc->irq); | ||
1174 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); | ||
1175 | |||
1176 | s3c_hsudc_reconfig(hsudc); | ||
1177 | s3c_hsudc_init_phy(); | ||
1178 | if (hsudc->pd->gpio_init) | ||
1179 | hsudc->pd->gpio_init(); | ||
1180 | |||
1181 | return 0; | ||
1182 | } | ||
1183 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
1184 | |||
1185 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1186 | { | ||
1187 | struct s3c_hsudc *hsudc = the_controller; | ||
1188 | unsigned long flags; | ||
1189 | |||
1190 | if (!hsudc) | ||
1191 | return -ENODEV; | ||
1192 | |||
1193 | if (!driver || driver != hsudc->driver || !driver->unbind) | ||
1194 | return -EINVAL; | ||
1195 | |||
1196 | spin_lock_irqsave(&hsudc->lock, flags); | ||
1197 | hsudc->driver = 0; | ||
1198 | s3c_hsudc_uninit_phy(); | ||
1199 | if (hsudc->pd->gpio_uninit) | ||
1200 | hsudc->pd->gpio_uninit(); | ||
1201 | s3c_hsudc_stop_activity(hsudc, driver); | ||
1202 | spin_unlock_irqrestore(&hsudc->lock, flags); | ||
1203 | |||
1204 | driver->unbind(&hsudc->gadget); | ||
1205 | device_del(&hsudc->gadget.dev); | ||
1206 | disable_irq(hsudc->irq); | ||
1207 | |||
1208 | dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", | ||
1209 | driver->driver.name); | ||
1210 | return 0; | ||
1211 | } | ||
1212 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1213 | |||
1214 | static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc) | ||
1215 | { | ||
1216 | return readl(hsudc->regs + S3C_FNR) & 0x3FF; | ||
1217 | } | ||
1218 | |||
1219 | static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget) | ||
1220 | { | ||
1221 | return s3c_hsudc_read_frameno(to_hsudc(gadget)); | ||
1222 | } | ||
1223 | |||
1224 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { | ||
1225 | .get_frame = s3c_hsudc_gadget_getframe, | ||
1226 | }; | ||
1227 | |||
1228 | static int s3c_hsudc_probe(struct platform_device *pdev) | ||
1229 | { | ||
1230 | struct device *dev = &pdev->dev; | ||
1231 | struct resource *res; | ||
1232 | struct s3c_hsudc *hsudc; | ||
1233 | struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data; | ||
1234 | int ret; | ||
1235 | |||
1236 | hsudc = kzalloc(sizeof(struct s3c_hsudc) + | ||
1237 | sizeof(struct s3c_hsudc_ep) * pd->epnum, | ||
1238 | GFP_KERNEL); | ||
1239 | if (!hsudc) { | ||
1240 | dev_err(dev, "cannot allocate memory\n"); | ||
1241 | return -ENOMEM; | ||
1242 | } | ||
1243 | |||
1244 | the_controller = hsudc; | ||
1245 | platform_set_drvdata(pdev, dev); | ||
1246 | hsudc->dev = dev; | ||
1247 | hsudc->pd = pdev->dev.platform_data; | ||
1248 | |||
1249 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1250 | if (!res) { | ||
1251 | dev_err(dev, "unable to obtain driver resource data\n"); | ||
1252 | ret = -ENODEV; | ||
1253 | goto err_res; | ||
1254 | } | ||
1255 | |||
1256 | hsudc->mem_rsrc = request_mem_region(res->start, resource_size(res), | ||
1257 | dev_name(&pdev->dev)); | ||
1258 | if (!hsudc->mem_rsrc) { | ||
1259 | dev_err(dev, "failed to reserve register area\n"); | ||
1260 | ret = -ENODEV; | ||
1261 | goto err_res; | ||
1262 | } | ||
1263 | |||
1264 | hsudc->regs = ioremap(res->start, resource_size(res)); | ||
1265 | if (!hsudc->regs) { | ||
1266 | dev_err(dev, "error mapping device register area\n"); | ||
1267 | ret = -EBUSY; | ||
1268 | goto err_remap; | ||
1269 | } | ||
1270 | |||
1271 | ret = platform_get_irq(pdev, 0); | ||
1272 | if (ret < 0) { | ||
1273 | dev_err(dev, "unable to obtain IRQ number\n"); | ||
1274 | goto err_irq; | ||
1275 | } | ||
1276 | hsudc->irq = ret; | ||
1277 | |||
1278 | ret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc); | ||
1279 | if (ret < 0) { | ||
1280 | dev_err(dev, "irq request failed\n"); | ||
1281 | goto err_irq; | ||
1282 | } | ||
1283 | |||
1284 | spin_lock_init(&hsudc->lock); | ||
1285 | |||
1286 | device_initialize(&hsudc->gadget.dev); | ||
1287 | dev_set_name(&hsudc->gadget.dev, "gadget"); | ||
1288 | |||
1289 | hsudc->gadget.is_dualspeed = 1; | ||
1290 | hsudc->gadget.ops = &s3c_hsudc_gadget_ops; | ||
1291 | hsudc->gadget.name = dev_name(dev); | ||
1292 | hsudc->gadget.dev.parent = dev; | ||
1293 | hsudc->gadget.dev.dma_mask = dev->dma_mask; | ||
1294 | hsudc->gadget.ep0 = &hsudc->ep[0].ep; | ||
1295 | |||
1296 | hsudc->gadget.is_otg = 0; | ||
1297 | hsudc->gadget.is_a_peripheral = 0; | ||
1298 | |||
1299 | s3c_hsudc_setup_ep(hsudc); | ||
1300 | |||
1301 | hsudc->uclk = clk_get(&pdev->dev, "usb-device"); | ||
1302 | if (IS_ERR(hsudc->uclk)) { | ||
1303 | dev_err(dev, "failed to find usb-device clock source\n"); | ||
1304 | return PTR_ERR(hsudc->uclk); | ||
1305 | } | ||
1306 | clk_enable(hsudc->uclk); | ||
1307 | |||
1308 | local_irq_disable(); | ||
1309 | |||
1310 | disable_irq(hsudc->irq); | ||
1311 | local_irq_enable(); | ||
1312 | return 0; | ||
1313 | |||
1314 | err_irq: | ||
1315 | iounmap(hsudc->regs); | ||
1316 | |||
1317 | err_remap: | ||
1318 | release_resource(hsudc->mem_rsrc); | ||
1319 | kfree(hsudc->mem_rsrc); | ||
1320 | |||
1321 | err_res: | ||
1322 | kfree(hsudc); | ||
1323 | return ret; | ||
1324 | } | ||
1325 | |||
1326 | static struct platform_driver s3c_hsudc_driver = { | ||
1327 | .driver = { | ||
1328 | .owner = THIS_MODULE, | ||
1329 | .name = "s3c-hsudc", | ||
1330 | }, | ||
1331 | .probe = s3c_hsudc_probe, | ||
1332 | }; | ||
1333 | |||
1334 | static int __init s3c_hsudc_modinit(void) | ||
1335 | { | ||
1336 | return platform_driver_register(&s3c_hsudc_driver); | ||
1337 | } | ||
1338 | |||
1339 | static void __exit s3c_hsudc_modexit(void) | ||
1340 | { | ||
1341 | platform_driver_unregister(&s3c_hsudc_driver); | ||
1342 | } | ||
1343 | |||
1344 | module_init(s3c_hsudc_modinit); | ||
1345 | module_exit(s3c_hsudc_modexit); | ||
1346 | |||
1347 | MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver"); | ||
1348 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); | ||
1349 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index b015561fd602..1fa4f705b0b4 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -708,13 +708,14 @@ static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr, | |||
708 | static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr, | 708 | static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr, |
709 | const char *buf, size_t count) | 709 | const char *buf, size_t count) |
710 | { | 710 | { |
711 | ssize_t rc = count; | 711 | ssize_t rc; |
712 | struct fsg_lun *curlun = fsg_lun_from_dev(dev); | 712 | struct fsg_lun *curlun = fsg_lun_from_dev(dev); |
713 | struct rw_semaphore *filesem = dev_get_drvdata(dev); | 713 | struct rw_semaphore *filesem = dev_get_drvdata(dev); |
714 | unsigned long ro; | 714 | unsigned ro; |
715 | 715 | ||
716 | if (strict_strtoul(buf, 2, &ro)) | 716 | rc = kstrtouint(buf, 2, &ro); |
717 | return -EINVAL; | 717 | if (rc) |
718 | return rc; | ||
718 | 719 | ||
719 | /* | 720 | /* |
720 | * Allow the write-enable status to change only while the | 721 | * Allow the write-enable status to change only while the |
@@ -728,6 +729,7 @@ static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr, | |||
728 | curlun->ro = ro; | 729 | curlun->ro = ro; |
729 | curlun->initially_ro = ro; | 730 | curlun->initially_ro = ro; |
730 | LDBG(curlun, "read-only status set to %d\n", curlun->ro); | 731 | LDBG(curlun, "read-only status set to %d\n", curlun->ro); |
732 | rc = count; | ||
731 | } | 733 | } |
732 | up_read(filesem); | 734 | up_read(filesem); |
733 | return rc; | 735 | return rc; |
@@ -738,10 +740,12 @@ static ssize_t fsg_store_nofua(struct device *dev, | |||
738 | const char *buf, size_t count) | 740 | const char *buf, size_t count) |
739 | { | 741 | { |
740 | struct fsg_lun *curlun = fsg_lun_from_dev(dev); | 742 | struct fsg_lun *curlun = fsg_lun_from_dev(dev); |
741 | unsigned long nofua; | 743 | unsigned nofua; |
744 | int ret; | ||
742 | 745 | ||
743 | if (strict_strtoul(buf, 2, &nofua)) | 746 | ret = kstrtouint(buf, 2, &nofua); |
744 | return -EINVAL; | 747 | if (ret) |
748 | return ret; | ||
745 | 749 | ||
746 | /* Sync data when switching from async mode to sync */ | 750 | /* Sync data when switching from async mode to sync */ |
747 | if (!nofua && curlun->nofua) | 751 | if (!nofua && curlun->nofua) |