diff options
Diffstat (limited to 'drivers/usb/gadget')
25 files changed, 4718 insertions, 996 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f771a7cae9ec..45e01e289455 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -42,6 +42,20 @@ config USB_GADGET | |||
42 | For more information, see <http://www.linux-usb.org/gadget> and | 42 | For more information, see <http://www.linux-usb.org/gadget> and |
43 | the kernel DocBook documentation for this API. | 43 | the kernel DocBook documentation for this API. |
44 | 44 | ||
45 | config USB_GADGET_DEBUG | ||
46 | boolean "Debugging messages" | ||
47 | depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL | ||
48 | help | ||
49 | Many controller and gadget drivers will print some debugging | ||
50 | messages if you use this option to ask for those messages. | ||
51 | |||
52 | Avoid enabling these messages, even if you're actively | ||
53 | debugging such a driver. Many drivers will emit so many | ||
54 | messages that the driver timings are affected, which will | ||
55 | either create new failure modes or remove the one you're | ||
56 | trying to track down. Never enable these messages for a | ||
57 | production build. | ||
58 | |||
45 | config USB_GADGET_DEBUG_FILES | 59 | config USB_GADGET_DEBUG_FILES |
46 | boolean "Debugging information files" | 60 | boolean "Debugging information files" |
47 | depends on USB_GADGET && PROC_FS | 61 | depends on USB_GADGET && PROC_FS |
@@ -208,6 +222,27 @@ config USB_OTG | |||
208 | 222 | ||
209 | Select this only if your OMAP board has a Mini-AB connector. | 223 | Select this only if your OMAP board has a Mini-AB connector. |
210 | 224 | ||
225 | config USB_GADGET_S3C2410 | ||
226 | boolean "S3C2410 USB Device Controller" | ||
227 | depends on ARCH_S3C2410 | ||
228 | help | ||
229 | Samsung's S3C2410 is an ARM-4 processor with an integrated | ||
230 | full speed USB 1.1 device controller. It has 4 configurable | ||
231 | endpoints, as well as endpoint zero (for control transfers). | ||
232 | |||
233 | This driver has been tested on the S3C2410, S3C2412, and | ||
234 | S3C2440 processors. | ||
235 | |||
236 | config USB_S3C2410 | ||
237 | tristate | ||
238 | depends on USB_GADGET_S3C2410 | ||
239 | default USB_GADGET | ||
240 | select USB_GADGET_SELECTED | ||
241 | |||
242 | config USB_S3C2410_DEBUG | ||
243 | boolean "S3C2410 udc debug messages" | ||
244 | depends on USB_GADGET_S3C2410 | ||
245 | |||
211 | config USB_GADGET_AT91 | 246 | config USB_GADGET_AT91 |
212 | boolean "AT91 USB Device Port" | 247 | boolean "AT91 USB Device Port" |
213 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL | 248 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL |
@@ -226,6 +261,24 @@ config USB_AT91 | |||
226 | depends on USB_GADGET_AT91 | 261 | depends on USB_GADGET_AT91 |
227 | default USB_GADGET | 262 | default USB_GADGET |
228 | 263 | ||
264 | config USB_GADGET_M66592 | ||
265 | boolean "M66592 driver" | ||
266 | select USB_GADGET_DUALSPEED | ||
267 | help | ||
268 | M66592 is a USB 2.0 peripheral controller. | ||
269 | |||
270 | It has seven configurable endpoints, and endpoint zero. | ||
271 | |||
272 | Say "y" to link the driver statically, or "m" to build a | ||
273 | dynamically linked module called "m66592_udc" and force all | ||
274 | gadget drivers to also be dynamically linked. | ||
275 | |||
276 | config USB_M66592 | ||
277 | tristate | ||
278 | depends on USB_GADGET_M66592 | ||
279 | default USB_GADGET | ||
280 | select USB_GADGET_SELECTED | ||
281 | |||
229 | config USB_GADGET_DUMMY_HCD | 282 | config USB_GADGET_DUMMY_HCD |
230 | boolean "Dummy HCD (DEVELOPMENT)" | 283 | boolean "Dummy HCD (DEVELOPMENT)" |
231 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL | 284 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5db19396631c..8ae76f738635 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -1,14 +1,20 @@ | |||
1 | # | 1 | # |
2 | # USB peripheral controller drivers | 2 | # USB peripheral controller drivers |
3 | # | 3 | # |
4 | ifeq ($(CONFIG_USB_GADGET_DEBUG),y) | ||
5 | EXTRA_CFLAGS += -DDEBUG | ||
6 | endif | ||
7 | |||
4 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | 8 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o |
5 | obj-$(CONFIG_USB_NET2280) += net2280.o | 9 | obj-$(CONFIG_USB_NET2280) += net2280.o |
6 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o | 10 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o |
7 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | 11 | obj-$(CONFIG_USB_GOKU) += goku_udc.o |
8 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | 12 | obj-$(CONFIG_USB_OMAP) += omap_udc.o |
9 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o | 13 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o |
14 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | ||
10 | obj-$(CONFIG_USB_AT91) += at91_udc.o | 15 | obj-$(CONFIG_USB_AT91) += at91_udc.o |
11 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 16 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
17 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | ||
12 | 18 | ||
13 | # | 19 | # |
14 | # USB gadget drivers | 20 | # USB gadget drivers |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index ba163f35bf21..63d7d6568699 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -601,25 +601,6 @@ static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
601 | kfree(req); | 601 | kfree(req); |
602 | } | 602 | } |
603 | 603 | ||
604 | static void *at91_ep_alloc_buffer( | ||
605 | struct usb_ep *_ep, | ||
606 | unsigned bytes, | ||
607 | dma_addr_t *dma, | ||
608 | gfp_t gfp_flags) | ||
609 | { | ||
610 | *dma = ~0; | ||
611 | return kmalloc(bytes, gfp_flags); | ||
612 | } | ||
613 | |||
614 | static void at91_ep_free_buffer( | ||
615 | struct usb_ep *ep, | ||
616 | void *buf, | ||
617 | dma_addr_t dma, | ||
618 | unsigned bytes) | ||
619 | { | ||
620 | kfree(buf); | ||
621 | } | ||
622 | |||
623 | static int at91_ep_queue(struct usb_ep *_ep, | 604 | static int at91_ep_queue(struct usb_ep *_ep, |
624 | struct usb_request *_req, gfp_t gfp_flags) | 605 | struct usb_request *_req, gfp_t gfp_flags) |
625 | { | 606 | { |
@@ -788,8 +769,6 @@ static const struct usb_ep_ops at91_ep_ops = { | |||
788 | .disable = at91_ep_disable, | 769 | .disable = at91_ep_disable, |
789 | .alloc_request = at91_ep_alloc_request, | 770 | .alloc_request = at91_ep_alloc_request, |
790 | .free_request = at91_ep_free_request, | 771 | .free_request = at91_ep_free_request, |
791 | .alloc_buffer = at91_ep_alloc_buffer, | ||
792 | .free_buffer = at91_ep_free_buffer, | ||
793 | .queue = at91_ep_queue, | 772 | .queue = at91_ep_queue, |
794 | .dequeue = at91_ep_dequeue, | 773 | .dequeue = at91_ep_dequeue, |
795 | .set_halt = at91_ep_set_halt, | 774 | .set_halt = at91_ep_set_halt, |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index fcb5526cb085..f2fbdc7fe376 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -497,38 +497,6 @@ dummy_free_request (struct usb_ep *_ep, struct usb_request *_req) | |||
497 | kfree (req); | 497 | kfree (req); |
498 | } | 498 | } |
499 | 499 | ||
500 | static void * | ||
501 | dummy_alloc_buffer ( | ||
502 | struct usb_ep *_ep, | ||
503 | unsigned bytes, | ||
504 | dma_addr_t *dma, | ||
505 | gfp_t mem_flags | ||
506 | ) { | ||
507 | char *retval; | ||
508 | struct dummy_ep *ep; | ||
509 | struct dummy *dum; | ||
510 | |||
511 | ep = usb_ep_to_dummy_ep (_ep); | ||
512 | dum = ep_to_dummy (ep); | ||
513 | |||
514 | if (!dum->driver) | ||
515 | return NULL; | ||
516 | retval = kmalloc (bytes, mem_flags); | ||
517 | *dma = (dma_addr_t) retval; | ||
518 | return retval; | ||
519 | } | ||
520 | |||
521 | static void | ||
522 | dummy_free_buffer ( | ||
523 | struct usb_ep *_ep, | ||
524 | void *buf, | ||
525 | dma_addr_t dma, | ||
526 | unsigned bytes | ||
527 | ) { | ||
528 | if (bytes) | ||
529 | kfree (buf); | ||
530 | } | ||
531 | |||
532 | static void | 500 | static void |
533 | fifo_complete (struct usb_ep *ep, struct usb_request *req) | 501 | fifo_complete (struct usb_ep *ep, struct usb_request *req) |
534 | { | 502 | { |
@@ -659,10 +627,6 @@ static const struct usb_ep_ops dummy_ep_ops = { | |||
659 | .alloc_request = dummy_alloc_request, | 627 | .alloc_request = dummy_alloc_request, |
660 | .free_request = dummy_free_request, | 628 | .free_request = dummy_free_request, |
661 | 629 | ||
662 | .alloc_buffer = dummy_alloc_buffer, | ||
663 | .free_buffer = dummy_free_buffer, | ||
664 | /* map, unmap, ... eventually hook the "generic" dma calls */ | ||
665 | |||
666 | .queue = dummy_queue, | 630 | .queue = dummy_queue, |
667 | .dequeue = dummy_dequeue, | 631 | .dequeue = dummy_dequeue, |
668 | 632 | ||
@@ -1784,8 +1748,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd) | |||
1784 | 1748 | ||
1785 | spin_lock_irq (&dum->lock); | 1749 | spin_lock_irq (&dum->lock); |
1786 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { | 1750 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
1787 | dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); | 1751 | rc = -ESHUTDOWN; |
1788 | rc = -ENODEV; | ||
1789 | } else { | 1752 | } else { |
1790 | dum->rh_state = DUMMY_RH_RUNNING; | 1753 | dum->rh_state = DUMMY_RH_RUNNING; |
1791 | set_link_state (dum); | 1754 | set_link_state (dum); |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 325bf7cfb83f..dbaf867436df 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -277,7 +277,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
277 | #define DEV_CONFIG_CDC | 277 | #define DEV_CONFIG_CDC |
278 | #endif | 278 | #endif |
279 | 279 | ||
280 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | 280 | #ifdef CONFIG_USB_GADGET_ATMEL_USBA |
281 | #define DEV_CONFIG_CDC | 281 | #define DEV_CONFIG_CDC |
282 | #endif | 282 | #endif |
283 | 283 | ||
@@ -292,7 +292,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
292 | #define DEV_CONFIG_SUBSET | 292 | #define DEV_CONFIG_SUBSET |
293 | #endif | 293 | #endif |
294 | 294 | ||
295 | #ifdef CONFIG_USB_GADGET_SH | 295 | #ifdef CONFIG_USB_GADGET_SUPERH |
296 | #define DEV_CONFIG_SUBSET | 296 | #define DEV_CONFIG_SUBSET |
297 | #endif | 297 | #endif |
298 | 298 | ||
@@ -301,6 +301,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
301 | #define DEV_CONFIG_SUBSET | 301 | #define DEV_CONFIG_SUBSET |
302 | #endif | 302 | #endif |
303 | 303 | ||
304 | #ifdef CONFIG_USB_GADGET_M66592 | ||
305 | #define DEV_CONFIG_CDC | ||
306 | #endif | ||
307 | |||
304 | 308 | ||
305 | /*-------------------------------------------------------------------------*/ | 309 | /*-------------------------------------------------------------------------*/ |
306 | 310 | ||
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 4639b629e60c..8712ef987179 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -3733,19 +3733,12 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) | |||
3733 | } | 3733 | } |
3734 | 3734 | ||
3735 | /* Free the data buffers */ | 3735 | /* Free the data buffers */ |
3736 | for (i = 0; i < NUM_BUFFERS; ++i) { | 3736 | for (i = 0; i < NUM_BUFFERS; ++i) |
3737 | struct fsg_buffhd *bh = &fsg->buffhds[i]; | 3737 | kfree(fsg->buffhds[i].buf); |
3738 | |||
3739 | if (bh->buf) | ||
3740 | usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma, | ||
3741 | mod_data.buflen); | ||
3742 | } | ||
3743 | 3738 | ||
3744 | /* Free the request and buffer for endpoint 0 */ | 3739 | /* Free the request and buffer for endpoint 0 */ |
3745 | if (req) { | 3740 | if (req) { |
3746 | if (req->buf) | 3741 | kfree(req->buf); |
3747 | usb_ep_free_buffer(fsg->ep0, req->buf, | ||
3748 | req->dma, EP0_BUFSIZE); | ||
3749 | usb_ep_free_request(fsg->ep0, req); | 3742 | usb_ep_free_request(fsg->ep0, req); |
3750 | } | 3743 | } |
3751 | 3744 | ||
@@ -3963,8 +3956,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3963 | #endif | 3956 | #endif |
3964 | 3957 | ||
3965 | if (gadget->is_otg) { | 3958 | if (gadget->is_otg) { |
3966 | otg_desc.bmAttributes |= USB_OTG_HNP, | 3959 | otg_desc.bmAttributes |= USB_OTG_HNP; |
3967 | config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
3968 | } | 3960 | } |
3969 | 3961 | ||
3970 | rc = -ENOMEM; | 3962 | rc = -ENOMEM; |
@@ -3973,8 +3965,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3973 | fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); | 3965 | fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); |
3974 | if (!req) | 3966 | if (!req) |
3975 | goto out; | 3967 | goto out; |
3976 | req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE, | 3968 | req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL); |
3977 | &req->dma, GFP_KERNEL); | ||
3978 | if (!req->buf) | 3969 | if (!req->buf) |
3979 | goto out; | 3970 | goto out; |
3980 | req->complete = ep0_complete; | 3971 | req->complete = ep0_complete; |
@@ -3986,8 +3977,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3986 | /* Allocate for the bulk-in endpoint. We assume that | 3977 | /* Allocate for the bulk-in endpoint. We assume that |
3987 | * the buffer will also work with the bulk-out (and | 3978 | * the buffer will also work with the bulk-out (and |
3988 | * interrupt-in) endpoint. */ | 3979 | * interrupt-in) endpoint. */ |
3989 | bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, | 3980 | bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL); |
3990 | &bh->dma, GFP_KERNEL); | ||
3991 | if (!bh->buf) | 3981 | if (!bh->buf) |
3992 | goto out; | 3982 | goto out; |
3993 | bh->next = bh + 1; | 3983 | bh->next = bh + 1; |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 3ca2b3159f00..10b2b33b8698 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -228,7 +228,7 @@ static int dr_controller_setup(struct fsl_udc *udc) | |||
228 | 228 | ||
229 | /* Config PHY interface */ | 229 | /* Config PHY interface */ |
230 | portctrl = fsl_readl(&dr_regs->portsc1); | 230 | portctrl = fsl_readl(&dr_regs->portsc1); |
231 | portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH); | 231 | portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); |
232 | switch (udc->phy_mode) { | 232 | switch (udc->phy_mode) { |
233 | case FSL_USB2_PHY_ULPI: | 233 | case FSL_USB2_PHY_ULPI: |
234 | portctrl |= PORTSCX_PTS_ULPI; | 234 | portctrl |= PORTSCX_PTS_ULPI; |
@@ -601,39 +601,6 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
601 | kfree(req); | 601 | kfree(req); |
602 | } | 602 | } |
603 | 603 | ||
604 | /*------------------------------------------------------------------ | ||
605 | * Allocate an I/O buffer | ||
606 | *---------------------------------------------------------------------*/ | ||
607 | static void *fsl_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | ||
608 | dma_addr_t *dma, gfp_t gfp_flags) | ||
609 | { | ||
610 | struct fsl_ep *ep; | ||
611 | |||
612 | if (!_ep) | ||
613 | return NULL; | ||
614 | |||
615 | ep = container_of(_ep, struct fsl_ep, ep); | ||
616 | |||
617 | return dma_alloc_coherent(ep->udc->gadget.dev.parent, | ||
618 | bytes, dma, gfp_flags); | ||
619 | } | ||
620 | |||
621 | /*------------------------------------------------------------------ | ||
622 | * frees an i/o buffer | ||
623 | *---------------------------------------------------------------------*/ | ||
624 | static void fsl_free_buffer(struct usb_ep *_ep, void *buf, | ||
625 | dma_addr_t dma, unsigned bytes) | ||
626 | { | ||
627 | struct fsl_ep *ep; | ||
628 | |||
629 | if (!_ep) | ||
630 | return; | ||
631 | |||
632 | ep = container_of(_ep, struct fsl_ep, ep); | ||
633 | |||
634 | dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma); | ||
635 | } | ||
636 | |||
637 | /*-------------------------------------------------------------------------*/ | 604 | /*-------------------------------------------------------------------------*/ |
638 | static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | 605 | static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) |
639 | { | 606 | { |
@@ -1047,9 +1014,6 @@ static struct usb_ep_ops fsl_ep_ops = { | |||
1047 | .alloc_request = fsl_alloc_request, | 1014 | .alloc_request = fsl_alloc_request, |
1048 | .free_request = fsl_free_request, | 1015 | .free_request = fsl_free_request, |
1049 | 1016 | ||
1050 | .alloc_buffer = fsl_alloc_buffer, | ||
1051 | .free_buffer = fsl_free_buffer, | ||
1052 | |||
1053 | .queue = fsl_ep_queue, | 1017 | .queue = fsl_ep_queue, |
1054 | .dequeue = fsl_ep_dequeue, | 1018 | .dequeue = fsl_ep_dequeue, |
1055 | 1019 | ||
@@ -2189,27 +2153,19 @@ static void fsl_udc_release(struct device *dev) | |||
2189 | * init resource for globle controller | 2153 | * init resource for globle controller |
2190 | * Return the udc handle on success or NULL on failure | 2154 | * Return the udc handle on success or NULL on failure |
2191 | ------------------------------------------------------------------*/ | 2155 | ------------------------------------------------------------------*/ |
2192 | static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | 2156 | static int __init struct_udc_setup(struct fsl_udc *udc, |
2157 | struct platform_device *pdev) | ||
2193 | { | 2158 | { |
2194 | struct fsl_udc *udc; | ||
2195 | struct fsl_usb2_platform_data *pdata; | 2159 | struct fsl_usb2_platform_data *pdata; |
2196 | size_t size; | 2160 | size_t size; |
2197 | 2161 | ||
2198 | udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); | ||
2199 | if (udc == NULL) { | ||
2200 | ERR("malloc udc failed\n"); | ||
2201 | return NULL; | ||
2202 | } | ||
2203 | |||
2204 | pdata = pdev->dev.platform_data; | 2162 | pdata = pdev->dev.platform_data; |
2205 | udc->phy_mode = pdata->phy_mode; | 2163 | udc->phy_mode = pdata->phy_mode; |
2206 | /* max_ep_nr is bidirectional ep number, max_ep doubles the number */ | ||
2207 | udc->max_ep = pdata->max_ep_nr * 2; | ||
2208 | 2164 | ||
2209 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); | 2165 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); |
2210 | if (!udc->eps) { | 2166 | if (!udc->eps) { |
2211 | ERR("malloc fsl_ep failed\n"); | 2167 | ERR("malloc fsl_ep failed\n"); |
2212 | goto cleanup; | 2168 | return -1; |
2213 | } | 2169 | } |
2214 | 2170 | ||
2215 | /* initialized QHs, take care of alignment */ | 2171 | /* initialized QHs, take care of alignment */ |
@@ -2225,7 +2181,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | |||
2225 | if (!udc->ep_qh) { | 2181 | if (!udc->ep_qh) { |
2226 | ERR("malloc QHs for udc failed\n"); | 2182 | ERR("malloc QHs for udc failed\n"); |
2227 | kfree(udc->eps); | 2183 | kfree(udc->eps); |
2228 | goto cleanup; | 2184 | return -1; |
2229 | } | 2185 | } |
2230 | 2186 | ||
2231 | udc->ep_qh_size = size; | 2187 | udc->ep_qh_size = size; |
@@ -2244,11 +2200,7 @@ static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) | |||
2244 | udc->remote_wakeup = 0; /* default to 0 on reset */ | 2200 | udc->remote_wakeup = 0; /* default to 0 on reset */ |
2245 | spin_lock_init(&udc->lock); | 2201 | spin_lock_init(&udc->lock); |
2246 | 2202 | ||
2247 | return udc; | 2203 | return 0; |
2248 | |||
2249 | cleanup: | ||
2250 | kfree(udc); | ||
2251 | return NULL; | ||
2252 | } | 2204 | } |
2253 | 2205 | ||
2254 | /*---------------------------------------------------------------- | 2206 | /*---------------------------------------------------------------- |
@@ -2287,35 +2239,37 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, | |||
2287 | } | 2239 | } |
2288 | 2240 | ||
2289 | /* Driver probe function | 2241 | /* Driver probe function |
2290 | * all intialize operations implemented here except enabling usb_intr reg | 2242 | * all intialization operations implemented here except enabling usb_intr reg |
2243 | * board setup should have been done in the platform code | ||
2291 | */ | 2244 | */ |
2292 | static int __init fsl_udc_probe(struct platform_device *pdev) | 2245 | static int __init fsl_udc_probe(struct platform_device *pdev) |
2293 | { | 2246 | { |
2294 | struct resource *res; | 2247 | struct resource *res; |
2295 | int ret = -ENODEV; | 2248 | int ret = -ENODEV; |
2296 | unsigned int i; | 2249 | unsigned int i; |
2250 | u32 dccparams; | ||
2297 | 2251 | ||
2298 | if (strcmp(pdev->name, driver_name)) { | 2252 | if (strcmp(pdev->name, driver_name)) { |
2299 | VDBG("Wrong device\n"); | 2253 | VDBG("Wrong device\n"); |
2300 | return -ENODEV; | 2254 | return -ENODEV; |
2301 | } | 2255 | } |
2302 | 2256 | ||
2303 | /* board setup should have been done in the platform code */ | 2257 | udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); |
2304 | 2258 | if (udc_controller == NULL) { | |
2305 | /* Initialize the udc structure including QH member and other member */ | 2259 | ERR("malloc udc failed\n"); |
2306 | udc_controller = struct_udc_setup(pdev); | ||
2307 | if (!udc_controller) { | ||
2308 | VDBG("udc_controller is NULL \n"); | ||
2309 | return -ENOMEM; | 2260 | return -ENOMEM; |
2310 | } | 2261 | } |
2311 | 2262 | ||
2312 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2263 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2313 | if (!res) | 2264 | if (!res) { |
2265 | kfree(udc_controller); | ||
2314 | return -ENXIO; | 2266 | return -ENXIO; |
2267 | } | ||
2315 | 2268 | ||
2316 | if (!request_mem_region(res->start, res->end - res->start + 1, | 2269 | if (!request_mem_region(res->start, res->end - res->start + 1, |
2317 | driver_name)) { | 2270 | driver_name)) { |
2318 | ERR("request mem region for %s failed \n", pdev->name); | 2271 | ERR("request mem region for %s failed \n", pdev->name); |
2272 | kfree(udc_controller); | ||
2319 | return -EBUSY; | 2273 | return -EBUSY; |
2320 | } | 2274 | } |
2321 | 2275 | ||
@@ -2328,13 +2282,24 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2328 | usb_sys_regs = (struct usb_sys_interface *) | 2282 | usb_sys_regs = (struct usb_sys_interface *) |
2329 | ((u32)dr_regs + USB_DR_SYS_OFFSET); | 2283 | ((u32)dr_regs + USB_DR_SYS_OFFSET); |
2330 | 2284 | ||
2285 | /* Read Device Controller Capability Parameters register */ | ||
2286 | dccparams = fsl_readl(&dr_regs->dccparams); | ||
2287 | if (!(dccparams & DCCPARAMS_DC)) { | ||
2288 | ERR("This SOC doesn't support device role\n"); | ||
2289 | ret = -ENODEV; | ||
2290 | goto err2; | ||
2291 | } | ||
2292 | /* Get max device endpoints */ | ||
2293 | /* DEN is bidirectional ep number, max_ep doubles the number */ | ||
2294 | udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; | ||
2295 | |||
2331 | udc_controller->irq = platform_get_irq(pdev, 0); | 2296 | udc_controller->irq = platform_get_irq(pdev, 0); |
2332 | if (!udc_controller->irq) { | 2297 | if (!udc_controller->irq) { |
2333 | ret = -ENODEV; | 2298 | ret = -ENODEV; |
2334 | goto err2; | 2299 | goto err2; |
2335 | } | 2300 | } |
2336 | 2301 | ||
2337 | ret = request_irq(udc_controller->irq, fsl_udc_irq, SA_SHIRQ, | 2302 | ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, |
2338 | driver_name, udc_controller); | 2303 | driver_name, udc_controller); |
2339 | if (ret != 0) { | 2304 | if (ret != 0) { |
2340 | ERR("cannot request irq %d err %d \n", | 2305 | ERR("cannot request irq %d err %d \n", |
@@ -2342,6 +2307,13 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2342 | goto err2; | 2307 | goto err2; |
2343 | } | 2308 | } |
2344 | 2309 | ||
2310 | /* Initialize the udc structure including QH member and other member */ | ||
2311 | if (struct_udc_setup(udc_controller, pdev)) { | ||
2312 | ERR("Can't initialize udc data structure\n"); | ||
2313 | ret = -ENOMEM; | ||
2314 | goto err3; | ||
2315 | } | ||
2316 | |||
2345 | /* initialize usb hw reg except for regs for EP, | 2317 | /* initialize usb hw reg except for regs for EP, |
2346 | * leave usbintr reg untouched */ | 2318 | * leave usbintr reg untouched */ |
2347 | dr_controller_setup(udc_controller); | 2319 | dr_controller_setup(udc_controller); |
@@ -2403,6 +2375,7 @@ err2: | |||
2403 | iounmap(dr_regs); | 2375 | iounmap(dr_regs); |
2404 | err1: | 2376 | err1: |
2405 | release_mem_region(res->start, res->end - res->start + 1); | 2377 | release_mem_region(res->start, res->end - res->start + 1); |
2378 | kfree(udc_controller); | ||
2406 | return ret; | 2379 | return ret; |
2407 | } | 2380 | } |
2408 | 2381 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index c6291e046507..832ab82b4882 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -101,6 +101,10 @@ struct usb_sys_interface { | |||
101 | #define WAIT_FOR_OUT_STATUS 3 | 101 | #define WAIT_FOR_OUT_STATUS 3 |
102 | #define DATA_STATE_RECV 4 | 102 | #define DATA_STATE_RECV 4 |
103 | 103 | ||
104 | /* Device Controller Capability Parameter register */ | ||
105 | #define DCCPARAMS_DC 0x00000080 | ||
106 | #define DCCPARAMS_DEN_MASK 0x0000001f | ||
107 | |||
104 | /* Frame Index Register Bit Masks */ | 108 | /* Frame Index Register Bit Masks */ |
105 | #define USB_FRINDEX_MASKS 0x3fff | 109 | #define USB_FRINDEX_MASKS 0x3fff |
106 | /* USB CMD Register Bit Masks */ | 110 | /* USB CMD Register Bit Masks */ |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index d041b919e7b8..53e9139ba388 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -8,6 +8,8 @@ | |||
8 | * (And avoiding all runtime comparisons in typical one-choice configs!) | 8 | * (And avoiding all runtime comparisons in typical one-choice configs!) |
9 | * | 9 | * |
10 | * NOTE: some of these controller drivers may not be available yet. | 10 | * NOTE: some of these controller drivers may not be available yet. |
11 | * Some are available on 2.4 kernels; several are available, but not | ||
12 | * yet pushed in the 2.6 mainline tree. | ||
11 | */ | 13 | */ |
12 | #ifdef CONFIG_USB_GADGET_NET2280 | 14 | #ifdef CONFIG_USB_GADGET_NET2280 |
13 | #define gadget_is_net2280(g) !strcmp("net2280", (g)->name) | 15 | #define gadget_is_net2280(g) !strcmp("net2280", (g)->name) |
@@ -33,12 +35,14 @@ | |||
33 | #define gadget_is_goku(g) 0 | 35 | #define gadget_is_goku(g) 0 |
34 | #endif | 36 | #endif |
35 | 37 | ||
38 | /* SH3 UDC -- not yet ported 2.4 --> 2.6 */ | ||
36 | #ifdef CONFIG_USB_GADGET_SUPERH | 39 | #ifdef CONFIG_USB_GADGET_SUPERH |
37 | #define gadget_is_sh(g) !strcmp("sh_udc", (g)->name) | 40 | #define gadget_is_sh(g) !strcmp("sh_udc", (g)->name) |
38 | #else | 41 | #else |
39 | #define gadget_is_sh(g) 0 | 42 | #define gadget_is_sh(g) 0 |
40 | #endif | 43 | #endif |
41 | 44 | ||
45 | /* not yet stable on 2.6 (would help "original Zaurus") */ | ||
42 | #ifdef CONFIG_USB_GADGET_SA1100 | 46 | #ifdef CONFIG_USB_GADGET_SA1100 |
43 | #define gadget_is_sa1100(g) !strcmp("sa1100_udc", (g)->name) | 47 | #define gadget_is_sa1100(g) !strcmp("sa1100_udc", (g)->name) |
44 | #else | 48 | #else |
@@ -51,6 +55,7 @@ | |||
51 | #define gadget_is_lh7a40x(g) 0 | 55 | #define gadget_is_lh7a40x(g) 0 |
52 | #endif | 56 | #endif |
53 | 57 | ||
58 | /* handhelds.org tree (?) */ | ||
54 | #ifdef CONFIG_USB_GADGET_MQ11XX | 59 | #ifdef CONFIG_USB_GADGET_MQ11XX |
55 | #define gadget_is_mq11xx(g) !strcmp("mq11xx_udc", (g)->name) | 60 | #define gadget_is_mq11xx(g) !strcmp("mq11xx_udc", (g)->name) |
56 | #else | 61 | #else |
@@ -63,22 +68,24 @@ | |||
63 | #define gadget_is_omap(g) 0 | 68 | #define gadget_is_omap(g) 0 |
64 | #endif | 69 | #endif |
65 | 70 | ||
71 | /* not yet ported 2.4 --> 2.6 */ | ||
66 | #ifdef CONFIG_USB_GADGET_N9604 | 72 | #ifdef CONFIG_USB_GADGET_N9604 |
67 | #define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name) | 73 | #define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name) |
68 | #else | 74 | #else |
69 | #define gadget_is_n9604(g) 0 | 75 | #define gadget_is_n9604(g) 0 |
70 | #endif | 76 | #endif |
71 | 77 | ||
78 | /* various unstable versions available */ | ||
72 | #ifdef CONFIG_USB_GADGET_PXA27X | 79 | #ifdef CONFIG_USB_GADGET_PXA27X |
73 | #define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name) | 80 | #define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name) |
74 | #else | 81 | #else |
75 | #define gadget_is_pxa27x(g) 0 | 82 | #define gadget_is_pxa27x(g) 0 |
76 | #endif | 83 | #endif |
77 | 84 | ||
78 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | 85 | #ifdef CONFIG_USB_GADGET_ATMEL_USBA |
79 | #define gadget_is_husb2dev(g) !strcmp("husb2_udc", (g)->name) | 86 | #define gadget_is_atmel_usba(g) !strcmp("atmel_usba_udc", (g)->name) |
80 | #else | 87 | #else |
81 | #define gadget_is_husb2dev(g) 0 | 88 | #define gadget_is_atmel_usba(g) 0 |
82 | #endif | 89 | #endif |
83 | 90 | ||
84 | #ifdef CONFIG_USB_GADGET_S3C2410 | 91 | #ifdef CONFIG_USB_GADGET_S3C2410 |
@@ -93,6 +100,7 @@ | |||
93 | #define gadget_is_at91(g) 0 | 100 | #define gadget_is_at91(g) 0 |
94 | #endif | 101 | #endif |
95 | 102 | ||
103 | /* status unclear */ | ||
96 | #ifdef CONFIG_USB_GADGET_IMX | 104 | #ifdef CONFIG_USB_GADGET_IMX |
97 | #define gadget_is_imx(g) !strcmp("imx_udc", (g)->name) | 105 | #define gadget_is_imx(g) !strcmp("imx_udc", (g)->name) |
98 | #else | 106 | #else |
@@ -106,6 +114,7 @@ | |||
106 | #endif | 114 | #endif |
107 | 115 | ||
108 | /* Mentor high speed function controller */ | 116 | /* Mentor high speed function controller */ |
117 | /* from Montavista kernel (?) */ | ||
109 | #ifdef CONFIG_USB_GADGET_MUSBHSFC | 118 | #ifdef CONFIG_USB_GADGET_MUSBHSFC |
110 | #define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) | 119 | #define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) |
111 | #else | 120 | #else |
@@ -119,12 +128,20 @@ | |||
119 | #define gadget_is_musbhdrc(g) 0 | 128 | #define gadget_is_musbhdrc(g) 0 |
120 | #endif | 129 | #endif |
121 | 130 | ||
131 | /* from Montavista kernel (?) */ | ||
122 | #ifdef CONFIG_USB_GADGET_MPC8272 | 132 | #ifdef CONFIG_USB_GADGET_MPC8272 |
123 | #define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name) | 133 | #define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name) |
124 | #else | 134 | #else |
125 | #define gadget_is_mpc8272(g) 0 | 135 | #define gadget_is_mpc8272(g) 0 |
126 | #endif | 136 | #endif |
127 | 137 | ||
138 | #ifdef CONFIG_USB_GADGET_M66592 | ||
139 | #define gadget_is_m66592(g) !strcmp("m66592_udc", (g)->name) | ||
140 | #else | ||
141 | #define gadget_is_m66592(g) 0 | ||
142 | #endif | ||
143 | |||
144 | |||
128 | // CONFIG_USB_GADGET_SX2 | 145 | // CONFIG_USB_GADGET_SX2 |
129 | // CONFIG_USB_GADGET_AU1X00 | 146 | // CONFIG_USB_GADGET_AU1X00 |
130 | // ... | 147 | // ... |
@@ -181,9 +198,11 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
181 | return 0x16; | 198 | return 0x16; |
182 | else if (gadget_is_mpc8272(gadget)) | 199 | else if (gadget_is_mpc8272(gadget)) |
183 | return 0x17; | 200 | return 0x17; |
184 | else if (gadget_is_husb2dev(gadget)) | 201 | else if (gadget_is_atmel_usba(gadget)) |
185 | return 0x18; | 202 | return 0x18; |
186 | else if (gadget_is_fsl_usb2(gadget)) | 203 | else if (gadget_is_fsl_usb2(gadget)) |
187 | return 0x19; | 204 | return 0x19; |
205 | else if (gadget_is_m66592(gadget)) | ||
206 | return 0x20; | ||
188 | return -ENOENT; | 207 | return -ENOENT; |
189 | } | 208 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index d08a8d0e6427..1c5aa49d7432 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -1248,17 +1248,11 @@ autoconf_fail: | |||
1248 | tasklet_init(&dev->tasklet, gmidi_in_tasklet, (unsigned long)dev); | 1248 | tasklet_init(&dev->tasklet, gmidi_in_tasklet, (unsigned long)dev); |
1249 | 1249 | ||
1250 | /* preallocate control response and buffer */ | 1250 | /* preallocate control response and buffer */ |
1251 | dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); | 1251 | dev->req = alloc_ep_req(gadget->ep0, USB_BUFSIZ); |
1252 | if (!dev->req) { | 1252 | if (!dev->req) { |
1253 | err = -ENOMEM; | 1253 | err = -ENOMEM; |
1254 | goto fail; | 1254 | goto fail; |
1255 | } | 1255 | } |
1256 | dev->req->buf = usb_ep_alloc_buffer(gadget->ep0, USB_BUFSIZ, | ||
1257 | &dev->req->dma, GFP_KERNEL); | ||
1258 | if (!dev->req->buf) { | ||
1259 | err = -ENOMEM; | ||
1260 | goto fail; | ||
1261 | } | ||
1262 | 1256 | ||
1263 | dev->req->complete = gmidi_setup_complete; | 1257 | dev->req->complete = gmidi_setup_complete; |
1264 | 1258 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index ae931af05cef..d6c5f1150ae7 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -20,7 +20,6 @@ | |||
20 | * - DMA works with ep1 (OUT transfers) and ep2 (IN transfers). | 20 | * - DMA works with ep1 (OUT transfers) and ep2 (IN transfers). |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #undef DEBUG | ||
24 | // #define VERBOSE /* extra debug messages (success too) */ | 23 | // #define VERBOSE /* extra debug messages (success too) */ |
25 | // #define USB_TRACE /* packet-level success messages */ | 24 | // #define USB_TRACE /* packet-level success messages */ |
26 | 25 | ||
@@ -296,51 +295,6 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
296 | 295 | ||
297 | /*-------------------------------------------------------------------------*/ | 296 | /*-------------------------------------------------------------------------*/ |
298 | 297 | ||
299 | /* allocating buffers this way eliminates dma mapping overhead, which | ||
300 | * on some platforms will mean eliminating a per-io buffer copy. with | ||
301 | * some kinds of system caches, further tweaks may still be needed. | ||
302 | */ | ||
303 | static void * | ||
304 | goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | ||
305 | dma_addr_t *dma, gfp_t gfp_flags) | ||
306 | { | ||
307 | void *retval; | ||
308 | struct goku_ep *ep; | ||
309 | |||
310 | ep = container_of(_ep, struct goku_ep, ep); | ||
311 | if (!_ep) | ||
312 | return NULL; | ||
313 | *dma = DMA_ADDR_INVALID; | ||
314 | |||
315 | if (ep->dma) { | ||
316 | /* the main problem with this call is that it wastes memory | ||
317 | * on typical 1/N page allocations: it allocates 1-N pages. | ||
318 | */ | ||
319 | #warning Using dma_alloc_coherent even with buffers smaller than a page. | ||
320 | retval = dma_alloc_coherent(&ep->dev->pdev->dev, | ||
321 | bytes, dma, gfp_flags); | ||
322 | } else | ||
323 | retval = kmalloc(bytes, gfp_flags); | ||
324 | return retval; | ||
325 | } | ||
326 | |||
327 | static void | ||
328 | goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes) | ||
329 | { | ||
330 | /* free memory into the right allocator */ | ||
331 | if (dma != DMA_ADDR_INVALID) { | ||
332 | struct goku_ep *ep; | ||
333 | |||
334 | ep = container_of(_ep, struct goku_ep, ep); | ||
335 | if (!_ep) | ||
336 | return; | ||
337 | dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma); | ||
338 | } else | ||
339 | kfree (buf); | ||
340 | } | ||
341 | |||
342 | /*-------------------------------------------------------------------------*/ | ||
343 | |||
344 | static void | 298 | static void |
345 | done(struct goku_ep *ep, struct goku_request *req, int status) | 299 | done(struct goku_ep *ep, struct goku_request *req, int status) |
346 | { | 300 | { |
@@ -485,7 +439,7 @@ top: | |||
485 | /* use ep1/ep2 double-buffering for OUT */ | 439 | /* use ep1/ep2 double-buffering for OUT */ |
486 | if (!(size & PACKET_ACTIVE)) | 440 | if (!(size & PACKET_ACTIVE)) |
487 | size = readl(®s->EPxSizeLB[ep->num]); | 441 | size = readl(®s->EPxSizeLB[ep->num]); |
488 | if (!(size & PACKET_ACTIVE)) // "can't happen" | 442 | if (!(size & PACKET_ACTIVE)) /* "can't happen" */ |
489 | break; | 443 | break; |
490 | size &= DATASIZE; /* EPxSizeH == 0 */ | 444 | size &= DATASIZE; /* EPxSizeH == 0 */ |
491 | 445 | ||
@@ -1026,9 +980,6 @@ static struct usb_ep_ops goku_ep_ops = { | |||
1026 | .alloc_request = goku_alloc_request, | 980 | .alloc_request = goku_alloc_request, |
1027 | .free_request = goku_free_request, | 981 | .free_request = goku_free_request, |
1028 | 982 | ||
1029 | .alloc_buffer = goku_alloc_buffer, | ||
1030 | .free_buffer = goku_free_buffer, | ||
1031 | |||
1032 | .queue = goku_queue, | 983 | .queue = goku_queue, |
1033 | .dequeue = goku_dequeue, | 984 | .dequeue = goku_dequeue, |
1034 | 985 | ||
@@ -1140,17 +1091,17 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, | |||
1140 | is_usb_connected | 1091 | is_usb_connected |
1141 | ? ((tmp & PW_PULLUP) ? "full speed" : "powered") | 1092 | ? ((tmp & PW_PULLUP) ? "full speed" : "powered") |
1142 | : "disconnected", | 1093 | : "disconnected", |
1143 | ({char *tmp; | 1094 | ({char *state; |
1144 | switch(dev->ep0state){ | 1095 | switch(dev->ep0state){ |
1145 | case EP0_DISCONNECT: tmp = "ep0_disconnect"; break; | 1096 | case EP0_DISCONNECT: state = "ep0_disconnect"; break; |
1146 | case EP0_IDLE: tmp = "ep0_idle"; break; | 1097 | case EP0_IDLE: state = "ep0_idle"; break; |
1147 | case EP0_IN: tmp = "ep0_in"; break; | 1098 | case EP0_IN: state = "ep0_in"; break; |
1148 | case EP0_OUT: tmp = "ep0_out"; break; | 1099 | case EP0_OUT: state = "ep0_out"; break; |
1149 | case EP0_STATUS: tmp = "ep0_status"; break; | 1100 | case EP0_STATUS: state = "ep0_status"; break; |
1150 | case EP0_STALL: tmp = "ep0_stall"; break; | 1101 | case EP0_STALL: state = "ep0_stall"; break; |
1151 | case EP0_SUSPEND: tmp = "ep0_suspend"; break; | 1102 | case EP0_SUSPEND: state = "ep0_suspend"; break; |
1152 | default: tmp = "ep0_?"; break; | 1103 | default: state = "ep0_?"; break; |
1153 | } tmp; }) | 1104 | } state; }) |
1154 | ); | 1105 | ); |
1155 | size -= t; | 1106 | size -= t; |
1156 | next += t; | 1107 | next += t; |
@@ -1195,7 +1146,6 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, | |||
1195 | for (i = 0; i < 4; i++) { | 1146 | for (i = 0; i < 4; i++) { |
1196 | struct goku_ep *ep = &dev->ep [i]; | 1147 | struct goku_ep *ep = &dev->ep [i]; |
1197 | struct goku_request *req; | 1148 | struct goku_request *req; |
1198 | int t; | ||
1199 | 1149 | ||
1200 | if (i && !ep->desc) | 1150 | if (i && !ep->desc) |
1201 | continue; | 1151 | continue; |
@@ -1283,7 +1233,7 @@ done: | |||
1283 | static void udc_reinit (struct goku_udc *dev) | 1233 | static void udc_reinit (struct goku_udc *dev) |
1284 | { | 1234 | { |
1285 | static char *names [] = { "ep0", "ep1-bulk", "ep2-bulk", "ep3-bulk" }; | 1235 | static char *names [] = { "ep0", "ep1-bulk", "ep2-bulk", "ep3-bulk" }; |
1286 | 1236 | ||
1287 | unsigned i; | 1237 | unsigned i; |
1288 | 1238 | ||
1289 | INIT_LIST_HEAD (&dev->gadget.ep_list); | 1239 | INIT_LIST_HEAD (&dev->gadget.ep_list); |
@@ -1896,9 +1846,9 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1896 | 1846 | ||
1897 | /* done */ | 1847 | /* done */ |
1898 | the_controller = dev; | 1848 | the_controller = dev; |
1899 | device_register(&dev->gadget.dev); | 1849 | retval = device_register(&dev->gadget.dev); |
1900 | 1850 | if (retval == 0) | |
1901 | return 0; | 1851 | return 0; |
1902 | 1852 | ||
1903 | done: | 1853 | done: |
1904 | if (dev) | 1854 | if (dev) |
@@ -1910,8 +1860,8 @@ done: | |||
1910 | /*-------------------------------------------------------------------------*/ | 1860 | /*-------------------------------------------------------------------------*/ |
1911 | 1861 | ||
1912 | static struct pci_device_id pci_ids [] = { { | 1862 | static struct pci_device_id pci_ids [] = { { |
1913 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | 1863 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), |
1914 | .class_mask = ~0, | 1864 | .class_mask = ~0, |
1915 | .vendor = 0x102f, /* Toshiba */ | 1865 | .vendor = 0x102f, /* Toshiba */ |
1916 | .device = 0x0107, /* this UDC */ | 1866 | .device = 0x0107, /* this UDC */ |
1917 | .subvendor = PCI_ANY_ID, | 1867 | .subvendor = PCI_ANY_ID, |
diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h index ea8c8e58cabf..bc4eb1e0b507 100644 --- a/drivers/usb/gadget/goku_udc.h +++ b/drivers/usb/gadget/goku_udc.h | |||
@@ -41,8 +41,10 @@ struct goku_udc_regs { | |||
41 | #define INT_SYSERROR 0x40000 | 41 | #define INT_SYSERROR 0x40000 |
42 | #define INT_PWRDETECT 0x80000 | 42 | #define INT_PWRDETECT 0x80000 |
43 | 43 | ||
44 | #define INT_DEVWIDE (INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND) | 44 | #define INT_DEVWIDE \ |
45 | #define INT_EP0 (INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK) | 45 | (INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND) |
46 | #define INT_EP0 \ | ||
47 | (INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK) | ||
46 | 48 | ||
47 | u32 dma_master; | 49 | u32 dma_master; |
48 | #define MST_EOPB_DIS 0x0800 | 50 | #define MST_EOPB_DIS 0x0800 |
@@ -231,7 +233,7 @@ struct goku_request { | |||
231 | enum ep0state { | 233 | enum ep0state { |
232 | EP0_DISCONNECT, /* no host */ | 234 | EP0_DISCONNECT, /* no host */ |
233 | EP0_IDLE, /* between STATUS ack and SETUP report */ | 235 | EP0_IDLE, /* between STATUS ack and SETUP report */ |
234 | EP0_IN, EP0_OUT, /* data stage */ | 236 | EP0_IN, EP0_OUT, /* data stage */ |
235 | EP0_STATUS, /* status stage */ | 237 | EP0_STATUS, /* status stage */ |
236 | EP0_STALL, /* data or status stages */ | 238 | EP0_STALL, /* data or status stages */ |
237 | EP0_SUSPEND, /* usb suspend */ | 239 | EP0_SUSPEND, /* usb suspend */ |
@@ -242,7 +244,7 @@ struct goku_udc { | |||
242 | struct usb_gadget gadget; | 244 | struct usb_gadget gadget; |
243 | spinlock_t lock; | 245 | spinlock_t lock; |
244 | struct goku_ep ep[4]; | 246 | struct goku_ep ep[4]; |
245 | struct usb_gadget_driver *driver; | 247 | struct usb_gadget_driver *driver; |
246 | 248 | ||
247 | enum ep0state ep0state; | 249 | enum ep0state ep0state; |
248 | unsigned got_irq:1, | 250 | unsigned got_irq:1, |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 46d0e5252744..e60745ffaf8e 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/device.h> | 37 | #include <linux/device.h> |
38 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
39 | 39 | ||
40 | #include <linux/usb_gadgetfs.h> | 40 | #include <linux/usb/gadgetfs.h> |
41 | #include <linux/usb_gadget.h> | 41 | #include <linux/usb_gadget.h> |
42 | 42 | ||
43 | 43 | ||
@@ -923,7 +923,7 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) | |||
923 | struct dev_data *dev = ep->driver_data; | 923 | struct dev_data *dev = ep->driver_data; |
924 | 924 | ||
925 | if (req->buf != dev->rbuf) { | 925 | if (req->buf != dev->rbuf) { |
926 | usb_ep_free_buffer (ep, req->buf, req->dma, req->length); | 926 | kfree(req->buf); |
927 | req->buf = dev->rbuf; | 927 | req->buf = dev->rbuf; |
928 | req->dma = DMA_ADDR_INVALID; | 928 | req->dma = DMA_ADDR_INVALID; |
929 | } | 929 | } |
@@ -963,7 +963,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) | |||
963 | return -EBUSY; | 963 | return -EBUSY; |
964 | } | 964 | } |
965 | if (len > sizeof (dev->rbuf)) | 965 | if (len > sizeof (dev->rbuf)) |
966 | req->buf = usb_ep_alloc_buffer (ep, len, &req->dma, GFP_ATOMIC); | 966 | req->buf = kmalloc(len, GFP_ATOMIC); |
967 | if (req->buf == 0) { | 967 | if (req->buf == 0) { |
968 | req->buf = dev->rbuf; | 968 | req->buf = dev->rbuf; |
969 | return -ENOMEM; | 969 | return -ENOMEM; |
@@ -1505,7 +1505,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1505 | } | 1505 | } |
1506 | break; | 1506 | break; |
1507 | 1507 | ||
1508 | #ifndef CONFIG_USB_GADGETFS_PXA2XX | 1508 | #ifndef CONFIG_USB_GADGET_PXA2XX |
1509 | /* PXA automagically handles this request too */ | 1509 | /* PXA automagically handles this request too */ |
1510 | case USB_REQ_GET_CONFIGURATION: | 1510 | case USB_REQ_GET_CONFIGURATION: |
1511 | if (ctrl->bRequestType != 0x80) | 1511 | if (ctrl->bRequestType != 0x80) |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index a0a73c08a344..e78c2ddc1f88 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -75,10 +75,6 @@ static int lh7a40x_ep_enable(struct usb_ep *ep, | |||
75 | static int lh7a40x_ep_disable(struct usb_ep *ep); | 75 | static int lh7a40x_ep_disable(struct usb_ep *ep); |
76 | static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t); | 76 | static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t); |
77 | static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *); | 77 | static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *); |
78 | static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *, | ||
79 | gfp_t); | ||
80 | static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t, | ||
81 | unsigned); | ||
82 | static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t); | 78 | static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t); |
83 | static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *); | 79 | static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *); |
84 | static int lh7a40x_set_halt(struct usb_ep *ep, int); | 80 | static int lh7a40x_set_halt(struct usb_ep *ep, int); |
@@ -104,9 +100,6 @@ static struct usb_ep_ops lh7a40x_ep_ops = { | |||
104 | .alloc_request = lh7a40x_alloc_request, | 100 | .alloc_request = lh7a40x_alloc_request, |
105 | .free_request = lh7a40x_free_request, | 101 | .free_request = lh7a40x_free_request, |
106 | 102 | ||
107 | .alloc_buffer = lh7a40x_alloc_buffer, | ||
108 | .free_buffer = lh7a40x_free_buffer, | ||
109 | |||
110 | .queue = lh7a40x_queue, | 103 | .queue = lh7a40x_queue, |
111 | .dequeue = lh7a40x_dequeue, | 104 | .dequeue = lh7a40x_dequeue, |
112 | 105 | ||
@@ -1134,26 +1127,6 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
1134 | kfree(req); | 1127 | kfree(req); |
1135 | } | 1128 | } |
1136 | 1129 | ||
1137 | static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes, | ||
1138 | dma_addr_t * dma, gfp_t gfp_flags) | ||
1139 | { | ||
1140 | char *retval; | ||
1141 | |||
1142 | DEBUG("%s (%p, %d, %d)\n", __FUNCTION__, ep, bytes, gfp_flags); | ||
1143 | |||
1144 | retval = kmalloc(bytes, gfp_flags & ~(__GFP_DMA | __GFP_HIGHMEM)); | ||
1145 | if (retval) | ||
1146 | *dma = virt_to_bus(retval); | ||
1147 | return retval; | ||
1148 | } | ||
1149 | |||
1150 | static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma, | ||
1151 | unsigned bytes) | ||
1152 | { | ||
1153 | DEBUG("%s, %p\n", __FUNCTION__, ep); | ||
1154 | kfree(buf); | ||
1155 | } | ||
1156 | |||
1157 | /** Queue one request | 1130 | /** Queue one request |
1158 | * Kickstart transfer if needed | 1131 | * Kickstart transfer if needed |
1159 | * NOTE: Sets INDEX register | 1132 | * NOTE: Sets INDEX register |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c new file mode 100644 index 000000000000..c0a962bb5f25 --- /dev/null +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -0,0 +1,1653 @@ | |||
1 | /* | ||
2 | * M66592 UDC (USB gadget) | ||
3 | * | ||
4 | * Copyright (C) 2006-2007 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/list.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/usb/ch9.h> | ||
35 | #include <linux/usb_gadget.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/system.h> | ||
40 | |||
41 | #include "m66592-udc.h" | ||
42 | |||
43 | MODULE_DESCRIPTION("M66592 USB gadget driiver"); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | MODULE_AUTHOR("Yoshihiro Shimoda"); | ||
46 | |||
47 | #define DRIVER_VERSION "29 May 2007" | ||
48 | |||
49 | /* module parameters */ | ||
50 | static unsigned short clock = M66592_XTAL24; | ||
51 | module_param(clock, ushort, 0644); | ||
52 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)"); | ||
53 | static unsigned short vif = M66592_LDRV; | ||
54 | module_param(vif, ushort, 0644); | ||
55 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); | ||
56 | static unsigned short endian = 0; | ||
57 | module_param(endian, ushort, 0644); | ||
58 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); | ||
59 | static unsigned short irq_sense = M66592_INTL; | ||
60 | module_param(irq_sense, ushort, 0644); | ||
61 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)"); | ||
62 | |||
63 | static const char udc_name[] = "m66592_udc"; | ||
64 | static const char *m66592_ep_name[] = { | ||
65 | "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7" | ||
66 | }; | ||
67 | |||
68 | static void disable_controller(struct m66592 *m66592); | ||
69 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req); | ||
70 | static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req); | ||
71 | static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
72 | gfp_t gfp_flags); | ||
73 | |||
74 | static void transfer_complete(struct m66592_ep *ep, | ||
75 | struct m66592_request *req, | ||
76 | int status); | ||
77 | /*-------------------------------------------------------------------------*/ | ||
78 | static inline u16 get_usb_speed(struct m66592 *m66592) | ||
79 | { | ||
80 | return (m66592_read(m66592, M66592_DVSTCTR) & M66592_RHST); | ||
81 | } | ||
82 | |||
83 | static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, | ||
84 | unsigned long reg) | ||
85 | { | ||
86 | u16 tmp; | ||
87 | |||
88 | tmp = m66592_read(m66592, M66592_INTENB0); | ||
89 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | ||
90 | M66592_INTENB0); | ||
91 | m66592_bset(m66592, (1 << pipenum), reg); | ||
92 | m66592_write(m66592, tmp, M66592_INTENB0); | ||
93 | } | ||
94 | |||
95 | static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, | ||
96 | unsigned long reg) | ||
97 | { | ||
98 | u16 tmp; | ||
99 | |||
100 | tmp = m66592_read(m66592, M66592_INTENB0); | ||
101 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | ||
102 | M66592_INTENB0); | ||
103 | m66592_bclr(m66592, (1 << pipenum), reg); | ||
104 | m66592_write(m66592, tmp, M66592_INTENB0); | ||
105 | } | ||
106 | |||
107 | static void m66592_usb_connect(struct m66592 *m66592) | ||
108 | { | ||
109 | m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); | ||
110 | m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | ||
111 | M66592_INTENB0); | ||
112 | m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | ||
113 | |||
114 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
115 | } | ||
116 | |||
117 | static void m66592_usb_disconnect(struct m66592 *m66592) | ||
118 | { | ||
119 | m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); | ||
120 | m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | ||
121 | M66592_INTENB0); | ||
122 | m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | ||
123 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
124 | |||
125 | m66592->gadget.speed = USB_SPEED_UNKNOWN; | ||
126 | spin_unlock(&m66592->lock); | ||
127 | m66592->driver->disconnect(&m66592->gadget); | ||
128 | spin_lock(&m66592->lock); | ||
129 | |||
130 | disable_controller(m66592); | ||
131 | INIT_LIST_HEAD(&m66592->ep[0].queue); | ||
132 | } | ||
133 | |||
134 | static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) | ||
135 | { | ||
136 | u16 pid = 0; | ||
137 | unsigned long offset; | ||
138 | |||
139 | if (pipenum == 0) | ||
140 | pid = m66592_read(m66592, M66592_DCPCTR) & M66592_PID; | ||
141 | else if (pipenum < M66592_MAX_NUM_PIPE) { | ||
142 | offset = get_pipectr_addr(pipenum); | ||
143 | pid = m66592_read(m66592, offset) & M66592_PID; | ||
144 | } else | ||
145 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | ||
146 | |||
147 | return pid; | ||
148 | } | ||
149 | |||
150 | static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, | ||
151 | u16 pid) | ||
152 | { | ||
153 | unsigned long offset; | ||
154 | |||
155 | if (pipenum == 0) | ||
156 | m66592_mdfy(m66592, pid, M66592_PID, M66592_DCPCTR); | ||
157 | else if (pipenum < M66592_MAX_NUM_PIPE) { | ||
158 | offset = get_pipectr_addr(pipenum); | ||
159 | m66592_mdfy(m66592, pid, M66592_PID, offset); | ||
160 | } else | ||
161 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | ||
162 | } | ||
163 | |||
164 | static inline void pipe_start(struct m66592 *m66592, u16 pipenum) | ||
165 | { | ||
166 | control_reg_set_pid(m66592, pipenum, M66592_PID_BUF); | ||
167 | } | ||
168 | |||
169 | static inline void pipe_stop(struct m66592 *m66592, u16 pipenum) | ||
170 | { | ||
171 | control_reg_set_pid(m66592, pipenum, M66592_PID_NAK); | ||
172 | } | ||
173 | |||
174 | static inline void pipe_stall(struct m66592 *m66592, u16 pipenum) | ||
175 | { | ||
176 | control_reg_set_pid(m66592, pipenum, M66592_PID_STALL); | ||
177 | } | ||
178 | |||
179 | static inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum) | ||
180 | { | ||
181 | u16 ret = 0; | ||
182 | unsigned long offset; | ||
183 | |||
184 | if (pipenum == 0) | ||
185 | ret = m66592_read(m66592, M66592_DCPCTR); | ||
186 | else if (pipenum < M66592_MAX_NUM_PIPE) { | ||
187 | offset = get_pipectr_addr(pipenum); | ||
188 | ret = m66592_read(m66592, offset); | ||
189 | } else | ||
190 | printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum) | ||
196 | { | ||
197 | unsigned long offset; | ||
198 | |||
199 | pipe_stop(m66592, pipenum); | ||
200 | |||
201 | if (pipenum == 0) | ||
202 | m66592_bset(m66592, M66592_SQCLR, M66592_DCPCTR); | ||
203 | else if (pipenum < M66592_MAX_NUM_PIPE) { | ||
204 | offset = get_pipectr_addr(pipenum); | ||
205 | m66592_bset(m66592, M66592_SQCLR, offset); | ||
206 | } else | ||
207 | printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum); | ||
208 | } | ||
209 | |||
210 | static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) | ||
211 | { | ||
212 | u16 tmp; | ||
213 | int size; | ||
214 | |||
215 | if (pipenum == 0) { | ||
216 | tmp = m66592_read(m66592, M66592_DCPCFG); | ||
217 | if ((tmp & M66592_CNTMD) != 0) | ||
218 | size = 256; | ||
219 | else { | ||
220 | tmp = m66592_read(m66592, M66592_DCPMAXP); | ||
221 | size = tmp & M66592_MAXP; | ||
222 | } | ||
223 | } else { | ||
224 | m66592_write(m66592, pipenum, M66592_PIPESEL); | ||
225 | tmp = m66592_read(m66592, M66592_PIPECFG); | ||
226 | if ((tmp & M66592_CNTMD) != 0) { | ||
227 | tmp = m66592_read(m66592, M66592_PIPEBUF); | ||
228 | size = ((tmp >> 10) + 1) * 64; | ||
229 | } else { | ||
230 | tmp = m66592_read(m66592, M66592_PIPEMAXP); | ||
231 | size = tmp & M66592_MXPS; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | return size; | ||
236 | } | ||
237 | |||
238 | static inline void pipe_change(struct m66592 *m66592, u16 pipenum) | ||
239 | { | ||
240 | struct m66592_ep *ep = m66592->pipenum2ep[pipenum]; | ||
241 | |||
242 | if (ep->use_dma) | ||
243 | return; | ||
244 | |||
245 | m66592_mdfy(m66592, pipenum, M66592_CURPIPE, ep->fifosel); | ||
246 | |||
247 | ndelay(450); | ||
248 | |||
249 | m66592_bset(m66592, M66592_MBW, ep->fifosel); | ||
250 | } | ||
251 | |||
252 | static int pipe_buffer_setting(struct m66592 *m66592, | ||
253 | struct m66592_pipe_info *info) | ||
254 | { | ||
255 | u16 bufnum = 0, buf_bsize = 0; | ||
256 | u16 pipecfg = 0; | ||
257 | |||
258 | if (info->pipe == 0) | ||
259 | return -EINVAL; | ||
260 | |||
261 | m66592_write(m66592, info->pipe, M66592_PIPESEL); | ||
262 | |||
263 | if (info->dir_in) | ||
264 | pipecfg |= M66592_DIR; | ||
265 | pipecfg |= info->type; | ||
266 | pipecfg |= info->epnum; | ||
267 | switch (info->type) { | ||
268 | case M66592_INT: | ||
269 | bufnum = 4 + (info->pipe - M66592_BASE_PIPENUM_INT); | ||
270 | buf_bsize = 0; | ||
271 | break; | ||
272 | case M66592_BULK: | ||
273 | bufnum = m66592->bi_bufnum + | ||
274 | (info->pipe - M66592_BASE_PIPENUM_BULK) * 16; | ||
275 | m66592->bi_bufnum += 16; | ||
276 | buf_bsize = 7; | ||
277 | pipecfg |= M66592_DBLB; | ||
278 | if (!info->dir_in) | ||
279 | pipecfg |= M66592_SHTNAK; | ||
280 | break; | ||
281 | case M66592_ISO: | ||
282 | bufnum = m66592->bi_bufnum + | ||
283 | (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16; | ||
284 | m66592->bi_bufnum += 16; | ||
285 | buf_bsize = 7; | ||
286 | break; | ||
287 | } | ||
288 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { | ||
289 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", | ||
290 | m66592->bi_bufnum); | ||
291 | return -ENOMEM; | ||
292 | } | ||
293 | |||
294 | m66592_write(m66592, pipecfg, M66592_PIPECFG); | ||
295 | m66592_write(m66592, (buf_bsize << 10) | (bufnum), M66592_PIPEBUF); | ||
296 | m66592_write(m66592, info->maxpacket, M66592_PIPEMAXP); | ||
297 | if (info->interval) | ||
298 | info->interval--; | ||
299 | m66592_write(m66592, info->interval, M66592_PIPEPERI); | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static void pipe_buffer_release(struct m66592 *m66592, | ||
305 | struct m66592_pipe_info *info) | ||
306 | { | ||
307 | if (info->pipe == 0) | ||
308 | return; | ||
309 | |||
310 | switch (info->type) { | ||
311 | case M66592_BULK: | ||
312 | if (is_bulk_pipe(info->pipe)) | ||
313 | m66592->bi_bufnum -= 16; | ||
314 | break; | ||
315 | case M66592_ISO: | ||
316 | if (is_isoc_pipe(info->pipe)) | ||
317 | m66592->bi_bufnum -= 16; | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | if (is_bulk_pipe(info->pipe)) { | ||
322 | m66592->bulk--; | ||
323 | } else if (is_interrupt_pipe(info->pipe)) | ||
324 | m66592->interrupt--; | ||
325 | else if (is_isoc_pipe(info->pipe)) { | ||
326 | m66592->isochronous--; | ||
327 | if (info->type == M66592_BULK) | ||
328 | m66592->bulk--; | ||
329 | } else | ||
330 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", | ||
331 | info->pipe); | ||
332 | } | ||
333 | |||
334 | static void pipe_initialize(struct m66592_ep *ep) | ||
335 | { | ||
336 | struct m66592 *m66592 = ep->m66592; | ||
337 | |||
338 | m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel); | ||
339 | |||
340 | m66592_write(m66592, M66592_ACLRM, ep->pipectr); | ||
341 | m66592_write(m66592, 0, ep->pipectr); | ||
342 | m66592_write(m66592, M66592_SQCLR, ep->pipectr); | ||
343 | if (ep->use_dma) { | ||
344 | m66592_mdfy(m66592, ep->pipenum, M66592_CURPIPE, ep->fifosel); | ||
345 | |||
346 | ndelay(450); | ||
347 | |||
348 | m66592_bset(m66592, M66592_MBW, ep->fifosel); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | ||
353 | const struct usb_endpoint_descriptor *desc, | ||
354 | u16 pipenum, int dma) | ||
355 | { | ||
356 | if ((pipenum != 0) && dma) { | ||
357 | if (m66592->num_dma == 0) { | ||
358 | m66592->num_dma++; | ||
359 | ep->use_dma = 1; | ||
360 | ep->fifoaddr = M66592_D0FIFO; | ||
361 | ep->fifosel = M66592_D0FIFOSEL; | ||
362 | ep->fifoctr = M66592_D0FIFOCTR; | ||
363 | ep->fifotrn = M66592_D0FIFOTRN; | ||
364 | } else if (m66592->num_dma == 1) { | ||
365 | m66592->num_dma++; | ||
366 | ep->use_dma = 1; | ||
367 | ep->fifoaddr = M66592_D1FIFO; | ||
368 | ep->fifosel = M66592_D1FIFOSEL; | ||
369 | ep->fifoctr = M66592_D1FIFOCTR; | ||
370 | ep->fifotrn = M66592_D1FIFOTRN; | ||
371 | } else { | ||
372 | ep->use_dma = 0; | ||
373 | ep->fifoaddr = M66592_CFIFO; | ||
374 | ep->fifosel = M66592_CFIFOSEL; | ||
375 | ep->fifoctr = M66592_CFIFOCTR; | ||
376 | ep->fifotrn = 0; | ||
377 | } | ||
378 | } else { | ||
379 | ep->use_dma = 0; | ||
380 | ep->fifoaddr = M66592_CFIFO; | ||
381 | ep->fifosel = M66592_CFIFOSEL; | ||
382 | ep->fifoctr = M66592_CFIFOCTR; | ||
383 | ep->fifotrn = 0; | ||
384 | } | ||
385 | |||
386 | ep->pipectr = get_pipectr_addr(pipenum); | ||
387 | ep->pipenum = pipenum; | ||
388 | ep->ep.maxpacket = desc->wMaxPacketSize; | ||
389 | m66592->pipenum2ep[pipenum] = ep; | ||
390 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; | ||
391 | INIT_LIST_HEAD(&ep->queue); | ||
392 | } | ||
393 | |||
394 | static void m66592_ep_release(struct m66592_ep *ep) | ||
395 | { | ||
396 | struct m66592 *m66592 = ep->m66592; | ||
397 | u16 pipenum = ep->pipenum; | ||
398 | |||
399 | if (pipenum == 0) | ||
400 | return; | ||
401 | |||
402 | if (ep->use_dma) | ||
403 | m66592->num_dma--; | ||
404 | ep->pipenum = 0; | ||
405 | ep->busy = 0; | ||
406 | ep->use_dma = 0; | ||
407 | } | ||
408 | |||
409 | static int alloc_pipe_config(struct m66592_ep *ep, | ||
410 | const struct usb_endpoint_descriptor *desc) | ||
411 | { | ||
412 | struct m66592 *m66592 = ep->m66592; | ||
413 | struct m66592_pipe_info info; | ||
414 | int dma = 0; | ||
415 | int *counter; | ||
416 | int ret; | ||
417 | |||
418 | ep->desc = desc; | ||
419 | |||
420 | BUG_ON(ep->pipenum); | ||
421 | |||
422 | switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
423 | case USB_ENDPOINT_XFER_BULK: | ||
424 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { | ||
425 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | ||
426 | printk(KERN_ERR "bulk pipe is insufficient\n"); | ||
427 | return -ENODEV; | ||
428 | } else { | ||
429 | info.pipe = M66592_BASE_PIPENUM_ISOC + | ||
430 | m66592->isochronous; | ||
431 | counter = &m66592->isochronous; | ||
432 | } | ||
433 | } else { | ||
434 | info.pipe = M66592_BASE_PIPENUM_BULK + m66592->bulk; | ||
435 | counter = &m66592->bulk; | ||
436 | } | ||
437 | info.type = M66592_BULK; | ||
438 | dma = 1; | ||
439 | break; | ||
440 | case USB_ENDPOINT_XFER_INT: | ||
441 | if (m66592->interrupt >= M66592_MAX_NUM_INT) { | ||
442 | printk(KERN_ERR "interrupt pipe is insufficient\n"); | ||
443 | return -ENODEV; | ||
444 | } | ||
445 | info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt; | ||
446 | info.type = M66592_INT; | ||
447 | counter = &m66592->interrupt; | ||
448 | break; | ||
449 | case USB_ENDPOINT_XFER_ISOC: | ||
450 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | ||
451 | printk(KERN_ERR "isochronous pipe is insufficient\n"); | ||
452 | return -ENODEV; | ||
453 | } | ||
454 | info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous; | ||
455 | info.type = M66592_ISO; | ||
456 | counter = &m66592->isochronous; | ||
457 | break; | ||
458 | default: | ||
459 | printk(KERN_ERR "unexpect xfer type\n"); | ||
460 | return -EINVAL; | ||
461 | } | ||
462 | ep->type = info.type; | ||
463 | |||
464 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
465 | info.maxpacket = desc->wMaxPacketSize; | ||
466 | info.interval = desc->bInterval; | ||
467 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
468 | info.dir_in = 1; | ||
469 | else | ||
470 | info.dir_in = 0; | ||
471 | |||
472 | ret = pipe_buffer_setting(m66592, &info); | ||
473 | if (ret < 0) { | ||
474 | printk(KERN_ERR "pipe_buffer_setting fail\n"); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | (*counter)++; | ||
479 | if ((counter == &m66592->isochronous) && info.type == M66592_BULK) | ||
480 | m66592->bulk++; | ||
481 | |||
482 | m66592_ep_setting(m66592, ep, desc, info.pipe, dma); | ||
483 | pipe_initialize(ep); | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static int free_pipe_config(struct m66592_ep *ep) | ||
489 | { | ||
490 | struct m66592 *m66592 = ep->m66592; | ||
491 | struct m66592_pipe_info info; | ||
492 | |||
493 | info.pipe = ep->pipenum; | ||
494 | info.type = ep->type; | ||
495 | pipe_buffer_release(m66592, &info); | ||
496 | m66592_ep_release(ep); | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | /*-------------------------------------------------------------------------*/ | ||
502 | static void pipe_irq_enable(struct m66592 *m66592, u16 pipenum) | ||
503 | { | ||
504 | enable_irq_ready(m66592, pipenum); | ||
505 | enable_irq_nrdy(m66592, pipenum); | ||
506 | } | ||
507 | |||
508 | static void pipe_irq_disable(struct m66592 *m66592, u16 pipenum) | ||
509 | { | ||
510 | disable_irq_ready(m66592, pipenum); | ||
511 | disable_irq_nrdy(m66592, pipenum); | ||
512 | } | ||
513 | |||
514 | /* if complete is true, gadget driver complete function is not call */ | ||
515 | static void control_end(struct m66592 *m66592, unsigned ccpl) | ||
516 | { | ||
517 | m66592->ep[0].internal_ccpl = ccpl; | ||
518 | pipe_start(m66592, 0); | ||
519 | m66592_bset(m66592, M66592_CCPL, M66592_DCPCTR); | ||
520 | } | ||
521 | |||
522 | static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | ||
523 | { | ||
524 | struct m66592 *m66592 = ep->m66592; | ||
525 | |||
526 | pipe_change(m66592, ep->pipenum); | ||
527 | m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, | ||
528 | (M66592_ISEL | M66592_CURPIPE), | ||
529 | M66592_CFIFOSEL); | ||
530 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | ||
531 | if (req->req.length == 0) { | ||
532 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | ||
533 | pipe_start(m66592, 0); | ||
534 | transfer_complete(ep, req, 0); | ||
535 | } else { | ||
536 | m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS); | ||
537 | irq_ep0_write(ep, req); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | static void start_packet_write(struct m66592_ep *ep, struct m66592_request *req) | ||
542 | { | ||
543 | struct m66592 *m66592 = ep->m66592; | ||
544 | u16 tmp; | ||
545 | |||
546 | pipe_change(m66592, ep->pipenum); | ||
547 | disable_irq_empty(m66592, ep->pipenum); | ||
548 | pipe_start(m66592, ep->pipenum); | ||
549 | |||
550 | tmp = m66592_read(m66592, ep->fifoctr); | ||
551 | if (unlikely((tmp & M66592_FRDY) == 0)) | ||
552 | pipe_irq_enable(m66592, ep->pipenum); | ||
553 | else | ||
554 | irq_packet_write(ep, req); | ||
555 | } | ||
556 | |||
557 | static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) | ||
558 | { | ||
559 | struct m66592 *m66592 = ep->m66592; | ||
560 | u16 pipenum = ep->pipenum; | ||
561 | |||
562 | if (ep->pipenum == 0) { | ||
563 | m66592_mdfy(m66592, M66592_PIPE0, | ||
564 | (M66592_ISEL | M66592_CURPIPE), | ||
565 | M66592_CFIFOSEL); | ||
566 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | ||
567 | pipe_start(m66592, pipenum); | ||
568 | pipe_irq_enable(m66592, pipenum); | ||
569 | } else { | ||
570 | if (ep->use_dma) { | ||
571 | m66592_bset(m66592, M66592_TRCLR, ep->fifosel); | ||
572 | pipe_change(m66592, pipenum); | ||
573 | m66592_bset(m66592, M66592_TRENB, ep->fifosel); | ||
574 | m66592_write(m66592, | ||
575 | (req->req.length + ep->ep.maxpacket - 1) / | ||
576 | ep->ep.maxpacket, ep->fifotrn); | ||
577 | } | ||
578 | pipe_start(m66592, pipenum); /* trigger once */ | ||
579 | pipe_irq_enable(m66592, pipenum); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | static void start_packet(struct m66592_ep *ep, struct m66592_request *req) | ||
584 | { | ||
585 | if (ep->desc->bEndpointAddress & USB_DIR_IN) | ||
586 | start_packet_write(ep, req); | ||
587 | else | ||
588 | start_packet_read(ep, req); | ||
589 | } | ||
590 | |||
591 | static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) | ||
592 | { | ||
593 | u16 ctsq; | ||
594 | |||
595 | ctsq = m66592_read(ep->m66592, M66592_INTSTS0) & M66592_CTSQ; | ||
596 | |||
597 | switch (ctsq) { | ||
598 | case M66592_CS_RDDS: | ||
599 | start_ep0_write(ep, req); | ||
600 | break; | ||
601 | case M66592_CS_WRDS: | ||
602 | start_packet_read(ep, req); | ||
603 | break; | ||
604 | |||
605 | case M66592_CS_WRND: | ||
606 | control_end(ep->m66592, 0); | ||
607 | break; | ||
608 | default: | ||
609 | printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq); | ||
610 | break; | ||
611 | } | ||
612 | } | ||
613 | |||
614 | static void init_controller(struct m66592 *m66592) | ||
615 | { | ||
616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), | ||
617 | M66592_PINCFG); | ||
618 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ | ||
619 | m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); | ||
620 | |||
621 | m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); | ||
622 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
623 | m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); | ||
624 | |||
625 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); | ||
626 | |||
627 | msleep(3); | ||
628 | |||
629 | m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); | ||
630 | |||
631 | msleep(1); | ||
632 | |||
633 | m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); | ||
634 | |||
635 | m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); | ||
636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, | ||
637 | M66592_DMA0CFG); | ||
638 | } | ||
639 | |||
640 | static void disable_controller(struct m66592 *m66592) | ||
641 | { | ||
642 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); | ||
643 | udelay(1); | ||
644 | m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); | ||
645 | udelay(1); | ||
646 | m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); | ||
647 | udelay(1); | ||
648 | m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); | ||
649 | } | ||
650 | |||
651 | static void m66592_start_xclock(struct m66592 *m66592) | ||
652 | { | ||
653 | u16 tmp; | ||
654 | |||
655 | tmp = m66592_read(m66592, M66592_SYSCFG); | ||
656 | if (!(tmp & M66592_XCKE)) | ||
657 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); | ||
658 | } | ||
659 | |||
660 | /*-------------------------------------------------------------------------*/ | ||
661 | static void transfer_complete(struct m66592_ep *ep, | ||
662 | struct m66592_request *req, | ||
663 | int status) | ||
664 | { | ||
665 | int restart = 0; | ||
666 | |||
667 | if (unlikely(ep->pipenum == 0)) { | ||
668 | if (ep->internal_ccpl) { | ||
669 | ep->internal_ccpl = 0; | ||
670 | return; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | list_del_init(&req->queue); | ||
675 | if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN) | ||
676 | req->req.status = -ESHUTDOWN; | ||
677 | else | ||
678 | req->req.status = status; | ||
679 | |||
680 | if (!list_empty(&ep->queue)) | ||
681 | restart = 1; | ||
682 | |||
683 | if (likely(req->req.complete)) | ||
684 | req->req.complete(&ep->ep, &req->req); | ||
685 | |||
686 | if (restart) { | ||
687 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
688 | if (ep->desc) | ||
689 | start_packet(ep, req); | ||
690 | } | ||
691 | } | ||
692 | |||
693 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | ||
694 | { | ||
695 | int i; | ||
696 | volatile u16 tmp; | ||
697 | unsigned bufsize; | ||
698 | size_t size; | ||
699 | void *buf; | ||
700 | u16 pipenum = ep->pipenum; | ||
701 | struct m66592 *m66592 = ep->m66592; | ||
702 | |||
703 | pipe_change(m66592, pipenum); | ||
704 | m66592_bset(m66592, M66592_ISEL, ep->fifosel); | ||
705 | |||
706 | i = 0; | ||
707 | do { | ||
708 | tmp = m66592_read(m66592, ep->fifoctr); | ||
709 | if (i++ > 100000) { | ||
710 | printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus" | ||
711 | "conflict. please power off this controller."); | ||
712 | return; | ||
713 | } | ||
714 | ndelay(1); | ||
715 | } while ((tmp & M66592_FRDY) == 0); | ||
716 | |||
717 | /* prepare parameters */ | ||
718 | bufsize = get_buffer_size(m66592, pipenum); | ||
719 | buf = req->req.buf + req->req.actual; | ||
720 | size = min(bufsize, req->req.length - req->req.actual); | ||
721 | |||
722 | /* write fifo */ | ||
723 | if (req->req.buf) { | ||
724 | if (size > 0) | ||
725 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | ||
726 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) | ||
727 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | ||
728 | } | ||
729 | |||
730 | /* update parameters */ | ||
731 | req->req.actual += size; | ||
732 | |||
733 | /* check transfer finish */ | ||
734 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | ||
735 | (size % ep->ep.maxpacket) || (size == 0)) { | ||
736 | disable_irq_ready(m66592, pipenum); | ||
737 | disable_irq_empty(m66592, pipenum); | ||
738 | } else { | ||
739 | disable_irq_ready(m66592, pipenum); | ||
740 | enable_irq_empty(m66592, pipenum); | ||
741 | } | ||
742 | pipe_start(m66592, pipenum); | ||
743 | } | ||
744 | |||
745 | static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | ||
746 | { | ||
747 | u16 tmp; | ||
748 | unsigned bufsize; | ||
749 | size_t size; | ||
750 | void *buf; | ||
751 | u16 pipenum = ep->pipenum; | ||
752 | struct m66592 *m66592 = ep->m66592; | ||
753 | |||
754 | pipe_change(m66592, pipenum); | ||
755 | tmp = m66592_read(m66592, ep->fifoctr); | ||
756 | if (unlikely((tmp & M66592_FRDY) == 0)) { | ||
757 | pipe_stop(m66592, pipenum); | ||
758 | pipe_irq_disable(m66592, pipenum); | ||
759 | printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum); | ||
760 | return; | ||
761 | } | ||
762 | |||
763 | /* prepare parameters */ | ||
764 | bufsize = get_buffer_size(m66592, pipenum); | ||
765 | buf = req->req.buf + req->req.actual; | ||
766 | size = min(bufsize, req->req.length - req->req.actual); | ||
767 | |||
768 | /* write fifo */ | ||
769 | if (req->req.buf) { | ||
770 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | ||
771 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0) || | ||
772 | ((bufsize != ep->ep.maxpacket) && (bufsize > size))) | ||
773 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | ||
774 | } | ||
775 | |||
776 | /* update parameters */ | ||
777 | req->req.actual += size; | ||
778 | /* check transfer finish */ | ||
779 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | ||
780 | (size % ep->ep.maxpacket) || (size == 0)) { | ||
781 | disable_irq_ready(m66592, pipenum); | ||
782 | enable_irq_empty(m66592, pipenum); | ||
783 | } else { | ||
784 | disable_irq_empty(m66592, pipenum); | ||
785 | pipe_irq_enable(m66592, pipenum); | ||
786 | } | ||
787 | } | ||
788 | |||
789 | static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) | ||
790 | { | ||
791 | u16 tmp; | ||
792 | int rcv_len, bufsize, req_len; | ||
793 | int size; | ||
794 | void *buf; | ||
795 | u16 pipenum = ep->pipenum; | ||
796 | struct m66592 *m66592 = ep->m66592; | ||
797 | int finish = 0; | ||
798 | |||
799 | pipe_change(m66592, pipenum); | ||
800 | tmp = m66592_read(m66592, ep->fifoctr); | ||
801 | if (unlikely((tmp & M66592_FRDY) == 0)) { | ||
802 | req->req.status = -EPIPE; | ||
803 | pipe_stop(m66592, pipenum); | ||
804 | pipe_irq_disable(m66592, pipenum); | ||
805 | printk(KERN_ERR "read fifo not ready"); | ||
806 | return; | ||
807 | } | ||
808 | |||
809 | /* prepare parameters */ | ||
810 | rcv_len = tmp & M66592_DTLN; | ||
811 | bufsize = get_buffer_size(m66592, pipenum); | ||
812 | |||
813 | buf = req->req.buf + req->req.actual; | ||
814 | req_len = req->req.length - req->req.actual; | ||
815 | if (rcv_len < bufsize) | ||
816 | size = min(rcv_len, req_len); | ||
817 | else | ||
818 | size = min(bufsize, req_len); | ||
819 | |||
820 | /* update parameters */ | ||
821 | req->req.actual += size; | ||
822 | |||
823 | /* check transfer finish */ | ||
824 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | ||
825 | (size % ep->ep.maxpacket) || (size == 0)) { | ||
826 | pipe_stop(m66592, pipenum); | ||
827 | pipe_irq_disable(m66592, pipenum); | ||
828 | finish = 1; | ||
829 | } | ||
830 | |||
831 | /* read fifo */ | ||
832 | if (req->req.buf) { | ||
833 | if (size == 0) | ||
834 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | ||
835 | else | ||
836 | m66592_read_fifo(m66592, ep->fifoaddr, buf, size); | ||
837 | } | ||
838 | |||
839 | if ((ep->pipenum != 0) && finish) | ||
840 | transfer_complete(ep, req, 0); | ||
841 | } | ||
842 | |||
843 | static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) | ||
844 | { | ||
845 | u16 check; | ||
846 | u16 pipenum; | ||
847 | struct m66592_ep *ep; | ||
848 | struct m66592_request *req; | ||
849 | |||
850 | if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { | ||
851 | m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); | ||
852 | m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, | ||
853 | M66592_CFIFOSEL); | ||
854 | |||
855 | ep = &m66592->ep[0]; | ||
856 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
857 | irq_packet_read(ep, req); | ||
858 | } else { | ||
859 | for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) { | ||
860 | check = 1 << pipenum; | ||
861 | if ((status & check) && (enb & check)) { | ||
862 | m66592_write(m66592, ~check, M66592_BRDYSTS); | ||
863 | ep = m66592->pipenum2ep[pipenum]; | ||
864 | req = list_entry(ep->queue.next, | ||
865 | struct m66592_request, queue); | ||
866 | if (ep->desc->bEndpointAddress & USB_DIR_IN) | ||
867 | irq_packet_write(ep, req); | ||
868 | else | ||
869 | irq_packet_read(ep, req); | ||
870 | } | ||
871 | } | ||
872 | } | ||
873 | } | ||
874 | |||
875 | static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) | ||
876 | { | ||
877 | u16 tmp; | ||
878 | u16 check; | ||
879 | u16 pipenum; | ||
880 | struct m66592_ep *ep; | ||
881 | struct m66592_request *req; | ||
882 | |||
883 | if ((status & M66592_BEMP0) && (enb & M66592_BEMP0)) { | ||
884 | m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS); | ||
885 | |||
886 | ep = &m66592->ep[0]; | ||
887 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
888 | irq_ep0_write(ep, req); | ||
889 | } else { | ||
890 | for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) { | ||
891 | check = 1 << pipenum; | ||
892 | if ((status & check) && (enb & check)) { | ||
893 | m66592_write(m66592, ~check, M66592_BEMPSTS); | ||
894 | tmp = control_reg_get(m66592, pipenum); | ||
895 | if ((tmp & M66592_INBUFM) == 0) { | ||
896 | disable_irq_empty(m66592, pipenum); | ||
897 | pipe_irq_disable(m66592, pipenum); | ||
898 | pipe_stop(m66592, pipenum); | ||
899 | ep = m66592->pipenum2ep[pipenum]; | ||
900 | req = list_entry(ep->queue.next, | ||
901 | struct m66592_request, | ||
902 | queue); | ||
903 | if (!list_empty(&ep->queue)) | ||
904 | transfer_complete(ep, req, 0); | ||
905 | } | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | } | ||
910 | |||
911 | static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | ||
912 | { | ||
913 | struct m66592_ep *ep; | ||
914 | u16 pid; | ||
915 | u16 status = 0; | ||
916 | |||
917 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
918 | case USB_RECIP_DEVICE: | ||
919 | status = 1; /* selfpower */ | ||
920 | break; | ||
921 | case USB_RECIP_INTERFACE: | ||
922 | status = 0; | ||
923 | break; | ||
924 | case USB_RECIP_ENDPOINT: | ||
925 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | ||
926 | pid = control_reg_get_pid(m66592, ep->pipenum); | ||
927 | if (pid == M66592_PID_STALL) | ||
928 | status = 1; | ||
929 | else | ||
930 | status = 0; | ||
931 | break; | ||
932 | default: | ||
933 | pipe_stall(m66592, 0); | ||
934 | return; /* exit */ | ||
935 | } | ||
936 | |||
937 | *m66592->ep0_buf = status; | ||
938 | m66592->ep0_req->buf = m66592->ep0_buf; | ||
939 | m66592->ep0_req->length = 2; | ||
940 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); | ||
941 | } | ||
942 | |||
943 | static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | ||
944 | { | ||
945 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
946 | case USB_RECIP_DEVICE: | ||
947 | control_end(m66592, 1); | ||
948 | break; | ||
949 | case USB_RECIP_INTERFACE: | ||
950 | control_end(m66592, 1); | ||
951 | break; | ||
952 | case USB_RECIP_ENDPOINT: { | ||
953 | struct m66592_ep *ep; | ||
954 | struct m66592_request *req; | ||
955 | |||
956 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | ||
957 | pipe_stop(m66592, ep->pipenum); | ||
958 | control_reg_sqclr(m66592, ep->pipenum); | ||
959 | |||
960 | control_end(m66592, 1); | ||
961 | |||
962 | req = list_entry(ep->queue.next, | ||
963 | struct m66592_request, queue); | ||
964 | if (ep->busy) { | ||
965 | ep->busy = 0; | ||
966 | if (list_empty(&ep->queue)) | ||
967 | break; | ||
968 | start_packet(ep, req); | ||
969 | } else if (!list_empty(&ep->queue)) | ||
970 | pipe_start(m66592, ep->pipenum); | ||
971 | } | ||
972 | break; | ||
973 | default: | ||
974 | pipe_stall(m66592, 0); | ||
975 | break; | ||
976 | } | ||
977 | } | ||
978 | |||
979 | static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | ||
980 | { | ||
981 | |||
982 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
983 | case USB_RECIP_DEVICE: | ||
984 | control_end(m66592, 1); | ||
985 | break; | ||
986 | case USB_RECIP_INTERFACE: | ||
987 | control_end(m66592, 1); | ||
988 | break; | ||
989 | case USB_RECIP_ENDPOINT: { | ||
990 | struct m66592_ep *ep; | ||
991 | |||
992 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | ||
993 | pipe_stall(m66592, ep->pipenum); | ||
994 | |||
995 | control_end(m66592, 1); | ||
996 | } | ||
997 | break; | ||
998 | default: | ||
999 | pipe_stall(m66592, 0); | ||
1000 | break; | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | /* if return value is true, call class driver's setup() */ | ||
1005 | static int setup_packet(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | ||
1006 | { | ||
1007 | u16 *p = (u16 *)ctrl; | ||
1008 | unsigned long offset = M66592_USBREQ; | ||
1009 | int i, ret = 0; | ||
1010 | |||
1011 | /* read fifo */ | ||
1012 | m66592_write(m66592, ~M66592_VALID, M66592_INTSTS0); | ||
1013 | |||
1014 | for (i = 0; i < 4; i++) | ||
1015 | p[i] = m66592_read(m66592, offset + i*2); | ||
1016 | |||
1017 | /* check request */ | ||
1018 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
1019 | switch (ctrl->bRequest) { | ||
1020 | case USB_REQ_GET_STATUS: | ||
1021 | get_status(m66592, ctrl); | ||
1022 | break; | ||
1023 | case USB_REQ_CLEAR_FEATURE: | ||
1024 | clear_feature(m66592, ctrl); | ||
1025 | break; | ||
1026 | case USB_REQ_SET_FEATURE: | ||
1027 | set_feature(m66592, ctrl); | ||
1028 | break; | ||
1029 | default: | ||
1030 | ret = 1; | ||
1031 | break; | ||
1032 | } | ||
1033 | } else | ||
1034 | ret = 1; | ||
1035 | return ret; | ||
1036 | } | ||
1037 | |||
1038 | static void m66592_update_usb_speed(struct m66592 *m66592) | ||
1039 | { | ||
1040 | u16 speed = get_usb_speed(m66592); | ||
1041 | |||
1042 | switch (speed) { | ||
1043 | case M66592_HSMODE: | ||
1044 | m66592->gadget.speed = USB_SPEED_HIGH; | ||
1045 | break; | ||
1046 | case M66592_FSMODE: | ||
1047 | m66592->gadget.speed = USB_SPEED_FULL; | ||
1048 | break; | ||
1049 | default: | ||
1050 | m66592->gadget.speed = USB_SPEED_UNKNOWN; | ||
1051 | printk(KERN_ERR "USB speed unknown\n"); | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | static void irq_device_state(struct m66592 *m66592) | ||
1056 | { | ||
1057 | u16 dvsq; | ||
1058 | |||
1059 | dvsq = m66592_read(m66592, M66592_INTSTS0) & M66592_DVSQ; | ||
1060 | m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0); | ||
1061 | |||
1062 | if (dvsq == M66592_DS_DFLT) { /* bus reset */ | ||
1063 | m66592->driver->disconnect(&m66592->gadget); | ||
1064 | m66592_update_usb_speed(m66592); | ||
1065 | } | ||
1066 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) | ||
1067 | m66592_update_usb_speed(m66592); | ||
1068 | if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) && | ||
1069 | m66592->gadget.speed == USB_SPEED_UNKNOWN) | ||
1070 | m66592_update_usb_speed(m66592); | ||
1071 | |||
1072 | m66592->old_dvsq = dvsq; | ||
1073 | } | ||
1074 | |||
1075 | static void irq_control_stage(struct m66592 *m66592) | ||
1076 | { | ||
1077 | struct usb_ctrlrequest ctrl; | ||
1078 | u16 ctsq; | ||
1079 | |||
1080 | ctsq = m66592_read(m66592, M66592_INTSTS0) & M66592_CTSQ; | ||
1081 | m66592_write(m66592, ~M66592_CTRT, M66592_INTSTS0); | ||
1082 | |||
1083 | switch (ctsq) { | ||
1084 | case M66592_CS_IDST: { | ||
1085 | struct m66592_ep *ep; | ||
1086 | struct m66592_request *req; | ||
1087 | ep = &m66592->ep[0]; | ||
1088 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
1089 | transfer_complete(ep, req, 0); | ||
1090 | } | ||
1091 | break; | ||
1092 | |||
1093 | case M66592_CS_RDDS: | ||
1094 | case M66592_CS_WRDS: | ||
1095 | case M66592_CS_WRND: | ||
1096 | if (setup_packet(m66592, &ctrl)) { | ||
1097 | if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) | ||
1098 | pipe_stall(m66592, 0); | ||
1099 | } | ||
1100 | break; | ||
1101 | case M66592_CS_RDSS: | ||
1102 | case M66592_CS_WRSS: | ||
1103 | control_end(m66592, 0); | ||
1104 | break; | ||
1105 | default: | ||
1106 | printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq); | ||
1107 | break; | ||
1108 | } | ||
1109 | } | ||
1110 | |||
1111 | static irqreturn_t m66592_irq(int irq, void *_m66592) | ||
1112 | { | ||
1113 | struct m66592 *m66592 = _m66592; | ||
1114 | u16 intsts0; | ||
1115 | u16 intenb0; | ||
1116 | u16 brdysts, nrdysts, bempsts; | ||
1117 | u16 brdyenb, nrdyenb, bempenb; | ||
1118 | u16 savepipe; | ||
1119 | u16 mask0; | ||
1120 | |||
1121 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | ||
1122 | intenb0 = m66592_read(m66592, M66592_INTENB0); | ||
1123 | |||
1124 | savepipe = m66592_read(m66592, M66592_CFIFOSEL); | ||
1125 | |||
1126 | mask0 = intsts0 & intenb0; | ||
1127 | if (mask0) { | ||
1128 | brdysts = m66592_read(m66592, M66592_BRDYSTS); | ||
1129 | nrdysts = m66592_read(m66592, M66592_NRDYSTS); | ||
1130 | bempsts = m66592_read(m66592, M66592_BEMPSTS); | ||
1131 | brdyenb = m66592_read(m66592, M66592_BRDYENB); | ||
1132 | nrdyenb = m66592_read(m66592, M66592_NRDYENB); | ||
1133 | bempenb = m66592_read(m66592, M66592_BEMPENB); | ||
1134 | |||
1135 | if (mask0 & M66592_VBINT) { | ||
1136 | m66592_write(m66592, (u16)~M66592_VBINT, | ||
1137 | M66592_INTSTS0); | ||
1138 | m66592_start_xclock(m66592); | ||
1139 | |||
1140 | /* start vbus sampling */ | ||
1141 | m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) | ||
1142 | & M66592_VBSTS; | ||
1143 | m66592->scount = M66592_MAX_SAMPLING; | ||
1144 | |||
1145 | mod_timer(&m66592->timer, | ||
1146 | jiffies + msecs_to_jiffies(50)); | ||
1147 | } | ||
1148 | if (intsts0 & M66592_DVSQ) | ||
1149 | irq_device_state(m66592); | ||
1150 | |||
1151 | if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) && | ||
1152 | (brdysts & brdyenb)) { | ||
1153 | irq_pipe_ready(m66592, brdysts, brdyenb); | ||
1154 | } | ||
1155 | if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) && | ||
1156 | (bempsts & bempenb)) { | ||
1157 | irq_pipe_empty(m66592, bempsts, bempenb); | ||
1158 | } | ||
1159 | |||
1160 | if (intsts0 & M66592_CTRT) | ||
1161 | irq_control_stage(m66592); | ||
1162 | } | ||
1163 | |||
1164 | m66592_write(m66592, savepipe, M66592_CFIFOSEL); | ||
1165 | |||
1166 | return IRQ_HANDLED; | ||
1167 | } | ||
1168 | |||
1169 | static void m66592_timer(unsigned long _m66592) | ||
1170 | { | ||
1171 | struct m66592 *m66592 = (struct m66592 *)_m66592; | ||
1172 | unsigned long flags; | ||
1173 | u16 tmp; | ||
1174 | |||
1175 | spin_lock_irqsave(&m66592->lock, flags); | ||
1176 | tmp = m66592_read(m66592, M66592_SYSCFG); | ||
1177 | if (!(tmp & M66592_RCKE)) { | ||
1178 | m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); | ||
1179 | udelay(10); | ||
1180 | m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); | ||
1181 | } | ||
1182 | if (m66592->scount > 0) { | ||
1183 | tmp = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS; | ||
1184 | if (tmp == m66592->old_vbus) { | ||
1185 | m66592->scount--; | ||
1186 | if (m66592->scount == 0) { | ||
1187 | if (tmp == M66592_VBSTS) | ||
1188 | m66592_usb_connect(m66592); | ||
1189 | else | ||
1190 | m66592_usb_disconnect(m66592); | ||
1191 | } else { | ||
1192 | mod_timer(&m66592->timer, | ||
1193 | jiffies + msecs_to_jiffies(50)); | ||
1194 | } | ||
1195 | } else { | ||
1196 | m66592->scount = M66592_MAX_SAMPLING; | ||
1197 | m66592->old_vbus = tmp; | ||
1198 | mod_timer(&m66592->timer, | ||
1199 | jiffies + msecs_to_jiffies(50)); | ||
1200 | } | ||
1201 | } | ||
1202 | spin_unlock_irqrestore(&m66592->lock, flags); | ||
1203 | } | ||
1204 | |||
1205 | /*-------------------------------------------------------------------------*/ | ||
1206 | static int m66592_enable(struct usb_ep *_ep, | ||
1207 | const struct usb_endpoint_descriptor *desc) | ||
1208 | { | ||
1209 | struct m66592_ep *ep; | ||
1210 | |||
1211 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1212 | return alloc_pipe_config(ep, desc); | ||
1213 | } | ||
1214 | |||
1215 | static int m66592_disable(struct usb_ep *_ep) | ||
1216 | { | ||
1217 | struct m66592_ep *ep; | ||
1218 | struct m66592_request *req; | ||
1219 | unsigned long flags; | ||
1220 | |||
1221 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1222 | BUG_ON(!ep); | ||
1223 | |||
1224 | while (!list_empty(&ep->queue)) { | ||
1225 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
1226 | spin_lock_irqsave(&ep->m66592->lock, flags); | ||
1227 | transfer_complete(ep, req, -ECONNRESET); | ||
1228 | spin_unlock_irqrestore(&ep->m66592->lock, flags); | ||
1229 | } | ||
1230 | |||
1231 | pipe_irq_disable(ep->m66592, ep->pipenum); | ||
1232 | return free_pipe_config(ep); | ||
1233 | } | ||
1234 | |||
1235 | static struct usb_request *m66592_alloc_request(struct usb_ep *_ep, | ||
1236 | gfp_t gfp_flags) | ||
1237 | { | ||
1238 | struct m66592_request *req; | ||
1239 | |||
1240 | req = kzalloc(sizeof(struct m66592_request), gfp_flags); | ||
1241 | if (!req) | ||
1242 | return NULL; | ||
1243 | |||
1244 | INIT_LIST_HEAD(&req->queue); | ||
1245 | |||
1246 | return &req->req; | ||
1247 | } | ||
1248 | |||
1249 | static void m66592_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
1250 | { | ||
1251 | struct m66592_request *req; | ||
1252 | |||
1253 | req = container_of(_req, struct m66592_request, req); | ||
1254 | kfree(req); | ||
1255 | } | ||
1256 | |||
1257 | static void *m66592_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | ||
1258 | dma_addr_t *dma, gfp_t gfp_flags) | ||
1259 | { | ||
1260 | void *buf; | ||
1261 | |||
1262 | buf = kzalloc(bytes, gfp_flags); | ||
1263 | if (dma) | ||
1264 | *dma = virt_to_bus(buf); | ||
1265 | |||
1266 | return buf; | ||
1267 | } | ||
1268 | |||
1269 | static void m66592_free_buffer(struct usb_ep *_ep, void *buf, | ||
1270 | dma_addr_t dma, unsigned bytes) | ||
1271 | { | ||
1272 | kfree(buf); | ||
1273 | } | ||
1274 | |||
1275 | static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1276 | gfp_t gfp_flags) | ||
1277 | { | ||
1278 | struct m66592_ep *ep; | ||
1279 | struct m66592_request *req; | ||
1280 | unsigned long flags; | ||
1281 | int request = 0; | ||
1282 | |||
1283 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1284 | req = container_of(_req, struct m66592_request, req); | ||
1285 | |||
1286 | if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN) | ||
1287 | return -ESHUTDOWN; | ||
1288 | |||
1289 | spin_lock_irqsave(&ep->m66592->lock, flags); | ||
1290 | |||
1291 | if (list_empty(&ep->queue)) | ||
1292 | request = 1; | ||
1293 | |||
1294 | list_add_tail(&req->queue, &ep->queue); | ||
1295 | req->req.actual = 0; | ||
1296 | req->req.status = -EINPROGRESS; | ||
1297 | |||
1298 | if (ep->desc == 0) /* control */ | ||
1299 | start_ep0(ep, req); | ||
1300 | else { | ||
1301 | if (request && !ep->busy) | ||
1302 | start_packet(ep, req); | ||
1303 | } | ||
1304 | |||
1305 | spin_unlock_irqrestore(&ep->m66592->lock, flags); | ||
1306 | |||
1307 | return 0; | ||
1308 | } | ||
1309 | |||
1310 | static int m66592_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
1311 | { | ||
1312 | struct m66592_ep *ep; | ||
1313 | struct m66592_request *req; | ||
1314 | unsigned long flags; | ||
1315 | |||
1316 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1317 | req = container_of(_req, struct m66592_request, req); | ||
1318 | |||
1319 | spin_lock_irqsave(&ep->m66592->lock, flags); | ||
1320 | if (!list_empty(&ep->queue)) | ||
1321 | transfer_complete(ep, req, -ECONNRESET); | ||
1322 | spin_unlock_irqrestore(&ep->m66592->lock, flags); | ||
1323 | |||
1324 | return 0; | ||
1325 | } | ||
1326 | |||
1327 | static int m66592_set_halt(struct usb_ep *_ep, int value) | ||
1328 | { | ||
1329 | struct m66592_ep *ep; | ||
1330 | struct m66592_request *req; | ||
1331 | unsigned long flags; | ||
1332 | int ret = 0; | ||
1333 | |||
1334 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1335 | req = list_entry(ep->queue.next, struct m66592_request, queue); | ||
1336 | |||
1337 | spin_lock_irqsave(&ep->m66592->lock, flags); | ||
1338 | if (!list_empty(&ep->queue)) { | ||
1339 | ret = -EAGAIN; | ||
1340 | goto out; | ||
1341 | } | ||
1342 | if (value) { | ||
1343 | ep->busy = 1; | ||
1344 | pipe_stall(ep->m66592, ep->pipenum); | ||
1345 | } else { | ||
1346 | ep->busy = 0; | ||
1347 | pipe_stop(ep->m66592, ep->pipenum); | ||
1348 | } | ||
1349 | |||
1350 | out: | ||
1351 | spin_unlock_irqrestore(&ep->m66592->lock, flags); | ||
1352 | return ret; | ||
1353 | } | ||
1354 | |||
1355 | static int m66592_fifo_status(struct usb_ep *_ep) | ||
1356 | { | ||
1357 | return -EOPNOTSUPP; | ||
1358 | } | ||
1359 | |||
1360 | static void m66592_fifo_flush(struct usb_ep *_ep) | ||
1361 | { | ||
1362 | struct m66592_ep *ep; | ||
1363 | unsigned long flags; | ||
1364 | |||
1365 | ep = container_of(_ep, struct m66592_ep, ep); | ||
1366 | spin_lock_irqsave(&ep->m66592->lock, flags); | ||
1367 | if (list_empty(&ep->queue) && !ep->busy) { | ||
1368 | pipe_stop(ep->m66592, ep->pipenum); | ||
1369 | m66592_bclr(ep->m66592, M66592_BCLR, ep->fifoctr); | ||
1370 | } | ||
1371 | spin_unlock_irqrestore(&ep->m66592->lock, flags); | ||
1372 | } | ||
1373 | |||
1374 | static struct usb_ep_ops m66592_ep_ops = { | ||
1375 | .enable = m66592_enable, | ||
1376 | .disable = m66592_disable, | ||
1377 | |||
1378 | .alloc_request = m66592_alloc_request, | ||
1379 | .free_request = m66592_free_request, | ||
1380 | |||
1381 | .alloc_buffer = m66592_alloc_buffer, | ||
1382 | .free_buffer = m66592_free_buffer, | ||
1383 | |||
1384 | .queue = m66592_queue, | ||
1385 | .dequeue = m66592_dequeue, | ||
1386 | |||
1387 | .set_halt = m66592_set_halt, | ||
1388 | .fifo_status = m66592_fifo_status, | ||
1389 | .fifo_flush = m66592_fifo_flush, | ||
1390 | }; | ||
1391 | |||
1392 | /*-------------------------------------------------------------------------*/ | ||
1393 | static struct m66592 *the_controller; | ||
1394 | |||
1395 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1396 | { | ||
1397 | struct m66592 *m66592 = the_controller; | ||
1398 | int retval; | ||
1399 | |||
1400 | if (!driver || | ||
1401 | driver->speed != USB_SPEED_HIGH || | ||
1402 | !driver->bind || | ||
1403 | !driver->unbind || | ||
1404 | !driver->setup) | ||
1405 | return -EINVAL; | ||
1406 | if (!m66592) | ||
1407 | return -ENODEV; | ||
1408 | if (m66592->driver) | ||
1409 | return -EBUSY; | ||
1410 | |||
1411 | /* hook up the driver */ | ||
1412 | driver->driver.bus = NULL; | ||
1413 | m66592->driver = driver; | ||
1414 | m66592->gadget.dev.driver = &driver->driver; | ||
1415 | |||
1416 | retval = device_add(&m66592->gadget.dev); | ||
1417 | if (retval) { | ||
1418 | printk(KERN_ERR "device_add error (%d)\n", retval); | ||
1419 | goto error; | ||
1420 | } | ||
1421 | |||
1422 | retval = driver->bind (&m66592->gadget); | ||
1423 | if (retval) { | ||
1424 | printk(KERN_ERR "bind to driver error (%d)\n", retval); | ||
1425 | device_del(&m66592->gadget.dev); | ||
1426 | goto error; | ||
1427 | } | ||
1428 | |||
1429 | m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | ||
1430 | if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { | ||
1431 | m66592_start_xclock(m66592); | ||
1432 | /* start vbus sampling */ | ||
1433 | m66592->old_vbus = m66592_read(m66592, | ||
1434 | M66592_INTSTS0) & M66592_VBSTS; | ||
1435 | m66592->scount = M66592_MAX_SAMPLING; | ||
1436 | mod_timer(&m66592->timer, | ||
1437 | jiffies + msecs_to_jiffies(50)); | ||
1438 | } | ||
1439 | |||
1440 | return 0; | ||
1441 | |||
1442 | error: | ||
1443 | m66592->driver = NULL; | ||
1444 | m66592->gadget.dev.driver = NULL; | ||
1445 | |||
1446 | return retval; | ||
1447 | } | ||
1448 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1449 | |||
1450 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1451 | { | ||
1452 | struct m66592 *m66592 = the_controller; | ||
1453 | unsigned long flags; | ||
1454 | |||
1455 | spin_lock_irqsave(&m66592->lock, flags); | ||
1456 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) | ||
1457 | m66592_usb_disconnect(m66592); | ||
1458 | spin_unlock_irqrestore(&m66592->lock, flags); | ||
1459 | |||
1460 | m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); | ||
1461 | |||
1462 | driver->unbind(&m66592->gadget); | ||
1463 | |||
1464 | init_controller(m66592); | ||
1465 | disable_controller(m66592); | ||
1466 | |||
1467 | device_del(&m66592->gadget.dev); | ||
1468 | m66592->driver = NULL; | ||
1469 | return 0; | ||
1470 | } | ||
1471 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1472 | |||
1473 | /*-------------------------------------------------------------------------*/ | ||
1474 | static int m66592_get_frame(struct usb_gadget *_gadget) | ||
1475 | { | ||
1476 | struct m66592 *m66592 = gadget_to_m66592(_gadget); | ||
1477 | return m66592_read(m66592, M66592_FRMNUM) & 0x03FF; | ||
1478 | } | ||
1479 | |||
1480 | static struct usb_gadget_ops m66592_gadget_ops = { | ||
1481 | .get_frame = m66592_get_frame, | ||
1482 | }; | ||
1483 | |||
1484 | #if defined(CONFIG_PM) | ||
1485 | static int m66592_suspend(struct platform_device *pdev, pm_message_t state) | ||
1486 | { | ||
1487 | pdev->dev.power.power_state = state; | ||
1488 | return 0; | ||
1489 | } | ||
1490 | |||
1491 | static int m66592_resume(struct platform_device *pdev) | ||
1492 | { | ||
1493 | pdev->dev.power.power_state = PMSG_ON; | ||
1494 | return 0; | ||
1495 | } | ||
1496 | #else /* if defined(CONFIG_PM) */ | ||
1497 | #define m66592_suspend NULL | ||
1498 | #define m66592_resume NULL | ||
1499 | #endif | ||
1500 | |||
1501 | static int __init_or_module m66592_remove(struct platform_device *pdev) | ||
1502 | { | ||
1503 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); | ||
1504 | |||
1505 | del_timer_sync(&m66592->timer); | ||
1506 | iounmap(m66592->reg); | ||
1507 | free_irq(platform_get_irq(pdev, 0), m66592); | ||
1508 | kfree(m66592); | ||
1509 | return 0; | ||
1510 | } | ||
1511 | |||
1512 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
1513 | static int __init m66592_probe(struct platform_device *pdev) | ||
1514 | { | ||
1515 | struct resource *res = NULL; | ||
1516 | int irq = -1; | ||
1517 | void __iomem *reg = NULL; | ||
1518 | struct m66592 *m66592 = NULL; | ||
1519 | int ret = 0; | ||
1520 | int i; | ||
1521 | |||
1522 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
1523 | (char *)udc_name); | ||
1524 | if (!res) { | ||
1525 | ret = -ENODEV; | ||
1526 | printk(KERN_ERR "platform_get_resource_byname error.\n"); | ||
1527 | goto clean_up; | ||
1528 | } | ||
1529 | |||
1530 | irq = platform_get_irq(pdev, 0); | ||
1531 | if (irq < 0) { | ||
1532 | ret = -ENODEV; | ||
1533 | printk(KERN_ERR "platform_get_irq error.\n"); | ||
1534 | goto clean_up; | ||
1535 | } | ||
1536 | |||
1537 | reg = ioremap(res->start, resource_len(res)); | ||
1538 | if (reg == NULL) { | ||
1539 | ret = -ENOMEM; | ||
1540 | printk(KERN_ERR "ioremap error.\n"); | ||
1541 | goto clean_up; | ||
1542 | } | ||
1543 | |||
1544 | /* initialize ucd */ | ||
1545 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | ||
1546 | if (m66592 == NULL) { | ||
1547 | printk(KERN_ERR "kzalloc error\n"); | ||
1548 | goto clean_up; | ||
1549 | } | ||
1550 | |||
1551 | spin_lock_init(&m66592->lock); | ||
1552 | dev_set_drvdata(&pdev->dev, m66592); | ||
1553 | |||
1554 | m66592->gadget.ops = &m66592_gadget_ops; | ||
1555 | device_initialize(&m66592->gadget.dev); | ||
1556 | strcpy(m66592->gadget.dev.bus_id, "gadget"); | ||
1557 | m66592->gadget.is_dualspeed = 1; | ||
1558 | m66592->gadget.dev.parent = &pdev->dev; | ||
1559 | m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
1560 | m66592->gadget.dev.release = pdev->dev.release; | ||
1561 | m66592->gadget.name = udc_name; | ||
1562 | |||
1563 | init_timer(&m66592->timer); | ||
1564 | m66592->timer.function = m66592_timer; | ||
1565 | m66592->timer.data = (unsigned long)m66592; | ||
1566 | m66592->reg = reg; | ||
1567 | |||
1568 | m66592->bi_bufnum = M66592_BASE_BUFNUM; | ||
1569 | |||
1570 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, | ||
1571 | udc_name, m66592); | ||
1572 | if (ret < 0) { | ||
1573 | printk(KERN_ERR "request_irq error (%d)\n", ret); | ||
1574 | goto clean_up; | ||
1575 | } | ||
1576 | |||
1577 | INIT_LIST_HEAD(&m66592->gadget.ep_list); | ||
1578 | m66592->gadget.ep0 = &m66592->ep[0].ep; | ||
1579 | INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list); | ||
1580 | for (i = 0; i < M66592_MAX_NUM_PIPE; i++) { | ||
1581 | struct m66592_ep *ep = &m66592->ep[i]; | ||
1582 | |||
1583 | if (i != 0) { | ||
1584 | INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); | ||
1585 | list_add_tail(&m66592->ep[i].ep.ep_list, | ||
1586 | &m66592->gadget.ep_list); | ||
1587 | } | ||
1588 | ep->m66592 = m66592; | ||
1589 | INIT_LIST_HEAD(&ep->queue); | ||
1590 | ep->ep.name = m66592_ep_name[i]; | ||
1591 | ep->ep.ops = &m66592_ep_ops; | ||
1592 | ep->ep.maxpacket = 512; | ||
1593 | } | ||
1594 | m66592->ep[0].ep.maxpacket = 64; | ||
1595 | m66592->ep[0].pipenum = 0; | ||
1596 | m66592->ep[0].fifoaddr = M66592_CFIFO; | ||
1597 | m66592->ep[0].fifosel = M66592_CFIFOSEL; | ||
1598 | m66592->ep[0].fifoctr = M66592_CFIFOCTR; | ||
1599 | m66592->ep[0].fifotrn = 0; | ||
1600 | m66592->ep[0].pipectr = get_pipectr_addr(0); | ||
1601 | m66592->pipenum2ep[0] = &m66592->ep[0]; | ||
1602 | m66592->epaddr2ep[0] = &m66592->ep[0]; | ||
1603 | |||
1604 | the_controller = m66592; | ||
1605 | |||
1606 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); | ||
1607 | if (m66592->ep0_req == NULL) | ||
1608 | goto clean_up; | ||
1609 | m66592->ep0_buf = m66592_alloc_buffer(&m66592->ep[0].ep, 2, NULL, | ||
1610 | GFP_KERNEL); | ||
1611 | if (m66592->ep0_buf == NULL) | ||
1612 | goto clean_up; | ||
1613 | |||
1614 | init_controller(m66592); | ||
1615 | |||
1616 | printk("driver %s, %s\n", udc_name, DRIVER_VERSION); | ||
1617 | return 0; | ||
1618 | |||
1619 | clean_up: | ||
1620 | if (m66592) { | ||
1621 | if (m66592->ep0_req) | ||
1622 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | ||
1623 | kfree(m66592); | ||
1624 | } | ||
1625 | if (reg) | ||
1626 | iounmap(reg); | ||
1627 | |||
1628 | return ret; | ||
1629 | } | ||
1630 | |||
1631 | /*-------------------------------------------------------------------------*/ | ||
1632 | static struct platform_driver m66592_driver = { | ||
1633 | .probe = m66592_probe, | ||
1634 | .remove = m66592_remove, | ||
1635 | .suspend = m66592_suspend, | ||
1636 | .resume = m66592_resume, | ||
1637 | .driver = { | ||
1638 | .name = (char *) udc_name, | ||
1639 | }, | ||
1640 | }; | ||
1641 | |||
1642 | static int __init m66592_udc_init(void) | ||
1643 | { | ||
1644 | return platform_driver_register(&m66592_driver); | ||
1645 | } | ||
1646 | module_init(m66592_udc_init); | ||
1647 | |||
1648 | static void __exit m66592_udc_cleanup(void) | ||
1649 | { | ||
1650 | platform_driver_unregister(&m66592_driver); | ||
1651 | } | ||
1652 | module_exit(m66592_udc_cleanup); | ||
1653 | |||
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h new file mode 100644 index 000000000000..26b54f8b8945 --- /dev/null +++ b/drivers/usb/gadget/m66592-udc.h | |||
@@ -0,0 +1,577 @@ | |||
1 | /* | ||
2 | * M66592 UDC (USB gadget) | ||
3 | * | ||
4 | * Copyright (C) 2006-2007 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __M66592_UDC_H__ | ||
24 | #define __M66592_UDC_H__ | ||
25 | |||
26 | #define M66592_SYSCFG 0x00 | ||
27 | #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ | ||
28 | #define M66592_XTAL48 0x8000 /* 48MHz */ | ||
29 | #define M66592_XTAL24 0x4000 /* 24MHz */ | ||
30 | #define M66592_XTAL12 0x0000 /* 12MHz */ | ||
31 | #define M66592_XCKE 0x2000 /* b13: External clock enable */ | ||
32 | #define M66592_RCKE 0x1000 /* b12: Register clock enable */ | ||
33 | #define M66592_PLLC 0x0800 /* b11: PLL control */ | ||
34 | #define M66592_SCKE 0x0400 /* b10: USB clock enable */ | ||
35 | #define M66592_ATCKM 0x0100 /* b8: Automatic supply functional enable */ | ||
36 | #define M66592_HSE 0x0080 /* b7: Hi-speed enable */ | ||
37 | #define M66592_DCFM 0x0040 /* b6: Controller function select */ | ||
38 | #define M66592_DMRPD 0x0020 /* b5: D- pull down control */ | ||
39 | #define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ | ||
40 | #define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ | ||
41 | #define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ | ||
42 | #define M66592_USBE 0x0001 /* b0: USB module operation enable */ | ||
43 | |||
44 | #define M66592_SYSSTS 0x02 | ||
45 | #define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ | ||
46 | #define M66592_SE1 0x0003 /* SE1 */ | ||
47 | #define M66592_KSTS 0x0002 /* K State */ | ||
48 | #define M66592_JSTS 0x0001 /* J State */ | ||
49 | #define M66592_SE0 0x0000 /* SE0 */ | ||
50 | |||
51 | #define M66592_DVSTCTR 0x04 | ||
52 | #define M66592_WKUP 0x0100 /* b8: Remote wakeup */ | ||
53 | #define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ | ||
54 | #define M66592_USBRST 0x0040 /* b6: USB reset enable */ | ||
55 | #define M66592_RESUME 0x0020 /* b5: Resume enable */ | ||
56 | #define M66592_UACT 0x0010 /* b4: USB bus enable */ | ||
57 | #define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ | ||
58 | #define M66592_HSMODE 0x0003 /* Hi-Speed mode */ | ||
59 | #define M66592_FSMODE 0x0002 /* Full-Speed mode */ | ||
60 | #define M66592_HSPROC 0x0001 /* HS handshake is processing */ | ||
61 | |||
62 | #define M66592_TESTMODE 0x06 | ||
63 | #define M66592_UTST 0x000F /* b4-0: Test select */ | ||
64 | #define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ | ||
65 | #define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ | ||
66 | #define M66592_H_TST_K 0x000A /* HOST TEST K */ | ||
67 | #define M66592_H_TST_J 0x0009 /* HOST TEST J */ | ||
68 | #define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ | ||
69 | #define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ | ||
70 | #define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ | ||
71 | #define M66592_P_TST_K 0x0002 /* PERI TEST K */ | ||
72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ | ||
73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ | ||
74 | |||
75 | #define M66592_PINCFG 0x0A | ||
76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ | ||
77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ | ||
78 | |||
79 | #define M66592_DMA0CFG 0x0C | ||
80 | #define M66592_DMA1CFG 0x0E | ||
81 | #define M66592_DREQA 0x4000 /* b14: Dreq active select */ | ||
82 | #define M66592_BURST 0x2000 /* b13: Burst mode */ | ||
83 | #define M66592_DACKA 0x0400 /* b10: Dack active select */ | ||
84 | #define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ | ||
85 | #define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ | ||
86 | #define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ | ||
87 | #define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ | ||
88 | #define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ | ||
89 | #define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ | ||
90 | #define M66592_DENDA 0x0040 /* b6: Dend active select */ | ||
91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ | ||
92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ | ||
93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ | ||
94 | |||
95 | #define M66592_CFIFO 0x10 | ||
96 | #define M66592_D0FIFO 0x14 | ||
97 | #define M66592_D1FIFO 0x18 | ||
98 | |||
99 | #define M66592_CFIFOSEL 0x1E | ||
100 | #define M66592_D0FIFOSEL 0x24 | ||
101 | #define M66592_D1FIFOSEL 0x2A | ||
102 | #define M66592_RCNT 0x8000 /* b15: Read count mode */ | ||
103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ | ||
104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ | ||
105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ | ||
106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO access */ | ||
107 | #define M66592_MBW_8 0x0000 /* 8bit */ | ||
108 | #define M66592_MBW_16 0x0400 /* 16bit */ | ||
109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ | ||
110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ | ||
111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet additional mode */ | ||
112 | #define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ | ||
113 | #define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ | ||
114 | |||
115 | #define M66592_CFIFOCTR 0x20 | ||
116 | #define M66592_D0FIFOCTR 0x26 | ||
117 | #define M66592_D1FIFOCTR 0x2c | ||
118 | #define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ | ||
119 | #define M66592_BCLR 0x4000 /* b14: Buffer clear */ | ||
120 | #define M66592_FRDY 0x2000 /* b13: FIFO ready */ | ||
121 | #define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ | ||
122 | |||
123 | #define M66592_CFIFOSIE 0x22 | ||
124 | #define M66592_TGL 0x8000 /* b15: Buffer toggle */ | ||
125 | #define M66592_SCLR 0x4000 /* b14: Buffer clear */ | ||
126 | #define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ | ||
127 | |||
128 | #define M66592_D0FIFOTRN 0x28 | ||
129 | #define M66592_D1FIFOTRN 0x2E | ||
130 | #define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ | ||
131 | |||
132 | #define M66592_INTENB0 0x30 | ||
133 | #define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ | ||
134 | #define M66592_RSME 0x4000 /* b14: Resume interrupt */ | ||
135 | #define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ | ||
136 | #define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ | ||
137 | #define M66592_CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ | ||
138 | #define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ | ||
139 | #define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ | ||
140 | #define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ | ||
141 | #define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ | ||
142 | #define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ | ||
143 | #define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ | ||
144 | #define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ | ||
145 | #define M66592_WDST 0x0008 /* b3: Control write data stage completed interrupt */ | ||
146 | #define M66592_RDST 0x0004 /* b2: Control read data stage completed interrupt */ | ||
147 | #define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ | ||
148 | #define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ | ||
149 | |||
150 | #define M66592_INTENB1 0x32 | ||
151 | #define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ | ||
152 | #define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ | ||
153 | #define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ | ||
154 | #define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ | ||
155 | #define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ | ||
156 | #define M66592_INTL 0x0002 /* b1: Interrupt sense select */ | ||
157 | #define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ | ||
158 | |||
159 | #define M66592_BRDYENB 0x36 | ||
160 | #define M66592_BRDYSTS 0x46 | ||
161 | #define M66592_BRDY7 0x0080 /* b7: PIPE7 */ | ||
162 | #define M66592_BRDY6 0x0040 /* b6: PIPE6 */ | ||
163 | #define M66592_BRDY5 0x0020 /* b5: PIPE5 */ | ||
164 | #define M66592_BRDY4 0x0010 /* b4: PIPE4 */ | ||
165 | #define M66592_BRDY3 0x0008 /* b3: PIPE3 */ | ||
166 | #define M66592_BRDY2 0x0004 /* b2: PIPE2 */ | ||
167 | #define M66592_BRDY1 0x0002 /* b1: PIPE1 */ | ||
168 | #define M66592_BRDY0 0x0001 /* b1: PIPE0 */ | ||
169 | |||
170 | #define M66592_NRDYENB 0x38 | ||
171 | #define M66592_NRDYSTS 0x48 | ||
172 | #define M66592_NRDY7 0x0080 /* b7: PIPE7 */ | ||
173 | #define M66592_NRDY6 0x0040 /* b6: PIPE6 */ | ||
174 | #define M66592_NRDY5 0x0020 /* b5: PIPE5 */ | ||
175 | #define M66592_NRDY4 0x0010 /* b4: PIPE4 */ | ||
176 | #define M66592_NRDY3 0x0008 /* b3: PIPE3 */ | ||
177 | #define M66592_NRDY2 0x0004 /* b2: PIPE2 */ | ||
178 | #define M66592_NRDY1 0x0002 /* b1: PIPE1 */ | ||
179 | #define M66592_NRDY0 0x0001 /* b1: PIPE0 */ | ||
180 | |||
181 | #define M66592_BEMPENB 0x3A | ||
182 | #define M66592_BEMPSTS 0x4A | ||
183 | #define M66592_BEMP7 0x0080 /* b7: PIPE7 */ | ||
184 | #define M66592_BEMP6 0x0040 /* b6: PIPE6 */ | ||
185 | #define M66592_BEMP5 0x0020 /* b5: PIPE5 */ | ||
186 | #define M66592_BEMP4 0x0010 /* b4: PIPE4 */ | ||
187 | #define M66592_BEMP3 0x0008 /* b3: PIPE3 */ | ||
188 | #define M66592_BEMP2 0x0004 /* b2: PIPE2 */ | ||
189 | #define M66592_BEMP1 0x0002 /* b1: PIPE1 */ | ||
190 | #define M66592_BEMP0 0x0001 /* b0: PIPE0 */ | ||
191 | |||
192 | #define M66592_SOFCFG 0x3C | ||
193 | #define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ | ||
194 | #define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ | ||
195 | #define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ | ||
196 | #define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ | ||
197 | |||
198 | #define M66592_INTSTS0 0x40 | ||
199 | #define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ | ||
200 | #define M66592_RESM 0x4000 /* b14: Resume interrupt */ | ||
201 | #define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ | ||
202 | #define M66592_DVST 0x1000 /* b12: Device state transition interrupt */ | ||
203 | #define M66592_CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ | ||
204 | #define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ | ||
205 | #define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ | ||
206 | #define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ | ||
207 | #define M66592_VBSTS 0x0080 /* b7: VBUS input port */ | ||
208 | #define M66592_DVSQ 0x0070 /* b6-4: Device state */ | ||
209 | #define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ | ||
210 | #define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ | ||
211 | #define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ | ||
212 | #define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ | ||
213 | #define M66592_DS_SUSP 0x0040 /* Suspend */ | ||
214 | #define M66592_DS_CNFG 0x0030 /* Configured */ | ||
215 | #define M66592_DS_ADDS 0x0020 /* Address */ | ||
216 | #define M66592_DS_DFLT 0x0010 /* Default */ | ||
217 | #define M66592_DS_POWR 0x0000 /* Powered */ | ||
218 | #define M66592_DVSQS 0x0030 /* b5-4: Device state */ | ||
219 | #define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ | ||
220 | #define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ | ||
221 | #define M66592_CS_SQER 0x0006 /* Sequence error */ | ||
222 | #define M66592_CS_WRND 0x0005 /* Control write nodata status stage */ | ||
223 | #define M66592_CS_WRSS 0x0004 /* Control write status stage */ | ||
224 | #define M66592_CS_WRDS 0x0003 /* Control write data stage */ | ||
225 | #define M66592_CS_RDSS 0x0002 /* Control read status stage */ | ||
226 | #define M66592_CS_RDDS 0x0001 /* Control read data stage */ | ||
227 | #define M66592_CS_IDST 0x0000 /* Idle or setup stage */ | ||
228 | |||
229 | #define M66592_INTSTS1 0x42 | ||
230 | #define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ | ||
231 | #define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ | ||
232 | #define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ | ||
233 | #define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ | ||
234 | |||
235 | #define M66592_FRMNUM 0x4C | ||
236 | #define M66592_OVRN 0x8000 /* b15: Overrun error */ | ||
237 | #define M66592_CRCE 0x4000 /* b14: Received data error */ | ||
238 | #define M66592_SOFRM 0x0800 /* b11: SOF output mode */ | ||
239 | #define M66592_FRNM 0x07FF /* b10-0: Frame number */ | ||
240 | |||
241 | #define M66592_UFRMNUM 0x4E | ||
242 | #define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ | ||
243 | |||
244 | #define M66592_RECOVER 0x50 | ||
245 | #define M66592_STSRECOV 0x0700 /* Status recovery */ | ||
246 | #define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ | ||
247 | #define M66592_STSR_DEFAULT 0x0100 /* Default state */ | ||
248 | #define M66592_STSR_ADDRESS 0x0200 /* Address state */ | ||
249 | #define M66592_STSR_CONFIG 0x0300 /* Configured state */ | ||
250 | #define M66592_USBADDR 0x007F /* b6-0: USB address */ | ||
251 | |||
252 | #define M66592_USBREQ 0x54 | ||
253 | #define M66592_bRequest 0xFF00 /* b15-8: bRequest */ | ||
254 | #define M66592_GET_STATUS 0x0000 | ||
255 | #define M66592_CLEAR_FEATURE 0x0100 | ||
256 | #define M66592_ReqRESERVED 0x0200 | ||
257 | #define M66592_SET_FEATURE 0x0300 | ||
258 | #define M66592_ReqRESERVED1 0x0400 | ||
259 | #define M66592_SET_ADDRESS 0x0500 | ||
260 | #define M66592_GET_DESCRIPTOR 0x0600 | ||
261 | #define M66592_SET_DESCRIPTOR 0x0700 | ||
262 | #define M66592_GET_CONFIGURATION 0x0800 | ||
263 | #define M66592_SET_CONFIGURATION 0x0900 | ||
264 | #define M66592_GET_INTERFACE 0x0A00 | ||
265 | #define M66592_SET_INTERFACE 0x0B00 | ||
266 | #define M66592_SYNCH_FRAME 0x0C00 | ||
267 | #define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ | ||
268 | #define M66592_bmRequestTypeDir 0x0080 /* b7 : Data transfer direction */ | ||
269 | #define M66592_HOST_TO_DEVICE 0x0000 | ||
270 | #define M66592_DEVICE_TO_HOST 0x0080 | ||
271 | #define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ | ||
272 | #define M66592_STANDARD 0x0000 | ||
273 | #define M66592_CLASS 0x0020 | ||
274 | #define M66592_VENDOR 0x0040 | ||
275 | #define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ | ||
276 | #define M66592_DEVICE 0x0000 | ||
277 | #define M66592_INTERFACE 0x0001 | ||
278 | #define M66592_ENDPOINT 0x0002 | ||
279 | |||
280 | #define M66592_USBVAL 0x56 | ||
281 | #define M66592_wValue 0xFFFF /* b15-0: wValue */ | ||
282 | /* Standard Feature Selector */ | ||
283 | #define M66592_ENDPOINT_HALT 0x0000 | ||
284 | #define M66592_DEVICE_REMOTE_WAKEUP 0x0001 | ||
285 | #define M66592_TEST_MODE 0x0002 | ||
286 | /* Descriptor Types */ | ||
287 | #define M66592_DT_TYPE 0xFF00 | ||
288 | #define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) | ||
289 | #define M66592_DT_DEVICE 0x01 | ||
290 | #define M66592_DT_CONFIGURATION 0x02 | ||
291 | #define M66592_DT_STRING 0x03 | ||
292 | #define M66592_DT_INTERFACE 0x04 | ||
293 | #define M66592_DT_ENDPOINT 0x05 | ||
294 | #define M66592_DT_DEVICE_QUALIFIER 0x06 | ||
295 | #define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 | ||
296 | #define M66592_DT_INTERFACE_POWER 0x08 | ||
297 | #define M66592_DT_INDEX 0x00FF | ||
298 | #define M66592_CONF_NUM 0x00FF | ||
299 | #define M66592_ALT_SET 0x00FF | ||
300 | |||
301 | #define M66592_USBINDEX 0x58 | ||
302 | #define M66592_wIndex 0xFFFF /* b15-0: wIndex */ | ||
303 | #define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode Selectors */ | ||
304 | #define M66592_TEST_J 0x0100 /* Test_J */ | ||
305 | #define M66592_TEST_K 0x0200 /* Test_K */ | ||
306 | #define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ | ||
307 | #define M66592_TEST_PACKET 0x0400 /* Test_Packet */ | ||
308 | #define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ | ||
309 | #define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ | ||
310 | #define M66592_TEST_Reserved 0x4000 /* Reserved */ | ||
311 | #define M66592_TEST_VSTModes 0xC000 /* Vendor-specific test modes */ | ||
312 | #define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ | ||
313 | #define M66592_EP_DIR_IN 0x0080 | ||
314 | #define M66592_EP_DIR_OUT 0x0000 | ||
315 | |||
316 | #define M66592_USBLENG 0x5A | ||
317 | #define M66592_wLength 0xFFFF /* b15-0: wLength */ | ||
318 | |||
319 | #define M66592_DCPCFG 0x5C | ||
320 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | ||
321 | #define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ | ||
322 | |||
323 | #define M66592_DCPMAXP 0x5E | ||
324 | #define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ | ||
325 | #define M66592_DEVICE_0 0x0000 /* Device address 0 */ | ||
326 | #define M66592_DEVICE_1 0x4000 /* Device address 1 */ | ||
327 | #define M66592_DEVICE_2 0x8000 /* Device address 2 */ | ||
328 | #define M66592_DEVICE_3 0xC000 /* Device address 3 */ | ||
329 | #define M66592_MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ | ||
330 | |||
331 | #define M66592_DCPCTR 0x60 | ||
332 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | ||
333 | #define M66592_SUREQ 0x4000 /* b14: Send USB request */ | ||
334 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | ||
335 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | ||
336 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | ||
337 | #define M66592_CCPL 0x0004 /* b2: Enable control transfer complete */ | ||
338 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | ||
339 | #define M66592_PID_STALL 0x0002 /* STALL */ | ||
340 | #define M66592_PID_BUF 0x0001 /* BUF */ | ||
341 | #define M66592_PID_NAK 0x0000 /* NAK */ | ||
342 | |||
343 | #define M66592_PIPESEL 0x64 | ||
344 | #define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ | ||
345 | #define M66592_PIPE0 0x0000 /* PIPE 0 */ | ||
346 | #define M66592_PIPE1 0x0001 /* PIPE 1 */ | ||
347 | #define M66592_PIPE2 0x0002 /* PIPE 2 */ | ||
348 | #define M66592_PIPE3 0x0003 /* PIPE 3 */ | ||
349 | #define M66592_PIPE4 0x0004 /* PIPE 4 */ | ||
350 | #define M66592_PIPE5 0x0005 /* PIPE 5 */ | ||
351 | #define M66592_PIPE6 0x0006 /* PIPE 6 */ | ||
352 | #define M66592_PIPE7 0x0007 /* PIPE 7 */ | ||
353 | |||
354 | #define M66592_PIPECFG 0x66 | ||
355 | #define M66592_TYP 0xC000 /* b15-14: Transfer type */ | ||
356 | #define M66592_ISO 0xC000 /* Isochronous */ | ||
357 | #define M66592_INT 0x8000 /* Interrupt */ | ||
358 | #define M66592_BULK 0x4000 /* Bulk */ | ||
359 | #define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ | ||
360 | #define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ | ||
361 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | ||
362 | #define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ | ||
363 | #define M66592_DIR 0x0010 /* b4: Transfer direction select */ | ||
364 | #define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ | ||
365 | #define M66592_DIR_P_IN 0x0010 /* PERI IN */ | ||
366 | #define M66592_DIR_H_IN 0x0000 /* HOST IN */ | ||
367 | #define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ | ||
368 | #define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ | ||
369 | #define M66592_EP1 0x0001 | ||
370 | #define M66592_EP2 0x0002 | ||
371 | #define M66592_EP3 0x0003 | ||
372 | #define M66592_EP4 0x0004 | ||
373 | #define M66592_EP5 0x0005 | ||
374 | #define M66592_EP6 0x0006 | ||
375 | #define M66592_EP7 0x0007 | ||
376 | #define M66592_EP8 0x0008 | ||
377 | #define M66592_EP9 0x0009 | ||
378 | #define M66592_EP10 0x000A | ||
379 | #define M66592_EP11 0x000B | ||
380 | #define M66592_EP12 0x000C | ||
381 | #define M66592_EP13 0x000D | ||
382 | #define M66592_EP14 0x000E | ||
383 | #define M66592_EP15 0x000F | ||
384 | |||
385 | #define M66592_PIPEBUF 0x68 | ||
386 | #define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ | ||
387 | #define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) | ||
388 | #define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ | ||
389 | |||
390 | #define M66592_PIPEMAXP 0x6A | ||
391 | #define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ | ||
392 | |||
393 | #define M66592_PIPEPERI 0x6C | ||
394 | #define M66592_IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ | ||
395 | #define M66592_IITV 0x0007 /* b2-0: Isochronous interval */ | ||
396 | |||
397 | #define M66592_PIPE1CTR 0x70 | ||
398 | #define M66592_PIPE2CTR 0x72 | ||
399 | #define M66592_PIPE3CTR 0x74 | ||
400 | #define M66592_PIPE4CTR 0x76 | ||
401 | #define M66592_PIPE5CTR 0x78 | ||
402 | #define M66592_PIPE6CTR 0x7A | ||
403 | #define M66592_PIPE7CTR 0x7C | ||
404 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | ||
405 | #define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ | ||
406 | #define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ | ||
407 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | ||
408 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | ||
409 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | ||
410 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | ||
411 | |||
412 | #define M66592_INVALID_REG 0x7E | ||
413 | |||
414 | |||
415 | #define __iomem | ||
416 | |||
417 | #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) | ||
418 | |||
419 | #define M66592_MAX_SAMPLING 10 | ||
420 | |||
421 | #define M66592_MAX_NUM_PIPE 8 | ||
422 | #define M66592_MAX_NUM_BULK 3 | ||
423 | #define M66592_MAX_NUM_ISOC 2 | ||
424 | #define M66592_MAX_NUM_INT 2 | ||
425 | |||
426 | #define M66592_BASE_PIPENUM_BULK 3 | ||
427 | #define M66592_BASE_PIPENUM_ISOC 1 | ||
428 | #define M66592_BASE_PIPENUM_INT 6 | ||
429 | |||
430 | #define M66592_BASE_BUFNUM 6 | ||
431 | #define M66592_MAX_BUFNUM 0x4F | ||
432 | |||
433 | struct m66592_pipe_info { | ||
434 | u16 pipe; | ||
435 | u16 epnum; | ||
436 | u16 maxpacket; | ||
437 | u16 type; | ||
438 | u16 interval; | ||
439 | u16 dir_in; | ||
440 | }; | ||
441 | |||
442 | struct m66592_request { | ||
443 | struct usb_request req; | ||
444 | struct list_head queue; | ||
445 | }; | ||
446 | |||
447 | struct m66592_ep { | ||
448 | struct usb_ep ep; | ||
449 | struct m66592 *m66592; | ||
450 | |||
451 | struct list_head queue; | ||
452 | unsigned busy:1; | ||
453 | unsigned internal_ccpl:1; /* use only control */ | ||
454 | |||
455 | /* this member can able to after m66592_enable */ | ||
456 | unsigned use_dma:1; | ||
457 | u16 pipenum; | ||
458 | u16 type; | ||
459 | const struct usb_endpoint_descriptor *desc; | ||
460 | /* register address */ | ||
461 | unsigned long fifoaddr; | ||
462 | unsigned long fifosel; | ||
463 | unsigned long fifoctr; | ||
464 | unsigned long fifotrn; | ||
465 | unsigned long pipectr; | ||
466 | }; | ||
467 | |||
468 | struct m66592 { | ||
469 | spinlock_t lock; | ||
470 | void __iomem *reg; | ||
471 | |||
472 | struct usb_gadget gadget; | ||
473 | struct usb_gadget_driver *driver; | ||
474 | |||
475 | struct m66592_ep ep[M66592_MAX_NUM_PIPE]; | ||
476 | struct m66592_ep *pipenum2ep[M66592_MAX_NUM_PIPE]; | ||
477 | struct m66592_ep *epaddr2ep[16]; | ||
478 | |||
479 | struct usb_request *ep0_req; /* for internal request */ | ||
480 | u16 *ep0_buf; /* for internal request */ | ||
481 | |||
482 | struct timer_list timer; | ||
483 | |||
484 | u16 old_vbus; | ||
485 | int scount; | ||
486 | |||
487 | int old_dvsq; | ||
488 | |||
489 | /* pipe config */ | ||
490 | int bulk; | ||
491 | int interrupt; | ||
492 | int isochronous; | ||
493 | int num_dma; | ||
494 | int bi_bufnum; /* bulk and isochronous's bufnum */ | ||
495 | }; | ||
496 | |||
497 | #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget) | ||
498 | #define m66592_to_gadget(m66592) (&m66592->gadget) | ||
499 | |||
500 | #define is_bulk_pipe(pipenum) \ | ||
501 | ((pipenum >= M66592_BASE_PIPENUM_BULK) && \ | ||
502 | (pipenum < (M66592_BASE_PIPENUM_BULK + M66592_MAX_NUM_BULK))) | ||
503 | #define is_interrupt_pipe(pipenum) \ | ||
504 | ((pipenum >= M66592_BASE_PIPENUM_INT) && \ | ||
505 | (pipenum < (M66592_BASE_PIPENUM_INT + M66592_MAX_NUM_INT))) | ||
506 | #define is_isoc_pipe(pipenum) \ | ||
507 | ((pipenum >= M66592_BASE_PIPENUM_ISOC) && \ | ||
508 | (pipenum < (M66592_BASE_PIPENUM_ISOC + M66592_MAX_NUM_ISOC))) | ||
509 | |||
510 | #define enable_irq_ready(m66592, pipenum) \ | ||
511 | enable_pipe_irq(m66592, pipenum, M66592_BRDYENB) | ||
512 | #define disable_irq_ready(m66592, pipenum) \ | ||
513 | disable_pipe_irq(m66592, pipenum, M66592_BRDYENB) | ||
514 | #define enable_irq_empty(m66592, pipenum) \ | ||
515 | enable_pipe_irq(m66592, pipenum, M66592_BEMPENB) | ||
516 | #define disable_irq_empty(m66592, pipenum) \ | ||
517 | disable_pipe_irq(m66592, pipenum, M66592_BEMPENB) | ||
518 | #define enable_irq_nrdy(m66592, pipenum) \ | ||
519 | enable_pipe_irq(m66592, pipenum, M66592_NRDYENB) | ||
520 | #define disable_irq_nrdy(m66592, pipenum) \ | ||
521 | disable_pipe_irq(m66592, pipenum, M66592_NRDYENB) | ||
522 | |||
523 | /*-------------------------------------------------------------------------*/ | ||
524 | static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) | ||
525 | { | ||
526 | return inw((unsigned long)m66592->reg + offset); | ||
527 | } | ||
528 | |||
529 | static inline void m66592_read_fifo(struct m66592 *m66592, | ||
530 | unsigned long offset, | ||
531 | void *buf, unsigned long len) | ||
532 | { | ||
533 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | ||
534 | |||
535 | len = (len + 1) / 2; | ||
536 | insw(fifoaddr, buf, len); | ||
537 | } | ||
538 | |||
539 | static inline void m66592_write(struct m66592 *m66592, u16 val, | ||
540 | unsigned long offset) | ||
541 | { | ||
542 | outw(val, (unsigned long)m66592->reg + offset); | ||
543 | } | ||
544 | |||
545 | static inline void m66592_write_fifo(struct m66592 *m66592, | ||
546 | unsigned long offset, | ||
547 | void *buf, unsigned long len) | ||
548 | { | ||
549 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | ||
550 | unsigned long odd = len & 0x0001; | ||
551 | |||
552 | len = len / 2; | ||
553 | outsw(fifoaddr, buf, len); | ||
554 | if (odd) { | ||
555 | unsigned char *p = buf + len*2; | ||
556 | outb(*p, fifoaddr); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | ||
561 | unsigned long offset) | ||
562 | { | ||
563 | u16 tmp; | ||
564 | tmp = m66592_read(m66592, offset); | ||
565 | tmp = tmp & (~pat); | ||
566 | tmp = tmp | val; | ||
567 | m66592_write(m66592, tmp, offset); | ||
568 | } | ||
569 | |||
570 | #define m66592_bclr(m66592, val, offset) \ | ||
571 | m66592_mdfy(m66592, 0, val, offset) | ||
572 | #define m66592_bset(m66592, val, offset) \ | ||
573 | m66592_mdfy(m66592, val, 0, offset) | ||
574 | |||
575 | #endif /* ifndef __M66592_UDC_H__ */ | ||
576 | |||
577 | |||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 00fda334dc72..c3d364ecd4f8 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -450,100 +450,6 @@ net2280_free_request (struct usb_ep *_ep, struct usb_request *_req) | |||
450 | 450 | ||
451 | /*-------------------------------------------------------------------------*/ | 451 | /*-------------------------------------------------------------------------*/ |
452 | 452 | ||
453 | /* | ||
454 | * dma-coherent memory allocation (for dma-capable endpoints) | ||
455 | * | ||
456 | * NOTE: the dma_*_coherent() API calls suck. Most implementations are | ||
457 | * (a) page-oriented, so small buffers lose big; and (b) asymmetric with | ||
458 | * respect to calls with irqs disabled: alloc is safe, free is not. | ||
459 | * We currently work around (b), but not (a). | ||
460 | */ | ||
461 | |||
462 | static void * | ||
463 | net2280_alloc_buffer ( | ||
464 | struct usb_ep *_ep, | ||
465 | unsigned bytes, | ||
466 | dma_addr_t *dma, | ||
467 | gfp_t gfp_flags | ||
468 | ) | ||
469 | { | ||
470 | void *retval; | ||
471 | struct net2280_ep *ep; | ||
472 | |||
473 | ep = container_of (_ep, struct net2280_ep, ep); | ||
474 | if (!_ep) | ||
475 | return NULL; | ||
476 | *dma = DMA_ADDR_INVALID; | ||
477 | |||
478 | if (ep->dma) | ||
479 | retval = dma_alloc_coherent(&ep->dev->pdev->dev, | ||
480 | bytes, dma, gfp_flags); | ||
481 | else | ||
482 | retval = kmalloc(bytes, gfp_flags); | ||
483 | return retval; | ||
484 | } | ||
485 | |||
486 | static DEFINE_SPINLOCK(buflock); | ||
487 | static LIST_HEAD(buffers); | ||
488 | |||
489 | struct free_record { | ||
490 | struct list_head list; | ||
491 | struct device *dev; | ||
492 | unsigned bytes; | ||
493 | dma_addr_t dma; | ||
494 | }; | ||
495 | |||
496 | static void do_free(unsigned long ignored) | ||
497 | { | ||
498 | spin_lock_irq(&buflock); | ||
499 | while (!list_empty(&buffers)) { | ||
500 | struct free_record *buf; | ||
501 | |||
502 | buf = list_entry(buffers.next, struct free_record, list); | ||
503 | list_del(&buf->list); | ||
504 | spin_unlock_irq(&buflock); | ||
505 | |||
506 | dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma); | ||
507 | |||
508 | spin_lock_irq(&buflock); | ||
509 | } | ||
510 | spin_unlock_irq(&buflock); | ||
511 | } | ||
512 | |||
513 | static DECLARE_TASKLET(deferred_free, do_free, 0); | ||
514 | |||
515 | static void | ||
516 | net2280_free_buffer ( | ||
517 | struct usb_ep *_ep, | ||
518 | void *address, | ||
519 | dma_addr_t dma, | ||
520 | unsigned bytes | ||
521 | ) { | ||
522 | /* free memory into the right allocator */ | ||
523 | if (dma != DMA_ADDR_INVALID) { | ||
524 | struct net2280_ep *ep; | ||
525 | struct free_record *buf = address; | ||
526 | unsigned long flags; | ||
527 | |||
528 | ep = container_of(_ep, struct net2280_ep, ep); | ||
529 | if (!_ep) | ||
530 | return; | ||
531 | |||
532 | ep = container_of (_ep, struct net2280_ep, ep); | ||
533 | buf->dev = &ep->dev->pdev->dev; | ||
534 | buf->bytes = bytes; | ||
535 | buf->dma = dma; | ||
536 | |||
537 | spin_lock_irqsave(&buflock, flags); | ||
538 | list_add_tail(&buf->list, &buffers); | ||
539 | tasklet_schedule(&deferred_free); | ||
540 | spin_unlock_irqrestore(&buflock, flags); | ||
541 | } else | ||
542 | kfree (address); | ||
543 | } | ||
544 | |||
545 | /*-------------------------------------------------------------------------*/ | ||
546 | |||
547 | /* load a packet into the fifo we use for usb IN transfers. | 453 | /* load a packet into the fifo we use for usb IN transfers. |
548 | * works for all endpoints. | 454 | * works for all endpoints. |
549 | * | 455 | * |
@@ -1392,9 +1298,6 @@ static const struct usb_ep_ops net2280_ep_ops = { | |||
1392 | .alloc_request = net2280_alloc_request, | 1298 | .alloc_request = net2280_alloc_request, |
1393 | .free_request = net2280_free_request, | 1299 | .free_request = net2280_free_request, |
1394 | 1300 | ||
1395 | .alloc_buffer = net2280_alloc_buffer, | ||
1396 | .free_buffer = net2280_free_buffer, | ||
1397 | |||
1398 | .queue = net2280_queue, | 1301 | .queue = net2280_queue, |
1399 | .dequeue = net2280_dequeue, | 1302 | .dequeue = net2280_dequeue, |
1400 | 1303 | ||
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index c4975a6cf777..9b0f0925dddf 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -296,111 +296,6 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
296 | 296 | ||
297 | /*-------------------------------------------------------------------------*/ | 297 | /*-------------------------------------------------------------------------*/ |
298 | 298 | ||
299 | /* | ||
300 | * dma-coherent memory allocation (for dma-capable endpoints) | ||
301 | * | ||
302 | * NOTE: the dma_*_coherent() API calls suck. Most implementations are | ||
303 | * (a) page-oriented, so small buffers lose big; and (b) asymmetric with | ||
304 | * respect to calls with irqs disabled: alloc is safe, free is not. | ||
305 | * We currently work around (b), but not (a). | ||
306 | */ | ||
307 | |||
308 | static void * | ||
309 | omap_alloc_buffer( | ||
310 | struct usb_ep *_ep, | ||
311 | unsigned bytes, | ||
312 | dma_addr_t *dma, | ||
313 | gfp_t gfp_flags | ||
314 | ) | ||
315 | { | ||
316 | void *retval; | ||
317 | struct omap_ep *ep; | ||
318 | |||
319 | if (!_ep) | ||
320 | return NULL; | ||
321 | |||
322 | ep = container_of(_ep, struct omap_ep, ep); | ||
323 | if (use_dma && ep->has_dma) { | ||
324 | static int warned; | ||
325 | if (!warned && bytes < PAGE_SIZE) { | ||
326 | dev_warn(ep->udc->gadget.dev.parent, | ||
327 | "using dma_alloc_coherent for " | ||
328 | "small allocations wastes memory\n"); | ||
329 | warned++; | ||
330 | } | ||
331 | return dma_alloc_coherent(ep->udc->gadget.dev.parent, | ||
332 | bytes, dma, gfp_flags); | ||
333 | } | ||
334 | |||
335 | retval = kmalloc(bytes, gfp_flags); | ||
336 | if (retval) | ||
337 | *dma = virt_to_phys(retval); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | static DEFINE_SPINLOCK(buflock); | ||
342 | static LIST_HEAD(buffers); | ||
343 | |||
344 | struct free_record { | ||
345 | struct list_head list; | ||
346 | struct device *dev; | ||
347 | unsigned bytes; | ||
348 | dma_addr_t dma; | ||
349 | }; | ||
350 | |||
351 | static void do_free(unsigned long ignored) | ||
352 | { | ||
353 | spin_lock_irq(&buflock); | ||
354 | while (!list_empty(&buffers)) { | ||
355 | struct free_record *buf; | ||
356 | |||
357 | buf = list_entry(buffers.next, struct free_record, list); | ||
358 | list_del(&buf->list); | ||
359 | spin_unlock_irq(&buflock); | ||
360 | |||
361 | dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma); | ||
362 | |||
363 | spin_lock_irq(&buflock); | ||
364 | } | ||
365 | spin_unlock_irq(&buflock); | ||
366 | } | ||
367 | |||
368 | static DECLARE_TASKLET(deferred_free, do_free, 0); | ||
369 | |||
370 | static void omap_free_buffer( | ||
371 | struct usb_ep *_ep, | ||
372 | void *buf, | ||
373 | dma_addr_t dma, | ||
374 | unsigned bytes | ||
375 | ) | ||
376 | { | ||
377 | if (!_ep) { | ||
378 | WARN_ON(1); | ||
379 | return; | ||
380 | } | ||
381 | |||
382 | /* free memory into the right allocator */ | ||
383 | if (dma != DMA_ADDR_INVALID) { | ||
384 | struct omap_ep *ep; | ||
385 | struct free_record *rec = buf; | ||
386 | unsigned long flags; | ||
387 | |||
388 | ep = container_of(_ep, struct omap_ep, ep); | ||
389 | |||
390 | rec->dev = ep->udc->gadget.dev.parent; | ||
391 | rec->bytes = bytes; | ||
392 | rec->dma = dma; | ||
393 | |||
394 | spin_lock_irqsave(&buflock, flags); | ||
395 | list_add_tail(&rec->list, &buffers); | ||
396 | tasklet_schedule(&deferred_free); | ||
397 | spin_unlock_irqrestore(&buflock, flags); | ||
398 | } else | ||
399 | kfree(buf); | ||
400 | } | ||
401 | |||
402 | /*-------------------------------------------------------------------------*/ | ||
403 | |||
404 | static void | 299 | static void |
405 | done(struct omap_ep *ep, struct omap_req *req, int status) | 300 | done(struct omap_ep *ep, struct omap_req *req, int status) |
406 | { | 301 | { |
@@ -1271,9 +1166,6 @@ static struct usb_ep_ops omap_ep_ops = { | |||
1271 | .alloc_request = omap_alloc_request, | 1166 | .alloc_request = omap_alloc_request, |
1272 | .free_request = omap_free_request, | 1167 | .free_request = omap_free_request, |
1273 | 1168 | ||
1274 | .alloc_buffer = omap_alloc_buffer, | ||
1275 | .free_buffer = omap_free_buffer, | ||
1276 | |||
1277 | .queue = omap_ep_queue, | 1169 | .queue = omap_ep_queue, |
1278 | .dequeue = omap_ep_dequeue, | 1170 | .dequeue = omap_ep_dequeue, |
1279 | 1171 | ||
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 84392e835d5f..63b9521c1322 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -24,9 +24,9 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #undef DEBUG | ||
28 | // #define VERBOSE DBG_VERBOSE | 27 | // #define VERBOSE DBG_VERBOSE |
29 | 28 | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
@@ -46,19 +46,17 @@ | |||
46 | 46 | ||
47 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
48 | #include <asm/dma.h> | 48 | #include <asm/dma.h> |
49 | #include <asm/gpio.h> | ||
49 | #include <asm/io.h> | 50 | #include <asm/io.h> |
50 | #include <asm/system.h> | 51 | #include <asm/system.h> |
51 | #include <asm/mach-types.h> | 52 | #include <asm/mach-types.h> |
52 | #include <asm/unaligned.h> | 53 | #include <asm/unaligned.h> |
53 | #include <asm/hardware.h> | 54 | #include <asm/hardware.h> |
54 | #ifdef CONFIG_ARCH_PXA | ||
55 | #include <asm/arch/pxa-regs.h> | ||
56 | #endif | ||
57 | 55 | ||
58 | #include <linux/usb/ch9.h> | 56 | #include <linux/usb/ch9.h> |
59 | #include <linux/usb_gadget.h> | 57 | #include <linux/usb_gadget.h> |
60 | 58 | ||
61 | #include <asm/arch/udc.h> | 59 | #include <asm/mach/udc_pxa2xx.h> |
62 | 60 | ||
63 | 61 | ||
64 | /* | 62 | /* |
@@ -76,9 +74,17 @@ | |||
76 | * it constrains the sorts of USB configuration change events that work. | 74 | * it constrains the sorts of USB configuration change events that work. |
77 | * The errata for these chips are misleading; some "fixed" bugs from | 75 | * The errata for these chips are misleading; some "fixed" bugs from |
78 | * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. | 76 | * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. |
77 | * | ||
78 | * Note that the UDC hardware supports DMA (except on IXP) but that's | ||
79 | * not used here. IN-DMA (to host) is simple enough, when the data is | ||
80 | * suitably aligned (16 bytes) ... the network stack doesn't do that, | ||
81 | * other software can. OUT-DMA is buggy in most chip versions, as well | ||
82 | * as poorly designed (data toggle not automatic). So this driver won't | ||
83 | * bother using DMA. (Mostly-working IN-DMA support was available in | ||
84 | * kernels before 2.6.23, but was never enabled or well tested.) | ||
79 | */ | 85 | */ |
80 | 86 | ||
81 | #define DRIVER_VERSION "4-May-2005" | 87 | #define DRIVER_VERSION "30-June-2007" |
82 | #define DRIVER_DESC "PXA 25x USB Device Controller driver" | 88 | #define DRIVER_DESC "PXA 25x USB Device Controller driver" |
83 | 89 | ||
84 | 90 | ||
@@ -87,12 +93,9 @@ static const char driver_name [] = "pxa2xx_udc"; | |||
87 | static const char ep0name [] = "ep0"; | 93 | static const char ep0name [] = "ep0"; |
88 | 94 | ||
89 | 95 | ||
90 | // #define USE_DMA | ||
91 | // #define USE_OUT_DMA | ||
92 | // #define DISABLE_TEST_MODE | 96 | // #define DISABLE_TEST_MODE |
93 | 97 | ||
94 | #ifdef CONFIG_ARCH_IXP4XX | 98 | #ifdef CONFIG_ARCH_IXP4XX |
95 | #undef USE_DMA | ||
96 | 99 | ||
97 | /* cpu-specific register addresses are compiled in to this code */ | 100 | /* cpu-specific register addresses are compiled in to this code */ |
98 | #ifdef CONFIG_ARCH_PXA | 101 | #ifdef CONFIG_ARCH_PXA |
@@ -104,25 +107,6 @@ static const char ep0name [] = "ep0"; | |||
104 | #include "pxa2xx_udc.h" | 107 | #include "pxa2xx_udc.h" |
105 | 108 | ||
106 | 109 | ||
107 | #ifdef USE_DMA | ||
108 | static int use_dma = 1; | ||
109 | module_param(use_dma, bool, 0); | ||
110 | MODULE_PARM_DESC (use_dma, "true to use dma"); | ||
111 | |||
112 | static void dma_nodesc_handler (int dmach, void *_ep); | ||
113 | static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req); | ||
114 | |||
115 | #ifdef USE_OUT_DMA | ||
116 | #define DMASTR " (dma support)" | ||
117 | #else | ||
118 | #define DMASTR " (dma in)" | ||
119 | #endif | ||
120 | |||
121 | #else /* !USE_DMA */ | ||
122 | #define DMASTR " (pio only)" | ||
123 | #undef USE_OUT_DMA | ||
124 | #endif | ||
125 | |||
126 | #ifdef CONFIG_USB_PXA2XX_SMALL | 110 | #ifdef CONFIG_USB_PXA2XX_SMALL |
127 | #define SIZE_STR " (small)" | 111 | #define SIZE_STR " (small)" |
128 | #else | 112 | #else |
@@ -155,7 +139,7 @@ static int is_vbus_present(void) | |||
155 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 139 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
156 | 140 | ||
157 | if (mach->gpio_vbus) | 141 | if (mach->gpio_vbus) |
158 | return udc_gpio_get(mach->gpio_vbus); | 142 | return gpio_get_value(mach->gpio_vbus); |
159 | if (mach->udc_is_connected) | 143 | if (mach->udc_is_connected) |
160 | return mach->udc_is_connected(); | 144 | return mach->udc_is_connected(); |
161 | return 1; | 145 | return 1; |
@@ -167,7 +151,7 @@ static void pullup_off(void) | |||
167 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 151 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
168 | 152 | ||
169 | if (mach->gpio_pullup) | 153 | if (mach->gpio_pullup) |
170 | udc_gpio_set(mach->gpio_pullup, 0); | 154 | gpio_set_value(mach->gpio_pullup, 0); |
171 | else if (mach->udc_command) | 155 | else if (mach->udc_command) |
172 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 156 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); |
173 | } | 157 | } |
@@ -177,7 +161,7 @@ static void pullup_on(void) | |||
177 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 161 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
178 | 162 | ||
179 | if (mach->gpio_pullup) | 163 | if (mach->gpio_pullup) |
180 | udc_gpio_set(mach->gpio_pullup, 1); | 164 | gpio_set_value(mach->gpio_pullup, 1); |
181 | else if (mach->udc_command) | 165 | else if (mach->udc_command) |
182 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | 166 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); |
183 | } | 167 | } |
@@ -281,9 +265,8 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, | |||
281 | } | 265 | } |
282 | 266 | ||
283 | ep->desc = desc; | 267 | ep->desc = desc; |
284 | ep->dma = -1; | ||
285 | ep->stopped = 0; | 268 | ep->stopped = 0; |
286 | ep->pio_irqs = ep->dma_irqs = 0; | 269 | ep->pio_irqs = 0; |
287 | ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); | 270 | ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); |
288 | 271 | ||
289 | /* flush fifo (mostly for OUT buffers) */ | 272 | /* flush fifo (mostly for OUT buffers) */ |
@@ -291,30 +274,6 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, | |||
291 | 274 | ||
292 | /* ... reset halt state too, if we could ... */ | 275 | /* ... reset halt state too, if we could ... */ |
293 | 276 | ||
294 | #ifdef USE_DMA | ||
295 | /* for (some) bulk and ISO endpoints, try to get a DMA channel and | ||
296 | * bind it to the endpoint. otherwise use PIO. | ||
297 | */ | ||
298 | switch (ep->bmAttributes) { | ||
299 | case USB_ENDPOINT_XFER_ISOC: | ||
300 | if (le16_to_cpu(desc->wMaxPacketSize) % 32) | ||
301 | break; | ||
302 | // fall through | ||
303 | case USB_ENDPOINT_XFER_BULK: | ||
304 | if (!use_dma || !ep->reg_drcmr) | ||
305 | break; | ||
306 | ep->dma = pxa_request_dma ((char *)_ep->name, | ||
307 | (le16_to_cpu (desc->wMaxPacketSize) > 64) | ||
308 | ? DMA_PRIO_MEDIUM /* some iso */ | ||
309 | : DMA_PRIO_LOW, | ||
310 | dma_nodesc_handler, ep); | ||
311 | if (ep->dma >= 0) { | ||
312 | *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma; | ||
313 | DMSG("%s using dma%d\n", _ep->name, ep->dma); | ||
314 | } | ||
315 | } | ||
316 | #endif | ||
317 | |||
318 | DBG(DBG_VERBOSE, "enabled %s\n", _ep->name); | 277 | DBG(DBG_VERBOSE, "enabled %s\n", _ep->name); |
319 | return 0; | 278 | return 0; |
320 | } | 279 | } |
@@ -334,14 +293,6 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) | |||
334 | 293 | ||
335 | nuke (ep, -ESHUTDOWN); | 294 | nuke (ep, -ESHUTDOWN); |
336 | 295 | ||
337 | #ifdef USE_DMA | ||
338 | if (ep->dma >= 0) { | ||
339 | *ep->reg_drcmr = 0; | ||
340 | pxa_free_dma (ep->dma); | ||
341 | ep->dma = -1; | ||
342 | } | ||
343 | #endif | ||
344 | |||
345 | /* flush fifo (mostly for IN buffers) */ | 296 | /* flush fifo (mostly for IN buffers) */ |
346 | pxa2xx_ep_fifo_flush (_ep); | 297 | pxa2xx_ep_fifo_flush (_ep); |
347 | 298 | ||
@@ -390,35 +341,6 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) | |||
390 | kfree(req); | 341 | kfree(req); |
391 | } | 342 | } |
392 | 343 | ||
393 | |||
394 | /* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's | ||
395 | * no device-affinity and the heap works perfectly well for i/o buffers. | ||
396 | * It wastes much less memory than dma_alloc_coherent() would, and even | ||
397 | * prevents cacheline (32 bytes wide) sharing problems. | ||
398 | */ | ||
399 | static void * | ||
400 | pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | ||
401 | dma_addr_t *dma, gfp_t gfp_flags) | ||
402 | { | ||
403 | char *retval; | ||
404 | |||
405 | retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM)); | ||
406 | if (retval) | ||
407 | #ifdef USE_DMA | ||
408 | *dma = virt_to_bus (retval); | ||
409 | #else | ||
410 | *dma = (dma_addr_t)~0; | ||
411 | #endif | ||
412 | return retval; | ||
413 | } | ||
414 | |||
415 | static void | ||
416 | pxa2xx_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, | ||
417 | unsigned bytes) | ||
418 | { | ||
419 | kfree (buf); | ||
420 | } | ||
421 | |||
422 | /*-------------------------------------------------------------------------*/ | 344 | /*-------------------------------------------------------------------------*/ |
423 | 345 | ||
424 | /* | 346 | /* |
@@ -518,18 +440,8 @@ write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) | |||
518 | /* requests complete when all IN data is in the FIFO */ | 440 | /* requests complete when all IN data is in the FIFO */ |
519 | if (is_last) { | 441 | if (is_last) { |
520 | done (ep, req, 0); | 442 | done (ep, req, 0); |
521 | if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) { | 443 | if (list_empty(&ep->queue)) |
522 | pio_irq_disable (ep->bEndpointAddress); | 444 | pio_irq_disable (ep->bEndpointAddress); |
523 | #ifdef USE_DMA | ||
524 | /* unaligned data and zlps couldn't use dma */ | ||
525 | if (unlikely(!list_empty(&ep->queue))) { | ||
526 | req = list_entry(ep->queue.next, | ||
527 | struct pxa2xx_request, queue); | ||
528 | kick_dma(ep,req); | ||
529 | return 0; | ||
530 | } | ||
531 | #endif | ||
532 | } | ||
533 | return 1; | 445 | return 1; |
534 | } | 446 | } |
535 | 447 | ||
@@ -728,182 +640,6 @@ read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) | |||
728 | return 0; | 640 | return 0; |
729 | } | 641 | } |
730 | 642 | ||
731 | #ifdef USE_DMA | ||
732 | |||
733 | #define MAX_IN_DMA ((DCMD_LENGTH + 1) - BULK_FIFO_SIZE) | ||
734 | |||
735 | static void | ||
736 | start_dma_nodesc(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int is_in) | ||
737 | { | ||
738 | u32 dcmd = req->req.length; | ||
739 | u32 buf = req->req.dma; | ||
740 | u32 fifo = io_v2p ((u32)ep->reg_uddr); | ||
741 | |||
742 | /* caller guarantees there's a packet or more remaining | ||
743 | * - IN may end with a short packet (TSP set separately), | ||
744 | * - OUT is always full length | ||
745 | */ | ||
746 | buf += req->req.actual; | ||
747 | dcmd -= req->req.actual; | ||
748 | ep->dma_fixup = 0; | ||
749 | |||
750 | /* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */ | ||
751 | DCSR(ep->dma) = DCSR_NODESC; | ||
752 | if (is_in) { | ||
753 | DSADR(ep->dma) = buf; | ||
754 | DTADR(ep->dma) = fifo; | ||
755 | if (dcmd > MAX_IN_DMA) | ||
756 | dcmd = MAX_IN_DMA; | ||
757 | else | ||
758 | ep->dma_fixup = (dcmd % ep->ep.maxpacket) != 0; | ||
759 | dcmd |= DCMD_BURST32 | DCMD_WIDTH1 | ||
760 | | DCMD_FLOWTRG | DCMD_INCSRCADDR; | ||
761 | } else { | ||
762 | #ifdef USE_OUT_DMA | ||
763 | DSADR(ep->dma) = fifo; | ||
764 | DTADR(ep->dma) = buf; | ||
765 | if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC) | ||
766 | dcmd = ep->ep.maxpacket; | ||
767 | dcmd |= DCMD_BURST32 | DCMD_WIDTH1 | ||
768 | | DCMD_FLOWSRC | DCMD_INCTRGADDR; | ||
769 | #endif | ||
770 | } | ||
771 | DCMD(ep->dma) = dcmd; | ||
772 | DCSR(ep->dma) = DCSR_RUN | DCSR_NODESC | ||
773 | | (unlikely(is_in) | ||
774 | ? DCSR_STOPIRQEN /* use dma_nodesc_handler() */ | ||
775 | : 0); /* use handle_ep() */ | ||
776 | } | ||
777 | |||
778 | static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req) | ||
779 | { | ||
780 | int is_in = ep->bEndpointAddress & USB_DIR_IN; | ||
781 | |||
782 | if (is_in) { | ||
783 | /* unaligned tx buffers and zlps only work with PIO */ | ||
784 | if ((req->req.dma & 0x0f) != 0 | ||
785 | || unlikely((req->req.length - req->req.actual) | ||
786 | == 0)) { | ||
787 | pio_irq_enable(ep->bEndpointAddress); | ||
788 | if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0) | ||
789 | (void) write_fifo(ep, req); | ||
790 | } else { | ||
791 | start_dma_nodesc(ep, req, USB_DIR_IN); | ||
792 | } | ||
793 | } else { | ||
794 | if ((req->req.length - req->req.actual) < ep->ep.maxpacket) { | ||
795 | DMSG("%s short dma read...\n", ep->ep.name); | ||
796 | /* we're always set up for pio out */ | ||
797 | read_fifo (ep, req); | ||
798 | } else { | ||
799 | *ep->reg_udccs = UDCCS_BO_DME | ||
800 | | (*ep->reg_udccs & UDCCS_BO_FST); | ||
801 | start_dma_nodesc(ep, req, USB_DIR_OUT); | ||
802 | } | ||
803 | } | ||
804 | } | ||
805 | |||
806 | static void cancel_dma(struct pxa2xx_ep *ep) | ||
807 | { | ||
808 | struct pxa2xx_request *req; | ||
809 | u32 tmp; | ||
810 | |||
811 | if (DCSR(ep->dma) == 0 || list_empty(&ep->queue)) | ||
812 | return; | ||
813 | |||
814 | DCSR(ep->dma) = 0; | ||
815 | while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0) | ||
816 | cpu_relax(); | ||
817 | |||
818 | req = list_entry(ep->queue.next, struct pxa2xx_request, queue); | ||
819 | tmp = DCMD(ep->dma) & DCMD_LENGTH; | ||
820 | req->req.actual = req->req.length - (tmp & DCMD_LENGTH); | ||
821 | |||
822 | /* the last tx packet may be incomplete, so flush the fifo. | ||
823 | * FIXME correct req.actual if we can | ||
824 | */ | ||
825 | if (ep->bEndpointAddress & USB_DIR_IN) | ||
826 | *ep->reg_udccs = UDCCS_BI_FTF; | ||
827 | } | ||
828 | |||
829 | /* dma channel stopped ... normal tx end (IN), or on error (IN/OUT) */ | ||
830 | static void dma_nodesc_handler(int dmach, void *_ep) | ||
831 | { | ||
832 | struct pxa2xx_ep *ep = _ep; | ||
833 | struct pxa2xx_request *req; | ||
834 | u32 tmp, completed; | ||
835 | |||
836 | local_irq_disable(); | ||
837 | |||
838 | req = list_entry(ep->queue.next, struct pxa2xx_request, queue); | ||
839 | |||
840 | ep->dma_irqs++; | ||
841 | ep->dev->stats.irqs++; | ||
842 | HEX_DISPLAY(ep->dev->stats.irqs); | ||
843 | |||
844 | /* ack/clear */ | ||
845 | tmp = DCSR(ep->dma); | ||
846 | DCSR(ep->dma) = tmp; | ||
847 | if ((tmp & DCSR_STOPSTATE) == 0 | ||
848 | || (DDADR(ep->dma) & DDADR_STOP) != 0) { | ||
849 | DBG(DBG_VERBOSE, "%s, dcsr %08x ddadr %08x\n", | ||
850 | ep->ep.name, DCSR(ep->dma), DDADR(ep->dma)); | ||
851 | goto done; | ||
852 | } | ||
853 | DCSR(ep->dma) = 0; /* clear DCSR_STOPSTATE */ | ||
854 | |||
855 | /* update transfer status */ | ||
856 | completed = tmp & DCSR_BUSERR; | ||
857 | if (ep->bEndpointAddress & USB_DIR_IN) | ||
858 | tmp = DSADR(ep->dma); | ||
859 | else | ||
860 | tmp = DTADR(ep->dma); | ||
861 | req->req.actual = tmp - req->req.dma; | ||
862 | |||
863 | /* FIXME seems we sometimes see partial transfers... */ | ||
864 | |||
865 | if (unlikely(completed != 0)) | ||
866 | req->req.status = -EIO; | ||
867 | else if (req->req.actual) { | ||
868 | /* these registers have zeroes in low bits; they miscount | ||
869 | * some (end-of-transfer) short packets: tx 14 as tx 12 | ||
870 | */ | ||
871 | if (ep->dma_fixup) | ||
872 | req->req.actual = min(req->req.actual + 3, | ||
873 | req->req.length); | ||
874 | |||
875 | tmp = (req->req.length - req->req.actual); | ||
876 | completed = (tmp == 0); | ||
877 | if (completed && (ep->bEndpointAddress & USB_DIR_IN)) { | ||
878 | |||
879 | /* maybe validate final short packet ... */ | ||
880 | if ((req->req.actual % ep->ep.maxpacket) != 0) | ||
881 | *ep->reg_udccs = UDCCS_BI_TSP/*|UDCCS_BI_TPC*/; | ||
882 | |||
883 | /* ... or zlp, using pio fallback */ | ||
884 | else if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK | ||
885 | && req->req.zero) { | ||
886 | DMSG("%s zlp terminate ...\n", ep->ep.name); | ||
887 | completed = 0; | ||
888 | } | ||
889 | } | ||
890 | } | ||
891 | |||
892 | if (likely(completed)) { | ||
893 | done(ep, req, 0); | ||
894 | |||
895 | /* maybe re-activate after completion */ | ||
896 | if (ep->stopped || list_empty(&ep->queue)) | ||
897 | goto done; | ||
898 | req = list_entry(ep->queue.next, struct pxa2xx_request, queue); | ||
899 | } | ||
900 | kick_dma(ep, req); | ||
901 | done: | ||
902 | local_irq_enable(); | ||
903 | } | ||
904 | |||
905 | #endif | ||
906 | |||
907 | /*-------------------------------------------------------------------------*/ | 643 | /*-------------------------------------------------------------------------*/ |
908 | 644 | ||
909 | static int | 645 | static int |
@@ -942,19 +678,8 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
942 | (ep->desc->wMaxPacketSize))) | 678 | (ep->desc->wMaxPacketSize))) |
943 | return -EMSGSIZE; | 679 | return -EMSGSIZE; |
944 | 680 | ||
945 | #ifdef USE_DMA | ||
946 | // FIXME caller may already have done the dma mapping | ||
947 | if (ep->dma >= 0) { | ||
948 | _req->dma = dma_map_single(dev->dev, | ||
949 | _req->buf, _req->length, | ||
950 | ((ep->bEndpointAddress & USB_DIR_IN) != 0) | ||
951 | ? DMA_TO_DEVICE | ||
952 | : DMA_FROM_DEVICE); | ||
953 | } | ||
954 | #endif | ||
955 | |||
956 | DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", | 681 | DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", |
957 | _ep->name, _req, _req->length, _req->buf); | 682 | _ep->name, _req, _req->length, _req->buf); |
958 | 683 | ||
959 | local_irq_save(flags); | 684 | local_irq_save(flags); |
960 | 685 | ||
@@ -1002,11 +727,6 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1002 | local_irq_restore (flags); | 727 | local_irq_restore (flags); |
1003 | return -EL2HLT; | 728 | return -EL2HLT; |
1004 | } | 729 | } |
1005 | #ifdef USE_DMA | ||
1006 | /* either start dma or prime pio pump */ | ||
1007 | } else if (ep->dma >= 0) { | ||
1008 | kick_dma(ep, req); | ||
1009 | #endif | ||
1010 | /* can the FIFO can satisfy the request immediately? */ | 730 | /* can the FIFO can satisfy the request immediately? */ |
1011 | } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { | 731 | } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { |
1012 | if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0 | 732 | if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0 |
@@ -1017,7 +737,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1017 | req = NULL; | 737 | req = NULL; |
1018 | } | 738 | } |
1019 | 739 | ||
1020 | if (likely (req && ep->desc) && ep->dma < 0) | 740 | if (likely (req && ep->desc)) |
1021 | pio_irq_enable(ep->bEndpointAddress); | 741 | pio_irq_enable(ep->bEndpointAddress); |
1022 | } | 742 | } |
1023 | 743 | ||
@@ -1038,10 +758,6 @@ static void nuke(struct pxa2xx_ep *ep, int status) | |||
1038 | struct pxa2xx_request *req; | 758 | struct pxa2xx_request *req; |
1039 | 759 | ||
1040 | /* called with irqs blocked */ | 760 | /* called with irqs blocked */ |
1041 | #ifdef USE_DMA | ||
1042 | if (ep->dma >= 0 && !ep->stopped) | ||
1043 | cancel_dma(ep); | ||
1044 | #endif | ||
1045 | while (!list_empty(&ep->queue)) { | 761 | while (!list_empty(&ep->queue)) { |
1046 | req = list_entry(ep->queue.next, | 762 | req = list_entry(ep->queue.next, |
1047 | struct pxa2xx_request, | 763 | struct pxa2xx_request, |
@@ -1076,19 +792,7 @@ static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1076 | return -EINVAL; | 792 | return -EINVAL; |
1077 | } | 793 | } |
1078 | 794 | ||
1079 | #ifdef USE_DMA | 795 | done(ep, req, -ECONNRESET); |
1080 | if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) { | ||
1081 | cancel_dma(ep); | ||
1082 | done(ep, req, -ECONNRESET); | ||
1083 | /* restart i/o */ | ||
1084 | if (!list_empty(&ep->queue)) { | ||
1085 | req = list_entry(ep->queue.next, | ||
1086 | struct pxa2xx_request, queue); | ||
1087 | kick_dma(ep, req); | ||
1088 | } | ||
1089 | } else | ||
1090 | #endif | ||
1091 | done(ep, req, -ECONNRESET); | ||
1092 | 796 | ||
1093 | local_irq_restore(flags); | 797 | local_irq_restore(flags); |
1094 | return 0; | 798 | return 0; |
@@ -1203,9 +907,6 @@ static struct usb_ep_ops pxa2xx_ep_ops = { | |||
1203 | .alloc_request = pxa2xx_ep_alloc_request, | 907 | .alloc_request = pxa2xx_ep_alloc_request, |
1204 | .free_request = pxa2xx_ep_free_request, | 908 | .free_request = pxa2xx_ep_free_request, |
1205 | 909 | ||
1206 | .alloc_buffer = pxa2xx_ep_alloc_buffer, | ||
1207 | .free_buffer = pxa2xx_ep_free_buffer, | ||
1208 | |||
1209 | .queue = pxa2xx_ep_queue, | 910 | .queue = pxa2xx_ep_queue, |
1210 | .dequeue = pxa2xx_ep_dequeue, | 911 | .dequeue = pxa2xx_ep_dequeue, |
1211 | 912 | ||
@@ -1325,7 +1026,7 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1325 | /* basic device status */ | 1026 | /* basic device status */ |
1326 | t = scnprintf(next, size, DRIVER_DESC "\n" | 1027 | t = scnprintf(next, size, DRIVER_DESC "\n" |
1327 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", | 1028 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", |
1328 | driver_name, DRIVER_VERSION SIZE_STR DMASTR, | 1029 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", |
1329 | dev->driver ? dev->driver->driver.name : "(none)", | 1030 | dev->driver ? dev->driver->driver.name : "(none)", |
1330 | is_vbus_present() ? "full speed" : "disconnected"); | 1031 | is_vbus_present() ? "full speed" : "disconnected"); |
1331 | size -= t; | 1032 | size -= t; |
@@ -1390,7 +1091,6 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1390 | for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { | 1091 | for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { |
1391 | struct pxa2xx_ep *ep = &dev->ep [i]; | 1092 | struct pxa2xx_ep *ep = &dev->ep [i]; |
1392 | struct pxa2xx_request *req; | 1093 | struct pxa2xx_request *req; |
1393 | int t; | ||
1394 | 1094 | ||
1395 | if (i != 0) { | 1095 | if (i != 0) { |
1396 | const struct usb_endpoint_descriptor *d; | 1096 | const struct usb_endpoint_descriptor *d; |
@@ -1400,10 +1100,9 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1400 | continue; | 1100 | continue; |
1401 | tmp = *dev->ep [i].reg_udccs; | 1101 | tmp = *dev->ep [i].reg_udccs; |
1402 | t = scnprintf(next, size, | 1102 | t = scnprintf(next, size, |
1403 | "%s max %d %s udccs %02x irqs %lu/%lu\n", | 1103 | "%s max %d %s udccs %02x irqs %lu\n", |
1404 | ep->ep.name, le16_to_cpu (d->wMaxPacketSize), | 1104 | ep->ep.name, le16_to_cpu (d->wMaxPacketSize), |
1405 | (ep->dma >= 0) ? "dma" : "pio", tmp, | 1105 | "pio", tmp, ep->pio_irqs); |
1406 | ep->pio_irqs, ep->dma_irqs); | ||
1407 | /* TODO translate all five groups of udccs bits! */ | 1106 | /* TODO translate all five groups of udccs bits! */ |
1408 | 1107 | ||
1409 | } else /* ep0 should only have one transfer queued */ | 1108 | } else /* ep0 should only have one transfer queued */ |
@@ -1423,19 +1122,7 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1423 | continue; | 1122 | continue; |
1424 | } | 1123 | } |
1425 | list_for_each_entry(req, &ep->queue, queue) { | 1124 | list_for_each_entry(req, &ep->queue, queue) { |
1426 | #ifdef USE_DMA | 1125 | t = scnprintf(next, size, |
1427 | if (ep->dma >= 0 && req->queue.prev == &ep->queue) | ||
1428 | t = scnprintf(next, size, | ||
1429 | "\treq %p len %d/%d " | ||
1430 | "buf %p (dma%d dcmd %08x)\n", | ||
1431 | &req->req, req->req.actual, | ||
1432 | req->req.length, req->req.buf, | ||
1433 | ep->dma, DCMD(ep->dma) | ||
1434 | // low 13 bits == bytes-to-go | ||
1435 | ); | ||
1436 | else | ||
1437 | #endif | ||
1438 | t = scnprintf(next, size, | ||
1439 | "\treq %p len %d/%d buf %p\n", | 1126 | "\treq %p len %d/%d buf %p\n", |
1440 | &req->req, req->req.actual, | 1127 | &req->req, req->req.actual, |
1441 | req->req.length, req->req.buf); | 1128 | req->req.length, req->req.buf); |
@@ -1488,7 +1175,6 @@ static void udc_disable(struct pxa2xx_udc *dev) | |||
1488 | 1175 | ||
1489 | ep0_idle (dev); | 1176 | ep0_idle (dev); |
1490 | dev->gadget.speed = USB_SPEED_UNKNOWN; | 1177 | dev->gadget.speed = USB_SPEED_UNKNOWN; |
1491 | LED_CONNECTED_OFF; | ||
1492 | } | 1178 | } |
1493 | 1179 | ||
1494 | 1180 | ||
@@ -1514,7 +1200,7 @@ static void udc_reinit(struct pxa2xx_udc *dev) | |||
1514 | ep->desc = NULL; | 1200 | ep->desc = NULL; |
1515 | ep->stopped = 0; | 1201 | ep->stopped = 0; |
1516 | INIT_LIST_HEAD (&ep->queue); | 1202 | INIT_LIST_HEAD (&ep->queue); |
1517 | ep->pio_irqs = ep->dma_irqs = 0; | 1203 | ep->pio_irqs = 0; |
1518 | } | 1204 | } |
1519 | 1205 | ||
1520 | /* the rest was statically initialized, and is read-only */ | 1206 | /* the rest was statically initialized, and is read-only */ |
@@ -1666,7 +1352,6 @@ stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver) | |||
1666 | del_timer_sync(&dev->timer); | 1352 | del_timer_sync(&dev->timer); |
1667 | 1353 | ||
1668 | /* report disconnect; the driver is already quiesced */ | 1354 | /* report disconnect; the driver is already quiesced */ |
1669 | LED_CONNECTED_OFF; | ||
1670 | if (driver) | 1355 | if (driver) |
1671 | driver->disconnect(&dev->gadget); | 1356 | driver->disconnect(&dev->gadget); |
1672 | 1357 | ||
@@ -1715,16 +1400,13 @@ lubbock_vbus_irq(int irq, void *_dev) | |||
1715 | int vbus; | 1400 | int vbus; |
1716 | 1401 | ||
1717 | dev->stats.irqs++; | 1402 | dev->stats.irqs++; |
1718 | HEX_DISPLAY(dev->stats.irqs); | ||
1719 | switch (irq) { | 1403 | switch (irq) { |
1720 | case LUBBOCK_USB_IRQ: | 1404 | case LUBBOCK_USB_IRQ: |
1721 | LED_CONNECTED_ON; | ||
1722 | vbus = 1; | 1405 | vbus = 1; |
1723 | disable_irq(LUBBOCK_USB_IRQ); | 1406 | disable_irq(LUBBOCK_USB_IRQ); |
1724 | enable_irq(LUBBOCK_USB_DISC_IRQ); | 1407 | enable_irq(LUBBOCK_USB_DISC_IRQ); |
1725 | break; | 1408 | break; |
1726 | case LUBBOCK_USB_DISC_IRQ: | 1409 | case LUBBOCK_USB_DISC_IRQ: |
1727 | LED_CONNECTED_OFF; | ||
1728 | vbus = 0; | 1410 | vbus = 0; |
1729 | disable_irq(LUBBOCK_USB_DISC_IRQ); | 1411 | disable_irq(LUBBOCK_USB_DISC_IRQ); |
1730 | enable_irq(LUBBOCK_USB_IRQ); | 1412 | enable_irq(LUBBOCK_USB_IRQ); |
@@ -1742,7 +1424,7 @@ lubbock_vbus_irq(int irq, void *_dev) | |||
1742 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) | 1424 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) |
1743 | { | 1425 | { |
1744 | struct pxa2xx_udc *dev = _dev; | 1426 | struct pxa2xx_udc *dev = _dev; |
1745 | int vbus = udc_gpio_get(dev->mach->gpio_vbus); | 1427 | int vbus = gpio_get_value(dev->mach->gpio_vbus); |
1746 | 1428 | ||
1747 | pxa2xx_udc_vbus_session(&dev->gadget, vbus); | 1429 | pxa2xx_udc_vbus_session(&dev->gadget, vbus); |
1748 | return IRQ_HANDLED; | 1430 | return IRQ_HANDLED; |
@@ -2040,18 +1722,6 @@ static void handle_ep(struct pxa2xx_ep *ep) | |||
2040 | 1722 | ||
2041 | /* fifos can hold packets, ready for reading... */ | 1723 | /* fifos can hold packets, ready for reading... */ |
2042 | if (likely(req)) { | 1724 | if (likely(req)) { |
2043 | #ifdef USE_OUT_DMA | ||
2044 | // TODO didn't yet debug out-dma. this approach assumes | ||
2045 | // the worst about short packets and RPC; it might be better. | ||
2046 | |||
2047 | if (likely(ep->dma >= 0)) { | ||
2048 | if (!(udccs & UDCCS_BO_RSP)) { | ||
2049 | *ep->reg_udccs = UDCCS_BO_RPC; | ||
2050 | ep->dma_irqs++; | ||
2051 | return; | ||
2052 | } | ||
2053 | } | ||
2054 | #endif | ||
2055 | completed = read_fifo(ep, req); | 1725 | completed = read_fifo(ep, req); |
2056 | } else | 1726 | } else |
2057 | pio_irq_disable (ep->bEndpointAddress); | 1727 | pio_irq_disable (ep->bEndpointAddress); |
@@ -2074,7 +1744,6 @@ pxa2xx_udc_irq(int irq, void *_dev) | |||
2074 | int handled; | 1744 | int handled; |
2075 | 1745 | ||
2076 | dev->stats.irqs++; | 1746 | dev->stats.irqs++; |
2077 | HEX_DISPLAY(dev->stats.irqs); | ||
2078 | do { | 1747 | do { |
2079 | u32 udccr = UDCCR; | 1748 | u32 udccr = UDCCR; |
2080 | 1749 | ||
@@ -2125,7 +1794,6 @@ pxa2xx_udc_irq(int irq, void *_dev) | |||
2125 | } else { | 1794 | } else { |
2126 | DBG(DBG_VERBOSE, "USB reset end\n"); | 1795 | DBG(DBG_VERBOSE, "USB reset end\n"); |
2127 | dev->gadget.speed = USB_SPEED_FULL; | 1796 | dev->gadget.speed = USB_SPEED_FULL; |
2128 | LED_CONNECTED_ON; | ||
2129 | memset(&dev->stats, 0, sizeof dev->stats); | 1797 | memset(&dev->stats, 0, sizeof dev->stats); |
2130 | /* driver and endpoints are still reset */ | 1798 | /* driver and endpoints are still reset */ |
2131 | } | 1799 | } |
@@ -2217,7 +1885,6 @@ static struct pxa2xx_udc memory = { | |||
2217 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 1885 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
2218 | .reg_udccs = &UDCCS1, | 1886 | .reg_udccs = &UDCCS1, |
2219 | .reg_uddr = &UDDR1, | 1887 | .reg_uddr = &UDDR1, |
2220 | drcmr (25) | ||
2221 | }, | 1888 | }, |
2222 | .ep[2] = { | 1889 | .ep[2] = { |
2223 | .ep = { | 1890 | .ep = { |
@@ -2232,7 +1899,6 @@ static struct pxa2xx_udc memory = { | |||
2232 | .reg_udccs = &UDCCS2, | 1899 | .reg_udccs = &UDCCS2, |
2233 | .reg_ubcr = &UBCR2, | 1900 | .reg_ubcr = &UBCR2, |
2234 | .reg_uddr = &UDDR2, | 1901 | .reg_uddr = &UDDR2, |
2235 | drcmr (26) | ||
2236 | }, | 1902 | }, |
2237 | #ifndef CONFIG_USB_PXA2XX_SMALL | 1903 | #ifndef CONFIG_USB_PXA2XX_SMALL |
2238 | .ep[3] = { | 1904 | .ep[3] = { |
@@ -2247,7 +1913,6 @@ static struct pxa2xx_udc memory = { | |||
2247 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | 1913 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, |
2248 | .reg_udccs = &UDCCS3, | 1914 | .reg_udccs = &UDCCS3, |
2249 | .reg_uddr = &UDDR3, | 1915 | .reg_uddr = &UDDR3, |
2250 | drcmr (27) | ||
2251 | }, | 1916 | }, |
2252 | .ep[4] = { | 1917 | .ep[4] = { |
2253 | .ep = { | 1918 | .ep = { |
@@ -2262,7 +1927,6 @@ static struct pxa2xx_udc memory = { | |||
2262 | .reg_udccs = &UDCCS4, | 1927 | .reg_udccs = &UDCCS4, |
2263 | .reg_ubcr = &UBCR4, | 1928 | .reg_ubcr = &UBCR4, |
2264 | .reg_uddr = &UDDR4, | 1929 | .reg_uddr = &UDDR4, |
2265 | drcmr (28) | ||
2266 | }, | 1930 | }, |
2267 | .ep[5] = { | 1931 | .ep[5] = { |
2268 | .ep = { | 1932 | .ep = { |
@@ -2291,7 +1955,6 @@ static struct pxa2xx_udc memory = { | |||
2291 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 1955 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
2292 | .reg_udccs = &UDCCS6, | 1956 | .reg_udccs = &UDCCS6, |
2293 | .reg_uddr = &UDDR6, | 1957 | .reg_uddr = &UDDR6, |
2294 | drcmr (30) | ||
2295 | }, | 1958 | }, |
2296 | .ep[7] = { | 1959 | .ep[7] = { |
2297 | .ep = { | 1960 | .ep = { |
@@ -2306,7 +1969,6 @@ static struct pxa2xx_udc memory = { | |||
2306 | .reg_udccs = &UDCCS7, | 1969 | .reg_udccs = &UDCCS7, |
2307 | .reg_ubcr = &UBCR7, | 1970 | .reg_ubcr = &UBCR7, |
2308 | .reg_uddr = &UDDR7, | 1971 | .reg_uddr = &UDDR7, |
2309 | drcmr (31) | ||
2310 | }, | 1972 | }, |
2311 | .ep[8] = { | 1973 | .ep[8] = { |
2312 | .ep = { | 1974 | .ep = { |
@@ -2320,7 +1982,6 @@ static struct pxa2xx_udc memory = { | |||
2320 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | 1982 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, |
2321 | .reg_udccs = &UDCCS8, | 1983 | .reg_udccs = &UDCCS8, |
2322 | .reg_uddr = &UDDR8, | 1984 | .reg_uddr = &UDDR8, |
2323 | drcmr (32) | ||
2324 | }, | 1985 | }, |
2325 | .ep[9] = { | 1986 | .ep[9] = { |
2326 | .ep = { | 1987 | .ep = { |
@@ -2335,7 +1996,6 @@ static struct pxa2xx_udc memory = { | |||
2335 | .reg_udccs = &UDCCS9, | 1996 | .reg_udccs = &UDCCS9, |
2336 | .reg_ubcr = &UBCR9, | 1997 | .reg_ubcr = &UBCR9, |
2337 | .reg_uddr = &UDDR9, | 1998 | .reg_uddr = &UDDR9, |
2338 | drcmr (33) | ||
2339 | }, | 1999 | }, |
2340 | .ep[10] = { | 2000 | .ep[10] = { |
2341 | .ep = { | 2001 | .ep = { |
@@ -2364,7 +2024,6 @@ static struct pxa2xx_udc memory = { | |||
2364 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 2024 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
2365 | .reg_udccs = &UDCCS11, | 2025 | .reg_udccs = &UDCCS11, |
2366 | .reg_uddr = &UDDR11, | 2026 | .reg_uddr = &UDDR11, |
2367 | drcmr (35) | ||
2368 | }, | 2027 | }, |
2369 | .ep[12] = { | 2028 | .ep[12] = { |
2370 | .ep = { | 2029 | .ep = { |
@@ -2379,7 +2038,6 @@ static struct pxa2xx_udc memory = { | |||
2379 | .reg_udccs = &UDCCS12, | 2038 | .reg_udccs = &UDCCS12, |
2380 | .reg_ubcr = &UBCR12, | 2039 | .reg_ubcr = &UBCR12, |
2381 | .reg_uddr = &UDDR12, | 2040 | .reg_uddr = &UDDR12, |
2382 | drcmr (36) | ||
2383 | }, | 2041 | }, |
2384 | .ep[13] = { | 2042 | .ep[13] = { |
2385 | .ep = { | 2043 | .ep = { |
@@ -2393,7 +2051,6 @@ static struct pxa2xx_udc memory = { | |||
2393 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | 2051 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, |
2394 | .reg_udccs = &UDCCS13, | 2052 | .reg_udccs = &UDCCS13, |
2395 | .reg_uddr = &UDDR13, | 2053 | .reg_uddr = &UDDR13, |
2396 | drcmr (37) | ||
2397 | }, | 2054 | }, |
2398 | .ep[14] = { | 2055 | .ep[14] = { |
2399 | .ep = { | 2056 | .ep = { |
@@ -2408,7 +2065,6 @@ static struct pxa2xx_udc memory = { | |||
2408 | .reg_udccs = &UDCCS14, | 2065 | .reg_udccs = &UDCCS14, |
2409 | .reg_ubcr = &UBCR14, | 2066 | .reg_ubcr = &UBCR14, |
2410 | .reg_uddr = &UDDR14, | 2067 | .reg_uddr = &UDDR14, |
2411 | drcmr (38) | ||
2412 | }, | 2068 | }, |
2413 | .ep[15] = { | 2069 | .ep[15] = { |
2414 | .ep = { | 2070 | .ep = { |
@@ -2466,7 +2122,7 @@ static struct pxa2xx_udc memory = { | |||
2466 | static int __init pxa2xx_udc_probe(struct platform_device *pdev) | 2122 | static int __init pxa2xx_udc_probe(struct platform_device *pdev) |
2467 | { | 2123 | { |
2468 | struct pxa2xx_udc *dev = &memory; | 2124 | struct pxa2xx_udc *dev = &memory; |
2469 | int retval, out_dma = 1, vbus_irq, irq; | 2125 | int retval, vbus_irq, irq; |
2470 | u32 chiprev; | 2126 | u32 chiprev; |
2471 | 2127 | ||
2472 | /* insist on Intel/ARM/XScale */ | 2128 | /* insist on Intel/ARM/XScale */ |
@@ -2489,7 +2145,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2489 | case PXA250_B2: case PXA210_B2: | 2145 | case PXA250_B2: case PXA210_B2: |
2490 | case PXA250_B1: case PXA210_B1: | 2146 | case PXA250_B1: case PXA210_B1: |
2491 | case PXA250_B0: case PXA210_B0: | 2147 | case PXA250_B0: case PXA210_B0: |
2492 | out_dma = 0; | 2148 | /* OUT-DMA is broken ... */ |
2493 | /* fall through */ | 2149 | /* fall through */ |
2494 | case PXA250_C0: case PXA210_C0: | 2150 | case PXA250_C0: case PXA210_C0: |
2495 | break; | 2151 | break; |
@@ -2498,11 +2154,9 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2498 | case IXP425_B0: | 2154 | case IXP425_B0: |
2499 | case IXP465_AD: | 2155 | case IXP465_AD: |
2500 | dev->has_cfr = 1; | 2156 | dev->has_cfr = 1; |
2501 | out_dma = 0; | ||
2502 | break; | 2157 | break; |
2503 | #endif | 2158 | #endif |
2504 | default: | 2159 | default: |
2505 | out_dma = 0; | ||
2506 | printk(KERN_ERR "%s: unrecognized processor: %08x\n", | 2160 | printk(KERN_ERR "%s: unrecognized processor: %08x\n", |
2507 | driver_name, chiprev); | 2161 | driver_name, chiprev); |
2508 | /* iop3xx, ixp4xx, ... */ | 2162 | /* iop3xx, ixp4xx, ... */ |
@@ -2513,36 +2167,41 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2513 | if (irq < 0) | 2167 | if (irq < 0) |
2514 | return -ENODEV; | 2168 | return -ENODEV; |
2515 | 2169 | ||
2516 | pr_debug("%s: IRQ %d%s%s%s\n", driver_name, irq, | 2170 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, |
2517 | dev->has_cfr ? "" : " (!cfr)", | 2171 | dev->has_cfr ? "" : " (!cfr)", |
2518 | out_dma ? "" : " (broken dma-out)", | 2172 | SIZE_STR "(pio)" |
2519 | SIZE_STR DMASTR | ||
2520 | ); | 2173 | ); |
2521 | 2174 | ||
2522 | #ifdef USE_DMA | ||
2523 | #ifndef USE_OUT_DMA | ||
2524 | out_dma = 0; | ||
2525 | #endif | ||
2526 | /* pxa 250 erratum 130 prevents using OUT dma (fixed C0) */ | ||
2527 | if (!out_dma) { | ||
2528 | DMSG("disabled OUT dma\n"); | ||
2529 | dev->ep[ 2].reg_drcmr = dev->ep[ 4].reg_drcmr = 0; | ||
2530 | dev->ep[ 7].reg_drcmr = dev->ep[ 9].reg_drcmr = 0; | ||
2531 | dev->ep[12].reg_drcmr = dev->ep[14].reg_drcmr = 0; | ||
2532 | } | ||
2533 | #endif | ||
2534 | |||
2535 | /* other non-static parts of init */ | 2175 | /* other non-static parts of init */ |
2536 | dev->dev = &pdev->dev; | 2176 | dev->dev = &pdev->dev; |
2537 | dev->mach = pdev->dev.platform_data; | 2177 | dev->mach = pdev->dev.platform_data; |
2178 | |||
2538 | if (dev->mach->gpio_vbus) { | 2179 | if (dev->mach->gpio_vbus) { |
2539 | udc_gpio_init_vbus(dev->mach->gpio_vbus); | 2180 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
2540 | vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus); | 2181 | "pxa2xx_udc GPIO VBUS"))) { |
2182 | dev_dbg(&pdev->dev, | ||
2183 | "can't get vbus gpio %d, err: %d\n", | ||
2184 | dev->mach->gpio_vbus, retval); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | gpio_direction_input(dev->mach->gpio_vbus); | ||
2188 | vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); | ||
2541 | set_irq_type(vbus_irq, IRQT_BOTHEDGE); | 2189 | set_irq_type(vbus_irq, IRQT_BOTHEDGE); |
2542 | } else | 2190 | } else |
2543 | vbus_irq = 0; | 2191 | vbus_irq = 0; |
2544 | if (dev->mach->gpio_pullup) | 2192 | |
2545 | udc_gpio_init_pullup(dev->mach->gpio_pullup); | 2193 | if (dev->mach->gpio_pullup) { |
2194 | if ((retval = gpio_request(dev->mach->gpio_pullup, | ||
2195 | "pca2xx_udc GPIO PULLUP"))) { | ||
2196 | dev_dbg(&pdev->dev, | ||
2197 | "can't get pullup gpio %d, err: %d\n", | ||
2198 | dev->mach->gpio_pullup, retval); | ||
2199 | if (dev->mach->gpio_vbus) | ||
2200 | gpio_free(dev->mach->gpio_vbus); | ||
2201 | return -EBUSY; | ||
2202 | } | ||
2203 | gpio_direction_output(dev->mach->gpio_pullup, 0); | ||
2204 | } | ||
2546 | 2205 | ||
2547 | init_timer(&dev->timer); | 2206 | init_timer(&dev->timer); |
2548 | dev->timer.function = udc_watchdog; | 2207 | dev->timer.function = udc_watchdog; |
@@ -2566,6 +2225,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2566 | if (retval != 0) { | 2225 | if (retval != 0) { |
2567 | printk(KERN_ERR "%s: can't get irq %d, err %d\n", | 2226 | printk(KERN_ERR "%s: can't get irq %d, err %d\n", |
2568 | driver_name, irq, retval); | 2227 | driver_name, irq, retval); |
2228 | if (dev->mach->gpio_pullup) | ||
2229 | gpio_free(dev->mach->gpio_pullup); | ||
2230 | if (dev->mach->gpio_vbus) | ||
2231 | gpio_free(dev->mach->gpio_vbus); | ||
2569 | return -EBUSY; | 2232 | return -EBUSY; |
2570 | } | 2233 | } |
2571 | dev->got_irq = 1; | 2234 | dev->got_irq = 1; |
@@ -2581,6 +2244,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
2581 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2244 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
2582 | lubbock_fail0: | 2245 | lubbock_fail0: |
2583 | free_irq(irq, dev); | 2246 | free_irq(irq, dev); |
2247 | if (dev->mach->gpio_pullup) | ||
2248 | gpio_free(dev->mach->gpio_pullup); | ||
2249 | if (dev->mach->gpio_vbus) | ||
2250 | gpio_free(dev->mach->gpio_vbus); | ||
2584 | return -EBUSY; | 2251 | return -EBUSY; |
2585 | } | 2252 | } |
2586 | retval = request_irq(LUBBOCK_USB_IRQ, | 2253 | retval = request_irq(LUBBOCK_USB_IRQ, |
@@ -2593,11 +2260,6 @@ lubbock_fail0: | |||
2593 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | 2260 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); |
2594 | goto lubbock_fail0; | 2261 | goto lubbock_fail0; |
2595 | } | 2262 | } |
2596 | #ifdef DEBUG | ||
2597 | /* with U-Boot (but not BLOB), hex is off by default */ | ||
2598 | HEX_DISPLAY(dev->stats.irqs); | ||
2599 | LUB_DISC_BLNK_LED &= 0xff; | ||
2600 | #endif | ||
2601 | } else | 2263 | } else |
2602 | #endif | 2264 | #endif |
2603 | if (vbus_irq) { | 2265 | if (vbus_irq) { |
@@ -2608,6 +2270,10 @@ lubbock_fail0: | |||
2608 | printk(KERN_ERR "%s: can't get irq %i, err %d\n", | 2270 | printk(KERN_ERR "%s: can't get irq %i, err %d\n", |
2609 | driver_name, vbus_irq, retval); | 2271 | driver_name, vbus_irq, retval); |
2610 | free_irq(irq, dev); | 2272 | free_irq(irq, dev); |
2273 | if (dev->mach->gpio_pullup) | ||
2274 | gpio_free(dev->mach->gpio_pullup); | ||
2275 | if (dev->mach->gpio_vbus) | ||
2276 | gpio_free(dev->mach->gpio_vbus); | ||
2611 | return -EBUSY; | 2277 | return -EBUSY; |
2612 | } | 2278 | } |
2613 | } | 2279 | } |
@@ -2641,8 +2307,13 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
2641 | free_irq(LUBBOCK_USB_IRQ, dev); | 2307 | free_irq(LUBBOCK_USB_IRQ, dev); |
2642 | } | 2308 | } |
2643 | #endif | 2309 | #endif |
2644 | if (dev->mach->gpio_vbus) | 2310 | if (dev->mach->gpio_vbus) { |
2645 | free_irq(IRQ_GPIO(dev->mach->gpio_vbus), dev); | 2311 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); |
2312 | gpio_free(dev->mach->gpio_vbus); | ||
2313 | } | ||
2314 | if (dev->mach->gpio_pullup) | ||
2315 | gpio_free(dev->mach->gpio_pullup); | ||
2316 | |||
2646 | platform_set_drvdata(pdev, NULL); | 2317 | platform_set_drvdata(pdev, NULL); |
2647 | the_controller = NULL; | 2318 | the_controller = NULL; |
2648 | return 0; | 2319 | return 0; |
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index 773e549aff3f..0e5d0e6fb0e2 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h | |||
@@ -54,8 +54,6 @@ struct pxa2xx_ep { | |||
54 | const struct usb_endpoint_descriptor *desc; | 54 | const struct usb_endpoint_descriptor *desc; |
55 | struct list_head queue; | 55 | struct list_head queue; |
56 | unsigned long pio_irqs; | 56 | unsigned long pio_irqs; |
57 | unsigned long dma_irqs; | ||
58 | short dma; | ||
59 | 57 | ||
60 | unsigned short fifo_size; | 58 | unsigned short fifo_size; |
61 | u8 bEndpointAddress; | 59 | u8 bEndpointAddress; |
@@ -63,7 +61,7 @@ struct pxa2xx_ep { | |||
63 | 61 | ||
64 | unsigned stopped : 1; | 62 | unsigned stopped : 1; |
65 | unsigned dma_fixup : 1; | 63 | unsigned dma_fixup : 1; |
66 | 64 | ||
67 | /* UDCCS = UDC Control/Status for this EP | 65 | /* UDCCS = UDC Control/Status for this EP |
68 | * UBCR = UDC Byte Count Remaining (contents of OUT fifo) | 66 | * UBCR = UDC Byte Count Remaining (contents of OUT fifo) |
69 | * UDDR = UDC Endpoint Data Register (the fifo) | 67 | * UDDR = UDC Endpoint Data Register (the fifo) |
@@ -72,12 +70,6 @@ struct pxa2xx_ep { | |||
72 | volatile u32 *reg_udccs; | 70 | volatile u32 *reg_udccs; |
73 | volatile u32 *reg_ubcr; | 71 | volatile u32 *reg_ubcr; |
74 | volatile u32 *reg_uddr; | 72 | volatile u32 *reg_uddr; |
75 | #ifdef USE_DMA | ||
76 | volatile u32 *reg_drcmr; | ||
77 | #define drcmr(n) .reg_drcmr = & DRCMR ## n , | ||
78 | #else | ||
79 | #define drcmr(n) | ||
80 | #endif | ||
81 | }; | 73 | }; |
82 | 74 | ||
83 | struct pxa2xx_request { | 75 | struct pxa2xx_request { |
@@ -85,7 +77,7 @@ struct pxa2xx_request { | |||
85 | struct list_head queue; | 77 | struct list_head queue; |
86 | }; | 78 | }; |
87 | 79 | ||
88 | enum ep0_state { | 80 | enum ep0_state { |
89 | EP0_IDLE, | 81 | EP0_IDLE, |
90 | EP0_IN_DATA_PHASE, | 82 | EP0_IN_DATA_PHASE, |
91 | EP0_OUT_DATA_PHASE, | 83 | EP0_OUT_DATA_PHASE, |
@@ -108,7 +100,6 @@ struct udc_stats { | |||
108 | 100 | ||
109 | #ifdef CONFIG_USB_PXA2XX_SMALL | 101 | #ifdef CONFIG_USB_PXA2XX_SMALL |
110 | /* when memory's tight, SMALL config saves code+data. */ | 102 | /* when memory's tight, SMALL config saves code+data. */ |
111 | #undef USE_DMA | ||
112 | #define PXA_UDC_NUM_ENDPOINTS 3 | 103 | #define PXA_UDC_NUM_ENDPOINTS 3 |
113 | #endif | 104 | #endif |
114 | 105 | ||
@@ -144,37 +135,8 @@ struct pxa2xx_udc { | |||
144 | #ifdef CONFIG_ARCH_LUBBOCK | 135 | #ifdef CONFIG_ARCH_LUBBOCK |
145 | #include <asm/arch/lubbock.h> | 136 | #include <asm/arch/lubbock.h> |
146 | /* lubbock can also report usb connect/disconnect irqs */ | 137 | /* lubbock can also report usb connect/disconnect irqs */ |
147 | |||
148 | #ifdef DEBUG | ||
149 | #define HEX_DISPLAY(n) if (machine_is_lubbock()) { LUB_HEXLED = (n); } | ||
150 | #endif | 138 | #endif |
151 | 139 | ||
152 | #endif | ||
153 | |||
154 | /*-------------------------------------------------------------------------*/ | ||
155 | |||
156 | /* LEDs are only for debug */ | ||
157 | #ifndef HEX_DISPLAY | ||
158 | #define HEX_DISPLAY(n) do {} while(0) | ||
159 | #endif | ||
160 | |||
161 | #ifdef DEBUG | ||
162 | #include <asm/leds.h> | ||
163 | |||
164 | #define LED_CONNECTED_ON leds_event(led_green_on) | ||
165 | #define LED_CONNECTED_OFF do { \ | ||
166 | leds_event(led_green_off); \ | ||
167 | HEX_DISPLAY(0); \ | ||
168 | } while(0) | ||
169 | #endif | ||
170 | |||
171 | #ifndef LED_CONNECTED_ON | ||
172 | #define LED_CONNECTED_ON do {} while(0) | ||
173 | #define LED_CONNECTED_OFF do {} while(0) | ||
174 | #endif | ||
175 | |||
176 | /*-------------------------------------------------------------------------*/ | ||
177 | |||
178 | static struct pxa2xx_udc *the_controller; | 140 | static struct pxa2xx_udc *the_controller; |
179 | 141 | ||
180 | /*-------------------------------------------------------------------------*/ | 142 | /*-------------------------------------------------------------------------*/ |
@@ -204,7 +166,7 @@ static const char *state_name[] = { | |||
204 | # define UDC_DEBUG DBG_NORMAL | 166 | # define UDC_DEBUG DBG_NORMAL |
205 | #endif | 167 | #endif |
206 | 168 | ||
207 | static void __attribute__ ((__unused__)) | 169 | static void __maybe_unused |
208 | dump_udccr(const char *label) | 170 | dump_udccr(const char *label) |
209 | { | 171 | { |
210 | u32 udccr = UDCCR; | 172 | u32 udccr = UDCCR; |
@@ -220,7 +182,7 @@ dump_udccr(const char *label) | |||
220 | (udccr & UDCCR_UDE) ? " ude" : ""); | 182 | (udccr & UDCCR_UDE) ? " ude" : ""); |
221 | } | 183 | } |
222 | 184 | ||
223 | static void __attribute__ ((__unused__)) | 185 | static void __maybe_unused |
224 | dump_udccs0(const char *label) | 186 | dump_udccs0(const char *label) |
225 | { | 187 | { |
226 | u32 udccs0 = UDCCS0; | 188 | u32 udccs0 = UDCCS0; |
@@ -237,7 +199,7 @@ dump_udccs0(const char *label) | |||
237 | (udccs0 & UDCCS0_OPR) ? " opr" : ""); | 199 | (udccs0 & UDCCS0_OPR) ? " opr" : ""); |
238 | } | 200 | } |
239 | 201 | ||
240 | static void __attribute__ ((__unused__)) | 202 | static void __maybe_unused |
241 | dump_state(struct pxa2xx_udc *dev) | 203 | dump_state(struct pxa2xx_udc *dev) |
242 | { | 204 | { |
243 | u32 tmp; | 205 | u32 tmp; |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 708657c89132..db1b2bfcee4e 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -53,7 +53,7 @@ | |||
53 | */ | 53 | */ |
54 | 54 | ||
55 | #if 0 | 55 | #if 0 |
56 | #define DEBUG(str,args...) do { \ | 56 | #define DBG(str,args...) do { \ |
57 | if (rndis_debug) \ | 57 | if (rndis_debug) \ |
58 | printk(KERN_DEBUG str , ## args ); \ | 58 | printk(KERN_DEBUG str , ## args ); \ |
59 | } while (0) | 59 | } while (0) |
@@ -65,7 +65,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); | |||
65 | #else | 65 | #else |
66 | 66 | ||
67 | #define rndis_debug 0 | 67 | #define rndis_debug 0 |
68 | #define DEBUG(str,args...) do{}while(0) | 68 | #define DBG(str,args...) do{}while(0) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #define RNDIS_MAX_CONFIGS 1 | 71 | #define RNDIS_MAX_CONFIGS 1 |
@@ -183,9 +183,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
183 | if (!resp) return -ENOMEM; | 183 | if (!resp) return -ENOMEM; |
184 | 184 | ||
185 | if (buf_len && rndis_debug > 1) { | 185 | if (buf_len && rndis_debug > 1) { |
186 | DEBUG("query OID %08x value, len %d:\n", OID, buf_len); | 186 | DBG("query OID %08x value, len %d:\n", OID, buf_len); |
187 | for (i = 0; i < buf_len; i += 16) { | 187 | for (i = 0; i < buf_len; i += 16) { |
188 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, | 188 | DBG("%03d: %08x %08x %08x %08x\n", i, |
189 | le32_to_cpu(get_unaligned((__le32 *) | 189 | le32_to_cpu(get_unaligned((__le32 *) |
190 | &buf[i])), | 190 | &buf[i])), |
191 | le32_to_cpu(get_unaligned((__le32 *) | 191 | le32_to_cpu(get_unaligned((__le32 *) |
@@ -207,7 +207,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
207 | 207 | ||
208 | /* mandatory */ | 208 | /* mandatory */ |
209 | case OID_GEN_SUPPORTED_LIST: | 209 | case OID_GEN_SUPPORTED_LIST: |
210 | DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); | 210 | DBG("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); |
211 | length = sizeof (oid_supported_list); | 211 | length = sizeof (oid_supported_list); |
212 | count = length / sizeof (u32); | 212 | count = length / sizeof (u32); |
213 | for (i = 0; i < count; i++) | 213 | for (i = 0; i < count; i++) |
@@ -217,7 +217,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
217 | 217 | ||
218 | /* mandatory */ | 218 | /* mandatory */ |
219 | case OID_GEN_HARDWARE_STATUS: | 219 | case OID_GEN_HARDWARE_STATUS: |
220 | DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); | 220 | DBG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); |
221 | /* Bogus question! | 221 | /* Bogus question! |
222 | * Hardware must be ready to receive high level protocols. | 222 | * Hardware must be ready to receive high level protocols. |
223 | * BTW: | 223 | * BTW: |
@@ -230,14 +230,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
230 | 230 | ||
231 | /* mandatory */ | 231 | /* mandatory */ |
232 | case OID_GEN_MEDIA_SUPPORTED: | 232 | case OID_GEN_MEDIA_SUPPORTED: |
233 | DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); | 233 | DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); |
234 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); | 234 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); |
235 | retval = 0; | 235 | retval = 0; |
236 | break; | 236 | break; |
237 | 237 | ||
238 | /* mandatory */ | 238 | /* mandatory */ |
239 | case OID_GEN_MEDIA_IN_USE: | 239 | case OID_GEN_MEDIA_IN_USE: |
240 | DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); | 240 | DBG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); |
241 | /* one medium, one transport... (maybe you do it better) */ | 241 | /* one medium, one transport... (maybe you do it better) */ |
242 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); | 242 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); |
243 | retval = 0; | 243 | retval = 0; |
@@ -245,7 +245,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
245 | 245 | ||
246 | /* mandatory */ | 246 | /* mandatory */ |
247 | case OID_GEN_MAXIMUM_FRAME_SIZE: | 247 | case OID_GEN_MAXIMUM_FRAME_SIZE: |
248 | DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); | 248 | DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); |
249 | if (rndis_per_dev_params [configNr].dev) { | 249 | if (rndis_per_dev_params [configNr].dev) { |
250 | *outbuf = cpu_to_le32 ( | 250 | *outbuf = cpu_to_le32 ( |
251 | rndis_per_dev_params [configNr].dev->mtu); | 251 | rndis_per_dev_params [configNr].dev->mtu); |
@@ -256,7 +256,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
256 | /* mandatory */ | 256 | /* mandatory */ |
257 | case OID_GEN_LINK_SPEED: | 257 | case OID_GEN_LINK_SPEED: |
258 | if (rndis_debug > 1) | 258 | if (rndis_debug > 1) |
259 | DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); | 259 | DBG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); |
260 | if (rndis_per_dev_params [configNr].media_state | 260 | if (rndis_per_dev_params [configNr].media_state |
261 | == NDIS_MEDIA_STATE_DISCONNECTED) | 261 | == NDIS_MEDIA_STATE_DISCONNECTED) |
262 | *outbuf = __constant_cpu_to_le32 (0); | 262 | *outbuf = __constant_cpu_to_le32 (0); |
@@ -268,7 +268,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
268 | 268 | ||
269 | /* mandatory */ | 269 | /* mandatory */ |
270 | case OID_GEN_TRANSMIT_BLOCK_SIZE: | 270 | case OID_GEN_TRANSMIT_BLOCK_SIZE: |
271 | DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); | 271 | DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); |
272 | if (rndis_per_dev_params [configNr].dev) { | 272 | if (rndis_per_dev_params [configNr].dev) { |
273 | *outbuf = cpu_to_le32 ( | 273 | *outbuf = cpu_to_le32 ( |
274 | rndis_per_dev_params [configNr].dev->mtu); | 274 | rndis_per_dev_params [configNr].dev->mtu); |
@@ -278,7 +278,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
278 | 278 | ||
279 | /* mandatory */ | 279 | /* mandatory */ |
280 | case OID_GEN_RECEIVE_BLOCK_SIZE: | 280 | case OID_GEN_RECEIVE_BLOCK_SIZE: |
281 | DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); | 281 | DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); |
282 | if (rndis_per_dev_params [configNr].dev) { | 282 | if (rndis_per_dev_params [configNr].dev) { |
283 | *outbuf = cpu_to_le32 ( | 283 | *outbuf = cpu_to_le32 ( |
284 | rndis_per_dev_params [configNr].dev->mtu); | 284 | rndis_per_dev_params [configNr].dev->mtu); |
@@ -288,7 +288,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
288 | 288 | ||
289 | /* mandatory */ | 289 | /* mandatory */ |
290 | case OID_GEN_VENDOR_ID: | 290 | case OID_GEN_VENDOR_ID: |
291 | DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); | 291 | DBG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); |
292 | *outbuf = cpu_to_le32 ( | 292 | *outbuf = cpu_to_le32 ( |
293 | rndis_per_dev_params [configNr].vendorID); | 293 | rndis_per_dev_params [configNr].vendorID); |
294 | retval = 0; | 294 | retval = 0; |
@@ -296,7 +296,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
296 | 296 | ||
297 | /* mandatory */ | 297 | /* mandatory */ |
298 | case OID_GEN_VENDOR_DESCRIPTION: | 298 | case OID_GEN_VENDOR_DESCRIPTION: |
299 | DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); | 299 | DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); |
300 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); | 300 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); |
301 | memcpy (outbuf, | 301 | memcpy (outbuf, |
302 | rndis_per_dev_params [configNr].vendorDescr, length); | 302 | rndis_per_dev_params [configNr].vendorDescr, length); |
@@ -304,7 +304,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
304 | break; | 304 | break; |
305 | 305 | ||
306 | case OID_GEN_VENDOR_DRIVER_VERSION: | 306 | case OID_GEN_VENDOR_DRIVER_VERSION: |
307 | DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); | 307 | DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); |
308 | /* Created as LE */ | 308 | /* Created as LE */ |
309 | *outbuf = rndis_driver_version; | 309 | *outbuf = rndis_driver_version; |
310 | retval = 0; | 310 | retval = 0; |
@@ -312,14 +312,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
312 | 312 | ||
313 | /* mandatory */ | 313 | /* mandatory */ |
314 | case OID_GEN_CURRENT_PACKET_FILTER: | 314 | case OID_GEN_CURRENT_PACKET_FILTER: |
315 | DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); | 315 | DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); |
316 | *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter); | 316 | *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter); |
317 | retval = 0; | 317 | retval = 0; |
318 | break; | 318 | break; |
319 | 319 | ||
320 | /* mandatory */ | 320 | /* mandatory */ |
321 | case OID_GEN_MAXIMUM_TOTAL_SIZE: | 321 | case OID_GEN_MAXIMUM_TOTAL_SIZE: |
322 | DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); | 322 | DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); |
323 | *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); | 323 | *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); |
324 | retval = 0; | 324 | retval = 0; |
325 | break; | 325 | break; |
@@ -327,14 +327,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
327 | /* mandatory */ | 327 | /* mandatory */ |
328 | case OID_GEN_MEDIA_CONNECT_STATUS: | 328 | case OID_GEN_MEDIA_CONNECT_STATUS: |
329 | if (rndis_debug > 1) | 329 | if (rndis_debug > 1) |
330 | DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); | 330 | DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); |
331 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 331 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
332 | .media_state); | 332 | .media_state); |
333 | retval = 0; | 333 | retval = 0; |
334 | break; | 334 | break; |
335 | 335 | ||
336 | case OID_GEN_PHYSICAL_MEDIUM: | 336 | case OID_GEN_PHYSICAL_MEDIUM: |
337 | DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); | 337 | DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); |
338 | *outbuf = __constant_cpu_to_le32 (0); | 338 | *outbuf = __constant_cpu_to_le32 (0); |
339 | retval = 0; | 339 | retval = 0; |
340 | break; | 340 | break; |
@@ -344,7 +344,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
344 | * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! | 344 | * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! |
345 | */ | 345 | */ |
346 | case OID_GEN_MAC_OPTIONS: /* from WinME */ | 346 | case OID_GEN_MAC_OPTIONS: /* from WinME */ |
347 | DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); | 347 | DBG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); |
348 | *outbuf = __constant_cpu_to_le32( | 348 | *outbuf = __constant_cpu_to_le32( |
349 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 349 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
350 | | NDIS_MAC_OPTION_FULL_DUPLEX); | 350 | | NDIS_MAC_OPTION_FULL_DUPLEX); |
@@ -356,7 +356,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
356 | /* mandatory */ | 356 | /* mandatory */ |
357 | case OID_GEN_XMIT_OK: | 357 | case OID_GEN_XMIT_OK: |
358 | if (rndis_debug > 1) | 358 | if (rndis_debug > 1) |
359 | DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); | 359 | DBG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); |
360 | if (rndis_per_dev_params [configNr].stats) { | 360 | if (rndis_per_dev_params [configNr].stats) { |
361 | *outbuf = cpu_to_le32 ( | 361 | *outbuf = cpu_to_le32 ( |
362 | rndis_per_dev_params [configNr].stats->tx_packets - | 362 | rndis_per_dev_params [configNr].stats->tx_packets - |
@@ -369,7 +369,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
369 | /* mandatory */ | 369 | /* mandatory */ |
370 | case OID_GEN_RCV_OK: | 370 | case OID_GEN_RCV_OK: |
371 | if (rndis_debug > 1) | 371 | if (rndis_debug > 1) |
372 | DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); | 372 | DBG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); |
373 | if (rndis_per_dev_params [configNr].stats) { | 373 | if (rndis_per_dev_params [configNr].stats) { |
374 | *outbuf = cpu_to_le32 ( | 374 | *outbuf = cpu_to_le32 ( |
375 | rndis_per_dev_params [configNr].stats->rx_packets - | 375 | rndis_per_dev_params [configNr].stats->rx_packets - |
@@ -382,7 +382,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
382 | /* mandatory */ | 382 | /* mandatory */ |
383 | case OID_GEN_XMIT_ERROR: | 383 | case OID_GEN_XMIT_ERROR: |
384 | if (rndis_debug > 1) | 384 | if (rndis_debug > 1) |
385 | DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); | 385 | DBG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); |
386 | if (rndis_per_dev_params [configNr].stats) { | 386 | if (rndis_per_dev_params [configNr].stats) { |
387 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 387 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
388 | .stats->tx_errors); | 388 | .stats->tx_errors); |
@@ -393,7 +393,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
393 | /* mandatory */ | 393 | /* mandatory */ |
394 | case OID_GEN_RCV_ERROR: | 394 | case OID_GEN_RCV_ERROR: |
395 | if (rndis_debug > 1) | 395 | if (rndis_debug > 1) |
396 | DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); | 396 | DBG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); |
397 | if (rndis_per_dev_params [configNr].stats) { | 397 | if (rndis_per_dev_params [configNr].stats) { |
398 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 398 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
399 | .stats->rx_errors); | 399 | .stats->rx_errors); |
@@ -403,7 +403,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
403 | 403 | ||
404 | /* mandatory */ | 404 | /* mandatory */ |
405 | case OID_GEN_RCV_NO_BUFFER: | 405 | case OID_GEN_RCV_NO_BUFFER: |
406 | DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); | 406 | DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); |
407 | if (rndis_per_dev_params [configNr].stats) { | 407 | if (rndis_per_dev_params [configNr].stats) { |
408 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 408 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
409 | .stats->rx_dropped); | 409 | .stats->rx_dropped); |
@@ -413,7 +413,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
413 | 413 | ||
414 | #ifdef RNDIS_OPTIONAL_STATS | 414 | #ifdef RNDIS_OPTIONAL_STATS |
415 | case OID_GEN_DIRECTED_BYTES_XMIT: | 415 | case OID_GEN_DIRECTED_BYTES_XMIT: |
416 | DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); | 416 | DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); |
417 | /* | 417 | /* |
418 | * Aunt Tilly's size of shoes | 418 | * Aunt Tilly's size of shoes |
419 | * minus antarctica count of penguins | 419 | * minus antarctica count of penguins |
@@ -433,7 +433,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
433 | break; | 433 | break; |
434 | 434 | ||
435 | case OID_GEN_DIRECTED_FRAMES_XMIT: | 435 | case OID_GEN_DIRECTED_FRAMES_XMIT: |
436 | DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); | 436 | DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); |
437 | /* dito */ | 437 | /* dito */ |
438 | if (rndis_per_dev_params [configNr].stats) { | 438 | if (rndis_per_dev_params [configNr].stats) { |
439 | *outbuf = cpu_to_le32 ( | 439 | *outbuf = cpu_to_le32 ( |
@@ -449,7 +449,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
449 | break; | 449 | break; |
450 | 450 | ||
451 | case OID_GEN_MULTICAST_BYTES_XMIT: | 451 | case OID_GEN_MULTICAST_BYTES_XMIT: |
452 | DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); | 452 | DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); |
453 | if (rndis_per_dev_params [configNr].stats) { | 453 | if (rndis_per_dev_params [configNr].stats) { |
454 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 454 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
455 | .stats->multicast*1234); | 455 | .stats->multicast*1234); |
@@ -458,7 +458,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
458 | break; | 458 | break; |
459 | 459 | ||
460 | case OID_GEN_MULTICAST_FRAMES_XMIT: | 460 | case OID_GEN_MULTICAST_FRAMES_XMIT: |
461 | DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); | 461 | DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); |
462 | if (rndis_per_dev_params [configNr].stats) { | 462 | if (rndis_per_dev_params [configNr].stats) { |
463 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 463 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
464 | .stats->multicast); | 464 | .stats->multicast); |
@@ -467,7 +467,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
467 | break; | 467 | break; |
468 | 468 | ||
469 | case OID_GEN_BROADCAST_BYTES_XMIT: | 469 | case OID_GEN_BROADCAST_BYTES_XMIT: |
470 | DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); | 470 | DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); |
471 | if (rndis_per_dev_params [configNr].stats) { | 471 | if (rndis_per_dev_params [configNr].stats) { |
472 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 472 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
473 | .stats->tx_packets/42*255); | 473 | .stats->tx_packets/42*255); |
@@ -476,7 +476,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
476 | break; | 476 | break; |
477 | 477 | ||
478 | case OID_GEN_BROADCAST_FRAMES_XMIT: | 478 | case OID_GEN_BROADCAST_FRAMES_XMIT: |
479 | DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); | 479 | DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); |
480 | if (rndis_per_dev_params [configNr].stats) { | 480 | if (rndis_per_dev_params [configNr].stats) { |
481 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 481 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
482 | .stats->tx_packets/42); | 482 | .stats->tx_packets/42); |
@@ -485,19 +485,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
485 | break; | 485 | break; |
486 | 486 | ||
487 | case OID_GEN_DIRECTED_BYTES_RCV: | 487 | case OID_GEN_DIRECTED_BYTES_RCV: |
488 | DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); | 488 | DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); |
489 | *outbuf = __constant_cpu_to_le32 (0); | 489 | *outbuf = __constant_cpu_to_le32 (0); |
490 | retval = 0; | 490 | retval = 0; |
491 | break; | 491 | break; |
492 | 492 | ||
493 | case OID_GEN_DIRECTED_FRAMES_RCV: | 493 | case OID_GEN_DIRECTED_FRAMES_RCV: |
494 | DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); | 494 | DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); |
495 | *outbuf = __constant_cpu_to_le32 (0); | 495 | *outbuf = __constant_cpu_to_le32 (0); |
496 | retval = 0; | 496 | retval = 0; |
497 | break; | 497 | break; |
498 | 498 | ||
499 | case OID_GEN_MULTICAST_BYTES_RCV: | 499 | case OID_GEN_MULTICAST_BYTES_RCV: |
500 | DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); | 500 | DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); |
501 | if (rndis_per_dev_params [configNr].stats) { | 501 | if (rndis_per_dev_params [configNr].stats) { |
502 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 502 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
503 | .stats->multicast * 1111); | 503 | .stats->multicast * 1111); |
@@ -506,7 +506,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
506 | break; | 506 | break; |
507 | 507 | ||
508 | case OID_GEN_MULTICAST_FRAMES_RCV: | 508 | case OID_GEN_MULTICAST_FRAMES_RCV: |
509 | DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); | 509 | DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); |
510 | if (rndis_per_dev_params [configNr].stats) { | 510 | if (rndis_per_dev_params [configNr].stats) { |
511 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 511 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
512 | .stats->multicast); | 512 | .stats->multicast); |
@@ -515,7 +515,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
515 | break; | 515 | break; |
516 | 516 | ||
517 | case OID_GEN_BROADCAST_BYTES_RCV: | 517 | case OID_GEN_BROADCAST_BYTES_RCV: |
518 | DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); | 518 | DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); |
519 | if (rndis_per_dev_params [configNr].stats) { | 519 | if (rndis_per_dev_params [configNr].stats) { |
520 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 520 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
521 | .stats->rx_packets/42*255); | 521 | .stats->rx_packets/42*255); |
@@ -524,7 +524,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
524 | break; | 524 | break; |
525 | 525 | ||
526 | case OID_GEN_BROADCAST_FRAMES_RCV: | 526 | case OID_GEN_BROADCAST_FRAMES_RCV: |
527 | DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); | 527 | DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); |
528 | if (rndis_per_dev_params [configNr].stats) { | 528 | if (rndis_per_dev_params [configNr].stats) { |
529 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 529 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
530 | .stats->rx_packets/42); | 530 | .stats->rx_packets/42); |
@@ -533,7 +533,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
533 | break; | 533 | break; |
534 | 534 | ||
535 | case OID_GEN_RCV_CRC_ERROR: | 535 | case OID_GEN_RCV_CRC_ERROR: |
536 | DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); | 536 | DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); |
537 | if (rndis_per_dev_params [configNr].stats) { | 537 | if (rndis_per_dev_params [configNr].stats) { |
538 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 538 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
539 | .stats->rx_crc_errors); | 539 | .stats->rx_crc_errors); |
@@ -542,7 +542,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
542 | break; | 542 | break; |
543 | 543 | ||
544 | case OID_GEN_TRANSMIT_QUEUE_LENGTH: | 544 | case OID_GEN_TRANSMIT_QUEUE_LENGTH: |
545 | DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); | 545 | DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); |
546 | *outbuf = __constant_cpu_to_le32 (0); | 546 | *outbuf = __constant_cpu_to_le32 (0); |
547 | retval = 0; | 547 | retval = 0; |
548 | break; | 548 | break; |
@@ -552,7 +552,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
552 | 552 | ||
553 | /* mandatory */ | 553 | /* mandatory */ |
554 | case OID_802_3_PERMANENT_ADDRESS: | 554 | case OID_802_3_PERMANENT_ADDRESS: |
555 | DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); | 555 | DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); |
556 | if (rndis_per_dev_params [configNr].dev) { | 556 | if (rndis_per_dev_params [configNr].dev) { |
557 | length = ETH_ALEN; | 557 | length = ETH_ALEN; |
558 | memcpy (outbuf, | 558 | memcpy (outbuf, |
@@ -564,7 +564,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
564 | 564 | ||
565 | /* mandatory */ | 565 | /* mandatory */ |
566 | case OID_802_3_CURRENT_ADDRESS: | 566 | case OID_802_3_CURRENT_ADDRESS: |
567 | DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); | 567 | DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); |
568 | if (rndis_per_dev_params [configNr].dev) { | 568 | if (rndis_per_dev_params [configNr].dev) { |
569 | length = ETH_ALEN; | 569 | length = ETH_ALEN; |
570 | memcpy (outbuf, | 570 | memcpy (outbuf, |
@@ -576,7 +576,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
576 | 576 | ||
577 | /* mandatory */ | 577 | /* mandatory */ |
578 | case OID_802_3_MULTICAST_LIST: | 578 | case OID_802_3_MULTICAST_LIST: |
579 | DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); | 579 | DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); |
580 | /* Multicast base address only */ | 580 | /* Multicast base address only */ |
581 | *outbuf = __constant_cpu_to_le32 (0xE0000000); | 581 | *outbuf = __constant_cpu_to_le32 (0xE0000000); |
582 | retval = 0; | 582 | retval = 0; |
@@ -584,21 +584,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
584 | 584 | ||
585 | /* mandatory */ | 585 | /* mandatory */ |
586 | case OID_802_3_MAXIMUM_LIST_SIZE: | 586 | case OID_802_3_MAXIMUM_LIST_SIZE: |
587 | DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); | 587 | DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); |
588 | /* Multicast base address only */ | 588 | /* Multicast base address only */ |
589 | *outbuf = __constant_cpu_to_le32 (1); | 589 | *outbuf = __constant_cpu_to_le32 (1); |
590 | retval = 0; | 590 | retval = 0; |
591 | break; | 591 | break; |
592 | 592 | ||
593 | case OID_802_3_MAC_OPTIONS: | 593 | case OID_802_3_MAC_OPTIONS: |
594 | DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); | 594 | DBG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); |
595 | break; | 595 | break; |
596 | 596 | ||
597 | /* ieee802.3 statistics OIDs (table 4-4) */ | 597 | /* ieee802.3 statistics OIDs (table 4-4) */ |
598 | 598 | ||
599 | /* mandatory */ | 599 | /* mandatory */ |
600 | case OID_802_3_RCV_ERROR_ALIGNMENT: | 600 | case OID_802_3_RCV_ERROR_ALIGNMENT: |
601 | DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); | 601 | DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); |
602 | if (rndis_per_dev_params [configNr].stats) { | 602 | if (rndis_per_dev_params [configNr].stats) { |
603 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 603 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] |
604 | .stats->rx_frame_errors); | 604 | .stats->rx_frame_errors); |
@@ -608,51 +608,51 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
608 | 608 | ||
609 | /* mandatory */ | 609 | /* mandatory */ |
610 | case OID_802_3_XMIT_ONE_COLLISION: | 610 | case OID_802_3_XMIT_ONE_COLLISION: |
611 | DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); | 611 | DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); |
612 | *outbuf = __constant_cpu_to_le32 (0); | 612 | *outbuf = __constant_cpu_to_le32 (0); |
613 | retval = 0; | 613 | retval = 0; |
614 | break; | 614 | break; |
615 | 615 | ||
616 | /* mandatory */ | 616 | /* mandatory */ |
617 | case OID_802_3_XMIT_MORE_COLLISIONS: | 617 | case OID_802_3_XMIT_MORE_COLLISIONS: |
618 | DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); | 618 | DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); |
619 | *outbuf = __constant_cpu_to_le32 (0); | 619 | *outbuf = __constant_cpu_to_le32 (0); |
620 | retval = 0; | 620 | retval = 0; |
621 | break; | 621 | break; |
622 | 622 | ||
623 | #ifdef RNDIS_OPTIONAL_STATS | 623 | #ifdef RNDIS_OPTIONAL_STATS |
624 | case OID_802_3_XMIT_DEFERRED: | 624 | case OID_802_3_XMIT_DEFERRED: |
625 | DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); | 625 | DBG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); |
626 | /* TODO */ | 626 | /* TODO */ |
627 | break; | 627 | break; |
628 | 628 | ||
629 | case OID_802_3_XMIT_MAX_COLLISIONS: | 629 | case OID_802_3_XMIT_MAX_COLLISIONS: |
630 | DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); | 630 | DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); |
631 | /* TODO */ | 631 | /* TODO */ |
632 | break; | 632 | break; |
633 | 633 | ||
634 | case OID_802_3_RCV_OVERRUN: | 634 | case OID_802_3_RCV_OVERRUN: |
635 | DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); | 635 | DBG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); |
636 | /* TODO */ | 636 | /* TODO */ |
637 | break; | 637 | break; |
638 | 638 | ||
639 | case OID_802_3_XMIT_UNDERRUN: | 639 | case OID_802_3_XMIT_UNDERRUN: |
640 | DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); | 640 | DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); |
641 | /* TODO */ | 641 | /* TODO */ |
642 | break; | 642 | break; |
643 | 643 | ||
644 | case OID_802_3_XMIT_HEARTBEAT_FAILURE: | 644 | case OID_802_3_XMIT_HEARTBEAT_FAILURE: |
645 | DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); | 645 | DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); |
646 | /* TODO */ | 646 | /* TODO */ |
647 | break; | 647 | break; |
648 | 648 | ||
649 | case OID_802_3_XMIT_TIMES_CRS_LOST: | 649 | case OID_802_3_XMIT_TIMES_CRS_LOST: |
650 | DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); | 650 | DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); |
651 | /* TODO */ | 651 | /* TODO */ |
652 | break; | 652 | break; |
653 | 653 | ||
654 | case OID_802_3_XMIT_LATE_COLLISIONS: | 654 | case OID_802_3_XMIT_LATE_COLLISIONS: |
655 | DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); | 655 | DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); |
656 | /* TODO */ | 656 | /* TODO */ |
657 | break; | 657 | break; |
658 | #endif /* RNDIS_OPTIONAL_STATS */ | 658 | #endif /* RNDIS_OPTIONAL_STATS */ |
@@ -660,7 +660,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
660 | #ifdef RNDIS_PM | 660 | #ifdef RNDIS_PM |
661 | /* power management OIDs (table 4-5) */ | 661 | /* power management OIDs (table 4-5) */ |
662 | case OID_PNP_CAPABILITIES: | 662 | case OID_PNP_CAPABILITIES: |
663 | DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); | 663 | DBG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); |
664 | 664 | ||
665 | /* for now, no wakeup capabilities */ | 665 | /* for now, no wakeup capabilities */ |
666 | length = sizeof (struct NDIS_PNP_CAPABILITIES); | 666 | length = sizeof (struct NDIS_PNP_CAPABILITIES); |
@@ -668,7 +668,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
668 | retval = 0; | 668 | retval = 0; |
669 | break; | 669 | break; |
670 | case OID_PNP_QUERY_POWER: | 670 | case OID_PNP_QUERY_POWER: |
671 | DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, | 671 | DBG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, |
672 | le32_to_cpu(get_unaligned((__le32 *)buf)) - 1); | 672 | le32_to_cpu(get_unaligned((__le32 *)buf)) - 1); |
673 | /* only suspend is a real power state, and | 673 | /* only suspend is a real power state, and |
674 | * it can't be entered by OID_PNP_SET_POWER... | 674 | * it can't be entered by OID_PNP_SET_POWER... |
@@ -705,9 +705,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
705 | return -ENOMEM; | 705 | return -ENOMEM; |
706 | 706 | ||
707 | if (buf_len && rndis_debug > 1) { | 707 | if (buf_len && rndis_debug > 1) { |
708 | DEBUG("set OID %08x value, len %d:\n", OID, buf_len); | 708 | DBG("set OID %08x value, len %d:\n", OID, buf_len); |
709 | for (i = 0; i < buf_len; i += 16) { | 709 | for (i = 0; i < buf_len; i += 16) { |
710 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, | 710 | DBG("%03d: %08x %08x %08x %08x\n", i, |
711 | le32_to_cpu(get_unaligned((__le32 *) | 711 | le32_to_cpu(get_unaligned((__le32 *) |
712 | &buf[i])), | 712 | &buf[i])), |
713 | le32_to_cpu(get_unaligned((__le32 *) | 713 | le32_to_cpu(get_unaligned((__le32 *) |
@@ -731,7 +731,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
731 | */ | 731 | */ |
732 | *params->filter = (u16) le32_to_cpu(get_unaligned( | 732 | *params->filter = (u16) le32_to_cpu(get_unaligned( |
733 | (__le32 *)buf)); | 733 | (__le32 *)buf)); |
734 | DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", | 734 | DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", |
735 | __FUNCTION__, *params->filter); | 735 | __FUNCTION__, *params->filter); |
736 | 736 | ||
737 | /* this call has a significant side effect: it's | 737 | /* this call has a significant side effect: it's |
@@ -756,7 +756,7 @@ update_linkstate: | |||
756 | 756 | ||
757 | case OID_802_3_MULTICAST_LIST: | 757 | case OID_802_3_MULTICAST_LIST: |
758 | /* I think we can ignore this */ | 758 | /* I think we can ignore this */ |
759 | DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); | 759 | DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); |
760 | retval = 0; | 760 | retval = 0; |
761 | break; | 761 | break; |
762 | #if 0 | 762 | #if 0 |
@@ -764,7 +764,7 @@ update_linkstate: | |||
764 | { | 764 | { |
765 | struct rndis_config_parameter *param; | 765 | struct rndis_config_parameter *param; |
766 | param = (struct rndis_config_parameter *) buf; | 766 | param = (struct rndis_config_parameter *) buf; |
767 | DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", | 767 | DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", |
768 | __FUNCTION__, | 768 | __FUNCTION__, |
769 | min(cpu_to_le32(param->ParameterNameLength),80), | 769 | min(cpu_to_le32(param->ParameterNameLength),80), |
770 | buf + param->ParameterNameOffset); | 770 | buf + param->ParameterNameOffset); |
@@ -781,7 +781,7 @@ update_linkstate: | |||
781 | * FIXME ... then things go batty; Windows wedges itself. | 781 | * FIXME ... then things go batty; Windows wedges itself. |
782 | */ | 782 | */ |
783 | i = le32_to_cpu(get_unaligned((__le32 *)buf)); | 783 | i = le32_to_cpu(get_unaligned((__le32 *)buf)); |
784 | DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); | 784 | DBG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); |
785 | switch (i) { | 785 | switch (i) { |
786 | case NdisDeviceStateD0: | 786 | case NdisDeviceStateD0: |
787 | *params->filter = params->saved_filter; | 787 | *params->filter = params->saved_filter; |
@@ -858,7 +858,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
858 | rndis_query_cmplt_type *resp; | 858 | rndis_query_cmplt_type *resp; |
859 | rndis_resp_t *r; | 859 | rndis_resp_t *r; |
860 | 860 | ||
861 | // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); | 861 | // DBG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); |
862 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; | 862 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; |
863 | 863 | ||
864 | /* | 864 | /* |
@@ -911,15 +911,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
911 | BufOffset = le32_to_cpu (buf->InformationBufferOffset); | 911 | BufOffset = le32_to_cpu (buf->InformationBufferOffset); |
912 | 912 | ||
913 | #ifdef VERBOSE | 913 | #ifdef VERBOSE |
914 | DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); | 914 | DBG("%s: Length: %d\n", __FUNCTION__, BufLength); |
915 | DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); | 915 | DBG("%s: Offset: %d\n", __FUNCTION__, BufOffset); |
916 | DEBUG("%s: InfoBuffer: ", __FUNCTION__); | 916 | DBG("%s: InfoBuffer: ", __FUNCTION__); |
917 | 917 | ||
918 | for (i = 0; i < BufLength; i++) { | 918 | for (i = 0; i < BufLength; i++) { |
919 | DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); | 919 | DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); |
920 | } | 920 | } |
921 | 921 | ||
922 | DEBUG ("\n"); | 922 | DBG("\n"); |
923 | #endif | 923 | #endif |
924 | 924 | ||
925 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); | 925 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); |
@@ -1082,14 +1082,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1082 | /* For USB: responses may take up to 10 seconds */ | 1082 | /* For USB: responses may take up to 10 seconds */ |
1083 | switch (MsgType) { | 1083 | switch (MsgType) { |
1084 | case REMOTE_NDIS_INITIALIZE_MSG: | 1084 | case REMOTE_NDIS_INITIALIZE_MSG: |
1085 | DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", | 1085 | DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", |
1086 | __FUNCTION__ ); | 1086 | __FUNCTION__ ); |
1087 | params->state = RNDIS_INITIALIZED; | 1087 | params->state = RNDIS_INITIALIZED; |
1088 | return rndis_init_response (configNr, | 1088 | return rndis_init_response (configNr, |
1089 | (rndis_init_msg_type *) buf); | 1089 | (rndis_init_msg_type *) buf); |
1090 | 1090 | ||
1091 | case REMOTE_NDIS_HALT_MSG: | 1091 | case REMOTE_NDIS_HALT_MSG: |
1092 | DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", | 1092 | DBG("%s: REMOTE_NDIS_HALT_MSG\n", |
1093 | __FUNCTION__ ); | 1093 | __FUNCTION__ ); |
1094 | params->state = RNDIS_UNINITIALIZED; | 1094 | params->state = RNDIS_UNINITIALIZED; |
1095 | if (params->dev) { | 1095 | if (params->dev) { |
@@ -1107,7 +1107,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1107 | (rndis_set_msg_type *) buf); | 1107 | (rndis_set_msg_type *) buf); |
1108 | 1108 | ||
1109 | case REMOTE_NDIS_RESET_MSG: | 1109 | case REMOTE_NDIS_RESET_MSG: |
1110 | DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", | 1110 | DBG("%s: REMOTE_NDIS_RESET_MSG\n", |
1111 | __FUNCTION__ ); | 1111 | __FUNCTION__ ); |
1112 | return rndis_reset_response (configNr, | 1112 | return rndis_reset_response (configNr, |
1113 | (rndis_reset_msg_type *) buf); | 1113 | (rndis_reset_msg_type *) buf); |
@@ -1115,7 +1115,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1115 | case REMOTE_NDIS_KEEPALIVE_MSG: | 1115 | case REMOTE_NDIS_KEEPALIVE_MSG: |
1116 | /* For USB: host does this every 5 seconds */ | 1116 | /* For USB: host does this every 5 seconds */ |
1117 | if (rndis_debug > 1) | 1117 | if (rndis_debug > 1) |
1118 | DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", | 1118 | DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", |
1119 | __FUNCTION__ ); | 1119 | __FUNCTION__ ); |
1120 | return rndis_keepalive_response (configNr, | 1120 | return rndis_keepalive_response (configNr, |
1121 | (rndis_keepalive_msg_type *) | 1121 | (rndis_keepalive_msg_type *) |
@@ -1132,7 +1132,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1132 | { | 1132 | { |
1133 | unsigned i; | 1133 | unsigned i; |
1134 | for (i = 0; i < MsgLength; i += 16) { | 1134 | for (i = 0; i < MsgLength; i += 16) { |
1135 | DEBUG ("%03d: " | 1135 | DBG("%03d: " |
1136 | " %02x %02x %02x %02x" | 1136 | " %02x %02x %02x %02x" |
1137 | " %02x %02x %02x %02x" | 1137 | " %02x %02x %02x %02x" |
1138 | " %02x %02x %02x %02x" | 1138 | " %02x %02x %02x %02x" |
@@ -1163,18 +1163,18 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *)) | |||
1163 | if (!rndis_per_dev_params [i].used) { | 1163 | if (!rndis_per_dev_params [i].used) { |
1164 | rndis_per_dev_params [i].used = 1; | 1164 | rndis_per_dev_params [i].used = 1; |
1165 | rndis_per_dev_params [i].ack = rndis_control_ack; | 1165 | rndis_per_dev_params [i].ack = rndis_control_ack; |
1166 | DEBUG("%s: configNr = %d\n", __FUNCTION__, i); | 1166 | DBG("%s: configNr = %d\n", __FUNCTION__, i); |
1167 | return i; | 1167 | return i; |
1168 | } | 1168 | } |
1169 | } | 1169 | } |
1170 | DEBUG("failed\n"); | 1170 | DBG("failed\n"); |
1171 | 1171 | ||
1172 | return -1; | 1172 | return -1; |
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | void rndis_deregister (int configNr) | 1175 | void rndis_deregister (int configNr) |
1176 | { | 1176 | { |
1177 | DEBUG("%s: \n", __FUNCTION__ ); | 1177 | DBG("%s: \n", __FUNCTION__ ); |
1178 | 1178 | ||
1179 | if (configNr >= RNDIS_MAX_CONFIGS) return; | 1179 | if (configNr >= RNDIS_MAX_CONFIGS) return; |
1180 | rndis_per_dev_params [configNr].used = 0; | 1180 | rndis_per_dev_params [configNr].used = 0; |
@@ -1186,7 +1186,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev, | |||
1186 | struct net_device_stats *stats, | 1186 | struct net_device_stats *stats, |
1187 | u16 *cdc_filter) | 1187 | u16 *cdc_filter) |
1188 | { | 1188 | { |
1189 | DEBUG("%s:\n", __FUNCTION__ ); | 1189 | DBG("%s:\n", __FUNCTION__ ); |
1190 | if (!dev || !stats) return -1; | 1190 | if (!dev || !stats) return -1; |
1191 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 1191 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; |
1192 | 1192 | ||
@@ -1199,7 +1199,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev, | |||
1199 | 1199 | ||
1200 | int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) | 1200 | int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) |
1201 | { | 1201 | { |
1202 | DEBUG("%s:\n", __FUNCTION__ ); | 1202 | DBG("%s:\n", __FUNCTION__ ); |
1203 | if (!vendorDescr) return -1; | 1203 | if (!vendorDescr) return -1; |
1204 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 1204 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; |
1205 | 1205 | ||
@@ -1211,7 +1211,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) | |||
1211 | 1211 | ||
1212 | int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) | 1212 | int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) |
1213 | { | 1213 | { |
1214 | DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed); | 1214 | DBG("%s: %u %u\n", __FUNCTION__, medium, speed); |
1215 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 1215 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; |
1216 | 1216 | ||
1217 | rndis_per_dev_params [configNr].medium = medium; | 1217 | rndis_per_dev_params [configNr].medium = medium; |
@@ -1390,7 +1390,7 @@ static int rndis_proc_write (struct file *file, const char __user *buffer, | |||
1390 | break; | 1390 | break; |
1391 | default: | 1391 | default: |
1392 | if (fl_speed) p->speed = speed; | 1392 | if (fl_speed) p->speed = speed; |
1393 | else DEBUG ("%c is not valid\n", c); | 1393 | else DBG("%c is not valid\n", c); |
1394 | break; | 1394 | break; |
1395 | } | 1395 | } |
1396 | 1396 | ||
@@ -1419,12 +1419,12 @@ int __devinit rndis_init (void) | |||
1419 | if (!(rndis_connect_state [i] | 1419 | if (!(rndis_connect_state [i] |
1420 | = create_proc_entry (name, 0660, NULL))) | 1420 | = create_proc_entry (name, 0660, NULL))) |
1421 | { | 1421 | { |
1422 | DEBUG ("%s :remove entries", __FUNCTION__); | 1422 | DBG("%s :remove entries", __FUNCTION__); |
1423 | while (i) { | 1423 | while (i) { |
1424 | sprintf (name, NAME_TEMPLATE, --i); | 1424 | sprintf (name, NAME_TEMPLATE, --i); |
1425 | remove_proc_entry (name, NULL); | 1425 | remove_proc_entry (name, NULL); |
1426 | } | 1426 | } |
1427 | DEBUG ("\n"); | 1427 | DBG("\n"); |
1428 | return -EIO; | 1428 | return -EIO; |
1429 | } | 1429 | } |
1430 | 1430 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c new file mode 100644 index 000000000000..0be80c635c48 --- /dev/null +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -0,0 +1,2045 @@ | |||
1 | /* | ||
2 | * linux/drivers/usb/gadget/s3c2410_udc.c | ||
3 | * | ||
4 | * Samsung S3C24xx series on-chip full speed USB device controllers | ||
5 | * | ||
6 | * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard | ||
7 | * Additional cleanups by Ben Dooks <ben-linux@fluff.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/list.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/version.h> | ||
39 | #include <linux/clk.h> | ||
40 | |||
41 | #include <linux/debugfs.h> | ||
42 | #include <linux/seq_file.h> | ||
43 | |||
44 | #include <linux/usb.h> | ||
45 | #include <linux/usb_gadget.h> | ||
46 | |||
47 | #include <asm/byteorder.h> | ||
48 | #include <asm/io.h> | ||
49 | #include <asm/irq.h> | ||
50 | #include <asm/system.h> | ||
51 | #include <asm/unaligned.h> | ||
52 | #include <asm/arch/irqs.h> | ||
53 | |||
54 | #include <asm/arch/hardware.h> | ||
55 | #include <asm/arch/regs-clock.h> | ||
56 | #include <asm/arch/regs-gpio.h> | ||
57 | #include <asm/arch/regs-udc.h> | ||
58 | #include <asm/arch/udc.h> | ||
59 | |||
60 | #include <asm/mach-types.h> | ||
61 | |||
62 | #include "s3c2410_udc.h" | ||
63 | |||
64 | #define DRIVER_DESC "S3C2410 USB Device Controller Gadget" | ||
65 | #define DRIVER_VERSION "29 Apr 2007" | ||
66 | #define DRIVER_AUTHOR "Herbert Pötzl <herbert@13thfloor.at>, " \ | ||
67 | "Arnaud Patard <arnaud.patard@rtp-net.org>" | ||
68 | |||
69 | static const char gadget_name[] = "s3c2410_udc"; | ||
70 | static const char driver_desc[] = DRIVER_DESC; | ||
71 | |||
72 | static struct s3c2410_udc *the_controller; | ||
73 | static struct clk *udc_clock; | ||
74 | static struct clk *usb_bus_clock; | ||
75 | static void __iomem *base_addr; | ||
76 | static u64 rsrc_start; | ||
77 | static u64 rsrc_len; | ||
78 | static struct dentry *s3c2410_udc_debugfs_root; | ||
79 | |||
80 | static inline u32 udc_read(u32 reg) | ||
81 | { | ||
82 | return readb(base_addr + reg); | ||
83 | } | ||
84 | |||
85 | static inline void udc_write(u32 value, u32 reg) | ||
86 | { | ||
87 | writeb(value, base_addr + reg); | ||
88 | } | ||
89 | |||
90 | static inline void udc_writeb(void __iomem *base, u32 value, u32 reg) | ||
91 | { | ||
92 | writeb(value, base + reg); | ||
93 | } | ||
94 | |||
95 | static struct s3c2410_udc_mach_info *udc_info; | ||
96 | |||
97 | /*************************** DEBUG FUNCTION ***************************/ | ||
98 | #define DEBUG_NORMAL 1 | ||
99 | #define DEBUG_VERBOSE 2 | ||
100 | |||
101 | #ifdef CONFIG_USB_S3C2410_DEBUG | ||
102 | #define USB_S3C2410_DEBUG_LEVEL 0 | ||
103 | |||
104 | static uint32_t s3c2410_ticks = 0; | ||
105 | |||
106 | static int dprintk(int level, const char *fmt, ...) | ||
107 | { | ||
108 | static char printk_buf[1024]; | ||
109 | static long prevticks; | ||
110 | static int invocation; | ||
111 | va_list args; | ||
112 | int len; | ||
113 | |||
114 | if (level > USB_S3C2410_DEBUG_LEVEL) | ||
115 | return 0; | ||
116 | |||
117 | if (s3c2410_ticks != prevticks) { | ||
118 | prevticks = s3c2410_ticks; | ||
119 | invocation = 0; | ||
120 | } | ||
121 | |||
122 | len = scnprintf(printk_buf, | ||
123 | sizeof(printk_buf), "%1lu.%02d USB: ", | ||
124 | prevticks, invocation++); | ||
125 | |||
126 | va_start(args, fmt); | ||
127 | len = vscnprintf(printk_buf+len, | ||
128 | sizeof(printk_buf)-len, fmt, args); | ||
129 | va_end(args); | ||
130 | |||
131 | return printk(KERN_DEBUG "%s", printk_buf); | ||
132 | } | ||
133 | #else | ||
134 | static int dprintk(int level, const char *fmt, ...) | ||
135 | { | ||
136 | return 0; | ||
137 | } | ||
138 | #endif | ||
139 | static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) | ||
140 | { | ||
141 | u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg; | ||
142 | u32 ep_int_en_reg, usb_int_en_reg, ep0_csr; | ||
143 | u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2; | ||
144 | u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2; | ||
145 | |||
146 | addr_reg = udc_read(S3C2410_UDC_FUNC_ADDR_REG); | ||
147 | pwr_reg = udc_read(S3C2410_UDC_PWR_REG); | ||
148 | ep_int_reg = udc_read(S3C2410_UDC_EP_INT_REG); | ||
149 | usb_int_reg = udc_read(S3C2410_UDC_USB_INT_REG); | ||
150 | ep_int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG); | ||
151 | usb_int_en_reg = udc_read(S3C2410_UDC_USB_INT_EN_REG); | ||
152 | udc_write(0, S3C2410_UDC_INDEX_REG); | ||
153 | ep0_csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
154 | udc_write(1, S3C2410_UDC_INDEX_REG); | ||
155 | ep1_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
156 | ep1_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG); | ||
157 | ep1_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
158 | ep1_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG); | ||
159 | udc_write(2, S3C2410_UDC_INDEX_REG); | ||
160 | ep2_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
161 | ep2_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG); | ||
162 | ep2_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
163 | ep2_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG); | ||
164 | |||
165 | seq_printf(m, "FUNC_ADDR_REG : 0x%04X\n" | ||
166 | "PWR_REG : 0x%04X\n" | ||
167 | "EP_INT_REG : 0x%04X\n" | ||
168 | "USB_INT_REG : 0x%04X\n" | ||
169 | "EP_INT_EN_REG : 0x%04X\n" | ||
170 | "USB_INT_EN_REG : 0x%04X\n" | ||
171 | "EP0_CSR : 0x%04X\n" | ||
172 | "EP1_I_CSR1 : 0x%04X\n" | ||
173 | "EP1_I_CSR2 : 0x%04X\n" | ||
174 | "EP1_O_CSR1 : 0x%04X\n" | ||
175 | "EP1_O_CSR2 : 0x%04X\n" | ||
176 | "EP2_I_CSR1 : 0x%04X\n" | ||
177 | "EP2_I_CSR2 : 0x%04X\n" | ||
178 | "EP2_O_CSR1 : 0x%04X\n" | ||
179 | "EP2_O_CSR2 : 0x%04X\n", | ||
180 | addr_reg,pwr_reg,ep_int_reg,usb_int_reg, | ||
181 | ep_int_en_reg, usb_int_en_reg, ep0_csr, | ||
182 | ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2, | ||
183 | ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2 | ||
184 | ); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int s3c2410_udc_debugfs_fops_open(struct inode *inode, | ||
190 | struct file *file) | ||
191 | { | ||
192 | return single_open(file, s3c2410_udc_debugfs_seq_show, NULL); | ||
193 | } | ||
194 | |||
195 | static const struct file_operations s3c2410_udc_debugfs_fops = { | ||
196 | .open = s3c2410_udc_debugfs_fops_open, | ||
197 | .read = seq_read, | ||
198 | .llseek = seq_lseek, | ||
199 | .release = single_release, | ||
200 | .owner = THIS_MODULE, | ||
201 | }; | ||
202 | |||
203 | /* io macros */ | ||
204 | |||
205 | static inline void s3c2410_udc_clear_ep0_opr(void __iomem *base) | ||
206 | { | ||
207 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
208 | udc_writeb(base, S3C2410_UDC_EP0_CSR_SOPKTRDY, | ||
209 | S3C2410_UDC_EP0_CSR_REG); | ||
210 | } | ||
211 | |||
212 | static inline void s3c2410_udc_clear_ep0_sst(void __iomem *base) | ||
213 | { | ||
214 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
215 | writeb(0x00, base + S3C2410_UDC_EP0_CSR_REG); | ||
216 | } | ||
217 | |||
218 | static inline void s3c2410_udc_clear_ep0_se(void __iomem *base) | ||
219 | { | ||
220 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
221 | udc_writeb(base, S3C2410_UDC_EP0_CSR_SSE, S3C2410_UDC_EP0_CSR_REG); | ||
222 | } | ||
223 | |||
224 | static inline void s3c2410_udc_set_ep0_ipr(void __iomem *base) | ||
225 | { | ||
226 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
227 | udc_writeb(base, S3C2410_UDC_EP0_CSR_IPKRDY, S3C2410_UDC_EP0_CSR_REG); | ||
228 | } | ||
229 | |||
230 | static inline void s3c2410_udc_set_ep0_de(void __iomem *base) | ||
231 | { | ||
232 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
233 | udc_writeb(base, S3C2410_UDC_EP0_CSR_DE, S3C2410_UDC_EP0_CSR_REG); | ||
234 | } | ||
235 | |||
236 | inline void s3c2410_udc_set_ep0_ss(void __iomem *b) | ||
237 | { | ||
238 | udc_writeb(b, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
239 | udc_writeb(b, S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG); | ||
240 | } | ||
241 | |||
242 | static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base) | ||
243 | { | ||
244 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
245 | |||
246 | udc_writeb(base,(S3C2410_UDC_EP0_CSR_SOPKTRDY | ||
247 | | S3C2410_UDC_EP0_CSR_DE), | ||
248 | S3C2410_UDC_EP0_CSR_REG); | ||
249 | } | ||
250 | |||
251 | static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base) | ||
252 | { | ||
253 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
254 | udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY | ||
255 | | S3C2410_UDC_EP0_CSR_SSE), | ||
256 | S3C2410_UDC_EP0_CSR_REG); | ||
257 | } | ||
258 | |||
259 | static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base) | ||
260 | { | ||
261 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
262 | udc_writeb(base, (S3C2410_UDC_EP0_CSR_IPKRDY | ||
263 | | S3C2410_UDC_EP0_CSR_DE), | ||
264 | S3C2410_UDC_EP0_CSR_REG); | ||
265 | } | ||
266 | |||
267 | /*------------------------- I/O ----------------------------------*/ | ||
268 | |||
269 | /* | ||
270 | * s3c2410_udc_done | ||
271 | */ | ||
272 | static void s3c2410_udc_done(struct s3c2410_ep *ep, | ||
273 | struct s3c2410_request *req, int status) | ||
274 | { | ||
275 | unsigned halted = ep->halted; | ||
276 | |||
277 | list_del_init(&req->queue); | ||
278 | |||
279 | if (likely (req->req.status == -EINPROGRESS)) | ||
280 | req->req.status = status; | ||
281 | else | ||
282 | status = req->req.status; | ||
283 | |||
284 | ep->halted = 1; | ||
285 | req->req.complete(&ep->ep, &req->req); | ||
286 | ep->halted = halted; | ||
287 | } | ||
288 | |||
289 | static void s3c2410_udc_nuke(struct s3c2410_udc *udc, | ||
290 | struct s3c2410_ep *ep, int status) | ||
291 | { | ||
292 | /* Sanity check */ | ||
293 | if (&ep->queue == NULL) | ||
294 | return; | ||
295 | |||
296 | while (!list_empty (&ep->queue)) { | ||
297 | struct s3c2410_request *req; | ||
298 | req = list_entry (ep->queue.next, struct s3c2410_request, | ||
299 | queue); | ||
300 | s3c2410_udc_done(ep, req, status); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | static inline void s3c2410_udc_clear_ep_state(struct s3c2410_udc *dev) | ||
305 | { | ||
306 | unsigned i; | ||
307 | |||
308 | /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint | ||
309 | * fifos, and pending transactions mustn't be continued in any case. | ||
310 | */ | ||
311 | |||
312 | for (i = 1; i < S3C2410_ENDPOINTS; i++) | ||
313 | s3c2410_udc_nuke(dev, &dev->ep[i], -ECONNABORTED); | ||
314 | } | ||
315 | |||
316 | static inline int s3c2410_udc_fifo_count_out(void) | ||
317 | { | ||
318 | int tmp; | ||
319 | |||
320 | tmp = udc_read(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8; | ||
321 | tmp |= udc_read(S3C2410_UDC_OUT_FIFO_CNT1_REG); | ||
322 | return tmp; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * s3c2410_udc_write_packet | ||
327 | */ | ||
328 | static inline int s3c2410_udc_write_packet(int fifo, | ||
329 | struct s3c2410_request *req, | ||
330 | unsigned max) | ||
331 | { | ||
332 | unsigned len = min(req->req.length - req->req.actual, max); | ||
333 | u8 *buf = req->req.buf + req->req.actual; | ||
334 | |||
335 | prefetch(buf); | ||
336 | |||
337 | dprintk(DEBUG_VERBOSE, "%s %d %d %d %d\n", __func__, | ||
338 | req->req.actual, req->req.length, len, req->req.actual + len); | ||
339 | |||
340 | req->req.actual += len; | ||
341 | |||
342 | udelay(5); | ||
343 | writesb(base_addr + fifo, buf, len); | ||
344 | return len; | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * s3c2410_udc_write_fifo | ||
349 | * | ||
350 | * return: 0 = still running, 1 = completed, negative = errno | ||
351 | */ | ||
352 | static int s3c2410_udc_write_fifo(struct s3c2410_ep *ep, | ||
353 | struct s3c2410_request *req) | ||
354 | { | ||
355 | unsigned count; | ||
356 | int is_last; | ||
357 | u32 idx; | ||
358 | int fifo_reg; | ||
359 | u32 ep_csr; | ||
360 | |||
361 | idx = ep->bEndpointAddress & 0x7F; | ||
362 | switch (idx) { | ||
363 | default: | ||
364 | idx = 0; | ||
365 | case 0: | ||
366 | fifo_reg = S3C2410_UDC_EP0_FIFO_REG; | ||
367 | break; | ||
368 | case 1: | ||
369 | fifo_reg = S3C2410_UDC_EP1_FIFO_REG; | ||
370 | break; | ||
371 | case 2: | ||
372 | fifo_reg = S3C2410_UDC_EP2_FIFO_REG; | ||
373 | break; | ||
374 | case 3: | ||
375 | fifo_reg = S3C2410_UDC_EP3_FIFO_REG; | ||
376 | break; | ||
377 | case 4: | ||
378 | fifo_reg = S3C2410_UDC_EP4_FIFO_REG; | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | count = s3c2410_udc_write_packet(fifo_reg, req, ep->ep.maxpacket); | ||
383 | |||
384 | /* last packet is often short (sometimes a zlp) */ | ||
385 | if (count != ep->ep.maxpacket) | ||
386 | is_last = 1; | ||
387 | else if (req->req.length != req->req.actual || req->req.zero) | ||
388 | is_last = 0; | ||
389 | else | ||
390 | is_last = 2; | ||
391 | |||
392 | /* Only ep0 debug messages are interesting */ | ||
393 | if (idx == 0) | ||
394 | dprintk(DEBUG_NORMAL, | ||
395 | "Written ep%d %d.%d of %d b [last %d,z %d]\n", | ||
396 | idx, count, req->req.actual, req->req.length, | ||
397 | is_last, req->req.zero); | ||
398 | |||
399 | if (is_last) { | ||
400 | /* The order is important. It prevents sending 2 packets | ||
401 | * at the same time */ | ||
402 | |||
403 | if (idx == 0) { | ||
404 | /* Reset signal => no need to say 'data sent' */ | ||
405 | if (! (udc_read(S3C2410_UDC_USB_INT_REG) | ||
406 | & S3C2410_UDC_USBINT_RESET)) | ||
407 | s3c2410_udc_set_ep0_de_in(base_addr); | ||
408 | ep->dev->ep0state=EP0_IDLE; | ||
409 | } else { | ||
410 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
411 | ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
412 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
413 | udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY, | ||
414 | S3C2410_UDC_IN_CSR1_REG); | ||
415 | } | ||
416 | |||
417 | s3c2410_udc_done(ep, req, 0); | ||
418 | is_last = 1; | ||
419 | } else { | ||
420 | if (idx == 0) { | ||
421 | /* Reset signal => no need to say 'data sent' */ | ||
422 | if (! (udc_read(S3C2410_UDC_USB_INT_REG) | ||
423 | & S3C2410_UDC_USBINT_RESET)) | ||
424 | s3c2410_udc_set_ep0_ipr(base_addr); | ||
425 | } else { | ||
426 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
427 | ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
428 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
429 | udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY, | ||
430 | S3C2410_UDC_IN_CSR1_REG); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | return is_last; | ||
435 | } | ||
436 | |||
437 | static inline int s3c2410_udc_read_packet(int fifo, u8 *buf, | ||
438 | struct s3c2410_request *req, unsigned avail) | ||
439 | { | ||
440 | unsigned len; | ||
441 | |||
442 | len = min(req->req.length - req->req.actual, avail); | ||
443 | req->req.actual += len; | ||
444 | |||
445 | readsb(fifo + base_addr, buf, len); | ||
446 | return len; | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * return: 0 = still running, 1 = queue empty, negative = errno | ||
451 | */ | ||
452 | static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep, | ||
453 | struct s3c2410_request *req) | ||
454 | { | ||
455 | u8 *buf; | ||
456 | u32 ep_csr; | ||
457 | unsigned bufferspace; | ||
458 | int is_last=1; | ||
459 | unsigned avail; | ||
460 | int fifo_count = 0; | ||
461 | u32 idx; | ||
462 | int fifo_reg; | ||
463 | |||
464 | idx = ep->bEndpointAddress & 0x7F; | ||
465 | |||
466 | switch (idx) { | ||
467 | default: | ||
468 | idx = 0; | ||
469 | case 0: | ||
470 | fifo_reg = S3C2410_UDC_EP0_FIFO_REG; | ||
471 | break; | ||
472 | case 1: | ||
473 | fifo_reg = S3C2410_UDC_EP1_FIFO_REG; | ||
474 | break; | ||
475 | case 2: | ||
476 | fifo_reg = S3C2410_UDC_EP2_FIFO_REG; | ||
477 | break; | ||
478 | case 3: | ||
479 | fifo_reg = S3C2410_UDC_EP3_FIFO_REG; | ||
480 | break; | ||
481 | case 4: | ||
482 | fifo_reg = S3C2410_UDC_EP4_FIFO_REG; | ||
483 | break; | ||
484 | } | ||
485 | |||
486 | if (!req->req.length) | ||
487 | return 1; | ||
488 | |||
489 | buf = req->req.buf + req->req.actual; | ||
490 | bufferspace = req->req.length - req->req.actual; | ||
491 | if (!bufferspace) { | ||
492 | dprintk(DEBUG_NORMAL, "%s: buffer full!\n", __func__); | ||
493 | return -1; | ||
494 | } | ||
495 | |||
496 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
497 | |||
498 | fifo_count = s3c2410_udc_fifo_count_out(); | ||
499 | dprintk(DEBUG_NORMAL, "%s fifo count : %d\n", __func__, fifo_count); | ||
500 | |||
501 | if (fifo_count > ep->ep.maxpacket) | ||
502 | avail = ep->ep.maxpacket; | ||
503 | else | ||
504 | avail = fifo_count; | ||
505 | |||
506 | fifo_count = s3c2410_udc_read_packet(fifo_reg, buf, req, avail); | ||
507 | |||
508 | /* checking this with ep0 is not accurate as we already | ||
509 | * read a control request | ||
510 | **/ | ||
511 | if (idx != 0 && fifo_count < ep->ep.maxpacket) { | ||
512 | is_last = 1; | ||
513 | /* overflowed this request? flush extra data */ | ||
514 | if (fifo_count != avail) | ||
515 | req->req.status = -EOVERFLOW; | ||
516 | } else { | ||
517 | is_last = (req->req.length <= req->req.actual) ? 1 : 0; | ||
518 | } | ||
519 | |||
520 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
521 | fifo_count = s3c2410_udc_fifo_count_out(); | ||
522 | |||
523 | /* Only ep0 debug messages are interesting */ | ||
524 | if (idx == 0) | ||
525 | dprintk(DEBUG_VERBOSE, "%s fifo count : %d [last %d]\n", | ||
526 | __func__, fifo_count,is_last); | ||
527 | |||
528 | if (is_last) { | ||
529 | if (idx == 0) { | ||
530 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
531 | ep->dev->ep0state = EP0_IDLE; | ||
532 | } else { | ||
533 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
534 | ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG); | ||
535 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
536 | udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY, | ||
537 | S3C2410_UDC_OUT_CSR1_REG); | ||
538 | } | ||
539 | |||
540 | s3c2410_udc_done(ep, req, 0); | ||
541 | } else { | ||
542 | if (idx == 0) { | ||
543 | s3c2410_udc_clear_ep0_opr(base_addr); | ||
544 | } else { | ||
545 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
546 | ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG); | ||
547 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
548 | udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY, | ||
549 | S3C2410_UDC_OUT_CSR1_REG); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | return is_last; | ||
554 | } | ||
555 | |||
556 | static int s3c2410_udc_read_fifo_crq(struct usb_ctrlrequest *crq) | ||
557 | { | ||
558 | unsigned char *outbuf = (unsigned char*)crq; | ||
559 | int bytes_read = 0; | ||
560 | |||
561 | udc_write(0, S3C2410_UDC_INDEX_REG); | ||
562 | |||
563 | bytes_read = s3c2410_udc_fifo_count_out(); | ||
564 | |||
565 | dprintk(DEBUG_NORMAL, "%s: fifo_count=%d\n", __func__, bytes_read); | ||
566 | |||
567 | if (bytes_read > sizeof(struct usb_ctrlrequest)) | ||
568 | bytes_read = sizeof(struct usb_ctrlrequest); | ||
569 | |||
570 | readsb(S3C2410_UDC_EP0_FIFO_REG + base_addr, outbuf, bytes_read); | ||
571 | |||
572 | dprintk(DEBUG_VERBOSE, "%s: len=%d %02x:%02x {%x,%x,%x}\n", __func__, | ||
573 | bytes_read, crq->bRequest, crq->bRequestType, | ||
574 | crq->wValue, crq->wIndex, crq->wLength); | ||
575 | |||
576 | return bytes_read; | ||
577 | } | ||
578 | |||
579 | static int s3c2410_udc_get_status(struct s3c2410_udc *dev, | ||
580 | struct usb_ctrlrequest *crq) | ||
581 | { | ||
582 | u16 status = 0; | ||
583 | u8 ep_num = crq->wIndex & 0x7F; | ||
584 | u8 is_in = crq->wIndex & USB_DIR_IN; | ||
585 | |||
586 | switch (crq->bRequestType & USB_RECIP_MASK) { | ||
587 | case USB_RECIP_INTERFACE: | ||
588 | break; | ||
589 | |||
590 | case USB_RECIP_DEVICE: | ||
591 | status = dev->devstatus; | ||
592 | break; | ||
593 | |||
594 | case USB_RECIP_ENDPOINT: | ||
595 | if (ep_num > 4 || crq->wLength > 2) | ||
596 | return 1; | ||
597 | |||
598 | if (ep_num == 0) { | ||
599 | udc_write(0, S3C2410_UDC_INDEX_REG); | ||
600 | status = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
601 | status = status & S3C2410_UDC_EP0_CSR_SENDSTL; | ||
602 | } else { | ||
603 | udc_write(ep_num, S3C2410_UDC_INDEX_REG); | ||
604 | if (is_in) { | ||
605 | status = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
606 | status = status & S3C2410_UDC_ICSR1_SENDSTL; | ||
607 | } else { | ||
608 | status = udc_read(S3C2410_UDC_OUT_CSR1_REG); | ||
609 | status = status & S3C2410_UDC_OCSR1_SENDSTL; | ||
610 | } | ||
611 | } | ||
612 | |||
613 | status = status ? 1 : 0; | ||
614 | break; | ||
615 | |||
616 | default: | ||
617 | return 1; | ||
618 | } | ||
619 | |||
620 | /* Seems to be needed to get it working. ouch :( */ | ||
621 | udelay(5); | ||
622 | udc_write(status & 0xFF, S3C2410_UDC_EP0_FIFO_REG); | ||
623 | udc_write(status >> 8, S3C2410_UDC_EP0_FIFO_REG); | ||
624 | s3c2410_udc_set_ep0_de_in(base_addr); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | /*------------------------- usb state machine -------------------------------*/ | ||
629 | static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value); | ||
630 | |||
631 | static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, | ||
632 | struct s3c2410_ep *ep, | ||
633 | struct usb_ctrlrequest *crq, | ||
634 | u32 ep0csr) | ||
635 | { | ||
636 | int len, ret, tmp; | ||
637 | |||
638 | /* start control request? */ | ||
639 | if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY)) | ||
640 | return; | ||
641 | |||
642 | s3c2410_udc_nuke(dev, ep, -EPROTO); | ||
643 | |||
644 | len = s3c2410_udc_read_fifo_crq(crq); | ||
645 | if (len != sizeof(*crq)) { | ||
646 | dprintk(DEBUG_NORMAL, "setup begin: fifo READ ERROR" | ||
647 | " wanted %d bytes got %d. Stalling out...\n", | ||
648 | sizeof(*crq), len); | ||
649 | s3c2410_udc_set_ep0_ss(base_addr); | ||
650 | return; | ||
651 | } | ||
652 | |||
653 | dprintk(DEBUG_NORMAL, "bRequest = %d bRequestType %d wLength = %d\n", | ||
654 | crq->bRequest, crq->bRequestType, crq->wLength); | ||
655 | |||
656 | /* cope with automagic for some standard requests. */ | ||
657 | dev->req_std = (crq->bRequestType & USB_TYPE_MASK) | ||
658 | == USB_TYPE_STANDARD; | ||
659 | dev->req_config = 0; | ||
660 | dev->req_pending = 1; | ||
661 | |||
662 | switch (crq->bRequest) { | ||
663 | case USB_REQ_SET_CONFIGURATION: | ||
664 | dprintk(DEBUG_NORMAL, "USB_REQ_SET_CONFIGURATION ... \n"); | ||
665 | |||
666 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
667 | dev->req_config = 1; | ||
668 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
669 | } | ||
670 | break; | ||
671 | |||
672 | case USB_REQ_SET_INTERFACE: | ||
673 | dprintk(DEBUG_NORMAL, "USB_REQ_SET_INTERFACE ... \n"); | ||
674 | |||
675 | if (crq->bRequestType == USB_RECIP_INTERFACE) { | ||
676 | dev->req_config = 1; | ||
677 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
678 | } | ||
679 | break; | ||
680 | |||
681 | case USB_REQ_SET_ADDRESS: | ||
682 | dprintk(DEBUG_NORMAL, "USB_REQ_SET_ADDRESS ... \n"); | ||
683 | |||
684 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
685 | tmp = crq->wValue & 0x7F; | ||
686 | dev->address = tmp; | ||
687 | udc_write((tmp | S3C2410_UDC_FUNCADDR_UPDATE), | ||
688 | S3C2410_UDC_FUNC_ADDR_REG); | ||
689 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
690 | return; | ||
691 | } | ||
692 | break; | ||
693 | |||
694 | case USB_REQ_GET_STATUS: | ||
695 | dprintk(DEBUG_NORMAL, "USB_REQ_GET_STATUS ... \n"); | ||
696 | s3c2410_udc_clear_ep0_opr(base_addr); | ||
697 | |||
698 | if (dev->req_std) { | ||
699 | if (!s3c2410_udc_get_status(dev, crq)) { | ||
700 | return; | ||
701 | } | ||
702 | } | ||
703 | break; | ||
704 | |||
705 | case USB_REQ_CLEAR_FEATURE: | ||
706 | s3c2410_udc_clear_ep0_opr(base_addr); | ||
707 | |||
708 | if (crq->bRequestType != USB_RECIP_ENDPOINT) | ||
709 | break; | ||
710 | |||
711 | if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0) | ||
712 | break; | ||
713 | |||
714 | s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 0); | ||
715 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
716 | return; | ||
717 | |||
718 | case USB_REQ_SET_FEATURE: | ||
719 | s3c2410_udc_clear_ep0_opr(base_addr); | ||
720 | |||
721 | if (crq->bRequestType != USB_RECIP_ENDPOINT) | ||
722 | break; | ||
723 | |||
724 | if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0) | ||
725 | break; | ||
726 | |||
727 | s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 1); | ||
728 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
729 | return; | ||
730 | |||
731 | default: | ||
732 | s3c2410_udc_clear_ep0_opr(base_addr); | ||
733 | break; | ||
734 | } | ||
735 | |||
736 | if (crq->bRequestType & USB_DIR_IN) | ||
737 | dev->ep0state = EP0_IN_DATA_PHASE; | ||
738 | else | ||
739 | dev->ep0state = EP0_OUT_DATA_PHASE; | ||
740 | |||
741 | ret = dev->driver->setup(&dev->gadget, crq); | ||
742 | if (ret < 0) { | ||
743 | if (dev->req_config) { | ||
744 | dprintk(DEBUG_NORMAL, "config change %02x fail %d?\n", | ||
745 | crq->bRequest, ret); | ||
746 | return; | ||
747 | } | ||
748 | |||
749 | if (ret == -EOPNOTSUPP) | ||
750 | dprintk(DEBUG_NORMAL, "Operation not supported\n"); | ||
751 | else | ||
752 | dprintk(DEBUG_NORMAL, | ||
753 | "dev->driver->setup failed. (%d)\n", ret); | ||
754 | |||
755 | udelay(5); | ||
756 | s3c2410_udc_set_ep0_ss(base_addr); | ||
757 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
758 | dev->ep0state = EP0_IDLE; | ||
759 | /* deferred i/o == no response yet */ | ||
760 | } else if (dev->req_pending) { | ||
761 | dprintk(DEBUG_VERBOSE, "dev->req_pending... what now?\n"); | ||
762 | dev->req_pending=0; | ||
763 | } | ||
764 | |||
765 | dprintk(DEBUG_VERBOSE, "ep0state %s\n", ep0states[dev->ep0state]); | ||
766 | } | ||
767 | |||
768 | static void s3c2410_udc_handle_ep0(struct s3c2410_udc *dev) | ||
769 | { | ||
770 | u32 ep0csr; | ||
771 | struct s3c2410_ep *ep = &dev->ep[0]; | ||
772 | struct s3c2410_request *req; | ||
773 | struct usb_ctrlrequest crq; | ||
774 | |||
775 | if (list_empty(&ep->queue)) | ||
776 | req = NULL; | ||
777 | else | ||
778 | req = list_entry(ep->queue.next, struct s3c2410_request, queue); | ||
779 | |||
780 | /* We make the assumption that S3C2410_UDC_IN_CSR1_REG equal to | ||
781 | * S3C2410_UDC_EP0_CSR_REG when index is zero */ | ||
782 | |||
783 | udc_write(0, S3C2410_UDC_INDEX_REG); | ||
784 | ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
785 | |||
786 | dprintk(DEBUG_NORMAL, "ep0csr %x ep0state %s\n", | ||
787 | ep0csr, ep0states[dev->ep0state]); | ||
788 | |||
789 | /* clear stall status */ | ||
790 | if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) { | ||
791 | s3c2410_udc_nuke(dev, ep, -EPIPE); | ||
792 | dprintk(DEBUG_NORMAL, "... clear SENT_STALL ...\n"); | ||
793 | s3c2410_udc_clear_ep0_sst(base_addr); | ||
794 | dev->ep0state = EP0_IDLE; | ||
795 | return; | ||
796 | } | ||
797 | |||
798 | /* clear setup end */ | ||
799 | if (ep0csr & S3C2410_UDC_EP0_CSR_SE) { | ||
800 | dprintk(DEBUG_NORMAL, "... serviced SETUP_END ...\n"); | ||
801 | s3c2410_udc_nuke(dev, ep, 0); | ||
802 | s3c2410_udc_clear_ep0_se(base_addr); | ||
803 | dev->ep0state = EP0_IDLE; | ||
804 | } | ||
805 | |||
806 | switch (dev->ep0state) { | ||
807 | case EP0_IDLE: | ||
808 | s3c2410_udc_handle_ep0_idle(dev, ep, &crq, ep0csr); | ||
809 | break; | ||
810 | |||
811 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */ | ||
812 | dprintk(DEBUG_NORMAL, "EP0_IN_DATA_PHASE ... what now?\n"); | ||
813 | if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY) && req) { | ||
814 | s3c2410_udc_write_fifo(ep, req); | ||
815 | } | ||
816 | break; | ||
817 | |||
818 | case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */ | ||
819 | dprintk(DEBUG_NORMAL, "EP0_OUT_DATA_PHASE ... what now?\n"); | ||
820 | if ((ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) && req ) { | ||
821 | s3c2410_udc_read_fifo(ep,req); | ||
822 | } | ||
823 | break; | ||
824 | |||
825 | case EP0_END_XFER: | ||
826 | dprintk(DEBUG_NORMAL, "EP0_END_XFER ... what now?\n"); | ||
827 | dev->ep0state = EP0_IDLE; | ||
828 | break; | ||
829 | |||
830 | case EP0_STALL: | ||
831 | dprintk(DEBUG_NORMAL, "EP0_STALL ... what now?\n"); | ||
832 | dev->ep0state = EP0_IDLE; | ||
833 | break; | ||
834 | } | ||
835 | } | ||
836 | |||
837 | /* | ||
838 | * handle_ep - Manage I/O endpoints | ||
839 | */ | ||
840 | |||
841 | static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) | ||
842 | { | ||
843 | struct s3c2410_request *req; | ||
844 | int is_in = ep->bEndpointAddress & USB_DIR_IN; | ||
845 | u32 ep_csr1; | ||
846 | u32 idx; | ||
847 | |||
848 | if (likely (!list_empty(&ep->queue))) | ||
849 | req = list_entry(ep->queue.next, | ||
850 | struct s3c2410_request, queue); | ||
851 | else | ||
852 | req = NULL; | ||
853 | |||
854 | idx = ep->bEndpointAddress & 0x7F; | ||
855 | |||
856 | if (is_in) { | ||
857 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
858 | ep_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
859 | dprintk(DEBUG_VERBOSE, "ep%01d write csr:%02x %d\n", | ||
860 | idx, ep_csr1, req ? 1 : 0); | ||
861 | |||
862 | if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) { | ||
863 | dprintk(DEBUG_VERBOSE, "st\n"); | ||
864 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
865 | udc_write(ep_csr1 & ~S3C2410_UDC_ICSR1_SENTSTL, | ||
866 | S3C2410_UDC_IN_CSR1_REG); | ||
867 | return; | ||
868 | } | ||
869 | |||
870 | if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) { | ||
871 | s3c2410_udc_write_fifo(ep,req); | ||
872 | } | ||
873 | } else { | ||
874 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
875 | ep_csr1 = udc_read(S3C2410_UDC_OUT_CSR1_REG); | ||
876 | dprintk(DEBUG_VERBOSE, "ep%01d rd csr:%02x\n", idx, ep_csr1); | ||
877 | |||
878 | if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) { | ||
879 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
880 | udc_write(ep_csr1 & ~S3C2410_UDC_OCSR1_SENTSTL, | ||
881 | S3C2410_UDC_OUT_CSR1_REG); | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) { | ||
886 | s3c2410_udc_read_fifo(ep,req); | ||
887 | } | ||
888 | } | ||
889 | } | ||
890 | |||
891 | #include <asm/arch/regs-irq.h> | ||
892 | |||
893 | /* | ||
894 | * s3c2410_udc_irq - interrupt handler | ||
895 | */ | ||
896 | static irqreturn_t s3c2410_udc_irq(int irq, void *_dev) | ||
897 | { | ||
898 | struct s3c2410_udc *dev = _dev; | ||
899 | int usb_status; | ||
900 | int usbd_status; | ||
901 | int pwr_reg; | ||
902 | int ep0csr; | ||
903 | int i; | ||
904 | u32 idx; | ||
905 | unsigned long flags; | ||
906 | |||
907 | spin_lock_irqsave(&dev->lock, flags); | ||
908 | |||
909 | /* Driver connected ? */ | ||
910 | if (!dev->driver) { | ||
911 | /* Clear interrupts */ | ||
912 | udc_write(udc_read(S3C2410_UDC_USB_INT_REG), | ||
913 | S3C2410_UDC_USB_INT_REG); | ||
914 | udc_write(udc_read(S3C2410_UDC_EP_INT_REG), | ||
915 | S3C2410_UDC_EP_INT_REG); | ||
916 | } | ||
917 | |||
918 | /* Save index */ | ||
919 | idx = udc_read(S3C2410_UDC_INDEX_REG); | ||
920 | |||
921 | /* Read status registers */ | ||
922 | usb_status = udc_read(S3C2410_UDC_USB_INT_REG); | ||
923 | usbd_status = udc_read(S3C2410_UDC_EP_INT_REG); | ||
924 | pwr_reg = udc_read(S3C2410_UDC_PWR_REG); | ||
925 | |||
926 | udc_writeb(base_addr, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
927 | ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
928 | |||
929 | dprintk(DEBUG_NORMAL, "usbs=%02x, usbds=%02x, pwr=%02x ep0csr=%02x\n", | ||
930 | usb_status, usbd_status, pwr_reg, ep0csr); | ||
931 | |||
932 | /* | ||
933 | * Now, handle interrupts. There's two types : | ||
934 | * - Reset, Resume, Suspend coming -> usb_int_reg | ||
935 | * - EP -> ep_int_reg | ||
936 | */ | ||
937 | |||
938 | /* RESET */ | ||
939 | if (usb_status & S3C2410_UDC_USBINT_RESET) { | ||
940 | /* two kind of reset : | ||
941 | * - reset start -> pwr reg = 8 | ||
942 | * - reset end -> pwr reg = 0 | ||
943 | **/ | ||
944 | dprintk(DEBUG_NORMAL, "USB reset csr %x pwr %x\n", | ||
945 | ep0csr, pwr_reg); | ||
946 | |||
947 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
948 | udc_write(0x00, S3C2410_UDC_INDEX_REG); | ||
949 | udc_write((dev->ep[0].ep.maxpacket & 0x7ff) >> 3, | ||
950 | S3C2410_UDC_MAXP_REG); | ||
951 | dev->address = 0; | ||
952 | |||
953 | dev->ep0state = EP0_IDLE; | ||
954 | dev->gadget.speed = USB_SPEED_FULL; | ||
955 | |||
956 | /* clear interrupt */ | ||
957 | udc_write(S3C2410_UDC_USBINT_RESET, | ||
958 | S3C2410_UDC_USB_INT_REG); | ||
959 | |||
960 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
961 | spin_unlock_irqrestore(&dev->lock, flags); | ||
962 | return IRQ_HANDLED; | ||
963 | } | ||
964 | |||
965 | /* RESUME */ | ||
966 | if (usb_status & S3C2410_UDC_USBINT_RESUME) { | ||
967 | dprintk(DEBUG_NORMAL, "USB resume\n"); | ||
968 | |||
969 | /* clear interrupt */ | ||
970 | udc_write(S3C2410_UDC_USBINT_RESUME, | ||
971 | S3C2410_UDC_USB_INT_REG); | ||
972 | |||
973 | if (dev->gadget.speed != USB_SPEED_UNKNOWN | ||
974 | && dev->driver | ||
975 | && dev->driver->resume) | ||
976 | dev->driver->resume(&dev->gadget); | ||
977 | } | ||
978 | |||
979 | /* SUSPEND */ | ||
980 | if (usb_status & S3C2410_UDC_USBINT_SUSPEND) { | ||
981 | dprintk(DEBUG_NORMAL, "USB suspend\n"); | ||
982 | |||
983 | /* clear interrupt */ | ||
984 | udc_write(S3C2410_UDC_USBINT_SUSPEND, | ||
985 | S3C2410_UDC_USB_INT_REG); | ||
986 | |||
987 | if (dev->gadget.speed != USB_SPEED_UNKNOWN | ||
988 | && dev->driver | ||
989 | && dev->driver->suspend) | ||
990 | dev->driver->suspend(&dev->gadget); | ||
991 | |||
992 | dev->ep0state = EP0_IDLE; | ||
993 | } | ||
994 | |||
995 | /* EP */ | ||
996 | /* control traffic */ | ||
997 | /* check on ep0csr != 0 is not a good idea as clearing in_pkt_ready | ||
998 | * generate an interrupt | ||
999 | */ | ||
1000 | if (usbd_status & S3C2410_UDC_INT_EP0) { | ||
1001 | dprintk(DEBUG_VERBOSE, "USB ep0 irq\n"); | ||
1002 | /* Clear the interrupt bit by setting it to 1 */ | ||
1003 | udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG); | ||
1004 | s3c2410_udc_handle_ep0(dev); | ||
1005 | } | ||
1006 | |||
1007 | /* endpoint data transfers */ | ||
1008 | for (i = 1; i < S3C2410_ENDPOINTS; i++) { | ||
1009 | u32 tmp = 1 << i; | ||
1010 | if (usbd_status & tmp) { | ||
1011 | dprintk(DEBUG_VERBOSE, "USB ep%d irq\n", i); | ||
1012 | |||
1013 | /* Clear the interrupt bit by setting it to 1 */ | ||
1014 | udc_write(tmp, S3C2410_UDC_EP_INT_REG); | ||
1015 | s3c2410_udc_handle_ep(&dev->ep[i]); | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", irq); | ||
1020 | |||
1021 | /* Restore old index */ | ||
1022 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
1023 | |||
1024 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1025 | |||
1026 | return IRQ_HANDLED; | ||
1027 | } | ||
1028 | /*------------------------- s3c2410_ep_ops ----------------------------------*/ | ||
1029 | |||
1030 | static inline struct s3c2410_ep *to_s3c2410_ep(struct usb_ep *ep) | ||
1031 | { | ||
1032 | return container_of(ep, struct s3c2410_ep, ep); | ||
1033 | } | ||
1034 | |||
1035 | static inline struct s3c2410_udc *to_s3c2410_udc(struct usb_gadget *gadget) | ||
1036 | { | ||
1037 | return container_of(gadget, struct s3c2410_udc, gadget); | ||
1038 | } | ||
1039 | |||
1040 | static inline struct s3c2410_request *to_s3c2410_req(struct usb_request *req) | ||
1041 | { | ||
1042 | return container_of(req, struct s3c2410_request, req); | ||
1043 | } | ||
1044 | |||
1045 | /* | ||
1046 | * s3c2410_udc_ep_enable | ||
1047 | */ | ||
1048 | static int s3c2410_udc_ep_enable(struct usb_ep *_ep, | ||
1049 | const struct usb_endpoint_descriptor *desc) | ||
1050 | { | ||
1051 | struct s3c2410_udc *dev; | ||
1052 | struct s3c2410_ep *ep; | ||
1053 | u32 max, tmp; | ||
1054 | unsigned long flags; | ||
1055 | u32 csr1,csr2; | ||
1056 | u32 int_en_reg; | ||
1057 | |||
1058 | ep = to_s3c2410_ep(_ep); | ||
1059 | |||
1060 | if (!_ep || !desc || ep->desc | ||
1061 | || _ep->name == ep0name | ||
1062 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
1063 | return -EINVAL; | ||
1064 | |||
1065 | dev = ep->dev; | ||
1066 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1067 | return -ESHUTDOWN; | ||
1068 | |||
1069 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff; | ||
1070 | |||
1071 | local_irq_save (flags); | ||
1072 | _ep->maxpacket = max & 0x7ff; | ||
1073 | ep->desc = desc; | ||
1074 | ep->halted = 0; | ||
1075 | ep->bEndpointAddress = desc->bEndpointAddress; | ||
1076 | |||
1077 | /* set max packet */ | ||
1078 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1079 | udc_write(max >> 3, S3C2410_UDC_MAXP_REG); | ||
1080 | |||
1081 | /* set type, direction, address; reset fifo counters */ | ||
1082 | if (desc->bEndpointAddress & USB_DIR_IN) { | ||
1083 | csr1 = S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT; | ||
1084 | csr2 = S3C2410_UDC_ICSR2_MODEIN|S3C2410_UDC_ICSR2_DMAIEN; | ||
1085 | |||
1086 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1087 | udc_write(csr1, S3C2410_UDC_IN_CSR1_REG); | ||
1088 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1089 | udc_write(csr2, S3C2410_UDC_IN_CSR2_REG); | ||
1090 | } else { | ||
1091 | /* don't flush in fifo or it will cause endpoint interrupt */ | ||
1092 | csr1 = S3C2410_UDC_ICSR1_CLRDT; | ||
1093 | csr2 = S3C2410_UDC_ICSR2_DMAIEN; | ||
1094 | |||
1095 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1096 | udc_write(csr1, S3C2410_UDC_IN_CSR1_REG); | ||
1097 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1098 | udc_write(csr2, S3C2410_UDC_IN_CSR2_REG); | ||
1099 | |||
1100 | csr1 = S3C2410_UDC_OCSR1_FFLUSH | S3C2410_UDC_OCSR1_CLRDT; | ||
1101 | csr2 = S3C2410_UDC_OCSR2_DMAIEN; | ||
1102 | |||
1103 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1104 | udc_write(csr1, S3C2410_UDC_OUT_CSR1_REG); | ||
1105 | udc_write(ep->num, S3C2410_UDC_INDEX_REG); | ||
1106 | udc_write(csr2, S3C2410_UDC_OUT_CSR2_REG); | ||
1107 | } | ||
1108 | |||
1109 | /* enable irqs */ | ||
1110 | int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG); | ||
1111 | udc_write(int_en_reg | (1 << ep->num), S3C2410_UDC_EP_INT_EN_REG); | ||
1112 | |||
1113 | /* print some debug message */ | ||
1114 | tmp = desc->bEndpointAddress; | ||
1115 | dprintk (DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n", | ||
1116 | _ep->name,ep->num, tmp, | ||
1117 | desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max); | ||
1118 | |||
1119 | local_irq_restore (flags); | ||
1120 | s3c2410_udc_set_halt(_ep, 0); | ||
1121 | |||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | /* | ||
1126 | * s3c2410_udc_ep_disable | ||
1127 | */ | ||
1128 | static int s3c2410_udc_ep_disable(struct usb_ep *_ep) | ||
1129 | { | ||
1130 | struct s3c2410_ep *ep = to_s3c2410_ep(_ep); | ||
1131 | unsigned long flags; | ||
1132 | u32 int_en_reg; | ||
1133 | |||
1134 | if (!_ep || !ep->desc) { | ||
1135 | dprintk(DEBUG_NORMAL, "%s not enabled\n", | ||
1136 | _ep ? ep->ep.name : NULL); | ||
1137 | return -EINVAL; | ||
1138 | } | ||
1139 | |||
1140 | local_irq_save(flags); | ||
1141 | |||
1142 | dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name); | ||
1143 | |||
1144 | ep->desc = NULL; | ||
1145 | ep->halted = 1; | ||
1146 | |||
1147 | s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN); | ||
1148 | |||
1149 | /* disable irqs */ | ||
1150 | int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG); | ||
1151 | udc_write(int_en_reg & ~(1<<ep->num), S3C2410_UDC_EP_INT_EN_REG); | ||
1152 | |||
1153 | local_irq_restore(flags); | ||
1154 | |||
1155 | dprintk(DEBUG_NORMAL, "%s disabled\n", _ep->name); | ||
1156 | |||
1157 | return 0; | ||
1158 | } | ||
1159 | |||
1160 | /* | ||
1161 | * s3c2410_udc_alloc_request | ||
1162 | */ | ||
1163 | static struct usb_request * | ||
1164 | s3c2410_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags) | ||
1165 | { | ||
1166 | struct s3c2410_request *req; | ||
1167 | |||
1168 | dprintk(DEBUG_VERBOSE,"%s(%p,%d)\n", __func__, _ep, mem_flags); | ||
1169 | |||
1170 | if (!_ep) | ||
1171 | return NULL; | ||
1172 | |||
1173 | req = kzalloc (sizeof(struct s3c2410_request), mem_flags); | ||
1174 | if (!req) | ||
1175 | return NULL; | ||
1176 | |||
1177 | INIT_LIST_HEAD (&req->queue); | ||
1178 | return &req->req; | ||
1179 | } | ||
1180 | |||
1181 | /* | ||
1182 | * s3c2410_udc_free_request | ||
1183 | */ | ||
1184 | static void | ||
1185 | s3c2410_udc_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
1186 | { | ||
1187 | struct s3c2410_ep *ep = to_s3c2410_ep(_ep); | ||
1188 | struct s3c2410_request *req = to_s3c2410_req(_req); | ||
1189 | |||
1190 | dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req); | ||
1191 | |||
1192 | if (!ep || !_req || (!ep->desc && _ep->name != ep0name)) | ||
1193 | return; | ||
1194 | |||
1195 | WARN_ON (!list_empty (&req->queue)); | ||
1196 | kfree(req); | ||
1197 | } | ||
1198 | |||
1199 | /* | ||
1200 | * s3c2410_udc_queue | ||
1201 | */ | ||
1202 | static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1203 | gfp_t gfp_flags) | ||
1204 | { | ||
1205 | struct s3c2410_request *req = to_s3c2410_req(_req); | ||
1206 | struct s3c2410_ep *ep = to_s3c2410_ep(_ep); | ||
1207 | struct s3c2410_udc *dev; | ||
1208 | u32 ep_csr = 0; | ||
1209 | int fifo_count = 0; | ||
1210 | unsigned long flags; | ||
1211 | |||
1212 | if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { | ||
1213 | dprintk(DEBUG_NORMAL, "%s: invalid args\n", __func__); | ||
1214 | return -EINVAL; | ||
1215 | } | ||
1216 | |||
1217 | dev = ep->dev; | ||
1218 | if (unlikely (!dev->driver | ||
1219 | || dev->gadget.speed == USB_SPEED_UNKNOWN)) { | ||
1220 | return -ESHUTDOWN; | ||
1221 | } | ||
1222 | |||
1223 | local_irq_save (flags); | ||
1224 | |||
1225 | if (unlikely(!_req || !_req->complete | ||
1226 | || !_req->buf || !list_empty(&req->queue))) { | ||
1227 | if (!_req) | ||
1228 | dprintk(DEBUG_NORMAL, "%s: 1 X X X\n", __func__); | ||
1229 | else { | ||
1230 | dprintk(DEBUG_NORMAL, "%s: 0 %01d %01d %01d\n", | ||
1231 | __func__, !_req->complete,!_req->buf, | ||
1232 | !list_empty(&req->queue)); | ||
1233 | } | ||
1234 | |||
1235 | local_irq_restore(flags); | ||
1236 | return -EINVAL; | ||
1237 | } | ||
1238 | |||
1239 | _req->status = -EINPROGRESS; | ||
1240 | _req->actual = 0; | ||
1241 | |||
1242 | dprintk(DEBUG_VERBOSE, "%s: ep%x len %d\n", | ||
1243 | __func__, ep->bEndpointAddress, _req->length); | ||
1244 | |||
1245 | if (ep->bEndpointAddress) { | ||
1246 | udc_write(ep->bEndpointAddress & 0x7F, S3C2410_UDC_INDEX_REG); | ||
1247 | |||
1248 | ep_csr = udc_read((ep->bEndpointAddress & USB_DIR_IN) | ||
1249 | ? S3C2410_UDC_IN_CSR1_REG | ||
1250 | : S3C2410_UDC_OUT_CSR1_REG); | ||
1251 | fifo_count = s3c2410_udc_fifo_count_out(); | ||
1252 | } else { | ||
1253 | udc_write(0, S3C2410_UDC_INDEX_REG); | ||
1254 | ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG); | ||
1255 | fifo_count = s3c2410_udc_fifo_count_out(); | ||
1256 | } | ||
1257 | |||
1258 | /* kickstart this i/o queue? */ | ||
1259 | if (list_empty(&ep->queue) && !ep->halted) { | ||
1260 | if (ep->bEndpointAddress == 0 /* ep0 */) { | ||
1261 | switch (dev->ep0state) { | ||
1262 | case EP0_IN_DATA_PHASE: | ||
1263 | if (!(ep_csr&S3C2410_UDC_EP0_CSR_IPKRDY) | ||
1264 | && s3c2410_udc_write_fifo(ep, | ||
1265 | req)) { | ||
1266 | dev->ep0state = EP0_IDLE; | ||
1267 | req = NULL; | ||
1268 | } | ||
1269 | break; | ||
1270 | |||
1271 | case EP0_OUT_DATA_PHASE: | ||
1272 | if ((!_req->length) | ||
1273 | || ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY) | ||
1274 | && s3c2410_udc_read_fifo(ep, | ||
1275 | req))) { | ||
1276 | dev->ep0state = EP0_IDLE; | ||
1277 | req = NULL; | ||
1278 | } | ||
1279 | break; | ||
1280 | |||
1281 | default: | ||
1282 | local_irq_restore(flags); | ||
1283 | return -EL2HLT; | ||
1284 | } | ||
1285 | } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0 | ||
1286 | && (!(ep_csr&S3C2410_UDC_OCSR1_PKTRDY)) | ||
1287 | && s3c2410_udc_write_fifo(ep, req)) { | ||
1288 | req = NULL; | ||
1289 | } else if ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY) | ||
1290 | && fifo_count | ||
1291 | && s3c2410_udc_read_fifo(ep, req)) { | ||
1292 | req = NULL; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | /* pio or dma irq handler advances the queue. */ | ||
1297 | if (likely (req != 0)) | ||
1298 | list_add_tail(&req->queue, &ep->queue); | ||
1299 | |||
1300 | local_irq_restore(flags); | ||
1301 | |||
1302 | dprintk(DEBUG_VERBOSE, "%s ok\n", __func__); | ||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1306 | /* | ||
1307 | * s3c2410_udc_dequeue | ||
1308 | */ | ||
1309 | static int s3c2410_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
1310 | { | ||
1311 | struct s3c2410_ep *ep = to_s3c2410_ep(_ep); | ||
1312 | struct s3c2410_udc *udc; | ||
1313 | int retval = -EINVAL; | ||
1314 | unsigned long flags; | ||
1315 | struct s3c2410_request *req = NULL; | ||
1316 | |||
1317 | dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req); | ||
1318 | |||
1319 | if (!the_controller->driver) | ||
1320 | return -ESHUTDOWN; | ||
1321 | |||
1322 | if (!_ep || !_req) | ||
1323 | return retval; | ||
1324 | |||
1325 | udc = to_s3c2410_udc(ep->gadget); | ||
1326 | |||
1327 | local_irq_save (flags); | ||
1328 | |||
1329 | list_for_each_entry (req, &ep->queue, queue) { | ||
1330 | if (&req->req == _req) { | ||
1331 | list_del_init (&req->queue); | ||
1332 | _req->status = -ECONNRESET; | ||
1333 | retval = 0; | ||
1334 | break; | ||
1335 | } | ||
1336 | } | ||
1337 | |||
1338 | if (retval == 0) { | ||
1339 | dprintk(DEBUG_VERBOSE, | ||
1340 | "dequeued req %p from %s, len %d buf %p\n", | ||
1341 | req, _ep->name, _req->length, _req->buf); | ||
1342 | |||
1343 | s3c2410_udc_done(ep, req, -ECONNRESET); | ||
1344 | } | ||
1345 | |||
1346 | local_irq_restore (flags); | ||
1347 | return retval; | ||
1348 | } | ||
1349 | |||
1350 | /* | ||
1351 | * s3c2410_udc_set_halt | ||
1352 | */ | ||
1353 | static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value) | ||
1354 | { | ||
1355 | struct s3c2410_ep *ep = to_s3c2410_ep(_ep); | ||
1356 | u32 ep_csr = 0; | ||
1357 | unsigned long flags; | ||
1358 | u32 idx; | ||
1359 | |||
1360 | if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { | ||
1361 | dprintk(DEBUG_NORMAL, "%s: inval 2\n", __func__); | ||
1362 | return -EINVAL; | ||
1363 | } | ||
1364 | |||
1365 | local_irq_save (flags); | ||
1366 | |||
1367 | idx = ep->bEndpointAddress & 0x7F; | ||
1368 | |||
1369 | if (idx == 0) { | ||
1370 | s3c2410_udc_set_ep0_ss(base_addr); | ||
1371 | s3c2410_udc_set_ep0_de_out(base_addr); | ||
1372 | } else { | ||
1373 | udc_write(idx, S3C2410_UDC_INDEX_REG); | ||
1374 | ep_csr = udc_read((ep->bEndpointAddress &USB_DIR_IN) | ||
1375 | ? S3C2410_UDC_IN_CSR1_REG | ||
1376 | : S3C2410_UDC_OUT_CSR1_REG); | ||
1377 | |||
1378 | if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { | ||
1379 | if (value) | ||
1380 | udc_write(ep_csr | S3C2410_UDC_ICSR1_SENDSTL, | ||
1381 | S3C2410_UDC_IN_CSR1_REG); | ||
1382 | else { | ||
1383 | ep_csr &= ~S3C2410_UDC_ICSR1_SENDSTL; | ||
1384 | udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG); | ||
1385 | ep_csr |= S3C2410_UDC_ICSR1_CLRDT; | ||
1386 | udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG); | ||
1387 | } | ||
1388 | } else { | ||
1389 | if (value) | ||
1390 | udc_write(ep_csr | S3C2410_UDC_OCSR1_SENDSTL, | ||
1391 | S3C2410_UDC_OUT_CSR1_REG); | ||
1392 | else { | ||
1393 | ep_csr &= ~S3C2410_UDC_OCSR1_SENDSTL; | ||
1394 | udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG); | ||
1395 | ep_csr |= S3C2410_UDC_OCSR1_CLRDT; | ||
1396 | udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG); | ||
1397 | } | ||
1398 | } | ||
1399 | } | ||
1400 | |||
1401 | ep->halted = value ? 1 : 0; | ||
1402 | local_irq_restore (flags); | ||
1403 | |||
1404 | return 0; | ||
1405 | } | ||
1406 | |||
1407 | static const struct usb_ep_ops s3c2410_ep_ops = { | ||
1408 | .enable = s3c2410_udc_ep_enable, | ||
1409 | .disable = s3c2410_udc_ep_disable, | ||
1410 | |||
1411 | .alloc_request = s3c2410_udc_alloc_request, | ||
1412 | .free_request = s3c2410_udc_free_request, | ||
1413 | |||
1414 | .queue = s3c2410_udc_queue, | ||
1415 | .dequeue = s3c2410_udc_dequeue, | ||
1416 | |||
1417 | .set_halt = s3c2410_udc_set_halt, | ||
1418 | }; | ||
1419 | |||
1420 | /*------------------------- usb_gadget_ops ----------------------------------*/ | ||
1421 | |||
1422 | /* | ||
1423 | * s3c2410_udc_get_frame | ||
1424 | */ | ||
1425 | static int s3c2410_udc_get_frame(struct usb_gadget *_gadget) | ||
1426 | { | ||
1427 | int tmp; | ||
1428 | |||
1429 | dprintk(DEBUG_VERBOSE, "%s()\n", __func__); | ||
1430 | |||
1431 | tmp = udc_read(S3C2410_UDC_FRAME_NUM2_REG) << 8; | ||
1432 | tmp |= udc_read(S3C2410_UDC_FRAME_NUM1_REG); | ||
1433 | return tmp; | ||
1434 | } | ||
1435 | |||
1436 | /* | ||
1437 | * s3c2410_udc_wakeup | ||
1438 | */ | ||
1439 | static int s3c2410_udc_wakeup(struct usb_gadget *_gadget) | ||
1440 | { | ||
1441 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1442 | return 0; | ||
1443 | } | ||
1444 | |||
1445 | /* | ||
1446 | * s3c2410_udc_set_selfpowered | ||
1447 | */ | ||
1448 | static int s3c2410_udc_set_selfpowered(struct usb_gadget *gadget, int value) | ||
1449 | { | ||
1450 | struct s3c2410_udc *udc = to_s3c2410_udc(gadget); | ||
1451 | |||
1452 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1453 | |||
1454 | if (value) | ||
1455 | udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED); | ||
1456 | else | ||
1457 | udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); | ||
1458 | |||
1459 | return 0; | ||
1460 | } | ||
1461 | |||
1462 | static void s3c2410_udc_disable(struct s3c2410_udc *dev); | ||
1463 | static void s3c2410_udc_enable(struct s3c2410_udc *dev); | ||
1464 | |||
1465 | static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on) | ||
1466 | { | ||
1467 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1468 | |||
1469 | if (udc_info && udc_info->udc_command) { | ||
1470 | if (is_on) | ||
1471 | s3c2410_udc_enable(udc); | ||
1472 | else { | ||
1473 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | ||
1474 | if (udc->driver && udc->driver->disconnect) | ||
1475 | udc->driver->disconnect(&udc->gadget); | ||
1476 | |||
1477 | } | ||
1478 | s3c2410_udc_disable(udc); | ||
1479 | } | ||
1480 | } | ||
1481 | else | ||
1482 | return -EOPNOTSUPP; | ||
1483 | |||
1484 | return 0; | ||
1485 | } | ||
1486 | |||
1487 | static int s3c2410_udc_vbus_session(struct usb_gadget *gadget, int is_active) | ||
1488 | { | ||
1489 | struct s3c2410_udc *udc = to_s3c2410_udc(gadget); | ||
1490 | |||
1491 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1492 | |||
1493 | udc->vbus = (is_active != 0); | ||
1494 | s3c2410_udc_set_pullup(udc, is_active); | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | static int s3c2410_udc_pullup(struct usb_gadget *gadget, int is_on) | ||
1499 | { | ||
1500 | struct s3c2410_udc *udc = to_s3c2410_udc(gadget); | ||
1501 | |||
1502 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1503 | |||
1504 | s3c2410_udc_set_pullup(udc, is_on ? 0 : 1); | ||
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) | ||
1509 | { | ||
1510 | struct s3c2410_udc *dev = _dev; | ||
1511 | unsigned int value; | ||
1512 | |||
1513 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1514 | value = s3c2410_gpio_getpin(udc_info->vbus_pin); | ||
1515 | |||
1516 | if (udc_info->vbus_pin_inverted) | ||
1517 | value = !value; | ||
1518 | |||
1519 | if (value != dev->vbus) | ||
1520 | s3c2410_udc_vbus_session(&dev->gadget, value); | ||
1521 | |||
1522 | return IRQ_HANDLED; | ||
1523 | } | ||
1524 | |||
1525 | static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) | ||
1526 | { | ||
1527 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1528 | |||
1529 | if (udc_info && udc_info->vbus_draw) { | ||
1530 | udc_info->vbus_draw(ma); | ||
1531 | return 0; | ||
1532 | } | ||
1533 | |||
1534 | return -ENOTSUPP; | ||
1535 | } | ||
1536 | |||
1537 | static const struct usb_gadget_ops s3c2410_ops = { | ||
1538 | .get_frame = s3c2410_udc_get_frame, | ||
1539 | .wakeup = s3c2410_udc_wakeup, | ||
1540 | .set_selfpowered = s3c2410_udc_set_selfpowered, | ||
1541 | .pullup = s3c2410_udc_pullup, | ||
1542 | .vbus_session = s3c2410_udc_vbus_session, | ||
1543 | .vbus_draw = s3c2410_vbus_draw, | ||
1544 | }; | ||
1545 | |||
1546 | /*------------------------- gadget driver handling---------------------------*/ | ||
1547 | /* | ||
1548 | * s3c2410_udc_disable | ||
1549 | */ | ||
1550 | static void s3c2410_udc_disable(struct s3c2410_udc *dev) | ||
1551 | { | ||
1552 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | ||
1553 | |||
1554 | /* Disable all interrupts */ | ||
1555 | udc_write(0x00, S3C2410_UDC_USB_INT_EN_REG); | ||
1556 | udc_write(0x00, S3C2410_UDC_EP_INT_EN_REG); | ||
1557 | |||
1558 | /* Clear the interrupt registers */ | ||
1559 | udc_write(S3C2410_UDC_USBINT_RESET | ||
1560 | | S3C2410_UDC_USBINT_RESUME | ||
1561 | | S3C2410_UDC_USBINT_SUSPEND, | ||
1562 | S3C2410_UDC_USB_INT_REG); | ||
1563 | |||
1564 | udc_write(0x1F, S3C2410_UDC_EP_INT_REG); | ||
1565 | |||
1566 | /* Good bye, cruel world */ | ||
1567 | if (udc_info && udc_info->udc_command) | ||
1568 | udc_info->udc_command(S3C2410_UDC_P_DISABLE); | ||
1569 | |||
1570 | /* Set speed to unknown */ | ||
1571 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
1572 | } | ||
1573 | |||
1574 | /* | ||
1575 | * s3c2410_udc_reinit | ||
1576 | */ | ||
1577 | static void s3c2410_udc_reinit(struct s3c2410_udc *dev) | ||
1578 | { | ||
1579 | u32 i; | ||
1580 | |||
1581 | /* device/ep0 records init */ | ||
1582 | INIT_LIST_HEAD (&dev->gadget.ep_list); | ||
1583 | INIT_LIST_HEAD (&dev->gadget.ep0->ep_list); | ||
1584 | dev->ep0state = EP0_IDLE; | ||
1585 | |||
1586 | for (i = 0; i < S3C2410_ENDPOINTS; i++) { | ||
1587 | struct s3c2410_ep *ep = &dev->ep[i]; | ||
1588 | |||
1589 | if (i != 0) | ||
1590 | list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); | ||
1591 | |||
1592 | ep->dev = dev; | ||
1593 | ep->desc = NULL; | ||
1594 | ep->halted = 0; | ||
1595 | INIT_LIST_HEAD (&ep->queue); | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | /* | ||
1600 | * s3c2410_udc_enable | ||
1601 | */ | ||
1602 | static void s3c2410_udc_enable(struct s3c2410_udc *dev) | ||
1603 | { | ||
1604 | int i; | ||
1605 | |||
1606 | dprintk(DEBUG_NORMAL, "s3c2410_udc_enable called\n"); | ||
1607 | |||
1608 | /* dev->gadget.speed = USB_SPEED_UNKNOWN; */ | ||
1609 | dev->gadget.speed = USB_SPEED_FULL; | ||
1610 | |||
1611 | /* Set MAXP for all endpoints */ | ||
1612 | for (i = 0; i < S3C2410_ENDPOINTS; i++) { | ||
1613 | udc_write(i, S3C2410_UDC_INDEX_REG); | ||
1614 | udc_write((dev->ep[i].ep.maxpacket & 0x7ff) >> 3, | ||
1615 | S3C2410_UDC_MAXP_REG); | ||
1616 | } | ||
1617 | |||
1618 | /* Set default power state */ | ||
1619 | udc_write(DEFAULT_POWER_STATE, S3C2410_UDC_PWR_REG); | ||
1620 | |||
1621 | /* Enable reset and suspend interrupt interrupts */ | ||
1622 | udc_write(S3C2410_UDC_USBINT_RESET | S3C2410_UDC_USBINT_SUSPEND, | ||
1623 | S3C2410_UDC_USB_INT_EN_REG); | ||
1624 | |||
1625 | /* Enable ep0 interrupt */ | ||
1626 | udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG); | ||
1627 | |||
1628 | /* time to say "hello, world" */ | ||
1629 | if (udc_info && udc_info->udc_command) | ||
1630 | udc_info->udc_command(S3C2410_UDC_P_ENABLE); | ||
1631 | } | ||
1632 | |||
1633 | /* | ||
1634 | * usb_gadget_register_driver | ||
1635 | */ | ||
1636 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1637 | { | ||
1638 | struct s3c2410_udc *udc = the_controller; | ||
1639 | int retval; | ||
1640 | |||
1641 | dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n", | ||
1642 | driver->driver.name); | ||
1643 | |||
1644 | /* Sanity checks */ | ||
1645 | if (!udc) | ||
1646 | return -ENODEV; | ||
1647 | |||
1648 | if (udc->driver) | ||
1649 | return -EBUSY; | ||
1650 | |||
1651 | if (!driver->bind || !driver->setup | ||
1652 | || driver->speed != USB_SPEED_FULL) { | ||
1653 | printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", | ||
1654 | driver->bind, driver->setup, driver->speed); | ||
1655 | return -EINVAL; | ||
1656 | } | ||
1657 | #if defined(MODULE) | ||
1658 | if (!driver->unbind) { | ||
1659 | printk(KERN_ERR "Invalid driver: no unbind method\n"); | ||
1660 | return -EINVAL; | ||
1661 | } | ||
1662 | #endif | ||
1663 | |||
1664 | /* Hook the driver */ | ||
1665 | udc->driver = driver; | ||
1666 | udc->gadget.dev.driver = &driver->driver; | ||
1667 | |||
1668 | /* Bind the driver */ | ||
1669 | if ((retval = device_add(&udc->gadget.dev)) != 0) { | ||
1670 | printk(KERN_ERR "Error in device_add() : %d\n",retval); | ||
1671 | goto register_error; | ||
1672 | } | ||
1673 | |||
1674 | dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", | ||
1675 | driver->driver.name); | ||
1676 | |||
1677 | if ((retval = driver->bind (&udc->gadget)) != 0) { | ||
1678 | device_del(&udc->gadget.dev); | ||
1679 | goto register_error; | ||
1680 | } | ||
1681 | |||
1682 | /* Enable udc */ | ||
1683 | s3c2410_udc_enable(udc); | ||
1684 | |||
1685 | return 0; | ||
1686 | |||
1687 | register_error: | ||
1688 | udc->driver = NULL; | ||
1689 | udc->gadget.dev.driver = NULL; | ||
1690 | return retval; | ||
1691 | } | ||
1692 | |||
1693 | /* | ||
1694 | * usb_gadget_unregister_driver | ||
1695 | */ | ||
1696 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1697 | { | ||
1698 | struct s3c2410_udc *udc = the_controller; | ||
1699 | |||
1700 | if (!udc) | ||
1701 | return -ENODEV; | ||
1702 | |||
1703 | if (!driver || driver != udc->driver || !driver->unbind) | ||
1704 | return -EINVAL; | ||
1705 | |||
1706 | dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n", | ||
1707 | driver->driver.name); | ||
1708 | |||
1709 | if (driver->disconnect) | ||
1710 | driver->disconnect(&udc->gadget); | ||
1711 | |||
1712 | device_del(&udc->gadget.dev); | ||
1713 | udc->driver = NULL; | ||
1714 | |||
1715 | /* Disable udc */ | ||
1716 | s3c2410_udc_disable(udc); | ||
1717 | |||
1718 | return 0; | ||
1719 | } | ||
1720 | |||
1721 | /*---------------------------------------------------------------------------*/ | ||
1722 | static struct s3c2410_udc memory = { | ||
1723 | .gadget = { | ||
1724 | .ops = &s3c2410_ops, | ||
1725 | .ep0 = &memory.ep[0].ep, | ||
1726 | .name = gadget_name, | ||
1727 | .dev = { | ||
1728 | .bus_id = "gadget", | ||
1729 | }, | ||
1730 | }, | ||
1731 | |||
1732 | /* control endpoint */ | ||
1733 | .ep[0] = { | ||
1734 | .num = 0, | ||
1735 | .ep = { | ||
1736 | .name = ep0name, | ||
1737 | .ops = &s3c2410_ep_ops, | ||
1738 | .maxpacket = EP0_FIFO_SIZE, | ||
1739 | }, | ||
1740 | .dev = &memory, | ||
1741 | }, | ||
1742 | |||
1743 | /* first group of endpoints */ | ||
1744 | .ep[1] = { | ||
1745 | .num = 1, | ||
1746 | .ep = { | ||
1747 | .name = "ep1-bulk", | ||
1748 | .ops = &s3c2410_ep_ops, | ||
1749 | .maxpacket = EP_FIFO_SIZE, | ||
1750 | }, | ||
1751 | .dev = &memory, | ||
1752 | .fifo_size = EP_FIFO_SIZE, | ||
1753 | .bEndpointAddress = 1, | ||
1754 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1755 | }, | ||
1756 | .ep[2] = { | ||
1757 | .num = 2, | ||
1758 | .ep = { | ||
1759 | .name = "ep2-bulk", | ||
1760 | .ops = &s3c2410_ep_ops, | ||
1761 | .maxpacket = EP_FIFO_SIZE, | ||
1762 | }, | ||
1763 | .dev = &memory, | ||
1764 | .fifo_size = EP_FIFO_SIZE, | ||
1765 | .bEndpointAddress = 2, | ||
1766 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1767 | }, | ||
1768 | .ep[3] = { | ||
1769 | .num = 3, | ||
1770 | .ep = { | ||
1771 | .name = "ep3-bulk", | ||
1772 | .ops = &s3c2410_ep_ops, | ||
1773 | .maxpacket = EP_FIFO_SIZE, | ||
1774 | }, | ||
1775 | .dev = &memory, | ||
1776 | .fifo_size = EP_FIFO_SIZE, | ||
1777 | .bEndpointAddress = 3, | ||
1778 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1779 | }, | ||
1780 | .ep[4] = { | ||
1781 | .num = 4, | ||
1782 | .ep = { | ||
1783 | .name = "ep4-bulk", | ||
1784 | .ops = &s3c2410_ep_ops, | ||
1785 | .maxpacket = EP_FIFO_SIZE, | ||
1786 | }, | ||
1787 | .dev = &memory, | ||
1788 | .fifo_size = EP_FIFO_SIZE, | ||
1789 | .bEndpointAddress = 4, | ||
1790 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
1791 | } | ||
1792 | |||
1793 | }; | ||
1794 | |||
1795 | /* | ||
1796 | * probe - binds to the platform device | ||
1797 | */ | ||
1798 | static int s3c2410_udc_probe(struct platform_device *pdev) | ||
1799 | { | ||
1800 | struct s3c2410_udc *udc = &memory; | ||
1801 | struct device *dev = &pdev->dev; | ||
1802 | int retval; | ||
1803 | unsigned int irq; | ||
1804 | |||
1805 | dev_dbg(dev, "%s()\n", __func__); | ||
1806 | |||
1807 | usb_bus_clock = clk_get(NULL, "usb-bus-gadget"); | ||
1808 | if (IS_ERR(usb_bus_clock)) { | ||
1809 | dev_err(dev, "failed to get usb bus clock source\n"); | ||
1810 | return PTR_ERR(usb_bus_clock); | ||
1811 | } | ||
1812 | |||
1813 | clk_enable(usb_bus_clock); | ||
1814 | |||
1815 | udc_clock = clk_get(NULL, "usb-device"); | ||
1816 | if (IS_ERR(udc_clock)) { | ||
1817 | dev_err(dev, "failed to get udc clock source\n"); | ||
1818 | return PTR_ERR(udc_clock); | ||
1819 | } | ||
1820 | |||
1821 | clk_enable(udc_clock); | ||
1822 | |||
1823 | mdelay(10); | ||
1824 | |||
1825 | dev_dbg(dev, "got and enabled clocks\n"); | ||
1826 | |||
1827 | if (strncmp(pdev->name, "s3c2440", 7) == 0) { | ||
1828 | dev_info(dev, "S3C2440: increasing FIFO to 128 bytes\n"); | ||
1829 | memory.ep[1].fifo_size = S3C2440_EP_FIFO_SIZE; | ||
1830 | memory.ep[2].fifo_size = S3C2440_EP_FIFO_SIZE; | ||
1831 | memory.ep[3].fifo_size = S3C2440_EP_FIFO_SIZE; | ||
1832 | memory.ep[4].fifo_size = S3C2440_EP_FIFO_SIZE; | ||
1833 | } | ||
1834 | |||
1835 | spin_lock_init (&udc->lock); | ||
1836 | udc_info = pdev->dev.platform_data; | ||
1837 | |||
1838 | rsrc_start = S3C2410_PA_USBDEV; | ||
1839 | rsrc_len = S3C24XX_SZ_USBDEV; | ||
1840 | |||
1841 | if (!request_mem_region(rsrc_start, rsrc_len, gadget_name)) | ||
1842 | return -EBUSY; | ||
1843 | |||
1844 | base_addr = ioremap(rsrc_start, rsrc_len); | ||
1845 | if (!base_addr) { | ||
1846 | retval = -ENOMEM; | ||
1847 | goto err_mem; | ||
1848 | } | ||
1849 | |||
1850 | device_initialize(&udc->gadget.dev); | ||
1851 | udc->gadget.dev.parent = &pdev->dev; | ||
1852 | udc->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
1853 | |||
1854 | the_controller = udc; | ||
1855 | platform_set_drvdata(pdev, udc); | ||
1856 | |||
1857 | s3c2410_udc_disable(udc); | ||
1858 | s3c2410_udc_reinit(udc); | ||
1859 | |||
1860 | /* irq setup after old hardware state is cleaned up */ | ||
1861 | retval = request_irq(IRQ_USBD, s3c2410_udc_irq, | ||
1862 | IRQF_DISABLED, gadget_name, udc); | ||
1863 | |||
1864 | if (retval != 0) { | ||
1865 | dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval); | ||
1866 | retval = -EBUSY; | ||
1867 | goto err_map; | ||
1868 | } | ||
1869 | |||
1870 | dev_dbg(dev, "got irq %i\n", IRQ_USBD); | ||
1871 | |||
1872 | if (udc_info && udc_info->vbus_pin > 0) { | ||
1873 | irq = s3c2410_gpio_getirq(udc_info->vbus_pin); | ||
1874 | retval = request_irq(irq, s3c2410_udc_vbus_irq, | ||
1875 | IRQF_DISABLED | IRQF_TRIGGER_RISING | ||
1876 | | IRQF_TRIGGER_FALLING, | ||
1877 | gadget_name, udc); | ||
1878 | |||
1879 | if (retval != 0) { | ||
1880 | dev_err(dev, "can't get vbus irq %i, err %d\n", | ||
1881 | irq, retval); | ||
1882 | retval = -EBUSY; | ||
1883 | goto err_int; | ||
1884 | } | ||
1885 | |||
1886 | dev_dbg(dev, "got irq %i\n", irq); | ||
1887 | } else { | ||
1888 | udc->vbus = 1; | ||
1889 | } | ||
1890 | |||
1891 | if (s3c2410_udc_debugfs_root) { | ||
1892 | udc->regs_info = debugfs_create_file("registers", S_IRUGO, | ||
1893 | s3c2410_udc_debugfs_root, | ||
1894 | udc, &s3c2410_udc_debugfs_fops); | ||
1895 | if (IS_ERR(udc->regs_info)) { | ||
1896 | dev_warn(dev, "debugfs file creation failed %ld\n", | ||
1897 | PTR_ERR(udc->regs_info)); | ||
1898 | udc->regs_info = NULL; | ||
1899 | } | ||
1900 | } | ||
1901 | |||
1902 | dev_dbg(dev, "probe ok\n"); | ||
1903 | |||
1904 | return 0; | ||
1905 | |||
1906 | err_int: | ||
1907 | free_irq(IRQ_USBD, udc); | ||
1908 | err_map: | ||
1909 | iounmap(base_addr); | ||
1910 | err_mem: | ||
1911 | release_mem_region(rsrc_start, rsrc_len); | ||
1912 | |||
1913 | return retval; | ||
1914 | } | ||
1915 | |||
1916 | /* | ||
1917 | * s3c2410_udc_remove | ||
1918 | */ | ||
1919 | static int s3c2410_udc_remove(struct platform_device *pdev) | ||
1920 | { | ||
1921 | struct s3c2410_udc *udc = platform_get_drvdata(pdev); | ||
1922 | unsigned int irq; | ||
1923 | |||
1924 | dev_dbg(&pdev->dev, "%s()\n", __func__); | ||
1925 | if (udc->driver) | ||
1926 | return -EBUSY; | ||
1927 | |||
1928 | debugfs_remove(udc->regs_info); | ||
1929 | |||
1930 | if (udc_info && udc_info->vbus_pin > 0) { | ||
1931 | irq = s3c2410_gpio_getirq(udc_info->vbus_pin); | ||
1932 | free_irq(irq, udc); | ||
1933 | } | ||
1934 | |||
1935 | free_irq(IRQ_USBD, udc); | ||
1936 | |||
1937 | iounmap(base_addr); | ||
1938 | release_mem_region(rsrc_start, rsrc_len); | ||
1939 | |||
1940 | platform_set_drvdata(pdev, NULL); | ||
1941 | |||
1942 | if (!IS_ERR(udc_clock) && udc_clock != NULL) { | ||
1943 | clk_disable(udc_clock); | ||
1944 | clk_put(udc_clock); | ||
1945 | udc_clock = NULL; | ||
1946 | } | ||
1947 | |||
1948 | if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) { | ||
1949 | clk_disable(usb_bus_clock); | ||
1950 | clk_put(usb_bus_clock); | ||
1951 | usb_bus_clock = NULL; | ||
1952 | } | ||
1953 | |||
1954 | dev_dbg(&pdev->dev, "%s: remove ok\n", __func__); | ||
1955 | return 0; | ||
1956 | } | ||
1957 | |||
1958 | #ifdef CONFIG_PM | ||
1959 | static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message) | ||
1960 | { | ||
1961 | if (udc_info && udc_info->udc_command) | ||
1962 | udc_info->udc_command(S3C2410_UDC_P_DISABLE); | ||
1963 | |||
1964 | return 0; | ||
1965 | } | ||
1966 | |||
1967 | static int s3c2410_udc_resume(struct platform_device *pdev) | ||
1968 | { | ||
1969 | if (udc_info && udc_info->udc_command) | ||
1970 | udc_info->udc_command(S3C2410_UDC_P_ENABLE); | ||
1971 | |||
1972 | return 0; | ||
1973 | } | ||
1974 | #else | ||
1975 | #define s3c2410_udc_suspend NULL | ||
1976 | #define s3c2410_udc_resume NULL | ||
1977 | #endif | ||
1978 | |||
1979 | static struct platform_driver udc_driver_2410 = { | ||
1980 | .driver = { | ||
1981 | .name = "s3c2410-usbgadget", | ||
1982 | .owner = THIS_MODULE, | ||
1983 | }, | ||
1984 | .probe = s3c2410_udc_probe, | ||
1985 | .remove = s3c2410_udc_remove, | ||
1986 | .suspend = s3c2410_udc_suspend, | ||
1987 | .resume = s3c2410_udc_resume, | ||
1988 | }; | ||
1989 | |||
1990 | static struct platform_driver udc_driver_2440 = { | ||
1991 | .driver = { | ||
1992 | .name = "s3c2440-usbgadget", | ||
1993 | .owner = THIS_MODULE, | ||
1994 | }, | ||
1995 | .probe = s3c2410_udc_probe, | ||
1996 | .remove = s3c2410_udc_remove, | ||
1997 | .suspend = s3c2410_udc_suspend, | ||
1998 | .resume = s3c2410_udc_resume, | ||
1999 | }; | ||
2000 | |||
2001 | static int __init udc_init(void) | ||
2002 | { | ||
2003 | int retval; | ||
2004 | |||
2005 | dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION); | ||
2006 | |||
2007 | s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); | ||
2008 | if (IS_ERR(s3c2410_udc_debugfs_root)) { | ||
2009 | printk(KERN_ERR "%s: debugfs dir creation failed %ld\n", | ||
2010 | gadget_name, PTR_ERR(s3c2410_udc_debugfs_root)); | ||
2011 | s3c2410_udc_debugfs_root = NULL; | ||
2012 | } | ||
2013 | |||
2014 | retval = platform_driver_register(&udc_driver_2410); | ||
2015 | if (retval) | ||
2016 | goto err; | ||
2017 | |||
2018 | retval = platform_driver_register(&udc_driver_2440); | ||
2019 | if (retval) | ||
2020 | goto err; | ||
2021 | |||
2022 | return 0; | ||
2023 | |||
2024 | err: | ||
2025 | debugfs_remove(s3c2410_udc_debugfs_root); | ||
2026 | return retval; | ||
2027 | } | ||
2028 | |||
2029 | static void __exit udc_exit(void) | ||
2030 | { | ||
2031 | platform_driver_unregister(&udc_driver_2410); | ||
2032 | platform_driver_unregister(&udc_driver_2440); | ||
2033 | debugfs_remove(s3c2410_udc_debugfs_root); | ||
2034 | } | ||
2035 | |||
2036 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2037 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
2038 | |||
2039 | module_init(udc_init); | ||
2040 | module_exit(udc_exit); | ||
2041 | |||
2042 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
2043 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
2044 | MODULE_VERSION(DRIVER_VERSION); | ||
2045 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h new file mode 100644 index 000000000000..9e0bece4f241 --- /dev/null +++ b/drivers/usb/gadget/s3c2410_udc.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * linux/drivers/usb/gadget/s3c2410_udc.h | ||
3 | * Samsung on-chip full speed USB device controllers | ||
4 | * | ||
5 | * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard | ||
6 | * Additional cleanups by Ben Dooks <ben-linux@fluff.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef _S3C2410_UDC_H | ||
25 | #define _S3C2410_UDC_H | ||
26 | |||
27 | struct s3c2410_ep { | ||
28 | struct list_head queue; | ||
29 | unsigned long last_io; /* jiffies timestamp */ | ||
30 | struct usb_gadget *gadget; | ||
31 | struct s3c2410_udc *dev; | ||
32 | const struct usb_endpoint_descriptor *desc; | ||
33 | struct usb_ep ep; | ||
34 | u8 num; | ||
35 | |||
36 | unsigned short fifo_size; | ||
37 | u8 bEndpointAddress; | ||
38 | u8 bmAttributes; | ||
39 | |||
40 | unsigned halted : 1; | ||
41 | unsigned already_seen : 1; | ||
42 | unsigned setup_stage : 1; | ||
43 | }; | ||
44 | |||
45 | |||
46 | /* Warning : ep0 has a fifo of 16 bytes */ | ||
47 | /* Don't try to set 32 or 64 */ | ||
48 | /* also testusb 14 fails wit 16 but is */ | ||
49 | /* fine with 8 */ | ||
50 | #define EP0_FIFO_SIZE 8 | ||
51 | #define EP_FIFO_SIZE 64 | ||
52 | #define DEFAULT_POWER_STATE 0x00 | ||
53 | |||
54 | #define S3C2440_EP_FIFO_SIZE 128 | ||
55 | |||
56 | static const char ep0name [] = "ep0"; | ||
57 | |||
58 | static const char *const ep_name[] = { | ||
59 | ep0name, /* everyone has ep0 */ | ||
60 | /* s3c2410 four bidirectional bulk endpoints */ | ||
61 | "ep1-bulk", "ep2-bulk", "ep3-bulk", "ep4-bulk", | ||
62 | }; | ||
63 | |||
64 | #define S3C2410_ENDPOINTS ARRAY_SIZE(ep_name) | ||
65 | |||
66 | struct s3c2410_request { | ||
67 | struct list_head queue; /* ep's requests */ | ||
68 | struct usb_request req; | ||
69 | }; | ||
70 | |||
71 | enum ep0_state { | ||
72 | EP0_IDLE, | ||
73 | EP0_IN_DATA_PHASE, | ||
74 | EP0_OUT_DATA_PHASE, | ||
75 | EP0_END_XFER, | ||
76 | EP0_STALL, | ||
77 | }; | ||
78 | |||
79 | static const char *ep0states[]= { | ||
80 | "EP0_IDLE", | ||
81 | "EP0_IN_DATA_PHASE", | ||
82 | "EP0_OUT_DATA_PHASE", | ||
83 | "EP0_END_XFER", | ||
84 | "EP0_STALL", | ||
85 | }; | ||
86 | |||
87 | struct s3c2410_udc { | ||
88 | spinlock_t lock; | ||
89 | |||
90 | struct s3c2410_ep ep[S3C2410_ENDPOINTS]; | ||
91 | int address; | ||
92 | struct usb_gadget gadget; | ||
93 | struct usb_gadget_driver *driver; | ||
94 | struct s3c2410_request fifo_req; | ||
95 | u8 fifo_buf[EP_FIFO_SIZE]; | ||
96 | u16 devstatus; | ||
97 | |||
98 | u32 port_status; | ||
99 | int ep0state; | ||
100 | |||
101 | unsigned got_irq : 1; | ||
102 | |||
103 | unsigned req_std : 1; | ||
104 | unsigned req_config : 1; | ||
105 | unsigned req_pending : 1; | ||
106 | u8 vbus; | ||
107 | struct dentry *regs_info; | ||
108 | }; | ||
109 | |||
110 | #endif | ||
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f847c3414be3..dd33ff0ae4ce 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -2215,7 +2215,7 @@ static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags) | |||
2215 | * | 2215 | * |
2216 | * Free the buffer and all associated memory. | 2216 | * Free the buffer and all associated memory. |
2217 | */ | 2217 | */ |
2218 | void gs_buf_free(struct gs_buf *gb) | 2218 | static void gs_buf_free(struct gs_buf *gb) |
2219 | { | 2219 | { |
2220 | if (gb) { | 2220 | if (gb) { |
2221 | kfree(gb->buf_buf); | 2221 | kfree(gb->buf_buf); |
@@ -2228,7 +2228,7 @@ void gs_buf_free(struct gs_buf *gb) | |||
2228 | * | 2228 | * |
2229 | * Clear out all data in the circular buffer. | 2229 | * Clear out all data in the circular buffer. |
2230 | */ | 2230 | */ |
2231 | void gs_buf_clear(struct gs_buf *gb) | 2231 | static void gs_buf_clear(struct gs_buf *gb) |
2232 | { | 2232 | { |
2233 | if (gb != NULL) | 2233 | if (gb != NULL) |
2234 | gb->buf_get = gb->buf_put; | 2234 | gb->buf_get = gb->buf_put; |
@@ -2241,7 +2241,7 @@ void gs_buf_clear(struct gs_buf *gb) | |||
2241 | * Return the number of bytes of data available in the circular | 2241 | * Return the number of bytes of data available in the circular |
2242 | * buffer. | 2242 | * buffer. |
2243 | */ | 2243 | */ |
2244 | unsigned int gs_buf_data_avail(struct gs_buf *gb) | 2244 | static unsigned int gs_buf_data_avail(struct gs_buf *gb) |
2245 | { | 2245 | { |
2246 | if (gb != NULL) | 2246 | if (gb != NULL) |
2247 | return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size; | 2247 | return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size; |
@@ -2255,7 +2255,7 @@ unsigned int gs_buf_data_avail(struct gs_buf *gb) | |||
2255 | * Return the number of bytes of space available in the circular | 2255 | * Return the number of bytes of space available in the circular |
2256 | * buffer. | 2256 | * buffer. |
2257 | */ | 2257 | */ |
2258 | unsigned int gs_buf_space_avail(struct gs_buf *gb) | 2258 | static unsigned int gs_buf_space_avail(struct gs_buf *gb) |
2259 | { | 2259 | { |
2260 | if (gb != NULL) | 2260 | if (gb != NULL) |
2261 | return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size; | 2261 | return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size; |
@@ -2271,7 +2271,8 @@ unsigned int gs_buf_space_avail(struct gs_buf *gb) | |||
2271 | * | 2271 | * |
2272 | * Return the number of bytes copied. | 2272 | * Return the number of bytes copied. |
2273 | */ | 2273 | */ |
2274 | unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count) | 2274 | static unsigned int |
2275 | gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count) | ||
2275 | { | 2276 | { |
2276 | unsigned int len; | 2277 | unsigned int len; |
2277 | 2278 | ||
@@ -2309,7 +2310,8 @@ unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count) | |||
2309 | * | 2310 | * |
2310 | * Return the number of bytes copied. | 2311 | * Return the number of bytes copied. |
2311 | */ | 2312 | */ |
2312 | unsigned int gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count) | 2313 | static unsigned int |
2314 | gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count) | ||
2313 | { | 2315 | { |
2314 | unsigned int len; | 2316 | unsigned int len; |
2315 | 2317 | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 7078374d0b79..a2e6e3fc8c8d 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -481,8 +481,7 @@ alloc_ep_req (struct usb_ep *ep, unsigned length) | |||
481 | req = usb_ep_alloc_request (ep, GFP_ATOMIC); | 481 | req = usb_ep_alloc_request (ep, GFP_ATOMIC); |
482 | if (req) { | 482 | if (req) { |
483 | req->length = length; | 483 | req->length = length; |
484 | req->buf = usb_ep_alloc_buffer (ep, length, | 484 | req->buf = kmalloc(length, GFP_ATOMIC); |
485 | &req->dma, GFP_ATOMIC); | ||
486 | if (!req->buf) { | 485 | if (!req->buf) { |
487 | usb_ep_free_request (ep, req); | 486 | usb_ep_free_request (ep, req); |
488 | req = NULL; | 487 | req = NULL; |
@@ -493,8 +492,7 @@ alloc_ep_req (struct usb_ep *ep, unsigned length) | |||
493 | 492 | ||
494 | static void free_ep_req (struct usb_ep *ep, struct usb_request *req) | 493 | static void free_ep_req (struct usb_ep *ep, struct usb_request *req) |
495 | { | 494 | { |
496 | if (req->buf) | 495 | kfree(req->buf); |
497 | usb_ep_free_buffer (ep, req->buf, req->dma, req->length); | ||
498 | usb_ep_free_request (ep, req); | 496 | usb_ep_free_request (ep, req); |
499 | } | 497 | } |
500 | 498 | ||
@@ -1199,8 +1197,7 @@ autoconf_fail: | |||
1199 | dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); | 1197 | dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); |
1200 | if (!dev->req) | 1198 | if (!dev->req) |
1201 | goto enomem; | 1199 | goto enomem; |
1202 | dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ, | 1200 | dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); |
1203 | &dev->req->dma, GFP_KERNEL); | ||
1204 | if (!dev->req->buf) | 1201 | if (!dev->req->buf) |
1205 | goto enomem; | 1202 | goto enomem; |
1206 | 1203 | ||