diff options
Diffstat (limited to 'drivers/usb/gadget')
28 files changed, 2111 insertions, 342 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f81d08d6538..c1395516468 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -12,10 +12,9 @@ # With help from a special transceiver and a "Mini-AB" jack, systems with # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG). # -menu "USB Gadget Support" -config USB_GADGET - tristate "Support for USB Gadgets" +menuconfig USB_GADGET + tristate "USB Gadget Support" help USB is a master/slave protocol, organized with one master host (such as a PC) controlling up to 127 peripheral devices. @@ -42,6 +41,8 @@ config USB_GADGET For more information, see <http://www.linux-usb.org/gadget> and the kernel DocBook documentation for this API. +if USB_GADGET + config USB_GADGET_DEBUG boolean "Debugging messages" depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL @@ -220,6 +221,16 @@ config USB_M66592 default USB_GADGET select USB_GADGET_SELECTED +config SUPERH_BUILT_IN_M66592 + boolean "Enable SuperH built-in USB like the M66592" + depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722 + help + SH7722 has USB like the M66592. + + The transfer rate is very slow when use "Ethernet Gadget". + However, this problem is improved if change a value of + NET_IP_ALIGN to 4. + config USB_GADGET_GOKU boolean "Toshiba TC86C001 'Goku-S'" depends on PCI @@ -308,7 +319,7 @@ config USB_S3C2410_DEBUG config USB_GADGET_AT91 boolean "AT91 USB Device Port" - depends on ARCH_AT91 && !ARCH_AT91SAM9RL + depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 select USB_GADGET_SELECTED help Many Atmel AT91 processors (such as the AT91RM2000) have a @@ -538,6 +549,20 @@ config USB_MIDI_GADGET Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_midi". +config USB_G_PRINTER + tristate "Printer Gadget" + help + The Printer Gadget channels data between the USB host and a + userspace program driving the print engine. The user space + program reads and writes the device file /dev/g_printer to + receive or send printer data. It can use ioctl calls to + the device file to get or set printer status. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_printer". + + For more information, see Documentation/usb/gadget_printer.txt + which includes sample code for accessing the device file. # put drivers that need isochronous transfer support (for audio # or video class gadget drivers), or specific hardware, here. @@ -546,4 +571,4 @@ config USB_MIDI_GADGET endchoice -endmenu +endif # USB_GADGET diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 904e57bf611..c3aab80b6c7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -28,6 +28,8 @@ g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o gadgetfs-objs := inode.o g_file_storage-objs := file_storage.o usbstring.o config.o \ epautoconf.o +g_printer-objs := printer.o usbstring.o config.o \ + epautoconf.o ifeq ($(CONFIG_USB_ETH_RNDIS),y) g_ether-objs += rndis.o @@ -38,5 +40,6 @@ obj-$(CONFIG_USB_ETH) += g_ether.o obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o obj-$(CONFIG_USB_G_SERIAL) += g_serial.o +obj-$(CONFIG_USB_G_PRINTER) += g_printer.o obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index c72e9620bf8..b663f23f264 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1244,7 +1244,7 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) /* stop OUT naking */ if (!ep->in) { if (!use_dma && udc_rxfifo_pending) { - DBG(dev, "udc_queue(): pending bytes in" + DBG(dev, "udc_queue(): pending bytes in " "rxfifo after nyet\n"); /* * read pending bytes afer nyet: @@ -2038,6 +2038,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&dev->lock, flags); driver->unbind(&dev->gadget); + dev->gadget.dev.driver = NULL; dev->driver = NULL; /* set SD */ diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index a6adf7e0f6f..a83e8b798ec 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -21,8 +21,7 @@ * Boston, MA 02111-1307, USA. */ -#undef DEBUG -#undef VERBOSE +#undef VERBOSE_DEBUG #undef PACKET_TRACE #include <linux/kernel.h> @@ -46,8 +45,8 @@ #include <asm/irq.h> #include <asm/system.h> #include <asm/mach-types.h> +#include <asm/gpio.h> -#include <asm/arch/gpio.h> #include <asm/arch/board.h> #include <asm/arch/cpu.h> #include <asm/arch/at91sam9261_matrix.h> @@ -580,7 +579,7 @@ static int at91_ep_disable (struct usb_ep * _ep) */ static struct usb_request * -at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags) +at91_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct at91_request *req; @@ -881,15 +880,18 @@ static void clk_off(struct at91_udc *udc) */ static void pullup(struct at91_udc *udc, int is_on) { + int active = !udc->board.pullup_active_low; + if (!udc->enabled || !udc->vbus) is_on = 0; DBG("%sactive\n", is_on ? "" : "in"); if (is_on) { clk_on(udc); + at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, 0); if (cpu_is_at91rm9200()) - at91_set_gpio_value(udc->board.pullup_pin, 1); + gpio_set_value(udc->board.pullup_pin, active); else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); @@ -904,9 +906,10 @@ static void pullup(struct at91_udc *udc, int is_on) } } else { stop_activity(udc); + at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); if (cpu_is_at91rm9200()) - at91_set_gpio_value(udc->board.pullup_pin, 0); + gpio_set_value(udc->board.pullup_pin, !active); else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); @@ -1151,7 +1154,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | USB_REQ_GET_STATUS: tmp = w_index & USB_ENDPOINT_NUMBER_MASK; ep = &udc->ep[tmp]; - if (tmp > NUM_ENDPOINTS || (tmp && !ep->desc)) + if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc)) goto stall; if (tmp) { @@ -1174,7 +1177,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | USB_REQ_SET_FEATURE: tmp = w_index & USB_ENDPOINT_NUMBER_MASK; ep = &udc->ep[tmp]; - if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) + if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) goto stall; if (!ep->desc || ep->is_iso) goto stall; @@ -1193,7 +1196,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | USB_REQ_CLEAR_FEATURE: tmp = w_index & USB_ENDPOINT_NUMBER_MASK; ep = &udc->ep[tmp]; - if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS) + if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS) goto stall; if (tmp == 0) goto succeed; @@ -1549,7 +1552,7 @@ static irqreturn_t at91_vbus_irq(int irq, void *_udc) /* vbus needs at least brief debouncing */ udelay(10); - value = at91_get_gpio_value(udc->board.vbus_pin); + value = gpio_get_value(udc->board.vbus_pin); if (value != udc->vbus) at91_vbus_session(&udc->gadget, value); @@ -1614,6 +1617,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) local_irq_enable(); driver->unbind(&udc->gadget); + udc->gadget.dev.driver = NULL; + udc->gadget.dev.driver_data = NULL; udc->driver = NULL; DBG("unbound from %s\n", driver->driver.name); @@ -1643,12 +1648,12 @@ static int __init at91udc_probe(struct platform_device *pdev) } if (pdev->num_resources != 2) { - DBG("invalid num_resources"); + DBG("invalid num_resources\n"); return -ENODEV; } if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) { - DBG("invalid resource type"); + DBG("invalid resource type\n"); return -ENODEV; } @@ -1670,10 +1675,26 @@ static int __init at91udc_probe(struct platform_device *pdev) udc->pdev = pdev; udc->enabled = 0; + /* rm9200 needs manual D+ pullup; off by default */ + if (cpu_is_at91rm9200()) { + if (udc->board.pullup_pin <= 0) { + DBG("no D+ pullup?\n"); + retval = -ENODEV; + goto fail0; + } + retval = gpio_request(udc->board.pullup_pin, "udc_pullup"); + if (retval) { + DBG("D+ pullup is busy\n"); + goto fail0; + } + gpio_direction_output(udc->board.pullup_pin, + udc->board.pullup_active_low); + } + udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); if (!udc->udp_baseaddr) { - release_mem_region(res->start, res->end - res->start + 1); - return -ENOMEM; + retval = -ENOMEM; + goto fail0a; } udc_reinit(udc); @@ -1684,12 +1705,13 @@ static int __init at91udc_probe(struct platform_device *pdev) if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { DBG("clocks missing\n"); retval = -ENODEV; - goto fail0; + /* NOTE: we "know" here that refcounts on these are NOPs */ + goto fail0b; } retval = device_register(&udc->gadget.dev); if (retval < 0) - goto fail0; + goto fail0b; /* don't do anything until we have both gadget driver and VBUS */ clk_enable(udc->iclk); @@ -1701,25 +1723,32 @@ static int __init at91udc_probe(struct platform_device *pdev) /* request UDC and maybe VBUS irqs */ udc->udp_irq = platform_get_irq(pdev, 0); - if (request_irq(udc->udp_irq, at91_udc_irq, - IRQF_DISABLED, driver_name, udc)) { + retval = request_irq(udc->udp_irq, at91_udc_irq, + IRQF_DISABLED, driver_name, udc); + if (retval < 0) { DBG("request irq %d failed\n", udc->udp_irq); - retval = -EBUSY; goto fail1; } if (udc->board.vbus_pin > 0) { + retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); + if (retval < 0) { + DBG("request vbus pin failed\n"); + goto fail2; + } + gpio_direction_input(udc->board.vbus_pin); + /* * Get the initial state of VBUS - we cannot expect * a pending interrupt. */ - udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); + udc->vbus = gpio_get_value(udc->board.vbus_pin); if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) { DBG("request vbus irq %d failed\n", udc->board.vbus_pin); free_irq(udc->udp_irq, udc); retval = -EBUSY; - goto fail1; + goto fail3; } } else { DBG("no VBUS detection, assuming always-on\n"); @@ -1732,8 +1761,18 @@ static int __init at91udc_probe(struct platform_device *pdev) INFO("%s version %s\n", driver_name, DRIVER_VERSION); return 0; +fail3: + if (udc->board.vbus_pin > 0) + gpio_free(udc->board.vbus_pin); +fail2: + free_irq(udc->udp_irq, udc); fail1: device_unregister(&udc->gadget.dev); +fail0b: + iounmap(udc->udp_baseaddr); +fail0a: + if (cpu_is_at91rm9200()) + gpio_free(udc->board.pullup_pin); fail0: release_mem_region(res->start, res->end - res->start + 1); DBG("%s probe failed, %d\n", driver_name, retval); @@ -1754,12 +1793,18 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); - if (udc->board.vbus_pin > 0) + if (udc->board.vbus_pin > 0) { free_irq(udc->board.vbus_pin, udc); + gpio_free(udc->board.vbus_pin); + } free_irq(udc->udp_irq, udc); device_unregister(&udc->gadget.dev); iounmap(udc->udp_baseaddr); + + if (cpu_is_at91rm9200()) + gpio_free(udc->board.pullup_pin); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 7e34e2f864f..a973f2a50fb 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h @@ -53,7 +53,7 @@ #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ -#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ +#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrupt Status */ #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ @@ -158,13 +158,7 @@ struct at91_request { /*-------------------------------------------------------------------------*/ -#ifdef DEBUG -#define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff) -#else -#define DBG(stuff...) do{}while(0) -#endif - -#ifdef VERBOSE +#ifdef VERBOSE_DEBUG # define VDBG DBG #else # define VDBG(stuff...) do{}while(0) @@ -176,9 +170,10 @@ struct at91_request { # define PACKET(stuff...) do{}while(0) #endif -#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) +#define ERR(stuff...) pr_err("udc: " stuff) +#define WARN(stuff...) pr_warning("udc: " stuff) +#define INFO(stuff...) pr_info("udc: " stuff) +#define DBG(stuff...) pr_debug("udc: " stuff) #endif diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 4fb5ff46957..af8b2a3a2d4 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1384,8 +1384,7 @@ delegate: return retval; stall: - printk(KERN_ERR - "udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " + pr_err("udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " "halting endpoint...\n", ep->ep.name, crq->bRequestType, crq->bRequest, le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex), @@ -1456,8 +1455,7 @@ restart: set_protocol_stall(udc, ep); break; default: - printk(KERN_ERR - "udc: %s: TXCOMP: Invalid endpoint state %d, " + pr_err("udc: %s: TXCOMP: Invalid endpoint state %d, " "halting endpoint...\n", ep->ep.name, ep->state); set_protocol_stall(udc, ep); @@ -1486,8 +1484,7 @@ restart: default: usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); - printk(KERN_ERR - "udc: %s: RXRDY: Invalid endpoint state %d, " + pr_err("udc: %s: RXRDY: Invalid endpoint state %d, " "halting endpoint...\n", ep->ep.name, ep->state); set_protocol_stall(udc, ep); @@ -1532,7 +1529,7 @@ restart: pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); DBG(DBG_HW, "Packet length: %u\n", pkt_len); if (pkt_len != sizeof(crq)) { - printk(KERN_WARNING "udc: Invalid packet length %u " + pr_warning("udc: Invalid packet length %u " "(expected %lu)\n", pkt_len, sizeof(crq)); set_protocol_stall(udc, ep); return; diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index a68304e31a6..08bf6f9aaf7 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h @@ -216,7 +216,6 @@ #define FIFO_IOMEM_ID 0 #define CTRL_IOMEM_ID 1 -#ifdef DEBUG #define DBG_ERR 0x0001 /* report all error returns */ #define DBG_HW 0x0002 /* debug hardware initialization */ #define DBG_GADGET 0x0004 /* calls to/from gadget driver */ @@ -230,14 +229,12 @@ #define DBG_NONE 0x0000 #define DEBUG_LEVEL (DBG_ERR) + #define DBG(level, fmt, ...) \ do { \ if ((level) & DEBUG_LEVEL) \ - printk(KERN_DEBUG "udc: " fmt, ## __VA_ARGS__); \ + pr_debug("udc: " fmt, ## __VA_ARGS__); \ } while (0) -#else -#define DBG(level, fmt...) -#endif enum usba_ctrl_state { WAIT_FOR_SETUP, diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9db2482bdfa..cbe44535c0f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -61,6 +61,8 @@ #define DRIVER_DESC "USB Host+Gadget Emulator" #define DRIVER_VERSION "02 May 2005" +#define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ + static const char driver_name [] = "dummy_hcd"; static const char driver_desc [] = "USB Host+Gadget Emulator"; @@ -772,18 +774,17 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) list_del_init (&dum->ep [0].ep.ep_list); INIT_LIST_HEAD(&dum->fifo_req.queue); + driver->driver.bus = NULL; dum->driver = driver; dum->gadget.dev.driver = &driver->driver; dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); - if ((retval = driver->bind (&dum->gadget)) != 0) - goto err_bind_gadget; - - driver->driver.bus = dum->gadget.dev.parent->bus; - if ((retval = driver_register (&driver->driver)) != 0) - goto err_register; - if ((retval = device_bind_driver (&dum->gadget.dev)) != 0) - goto err_bind_driver; + retval = driver->bind(&dum->gadget); + if (retval) { + dum->driver = NULL; + dum->gadget.dev.driver = NULL; + return retval; + } /* khubd will enumerate this in a while */ spin_lock_irq (&dum->lock); @@ -793,20 +794,6 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) usb_hcd_poll_rh_status (dummy_to_hcd (dum)); return 0; - -err_bind_driver: - driver_unregister (&driver->driver); -err_register: - if (driver->unbind) - driver->unbind (&dum->gadget); - spin_lock_irq (&dum->lock); - dum->pullup = 0; - set_link_state (dum); - spin_unlock_irq (&dum->lock); -err_bind_gadget: - dum->driver = NULL; - dum->gadget.dev.driver = NULL; - return retval; } EXPORT_SYMBOL (usb_gadget_register_driver); @@ -830,11 +817,9 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver) spin_unlock_irqrestore (&dum->lock, flags); driver->unbind (&dum->gadget); + dum->gadget.dev.driver = NULL; dum->driver = NULL; - device_release_driver (&dum->gadget.dev); - driver_unregister (&driver->driver); - spin_lock_irqsave (&dum->lock, flags); dum->pullup = 0; set_link_state (dum); @@ -1827,8 +1812,7 @@ static int dummy_start (struct usb_hcd *hcd) INIT_LIST_HEAD (&dum->urbp_list); - /* only show a low-power port: just 8mA */ - hcd->power_budget = 8; + hcd->power_budget = POWER_BUDGET; hcd->state = HC_STATE_RUNNING; hcd->uses_new_polling = 1; diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 9e732bff9df..a70e255402b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1067,19 +1067,19 @@ done: /* on error, disable any endpoints */ if (result < 0) { - if (!subset_active(dev)) + if (!subset_active(dev) && dev->status_ep) (void) usb_ep_disable (dev->status_ep); dev->status = NULL; (void) usb_ep_disable (dev->in_ep); (void) usb_ep_disable (dev->out_ep); dev->in = NULL; dev->out = NULL; - } else + } /* activate non-CDC configs right away * this isn't strictly according to the RNDIS spec */ - if (!cdc_active (dev)) { + else if (!cdc_active (dev)) { netif_carrier_on (dev->net); if (netif_running (dev->net)) { spin_unlock (&dev->lock); diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 1d174dcb3ac..3301167d4f2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -275,19 +275,15 @@ MODULE_LICENSE("Dual BSD/GPL"); /*-------------------------------------------------------------------------*/ -#ifdef DEBUG #define LDBG(lun,fmt,args...) \ dev_dbg(&(lun)->dev , fmt , ## args) #define MDBG(fmt,args...) \ - printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) -#else -#define LDBG(lun,fmt,args...) \ - do { } while (0) -#define MDBG(fmt,args...) \ - do { } while (0) + pr_debug(DRIVER_NAME ": " fmt , ## args) + +#ifndef DEBUG #undef VERBOSE_DEBUG #undef DUMP_MSGS -#endif /* DEBUG */ +#endif /* !DEBUG */ #ifdef VERBOSE_DEBUG #define VLDBG LDBG @@ -304,7 +300,7 @@ MODULE_LICENSE("Dual BSD/GPL"); dev_info(&(lun)->dev , fmt , ## args) #define MINFO(fmt,args...) \ - printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) + pr_info(DRIVER_NAME ": " fmt , ## args) #define DBG(d, fmt, args...) \ dev_dbg(&(d)->gadget->dev , fmt , ## args) diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 9bb7f64a85c..63e8fa3a69e 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -776,7 +776,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) VDBG("%s, bad params\n", __FUNCTION__); return -EINVAL; } - if (!_ep || (!ep->desc && ep_index(ep))) { + if (unlikely(!_ep || !ep->desc)) { VDBG("%s, bad ep\n", __FUNCTION__); return -EINVAL; } @@ -1318,7 +1318,7 @@ static void setup_received_irq(struct fsl_udc *udc, | USB_TYPE_STANDARD)) { /* Note: The driver has not include OTG support yet. * This will be set when OTG support is added */ - if (!gadget_is_otg(udc->gadget)) + if (!gadget_is_otg(&udc->gadget)) break; else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) udc->gadget.b_hnp_enable = 1; @@ -1896,7 +1896,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, spin_lock_irqsave(&udc->lock, flags); - /* ------basic driver infomation ---- */ + /* ------basic driver information ---- */ t = scnprintf(next, size, DRIVER_DESC "\n" "%s version: %s\n" diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 832ab82b488..9fb0b1ec852 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -551,9 +551,9 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) #define VDBG(stuff...) do{}while(0) #endif -#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) +#define ERR(stuff...) pr_err("udc: " stuff) +#define WARN(stuff...) pr_warning("udc: " stuff) +#define INFO(stuff...) pr_info("udc: " stuff) /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 0689189550b..5b42ccd0035 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -24,7 +24,6 @@ #include <linux/utsname.h> #include <linux/device.h> -#include <sound/driver.h> #include <sound/core.h> #include <sound/initval.h> #include <sound/rawmidi.h> @@ -1159,7 +1158,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget) /* support optional vendor/distro customization */ if (idVendor) { if (!idProduct) { - printk(KERN_ERR "idVendor needs idProduct!\n"); + pr_err("idVendor needs idProduct!\n"); return -ENODEV; } device_desc.idVendor = cpu_to_le16(idVendor); @@ -1191,7 +1190,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget) in_ep = usb_ep_autoconfig(gadget, &bulk_in_desc); if (!in_ep) { autoconf_fail: - printk(KERN_ERR "%s: can't autoconfigure on %s\n", + pr_err("%s: can't autoconfigure on %s\n", shortname, gadget->name); return -ENODEV; } @@ -1213,7 +1212,7 @@ autoconf_fail: * it SHOULD NOT have problems with bulk-capable hardware. * so warn about unrecognized controllers, don't panic. */ - printk(KERN_WARNING "%s: controller '%s' not recognized\n", + pr_warning("%s: controller '%s' not recognized\n", shortname, gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); } diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 2ec9d196a8c..d3e702576de 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1422,6 +1422,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&dev->lock, flags); driver->unbind(&dev->gadget); + dev->gadget.dev.driver = NULL; DBG(dev, "unregistered driver '%s'\n", driver->driver.name); return 0; diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 47ef8bd58a0..805602a687c 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1699,7 +1699,7 @@ gadgetfs_bind (struct usb_gadget *gadget) if (!dev) return -ESRCH; if (0 != strcmp (CHIP, gadget->name)) { - printk (KERN_ERR "%s expected %s controller not %s\n", + pr_err("%s expected %s controller not %s\n", shortname, CHIP, gadget->name); return -ENODEV; } diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 367b75c0b25..37243ef7104 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -474,6 +474,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&dev->lock, flags); driver->unbind(&dev->gadget); + dev->gadget.dev.driver = NULL; device_del(&dev->gadget.dev); udc_disable(dev); diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index ebc5536aa27..835948f0715 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -36,9 +36,14 @@ MODULE_DESCRIPTION("M66592 USB gadget driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yoshihiro Shimoda"); -#define DRIVER_VERSION "29 May 2007" +#define DRIVER_VERSION "18 Oct 2007" /* module parameters */ +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +static unsigned short endian = M66592_LITTLE; +module_param(endian, ushort, 0644); +MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)"); +#else static unsigned short clock = M66592_XTAL24; module_param(clock, ushort, 0644); MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " @@ -56,6 +61,7 @@ static unsigned short irq_sense = M66592_INTL; module_param(irq_sense, ushort, 0644); MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " "(default=2)"); +#endif static const char udc_name[] = "m66592_udc"; static const char *m66592_ep_name[] = { @@ -141,7 +147,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) offset = get_pipectr_addr(pipenum); pid = m66592_read(m66592, offset) & M66592_PID; } else - printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); + pr_err("unexpect pipe num (%d)\n", pipenum); return pid; } @@ -157,7 +163,7 @@ static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, offset = get_pipectr_addr(pipenum); m66592_mdfy(m66592, pid, M66592_PID, offset); } else - printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); + pr_err("unexpect pipe num (%d)\n", pipenum); } static inline void pipe_start(struct m66592 *m66592, u16 pipenum) @@ -186,7 +192,7 @@ static inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum) offset = get_pipectr_addr(pipenum); ret = m66592_read(m66592, offset); } else - printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum); + pr_err("unexpect pipe num (%d)\n", pipenum); return ret; } @@ -203,7 +209,7 @@ static inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum) offset = get_pipectr_addr(pipenum); m66592_bset(m66592, M66592_SQCLR, offset); } else - printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum); + pr_err("unexpect pipe num(%d)\n", pipenum); } static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) @@ -285,7 +291,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, break; } if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { - printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", + pr_err("m66592 pipe memory is insufficient(%d)\n", m66592->bi_bufnum); return -ENOMEM; } @@ -326,7 +332,7 @@ static void pipe_buffer_release(struct m66592 *m66592, if (info->type == M66592_BULK) m66592->bulk--; } else - printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", + pr_err("ep_release: unexpect pipenum (%d)\n", info->pipe); } @@ -360,6 +366,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, ep->fifosel = M66592_D0FIFOSEL; ep->fifoctr = M66592_D0FIFOCTR; ep->fifotrn = M66592_D0FIFOTRN; +#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) } else if (m66592->num_dma == 1) { m66592->num_dma++; ep->use_dma = 1; @@ -367,6 +374,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, ep->fifosel = M66592_D1FIFOSEL; ep->fifoctr = M66592_D1FIFOCTR; ep->fifotrn = M66592_D1FIFOTRN; +#endif } else { ep->use_dma = 0; ep->fifoaddr = M66592_CFIFO; @@ -422,7 +430,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, case USB_ENDPOINT_XFER_BULK: if (m66592->bulk >= M66592_MAX_NUM_BULK) { if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { - printk(KERN_ERR "bulk pipe is insufficient\n"); + pr_err("bulk pipe is insufficient\n"); return -ENODEV; } else { info.pipe = M66592_BASE_PIPENUM_ISOC @@ -438,7 +446,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, break; case USB_ENDPOINT_XFER_INT: if (m66592->interrupt >= M66592_MAX_NUM_INT) { - printk(KERN_ERR "interrupt pipe is insufficient\n"); + pr_err("interrupt pipe is insufficient\n"); return -ENODEV; } info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt; @@ -447,7 +455,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, break; case USB_ENDPOINT_XFER_ISOC: if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { - printk(KERN_ERR "isochronous pipe is insufficient\n"); + pr_err("isochronous pipe is insufficient\n"); return -ENODEV; } info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous; @@ -455,7 +463,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, counter = &m66592->isochronous; break; default: - printk(KERN_ERR "unexpect xfer type\n"); + pr_err("unexpect xfer type\n"); return -EINVAL; } ep->type = info.type; @@ -470,7 +478,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, ret = pipe_buffer_setting(m66592, &info); if (ret < 0) { - printk(KERN_ERR "pipe_buffer_setting fail\n"); + pr_err("pipe_buffer_setting fail\n"); return ret; } @@ -606,11 +614,33 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) control_end(ep->m66592, 0); break; default: - printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq); + pr_err("start_ep0: unexpect ctsq(%x)\n", ctsq); break; } } +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +static void init_controller(struct m66592 *m66592) +{ + usbf_start_clock(); + m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ + m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); + m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); + m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); + + /* This is a workaound for SH7722 2nd cut */ + m66592_bset(m66592, 0x8000, M66592_DVSTCTR); + m66592_bset(m66592, 0x1000, M66592_TESTMODE); + m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); + + m66592_bset(m66592, M66592_INTL, M66592_INTENB1); + + m66592_write(m66592, 0, M66592_CFBCFG); + m66592_write(m66592, 0, M66592_D0FBCFG); + m66592_bset(m66592, endian, M66592_CFBCFG); + m66592_bset(m66592, endian, M66592_D0FBCFG); +} +#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ static void init_controller(struct m66592 *m66592) { m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), @@ -636,9 +666,13 @@ static void init_controller(struct m66592 *m66592) m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, M66592_DMA0CFG); } +#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ static void disable_controller(struct m66592 *m66592) { +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) + usbf_stop_clock(); +#else m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); udelay(1); m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); @@ -646,15 +680,20 @@ static void disable_controller(struct m66592 *m66592) m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); udelay(1); m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); +#endif } static void m66592_start_xclock(struct m66592 *m66592) { +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) + usbf_start_clock(); +#else u16 tmp; tmp = m66592_read(m66592, M66592_SYSCFG); if (!(tmp & M66592_XCKE)) m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); +#endif } /*-------------------------------------------------------------------------*/ @@ -709,7 +748,7 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) do { tmp = m66592_read(m66592, ep->fifoctr); if (i++ > 100000) { - printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus" + pr_err("pipe0 is busy. maybe cpu i/o bus " "conflict. please power off this controller."); return; } @@ -759,7 +798,7 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) if (unlikely((tmp & M66592_FRDY) == 0)) { pipe_stop(m66592, pipenum); pipe_irq_disable(m66592, pipenum); - printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum); + pr_err("write fifo not ready. pipnum=%d\n", pipenum); return; } @@ -808,7 +847,7 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) req->req.status = -EPIPE; pipe_stop(m66592, pipenum); pipe_irq_disable(m66592, pipenum); - printk(KERN_ERR "read fifo not ready"); + pr_err("read fifo not ready"); return; } @@ -1063,7 +1102,7 @@ static void m66592_update_usb_speed(struct m66592 *m66592) break; default: m66592->gadget.speed = USB_SPEED_UNKNOWN; - printk(KERN_ERR "USB speed unknown\n"); + pr_err("USB speed unknown\n"); } } @@ -1122,7 +1161,7 @@ __acquires(m66592->lock) control_end(m66592, 0); break; default: - printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq); + pr_err("ctrl_stage: unexpect ctsq(%x)\n", ctsq); break; } } @@ -1142,6 +1181,19 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) intsts0 = m66592_read(m66592, M66592_INTSTS0); intenb0 = m66592_read(m66592, M66592_INTENB0); +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) + if (!intsts0 && !intenb0) { + /* + * When USB clock stops, it cannot read register. Even if a + * clock stops, the interrupt occurs. So this driver turn on + * a clock by this timing and do re-reading of register. + */ + m66592_start_xclock(m66592); + intsts0 = m66592_read(m66592, M66592_INTSTS0); + intenb0 = m66592_read(m66592, M66592_INTENB0); + } +#endif + savepipe = m66592_read(m66592, M66592_CFIFOSEL); mask0 = intsts0 & intenb0; @@ -1409,13 +1461,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) retval = device_add(&m66592->gadget.dev); if (retval) { - printk(KERN_ERR "device_add error (%d)\n", retval); + pr_err("device_add error (%d)\n", retval); goto error; } retval = driver->bind (&m66592->gadget); if (retval) { - printk(KERN_ERR "bind to driver error (%d)\n", retval); + pr_err("bind to driver error (%d)\n", retval); device_del(&m66592->gadget.dev); goto error; } @@ -1456,6 +1508,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); driver->unbind(&m66592->gadget); + m66592->gadget.dev.driver = NULL; init_controller(m66592); disable_controller(m66592); @@ -1485,6 +1538,7 @@ static int __exit m66592_remove(struct platform_device *pdev) iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); + usbf_stop_clock(); kfree(m66592); return 0; } @@ -1508,28 +1562,28 @@ static int __init m66592_probe(struct platform_device *pdev) (char *)udc_name); if (!res) { ret = -ENODEV; - printk(KERN_ERR "platform_get_resource_byname error.\n"); + pr_err("platform_get_resource_byname error.\n"); goto clean_up; } irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENODEV; - printk(KERN_ERR "platform_get_irq error.\n"); + pr_err("platform_get_irq error.\n"); goto clean_up; } reg = ioremap(res->start, resource_len(res)); if (reg == NULL) { ret = -ENOMEM; - printk(KERN_ERR "ioremap error.\n"); + pr_err("ioremap error.\n"); goto clean_up; } /* initialize ucd */ m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); if (m66592 == NULL) { - printk(KERN_ERR "kzalloc error\n"); + pr_err("kzalloc error\n"); goto clean_up; } @@ -1555,7 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev) ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, udc_name, m66592); if (ret < 0) { - printk(KERN_ERR "request_irq error (%d)\n", ret); + pr_err("request_irq error (%d)\n", ret); goto clean_up; } diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index bfa0c645f22..17b792b7f6b 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h @@ -72,6 +72,11 @@ #define M66592_P_TST_J 0x0001 /* PERI TEST J */ #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +#define M66592_CFBCFG 0x0A +#define M66592_D0FBCFG 0x0C +#define M66592_LITTLE 0x0100 /* b8: Little endian mode */ +#else #define M66592_PINCFG 0x0A #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ @@ -91,6 +96,7 @@ #define M66592_PKTM 0x0020 /* b5: Packet mode */ #define M66592_DENDE 0x0010 /* b4: Dend enable */ #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ +#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ #define M66592_CFIFO 0x10 #define M66592_D0FIFO 0x14 @@ -103,9 +109,13 @@ #define M66592_REW 0x4000 /* b14: Buffer rewind */ #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +#define M66592_MBW 0x0800 /* b11: Maximum bit width for FIFO */ +#else #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ #define M66592_MBW_8 0x0000 /* 8bit */ #define M66592_MBW_16 0x0400 /* 16bit */ +#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ @@ -530,8 +540,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592, { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) + len = (len + 3) / 4; + insl(fifoaddr, buf, len); +#else len = (len + 1) / 2; insw(fifoaddr, buf, len); +#endif } static inline void m66592_write(struct m66592 *m66592, u16 val, @@ -545,6 +560,24 @@ static inline void m66592_write_fifo(struct m66592 *m66592, void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) + unsigned long count; + unsigned char *pb; + int i; + + count = len / 4; + outsl(fifoaddr, buf, count); + + if (len & 0x00000003) { + pb = buf + count * 4; + for (i = 0; i < (len & 0x00000003); i++) { + if (m66592_read(m66592, M66592_CFBCFG)) /* little */ + outb(pb[i], fifoaddr + (3 - i)); + else + outb(pb[i], fifoaddr + i); + } + } +#else unsigned long odd = len & 0x0001; len = len / 2; @@ -553,6 +586,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, unsigned char *p = buf + len*2; outb(*p, fifoaddr); } +#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ } static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, @@ -570,6 +604,26 @@ static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, #define m66592_bset(m66592, val, offset) \ m66592_mdfy(m66592, val, 0, offset) +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) +#include <asm/io.h> +#define MSTPCR2 0xA4150038 /* for SH7722 */ +#define MSTPCR2_USB 0x00000800 + +static inline void usbf_start_clock(void) +{ + ctrl_outl(ctrl_inl(MSTPCR2) & ~MSTPCR2_USB, MSTPCR2); +} + +static inline void usbf_stop_clock(void) +{ + ctrl_outl(ctrl_inl(MSTPCR2) | MSTPCR2_USB, MSTPCR2); +} + +#else +#define usbf_start_clock(x) +#define usbf_stop_clock(x) +#endif /* if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ + #endif /* ifndef __M66592_UDC_H__ */ diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index d5d473f8144..33469cf5aec 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2435,7 +2435,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) break; default: delegate: - VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x" + VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x " "ep_cfg %08x\n", u.r.bRequestType, u.r.bRequest, w_value, w_index, w_length, diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 87c4f50dfb6..e6d68bda428 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -4,6 +4,8 @@ * Copyright (C) 2004 Texas Instruments, Inc. * Copyright (C) 2004-2005 David Brownell * + * OMAP2 & DMA support by Kyungmin Park <kyungmin.park@samsung.com> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -60,11 +62,6 @@ /* bulk DMA seems to be behaving for both IN and OUT */ #define USE_DMA -/* FIXME: OMAP2 currently has some problem in DMA mode */ -#ifdef CONFIG_ARCH_OMAP2 -#undef USE_DMA -#endif - /* ISO too */ #define USE_ISO @@ -73,6 +70,8 @@ #define DMA_ADDR_INVALID (~(dma_addr_t)0) +#define OMAP2_DMA_CH(ch) (((ch) - 1) << 1) +#define OMAP24XX_DMA(name, ch) (OMAP24XX_DMA_##name + OMAP2_DMA_CH(ch)) /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the @@ -571,20 +570,25 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) const int sync_mode = cpu_is_omap15xx() ? OMAP_DMA_SYNC_FRAME : OMAP_DMA_SYNC_ELEMENT; + int dma_trigger = 0; + + if (cpu_is_omap24xx()) + dma_trigger = OMAP24XX_DMA(USB_W2FC_TX0, ep->dma_channel); /* measure length in either bytes or packets */ if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) + || (cpu_is_omap24xx() && length < ep->maxpacket) || (cpu_is_omap15xx() && length < ep->maxpacket)) { txdma_ctrl = UDC_TXN_EOT | length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, - length, 1, sync_mode, 0, 0); + length, 1, sync_mode, dma_trigger, 0); } else { length = min(length / ep->maxpacket, (unsigned) UDC_TXN_TSC + 1); txdma_ctrl = length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, ep->ep.maxpacket >> 1, length, sync_mode, - 0, 0); + dma_trigger, 0); length *= ep->maxpacket; } omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, @@ -622,20 +626,31 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) static void next_out_dma(struct omap_ep *ep, struct omap_req *req) { - unsigned packets; + unsigned packets = req->req.length - req->req.actual; + int dma_trigger = 0; + + if (cpu_is_omap24xx()) + dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); /* NOTE: we filtered out "short reads" before, so we know * the buffer has only whole numbers of packets. + * except MODE SELECT(6) sent the 24 bytes data in OMAP24XX DMA mode */ - - /* set up this DMA transfer, enable the fifo, start */ - packets = (req->req.length - req->req.actual) / ep->ep.maxpacket; - packets = min(packets, (unsigned)UDC_RXN_TC + 1); - req->dma_bytes = packets * ep->ep.maxpacket; - omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, - ep->ep.maxpacket >> 1, packets, - OMAP_DMA_SYNC_ELEMENT, - 0, 0); + if (cpu_is_omap24xx() && packets < ep->maxpacket) { + omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, + packets, 1, OMAP_DMA_SYNC_ELEMENT, + dma_trigger, 0); + req->dma_bytes = packets; + } else { + /* set up this DMA transfer, enable the fifo, start */ + packets /= ep->ep.maxpacket; + packets = min(packets, (unsigned)UDC_RXN_TC + 1); + req->dma_bytes = packets * ep->ep.maxpacket; + omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, + ep->ep.maxpacket >> 1, packets, + OMAP_DMA_SYNC_ELEMENT, + dma_trigger, 0); + } omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, 0, 0); @@ -743,6 +758,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) { u16 reg; int status, restart, is_in; + int dma_channel; is_in = ep->bEndpointAddress & USB_DIR_IN; if (is_in) @@ -769,11 +785,15 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) ep->dma_channel = channel; if (is_in) { - status = omap_request_dma(OMAP_DMA_USB_W2FC_TX0 - 1 + channel, + if (cpu_is_omap24xx()) + dma_channel = OMAP24XX_DMA(USB_W2FC_TX0, channel); + else + dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; + status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { UDC_TXDMA_CFG_REG = reg; - /* EMIFF */ + /* EMIFF or SDRC */ omap_set_dma_src_burst_mode(ep->lch, OMAP_DMA_DATA_BURST_4); omap_set_dma_src_data_pack(ep->lch, 1); @@ -785,7 +805,12 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) 0, 0); } } else { - status = omap_request_dma(OMAP_DMA_USB_W2FC_RX0 - 1 + channel, + if (cpu_is_omap24xx()) + dma_channel = OMAP24XX_DMA(USB_W2FC_RX0, channel); + else + dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; + + status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { UDC_RXDMA_CFG_REG = reg; @@ -795,7 +820,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) OMAP_DMA_AMODE_CONSTANT, (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), 0, 0); - /* EMIFF */ + /* EMIFF or SDRC */ omap_set_dma_dest_burst_mode(ep->lch, OMAP_DMA_DATA_BURST_4); omap_set_dma_dest_data_pack(ep->lch, 1); @@ -808,7 +833,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); /* channel type P: hw synch (fifo) */ - if (!cpu_is_omap15xx()) + if (cpu_class_is_omap1() && !cpu_is_omap15xx()) OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; } @@ -926,11 +951,13 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* this isn't bogus, but OMAP DMA isn't the only hardware to * have a hard time with partial packet reads... reject it. + * Except OMAP2 can handle the small packets. */ if (use_dma && ep->has_dma && ep->bEndpointAddress != 0 && (ep->bEndpointAddress & USB_DIR_IN) == 0 + && !cpu_class_is_omap2() && (req->req.length % ep->ep.maxpacket) != 0) { DBG("%s, no partial packet OUT reads\n", __FUNCTION__); return -EMSGSIZE; @@ -1001,7 +1028,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* STATUS for zero length DATA stages is * always an IN ... even for IN transfers, - * a wierd case which seem to stall OMAP. + * a weird case which seem to stall OMAP. */ UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); UDC_CTRL_REG = UDC_CLR_EP; @@ -1241,14 +1268,14 @@ static void pullup_enable(struct omap_udc *udc) udc->gadget.dev.parent->power.power_state = PMSG_ON; udc->gadget.dev.power.power_state = PMSG_ON; UDC_SYSCON1_REG |= UDC_PULLUP_EN; - if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) OTG_CTRL_REG |= OTG_BSESSVLD; UDC_IRQ_EN_REG = UDC_DS_CHG_IE; } static void pullup_disable(struct omap_udc *udc) { - if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) OTG_CTRL_REG &= ~OTG_BSESSVLD; UDC_IRQ_EN_REG = UDC_DS_CHG_IE; UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; @@ -1386,7 +1413,7 @@ static void update_otg(struct omap_udc *udc) { u16 devstat; - if (!gadget_is_otg(udc->gadget)) + if (!gadget_is_otg(&udc->gadget)) return; if (OTG_CTRL_REG & OTG_ID) diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h index 1dc398bb9ab..c6b9cbc7230 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/omap_udc.h @@ -182,21 +182,16 @@ struct omap_udc { /*-------------------------------------------------------------------------*/ -#ifdef DEBUG -#define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff) -#else -#define DBG(stuff...) do{}while(0) -#endif - #ifdef VERBOSE # define VDBG DBG #else # define VDBG(stuff...) do{}while(0) #endif -#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) +#define ERR(stuff...) pr_err("udc: " stuff) +#define WARN(stuff...) pr_warning("udc: " stuff) +#define INFO(stuff...) pr_info("udc: " stuff) +#define DBG(stuff...) pr_debug("udc: " stuff) /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c new file mode 100644 index 00000000000..9fdabc8fcac --- /dev/null +++ b/drivers/usb/gadget/printer.c @@ -0,0 +1,1592 @@ +/* + * printer.c -- Printer gadget driver + * + * Copyright (C) 2003-2005 David Brownell + * Copyright (C) 2006 Craig W. Nadler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/smp_lock.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/timer.h> +#include <linux/list.h> +#include <linux/interrupt.h> +#include <linux/utsname.h> +#include <linux/device.h> +#include <linux/moduleparam.h> +#include <linux/fs.h> +#include <linux/poll.h> +#include <linux/types.h> +#include <linux/ctype.h> +#include <linux/cdev.h> + +#include <asm/byteorder.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <asm/system.h> +#include <linux/uaccess.h> +#include <asm/unaligned.h> + +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/g_printer.h> + +#include "gadget_chips.h" + +#define DRIVER_DESC "Printer Gadget" +#define DRIVER_VERSION "2007 OCT 06" + +static const char shortname [] = "printer"; +static const char driver_desc [] = DRIVER_DESC; + +static dev_t g_printer_devno; + +static struct class *usb_gadget_class; + +/*-------------------------------------------------------------------------*/ + +struct printer_dev { + spinlock_t lock; /* lock this structure */ + /* lock buffer lists during read/write calls */ + spinlock_t lock_printer_io; + struct usb_gadget *gadget; + struct usb_request *req; /* for control responses */ + u8 config; + s8 interface; + struct usb_ep *in_ep, *out_ep; + const struct usb_endpoint_descriptor + *in, *out; + struct list_head rx_reqs; /* List of free RX structs */ + struct list_head rx_reqs_active; /* List of Active RX xfers */ + struct list_head rx_buffers; /* List of completed xfers */ + /* wait until there is data to be read. */ + wait_queue_head_t rx_wait; + struct list_head tx_reqs; /* List of free TX structs */ + struct list_head tx_reqs_active; /* List of Active TX xfers */ + /* Wait until there are write buffers available to use. */ + wait_queue_head_t tx_wait; + /* Wait until all write buffers have been sent. */ + wait_queue_head_t tx_flush_wait; + struct usb_request *current_rx_req; + size_t current_rx_bytes; + u8 *current_rx_buf; + u8 printer_status; + u8 reset_printer; + struct class_device *printer_class_dev; + struct cdev printer_cdev; + struct device *pdev; + u8 printer_cdev_open; + wait_queue_head_t wait; +}; + +static struct printer_dev usb_printer_gadget; + +/*-------------------------------------------------------------------------*/ + +/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! + * Instead: allocate your own, using normal USB-IF procedures. + */ + +/* Thanks to NetChip Technologies for donating this product ID. + */ +#define PRINTER_VENDOR_NUM 0x0525 /* NetChip */ +#define PRINTER_PRODUCT_NUM 0xa4a8 /* Linux-USB Printer Gadget */ + +/* Some systems will want different product identifers published in the + * device descriptor, either numbers or strings or both. These string + * parameters are in UTF-8 (superset of ASCII's 7 bit characters). + */ + +static ushort __initdata idVendor; +module_param(idVendor, ushort, S_IRUGO); +MODULE_PARM_DESC(idVendor, "USB Vendor ID"); + +static ushort __initdata idProduct; +module_param(idProduct, ushort, S_IRUGO); +MODULE_PARM_DESC(idProduct, "USB Product ID"); + +static ushort __initdata bcdDevice; +module_param(bcdDevice, ushort, S_IRUGO); +MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); + +static char *__initdata iManufacturer; +module_param(iManufacturer, charp, S_IRUGO); +MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); + +static char *__initdata iProduct; +module_param(iProduct, charp, S_IRUGO); +MODULE_PARM_DESC(iProduct, "USB Product string"); + +static char *__initdata iSerialNum; +module_param(iSerialNum, charp, S_IRUGO); +MODULE_PARM_DESC(iSerialNum, "1"); + +static char *__initdata iPNPstring; +module_param(iPNPstring, charp, S_IRUGO); +MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"); + +/* Number of requests to allocate per endpoint, not used for ep0. */ +static unsigned qlen = 10; +module_param(qlen, uint, S_IRUGO|S_IWUSR); + +#define QLEN qlen + +#ifdef CONFIG_USB_GADGET_DUALSPEED +#define DEVSPEED USB_SPEED_HIGH +#else /* full speed (low speed doesn't do bulk) */ +#define DEVSPEED USB_SPEED_FULL +#endif + +/*-------------------------------------------------------------------------*/ + +#define xprintk(d, level, fmt, args...) \ + printk(level "%s: " fmt, DRIVER_DESC, ## args) + +#ifdef DEBUG +#define DBG(dev, fmt, args...) \ + xprintk(dev, KERN_DEBUG, fmt, ## args) +#else +#define DBG(dev, fmt, args...) \ + do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG(dev, fmt, args...) \ + xprintk(dev, KERN_DEBUG, fmt, ## args) +#else +#define VDBG(dev, fmt, args...) \ + do { } while (0) +#endif /* VERBOSE */ + +#define ERROR(dev, fmt, args...) \ + xprintk(dev, KERN_ERR, fmt, ## args) +#define WARN(dev, fmt, args...) \ + xprintk(dev, KERN_WARNING, fmt, ## args) +#define INFO(dev, fmt, args...) \ + xprintk(dev, KERN_INFO, fmt, ## args) + +/*-------------------------------------------------------------------------*/ + +/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly + * ep0 implementation: descriptors, config management, setup(). + * also optional class-specific notification interrupt transfer. + */ + +/* + * DESCRIPTORS ... most are static, but strings and (full) configuration + * descriptors are built on demand. + */ + +#define STRING_MANUFACTURER 1 +#define STRING_PRODUCT 2 +#define STRING_SERIALNUM 3 + +/* holds our biggest descriptor */ +#define USB_DESC_BUFSIZE 256 +#define USB_BUFSIZE 8192 + +/* This device advertises one configuration. */ +#define DEV_CONFIG_VALUE 1 +#define PRINTER_INTERFACE 0 + +static struct usb_device_descriptor device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM), + .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM), + .iManufacturer = STRING_MANUFACTURER, + .iProduct = STRING_PRODUCT, + .iSerialNumber = STRING_SERIALNUM, + .bNumConfigurations = 1 +}; + +static struct usb_otg_descriptor otg_desc = { + .bLength = sizeof otg_desc, + .bDescriptorType = USB_DT_OTG, + .bmAttributes = USB_OTG_SRP +}; + +static struct usb_config_descriptor config_desc = { + .bLength = sizeof config_desc, + .bDescriptorType = USB_DT_CONFIG, + + /* compute wTotalLength on the fly */ + .bNumInterfaces = 1, + .bConfigurationValue = DEV_CONFIG_VALUE, + .iConfiguration = 0, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 1 /* Self-Powered */ +}; + +static struct usb_interface_descriptor intf_desc = { + .bLength = sizeof intf_desc, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = PRINTER_INTERFACE, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_PRINTER, + .bInterfaceSubClass = 1, /* Printer Sub-Class */ + .bInterfaceProtocol = 2, /* Bi-Directional */ + .iInterface = 0 +}; + +static struct usb_endpoint_descriptor fs_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK +}; + +static struct usb_endpoint_descriptor fs_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK +}; + +static const struct usb_descriptor_header *fs_printer_function [11] = { + (struct usb_descriptor_header *) &otg_desc, + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &fs_ep_in_desc, + (struct usb_descriptor_header *) &fs_ep_out_desc, + NULL +}; + +#ifdef CONFIG_USB_GADGET_DUALSPEED + +/* + * usb 2.0 devices need to expose both high speed and full speed + * descriptors, unless they only run at full speed. + */ + +static struct usb_endpoint_descriptor hs_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512) +}; + +static struct usb_endpoint_descriptor hs_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512) +}; + +static struct usb_qualifier_descriptor dev_qualifier = { + .bLength = sizeof dev_qualifier, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_PRINTER, + .bNumConfigurations = 1 +}; + +static const struct usb_descriptor_header *hs_printer_function [11] = { + (struct usb_descriptor_header *) &otg_desc, + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &hs_ep_in_desc, + (struct usb_descriptor_header *) &hs_ep_out_desc, + NULL +}; + +/* maxpacket and other transfer characteristics vary by speed. */ +#define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) + +#else + +/* if there's no high speed support, maxpacket doesn't change. */ +#define ep_desc(g, hs, fs) (((void)(g)), (fs)) + +#endif /* !CONFIG_USB_GADGET_DUALSPEED */ + +/*-------------------------------------------------------------------------*/ + +/* descriptors that are built on-demand */ + +static char manufacturer [50]; +static char product_desc [40] = DRIVER_DESC; +static char serial_num [40] = "1"; +static char pnp_string [1024] = + "XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"; + +/* static strings, in UTF-8 */ +static struct usb_string strings [] = { + { STRING_MANUFACTURER, manufacturer, }, + { STRING_PRODUCT, product_desc, }, + { STRING_SERIALNUM, serial_num, }, + { } /* end of list */ +}; + +static struct usb_gadget_strings stringtab = { + .language = 0x0409, /* en-us */ + .strings = strings, +}; + +/*-------------------------------------------------------------------------*/ + +static struct usb_request * +printer_req_alloc(struct usb_ep *ep, unsigned len, gfp_t gfp_flags) +{ + struct usb_request *req; + + req = usb_ep_alloc_request(ep, gfp_flags); + + if (req != NULL) { + req->length = len; + req->buf = kmalloc(len, gfp_flags); + if (req->buf == NULL) { + usb_ep_free_request(ep, req); + return NULL; + } + } + + return req; +} + +static void +printer_req_free(struct usb_ep *ep, struct usb_request *req) +{ + if (ep != NULL && req != NULL) { + kfree(req->buf); + usb_ep_free_request(ep, req); + } +} + +/*-------------------------------------------------------------------------*/ + +static void rx_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct printer_dev *dev = ep->driver_data; + int status = req->status; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + + list_del_init(&req->list); /* Remode from Active List */ + + switch (status) { + + /* normal completion */ + case 0: + list_add_tail(&req->list, &dev->rx_buffers); + wake_up_interruptible(&dev->rx_wait); + DBG(dev, "G_Printer : rx length %d\n", req->actual); + break; + + /* software-driven interface shutdown */ + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: /* disconnect etc */ + VDBG(dev, "rx shutdown, code %d\n", status); + list_add(&req->list, &dev->rx_reqs); + break; + + /* for hardware automagic (such as pxa) */ + case -ECONNABORTED: /* endpoint reset */ + DBG(dev, "rx %s reset\n", ep->name); + list_add(&req->list, &dev->rx_reqs); + break; + + /* data overrun */ + case -EOVERFLOW: + /* FALLTHROUGH */ + + default: + DBG(dev, "rx status %d\n", status); + list_add(&req->list, &dev->rx_reqs); + break; + } + spin_unlock_irqrestore(&dev->lock, flags); +} + +static void tx_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct printer_dev *dev = ep->driver_data; + + switch (req->status) { + default: + VDBG(dev, "tx err %d\n", req->status); + /* FALLTHROUGH */ + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: /* disconnect etc */ + break; + case 0: + break; + } + + spin_lock(&dev->lock); + /* Take the request struct off the active list and put it on the + * free list. + */ + list_del_init(&req->list); + list_add(&req->list, &dev->tx_reqs); + wake_up_interruptible(&dev->tx_wait); + if (likely(list_empty(&dev->tx_reqs_active))) + wake_up_interruptible(&dev->tx_flush_wait); + + spin_unlock(&dev->lock); +} + +/*-------------------------------------------------------------------------*/ + +static int +printer_open(struct inode *inode, struct file *fd) +{ + struct printer_dev *dev; + unsigned long flags; + int ret = -EBUSY; + + dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev); + + spin_lock_irqsave(&dev->lock, flags); + + if (!dev->printer_cdev_open) { + dev->printer_cdev_open = 1; + fd->private_data = dev; + ret = 0; + /* Change the printer status to show that it's on-line. */ + dev->printer_status |= PRINTER_SELECTED; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + DBG(dev, "printer_open returned %x\n", ret); + + return ret; +} + +static int +printer_close(struct inode *inode, struct file *fd) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + dev->printer_cdev_open = 0; + fd->private_data = NULL; + /* Change printer status to show that the printer is off-line. */ + dev->printer_status &= ~PRINTER_SELECTED; + spin_unlock_irqrestore(&dev->lock, flags); + + DBG(dev, "printer_close\n"); + + return 0; +} + +static ssize_t +printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + size_t size; + size_t bytes_copied; + struct usb_request *req; + /* This is a pointer to the current USB rx request. */ + struct usb_request *current_rx_req; + /* This is the number of bytes in the current rx buffer. */ + size_t current_rx_bytes; + /* This is a pointer to the current rx buffer. */ + u8 *current_rx_buf; + + if (len == 0) + return -EINVAL; + + DBG(dev, "printer_read trying to read %d bytes\n", (int)len); + + spin_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + + /* We will use this flag later to check if a printer reset happened + * after we turn interrupts back on. + */ + dev->reset_printer = 0; + + while (likely(!list_empty(&dev->rx_reqs))) { + int error; + + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del_init(&req->list); + + /* The USB Host sends us whatever amount of data it wants to + * so we always set the length field to the full USB_BUFSIZE. + * If the amount of data is more than the read() caller asked + * for it will be stored in the request buffer until it is + * asked for by read(). + */ + req->length = USB_BUFSIZE; + req->complete = rx_complete; + + error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + if (error) { + DBG(dev, "rx submit --> %d\n", error); + list_add(&req->list, &dev->rx_reqs); + break; + } else { + list_add(&req->list, &dev->rx_reqs_active); + } + } + + bytes_copied = 0; + current_rx_req = dev->current_rx_req; + current_rx_bytes = dev->current_rx_bytes; + current_rx_buf = dev->current_rx_buf; + dev->current_rx_req = NULL; + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + + /* Check if there is any data in the read buffers. Please note that + * current_rx_bytes is the number of bytes in the current rx buffer. + * If it is zero then check if there are any other rx_buffers that + * are on the completed list. We are only out of data if all rx + * buffers are empty. + */ + if ((current_rx_bytes == 0) && + (likely(list_empty(&dev->rx_buffers)))) { + /* Turn interrupts back on before sleeping. */ + spin_unlock_irqrestore(&dev->lock, flags); + + /* + * If no data is available check if this is a NON-Blocking + * call or not. + */ + if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { + spin_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* Sleep until data is available */ + wait_event_interruptible(dev->rx_wait, + (likely(!list_empty(&dev->rx_buffers)))); + spin_lock_irqsave(&dev->lock, flags); + } + + /* We have data to return then copy it to the caller's buffer.*/ + while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers))) + && len) { + if (current_rx_bytes == 0) { + req = container_of(dev->rx_buffers.next, + struct usb_request, list); + list_del_init(&req->list); + + if (req->actual && req->buf) { + current_rx_req = req; + current_rx_bytes = req->actual; + current_rx_buf = req->buf; + } else { + list_add(&req->list, &dev->rx_reqs); + continue; + } + } + + /* Don't leave irqs off while doing memory copies */ + spin_unlock_irqrestore(&dev->lock, flags); + + if (len > current_rx_bytes) + size = current_rx_bytes; + else + size = len; + + size -= copy_to_user(buf, current_rx_buf, size); + bytes_copied += size; + len -= size; + buf += size; + + spin_lock_irqsave(&dev->lock, flags); + + /* We've disconnected or reset free the req and buffer */ + if (dev->reset_printer) { + printer_req_free(dev->out_ep, current_rx_req); + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* If we not returning all the data left in this RX request + * buffer then adjust the amount of data left in the buffer. + * Othewise if we are done with this RX request buffer then + * requeue it to get any incoming data from the USB host. + */ + if (size < current_rx_bytes) { + current_rx_bytes -= size; + current_rx_buf += size; + } else { + list_add(¤t_rx_req->list, &dev->rx_reqs); + current_rx_bytes = 0; + current_rx_buf = NULL; + current_rx_req = NULL; + } + } + + dev->current_rx_req = current_rx_req; + dev->current_rx_bytes = current_rx_bytes; + dev->current_rx_buf = current_rx_buf; + + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + + DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); + + if (bytes_copied) + return bytes_copied; + else + return -EAGAIN; +} + +static ssize_t +printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + size_t size; /* Amount of data in a TX request. */ + size_t bytes_copied = 0; + struct usb_request *req; + + DBG(dev, "printer_write trying to send %d bytes\n", (int)len); + + if (len == 0) + return -EINVAL; + + spin_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + + /* Check if a printer reset happens while we have interrupts on */ + dev->reset_printer = 0; + + /* Check if there is any available write buffers */ + if (likely(list_empty(&dev->tx_reqs))) { + /* Turn interrupts back on before sleeping. */ + spin_unlock_irqrestore(&dev->lock, flags); + + /* + * If write buffers are available check if this is + * a NON-Blocking call or not. + */ + if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { + spin_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + /* Sleep until a write buffer is available */ + wait_event_interruptible(dev->tx_wait, + (likely(!list_empty(&dev->tx_reqs)))); + spin_lock_irqsave(&dev->lock, flags); + } + + while (likely(!list_empty(&dev->tx_reqs)) && len) { + + if (len > USB_BUFSIZE) + size = USB_BUFSIZE; + else + size = len; + + req = container_of(dev->tx_reqs.next, struct usb_request, + list); + list_del_init(&req->list); + + req->complete = tx_complete; + req->length = size; + + /* Check if we need to send a zero length packet. */ + if (len > size) + /* They will be more TX requests so no yet. */ + req->zero = 0; + else + /* If the data amount is not a multple of the + * maxpacket size then send a zero length packet. + */ + req->zero = ((len % dev->in_ep->maxpacket) == 0); + + /* Don't leave irqs off while doing memory copies */ + spin_unlock_irqrestore(&dev->lock, flags); + + if (copy_from_user(req->buf, buf, size)) { + list_add(&req->list, &dev->tx_reqs); + spin_unlock(&dev->lock_printer_io); + return bytes_copied; + } + + bytes_copied += size; + len -= size; + buf += size; + + spin_lock_irqsave(&dev->lock, flags); + + /* We've disconnected or reset so free the req and buffer */ + if (dev->reset_printer) { + printer_req_free(dev->in_ep, req); + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + list_add(&req->list, &dev->tx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + return -EAGAIN; + } + + list_add(&req->list, &dev->tx_reqs_active); + + } + + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + + DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); + + if (bytes_copied) { + return bytes_copied; + } else { + return -EAGAIN; + } +} + +static int +printer_fsync(struct file *fd, struct dentry *dentry, int datasync) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + int tx_list_empty; + + spin_lock_irqsave(&dev->lock, flags); + tx_list_empty = (likely(list_empty(&dev->tx_reqs))); + spin_unlock_irqrestore(&dev->lock, flags); + + if (!tx_list_empty) { + /* Sleep until all data has been sent */ + wait_event_interruptible(dev->tx_flush_wait, + (likely(list_empty(&dev->tx_reqs_active)))); + } + + return 0; +} + +static unsigned int +printer_poll(struct file *fd, poll_table *wait) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + int status = 0; + + poll_wait(fd, &dev->rx_wait, wait); + poll_wait(fd, &dev->tx_wait, wait); + + spin_lock_irqsave(&dev->lock, flags); + if (likely(!list_empty(&dev->tx_reqs))) + status |= POLLOUT | POLLWRNORM; + + if (likely(!list_empty(&dev->rx_buffers))) + status |= POLLIN | POLLRDNORM; + + spin_unlock_irqrestore(&dev->lock, flags); + + return status; +} + +static int +printer_ioctl(struct inode *inode, struct file *fd, unsigned int code, + unsigned long arg) +{ + struct printer_dev *dev = fd->private_data; + unsigned long flags; + int status = 0; + + DBG(dev, "printer_ioctl: cmd=0x%4.4x, arg=%lu\n", code, arg); + + /* handle ioctls */ + + spin_lock_irqsave(&dev->lock, flags); + + switch (code) { + case GADGET_GET_PRINTER_STATUS: + status = (int)dev->printer_status; + break; + case GADGET_SET_PRINTER_STATUS: + dev->printer_status = (u8)arg; + break; + default: + /* could not handle ioctl */ + DBG(dev, "printer_ioctl: ERROR cmd=0x%4.4xis not supported\n", + code); + status = -ENOTTY; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + return status; +} + +/* used after endpoint configuration */ +static struct file_operations printer_io_operations = { + .owner = THIS_MODULE, + .open = printer_open, + .read = printer_read, + .write = printer_write, + .fsync = printer_fsync, + .poll = printer_poll, + .ioctl = printer_ioctl, + .release = printer_close +}; + +/*-------------------------------------------------------------------------*/ + +static int +set_printer_interface(struct printer_dev *dev) +{ + int result = 0; + + dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); + dev->in_ep->driver_data = dev; + + dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc); + dev->out_ep->driver_data = dev; + + result = usb_ep_enable(dev->in_ep, dev->in); + if (result != 0) { + DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); + goto done; + } + + result = usb_ep_enable(dev->out_ep, dev->out); + if (result != 0) { + DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); + goto done; + } + +done: + /* on error, disable any endpoints */ + if (result != 0) { + (void) usb_ep_disable(dev->in_ep); + (void) usb_ep_disable(dev->out_ep); + dev->in = NULL; + dev->out = NULL; + } + + /* caller is responsible for cleanup on error */ + return result; +} + +static void printer_reset_interface(struct printer_dev *dev) +{ + if (dev->interface < 0) + return; + + DBG(dev, "%s\n", __FUNCTION__); + + if (dev->in) + usb_ep_disable(dev->in_ep); + + if (dev->out) + usb_ep_disable(dev->out_ep); + + dev->interface = -1; +} + +/* change our operational config. must agree with the code + * that returns config descriptors, and altsetting code. + */ +static int +printer_set_config(struct printer_dev *dev, unsigned number) +{ + int result = 0; + struct usb_gadget *gadget = dev->gadget; + + if (gadget_is_sa1100(gadget) && dev->config) { + /* tx fifo is full, but we can't clear it...*/ + INFO(dev, "can't change configurations\n"); + return -ESPIPE; + } + + switch (number) { + case DEV_CONFIG_VALUE: + result = 0; + break; + default: + result = -EINVAL; + /* FALL THROUGH */ + case 0: + break; + } + + if (result) { + usb_gadget_vbus_draw(dev->gadget, + dev->gadget->is_otg ? 8 : 100); + } else { + char *speed; + unsigned power; + + power = 2 * config_desc.bMaxPower; + usb_gadget_vbus_draw(dev->gadget, power); + + switch (gadget->speed) { + case USB_SPEED_FULL: speed = "full"; break; +#ifdef CONFIG_USB_GADGET_DUALSPEED + case USB_SPEED_HIGH: speed = "high"; break; +#endif + default: speed = "?"; break; + } + + dev->config = number; + INFO(dev, "%s speed config #%d: %d mA, %s\n", + speed, number, power, driver_desc); + } + return result; +} + +static int +config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index, + int is_otg) +{ + int len; + const struct usb_descriptor_header **function; +#ifdef CONFIG_USB_GADGET_DUALSPEED + int hs = (speed == USB_SPEED_HIGH); + + if (type == USB_DT_OTHER_SPEED_CONFIG) + hs = !hs; + + if (hs) { + function = hs_printer_function; + } else { + function = fs_printer_function; + } +#else + function = fs_printer_function; +#endif + + if (index >= device_desc.bNumConfigurations) + return -EINVAL; + + /* for now, don't advertise srp-only devices */ + if (!is_otg) + function++; + + len = usb_gadget_config_buf(&config_desc, buf, USB_DESC_BUFSIZE, + function); + if (len < 0) + return len; + ((struct usb_config_descriptor *) buf)->bDescriptorType = type; + return len; +} + +/* Change our operational Interface. */ +static int +set_interface(struct printer_dev *dev, unsigned number) +{ + int result = 0; + + if (gadget_is_sa1100(dev->gadget) && dev->interface < 0) { + /* tx fifo is full, but we can't clear it...*/ + INFO(dev, "can't change interfaces\n"); + return -ESPIPE; + } + + /* Free the current interface */ + switch (dev->interface) { + case PRINTER_INTERFACE: + printer_reset_interface(dev); + break; + } + + switch (number) { + case PRINTER_INTERFACE: + result = set_printer_interface(dev); + if (result) { + printer_reset_interface(dev); + } else { + dev->interface = PRINTER_INTERFACE; + } + break; + default: + result = -EINVAL; + /* FALL THROUGH */ + } + + if (!result) + INFO(dev, "Using interface %x\n", number); + + return result; +} + +static void printer_setup_complete(struct usb_ep *ep, struct usb_request *req) +{ + if (req->status || req->actual != req->length) + DBG((struct printer_dev *) ep->driver_data, + "setup complete --> %d, %d/%d\n", + req->status, req->actual, req->length); +} + +static void printer_soft_reset(struct printer_dev *dev) +{ + struct usb_request *req; + + INFO(dev, "Received Printer Reset Request\n"); + + if (usb_ep_disable(dev->in_ep)) + DBG(dev, "Failed to disable USB in_ep\n"); + if (usb_ep_disable(dev->out_ep)) + DBG(dev, "Failed to disable USB out_ep\n"); + + if (dev->current_rx_req != NULL) { + list_add(&dev->current_rx_req->list, &dev->rx_reqs); + dev->current_rx_req = NULL; + } + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + dev->reset_printer = 1; + + while (likely(!(list_empty(&dev->rx_buffers)))) { + req = container_of(dev->rx_buffers.next, struct usb_request, + list); + list_del_init(&req->list); + list_add(&req->list, &dev->rx_reqs); + } + + while (likely(!(list_empty(&dev->rx_reqs_active)))) { + req = container_of(dev->rx_buffers.next, struct usb_request, + list); + list_del_init(&req->list); + list_add(&req->list, &dev->rx_reqs); + } + + while (likely(!(list_empty(&dev->tx_reqs_active)))) { + req = container_of(dev->tx_reqs_active.next, + struct usb_request, list); + list_del_init(&req->list); + list_add(&req->list, &dev->tx_reqs); + } + + if (usb_ep_enable(dev->in_ep, dev->in)) + DBG(dev, "Failed to enable USB in_ep\n"); + if (usb_ep_enable(dev->out_ep, dev->out)) + DBG(dev, "Failed to enable USB out_ep\n"); + + wake_up_interruptible(&dev->tx_wait); + wake_up_interruptible(&dev->tx_flush_wait); +} + +/*-------------------------------------------------------------------------*/ + +/* + * The setup() callback implements all the ep0 functionality that's not + * handled lower down. + */ +static int +printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct printer_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev->req; + int value = -EOPNOTSUPP; + u16 wIndex = le16_to_cpu(ctrl->wIndex); + u16 wValue = le16_to_cpu(ctrl->wValue); + u16 wLength = le16_to_cpu(ctrl->wLength); + + DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n", + ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); + + req->complete = printer_setup_complete; + + switch (ctrl->bRequestType&USB_TYPE_MASK) { + + case USB_TYPE_STANDARD: + switch (ctrl->bRequest) { + + case USB_REQ_GET_DESCRIPTOR: + if (ctrl->bRequestType != USB_DIR_IN) + break; + switch (wValue >> 8) { + + case USB_DT_DEVICE: + value = min(wLength, (u16) sizeof device_desc); + memcpy(req->buf, &device_desc, value); + break; +#ifdef CONFIG_USB_GADGET_DUALSPEED + case USB_DT_DEVICE_QUALIFIER: + if (!gadget->is_dualspeed) + break; + value = min(wLength, + (u16) sizeof dev_qualifier); + memcpy(req->buf, &dev_qualifier, value); + break; + + case USB_DT_OTHER_SPEED_CONFIG: + if (!gadget->is_dualspeed) + break; + /* FALLTHROUGH */ +#endif /* CONFIG_USB_GADGET_DUALSPEED */ + case USB_DT_CONFIG: + value = config_buf(gadget->speed, req->buf, + wValue >> 8, + wValue & 0xff, + gadget->is_otg); + if (value >= 0) + value = min(wLength, (u16) value); + break; + + case USB_DT_STRING: + value = usb_gadget_get_string(&stringtab, + wValue & 0xff, req->buf); + if (value >= 0) + value = min(wLength, (u16) value); + break; + } + break; + + case USB_REQ_SET_CONFIGURATION: + if (ctrl->bRequestType != 0) + break; + if (gadget->a_hnp_support) + DBG(dev, "HNP available\n"); + else if (gadget->a_alt_hnp_support) + DBG(dev, "HNP needs a different root port\n"); + value = printer_set_config(dev, wValue); + break; + case USB_REQ_GET_CONFIGURATION: + if (ctrl->bRequestType != USB_DIR_IN) + break; + *(u8 *)req->buf = dev->config; + value = min(wLength, (u16) 1); + break; + + case USB_REQ_SET_INTERFACE: + if (ctrl->bRequestType != USB_RECIP_INTERFACE || + !dev->config) + break; + + value = set_interface(dev, PRINTER_INTERFACE); + break; + case USB_REQ_GET_INTERFACE: + if (ctrl->bRequestType != + (USB_DIR_IN|USB_RECIP_INTERFACE) + || !dev->config) + break; + + *(u8 *)req->buf = dev->interface; + value = min(wLength, (u16) 1); + break; + + default: + goto unknown; + } + break; + + case USB_TYPE_CLASS: + switch (ctrl->bRequest) { + case 0: /* Get the IEEE-1284 PNP String */ + /* Only one printer interface is supported. */ + if ((wIndex>>8) != PRINTER_INTERFACE) + break; + + value = (pnp_string[0]<<8)|pnp_string[1]; + memcpy(req->buf, pnp_string, value); + DBG(dev, "1284 PNP String: %x %s\n", value, + &pnp_string[2]); + break; + + case 1: /* Get Port Status */ + /* Only one printer interface is supported. */ + if (wIndex != PRINTER_INTERFACE) + break; + + *(u8 *)req->buf = dev->printer_status; + value = min(wLength, (u16) 1); + break; + + case 2: /* Soft Reset */ + /* Only one printer interface is supported. */ + if (wIndex != PRINTER_INTERFACE) + break; + + printer_soft_reset(dev); + + value = 0; + break; + + default: + goto unknown; + } + break; + + default: +unknown: + VDBG(dev, + "unknown ctrl req%02x.%02x v%04x i%04x l%d\n", + ctrl->bRequestType, ctrl->bRequest, + wValue, wIndex, wLength); + break; + } + + /* respond with data transfer before status phase? */ + if (value >= 0) { + req->length = value; + req->zero = value < wLength + && (value % gadget->ep0->maxpacket) == 0; + value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + DBG(dev, "ep_queue --> %d\n", value); + req->status = 0; + printer_setup_complete(gadget->ep0, req); + } + } + + /* host either stalls (value < 0) or reports success */ + return value; +} + +static void +printer_disconnect(struct usb_gadget *gadget) +{ + struct printer_dev *dev = get_gadget_data(gadget); + unsigned long flags; + + DBG(dev, "%s\n", __FUNCTION__); + + spin_lock_irqsave(&dev->lock, flags); + + printer_reset_interface(dev); + + spin_unlock_irqrestore(&dev->lock, flags); +} + +static void +printer_unbind(struct usb_gadget *gadget) +{ + struct printer_dev *dev = get_gadget_data(gadget); + struct usb_request *req; + + + DBG(dev, "%s\n", __FUNCTION__); + + /* Remove sysfs files */ + device_destroy(usb_gadget_class, g_printer_devno); + + /* Remove Character Device */ + cdev_del(&dev->printer_cdev); + + /* we must already have been disconnected ... no i/o may be active */ + WARN_ON(!list_empty(&dev->tx_reqs_active)); + WARN_ON(!list_empty(&dev->rx_reqs_active)); + + /* Free all memory for this driver. */ + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, struct usb_request, + list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + + if (dev->current_rx_req != NULL); + printer_req_free(dev->out_ep, dev->current_rx_req); + + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + + while (!list_empty(&dev->rx_buffers)) { + req = container_of(dev->rx_buffers.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + + if (dev->req) { + printer_req_free(gadget->ep0, dev->req); + dev->req = NULL; + } + + set_gadget_data(gadget, NULL); +} + +static int __init +printer_bind(struct usb_gadget *gadget) +{ + struct printer_dev *dev; + struct usb_ep *in_ep, *out_ep; + int status = -ENOMEM; + int gcnum; + size_t len; + u32 i; + struct usb_request *req; + + dev = &usb_printer_gadget; + + + /* Setup the sysfs files for the printer gadget. */ + dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, + "g_printer"); + if (IS_ERR(dev->pdev)) { + ERROR(dev, "Failed to create device: g_printer\n"); + goto fail; + } + + /* + * Register a character device as an interface to a user mode + * program that handles the printer specific functionality. + */ + cdev_init(&dev->printer_cdev, &printer_io_operations); + dev->printer_cdev.owner = THIS_MODULE; + status = cdev_add(&dev->printer_cdev, g_printer_devno, 1); + if (status) { + ERROR(dev, "Failed to open char device\n"); + goto fail; + } + + if (gadget_is_sa1100(gadget)) { + /* hardware can't write zero length packets. */ + ERROR(dev, "SA1100 controller is unsupport by this driver\n"); + goto fail; + } + + gcnum = usb_gadget_controller_number(gadget); + if (gcnum >= 0) { + device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); + } else { + dev_warn(&gadget->dev, "controller '%s' not recognized\n", + gadget->name); + /* unrecognized, but safe unless bulk is REALLY quirky */ + device_desc.bcdDevice = + __constant_cpu_to_le16(0xFFFF); + } + snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", + init_utsname()->sysname, init_utsname()->release, + gadget->name); + + device_desc.idVendor = + __constant_cpu_to_le16(PRINTER_VENDOR_NUM); + device_desc.idProduct = + __constant_cpu_to_le16(PRINTER_PRODUCT_NUM); + + /* support optional vendor/distro customization */ + if (idVendor) { + if (!idProduct) { + dev_err(&gadget->dev, "idVendor needs idProduct!\n"); + return -ENODEV; + } + device_desc.idVendor = cpu_to_le16(idVendor); + device_desc.idProduct = cpu_to_le16(idProduct); + if (bcdDevice) + device_desc.bcdDevice = cpu_to_le16(bcdDevice); + } + + if (iManufacturer) + strlcpy(manufacturer, iManufacturer, sizeof manufacturer); + + if (iProduct) + strlcpy(product_desc, iProduct, sizeof product_desc); + + if (iSerialNum) + strlcpy(serial_num, iSerialNum, sizeof serial_num); + + if (iPNPstring) + strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); + + len = strlen(pnp_string); + pnp_string[0] = (len >> 8) & 0xFF; + pnp_string[1] = len & 0xFF; + + /* all we really need is bulk IN/OUT */ + usb_ep_autoconfig_reset(gadget); + in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc); + if (!in_ep) { +autoconf_fail: + dev_err(&gadget->dev, "can't autoconfigure on %s\n", + gadget->name); + return -ENODEV; + } + in_ep->driver_data = in_ep; /* claim */ + + out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc); + if (!out_ep) + goto autoconf_fail; + out_ep->driver_data = out_ep; /* claim */ + +#ifdef CONFIG_USB_GADGET_DUALSPEED + /* assumes ep0 uses the same value for both speeds ... */ + dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; + + /* and that all endpoints are dual-speed */ + hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; +#endif /* DUALSPEED */ + + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; + usb_gadget_set_selfpowered(gadget); + + if (gadget->is_otg) { + otg_desc.bmAttributes |= USB_OTG_HNP, + config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + config_desc.bMaxPower = 4; + } + + spin_lock_init(&dev->lock); + spin_lock_init(&dev->lock_printer_io); + INIT_LIST_HEAD(&dev->tx_reqs); + INIT_LIST_HEAD(&dev->tx_reqs_active); + INIT_LIST_HEAD(&dev->rx_reqs); + INIT_LIST_HEAD(&dev->rx_reqs_active); + INIT_LIST_HEAD(&dev->rx_buffers); + init_waitqueue_head(&dev->rx_wait); + init_waitqueue_head(&dev->tx_wait); + init_waitqueue_head(&dev->tx_flush_wait); + + dev->config = 0; + dev->interface = -1; + dev->printer_cdev_open = 0; + dev->printer_status = PRINTER_NOT_ERROR; + dev->current_rx_req = NULL; + dev->current_rx_bytes = 0; + dev->current_rx_buf = NULL; + + dev->in_ep = in_ep; + dev->out_ep = out_ep; + + /* preallocate control message data and buffer */ + dev->req = printer_req_alloc(gadget->ep0, USB_DESC_BUFSIZE, + GFP_KERNEL); + if (!dev->req) { + status = -ENOMEM; + goto fail; + } + + for (i = 0; i < QLEN; i++) { + req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) { + while (!list_empty(&dev->tx_reqs)) { + req = container_of(dev->tx_reqs.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->in_ep, req); + } + return -ENOMEM; + } + list_add(&req->list, &dev->tx_reqs); + } + + for (i = 0; i < QLEN; i++) { + req = printer_req_alloc(dev->out_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) { + while (!list_empty(&dev->rx_reqs)) { + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del(&req->list); + printer_req_free(dev->out_ep, req); + } + return -ENOMEM; + } + list_add(&req->list, &dev->rx_reqs); + } + + dev->req->complete = printer_setup_complete; + + /* finish hookup to lower layer ... */ + dev->gadget = gadget; + set_gadget_data(gadget, dev); + gadget->ep0->driver_data = dev; + + INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); + INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name, + in_ep->name); + + return 0; + +fail: + printer_unbind(gadget); + return status; +} + +/*-------------------------------------------------------------------------*/ + +static struct usb_gadget_driver printer_driver = { + .speed = DEVSPEED, + + .function = (char *) driver_desc, + .bind = printer_bind, + .unbind = printer_unbind, + + .setup = printer_setup, + .disconnect = printer_disconnect, + + .driver = { + .name = (char *) shortname, + .owner = THIS_MODULE, + }, +}; + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Craig Nadler"); +MODULE_LICENSE("GPL"); + +static int __init +init(void) +{ + int status; + + usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget"); + if (IS_ERR(usb_gadget_class)) { + status = PTR_ERR(usb_gadget_class); + ERROR(dev, "unable to create usb_gadget class %d\n", status); + return status; + } + + status = alloc_chrdev_region(&g_printer_devno, 0, 1, + "USB printer gadget"); + if (status) { + ERROR(dev, "alloc_chrdev_region %d\n", status); + class_destroy(usb_gadget_class); + return status; + } + + status = usb_gadget_register_driver(&printer_driver); + if (status) { + class_destroy(usb_gadget_class); + unregister_chrdev_region(g_printer_devno, 1); + DBG(dev, "usb_gadget_register_driver %x\n", status); + } + + return status; +} +module_init(init); + +static void __exit +cleanup(void) +{ + int status; + + spin_lock(&usb_printer_gadget.lock_printer_io); + class_destroy(usb_gadget_class); + unregister_chrdev_region(g_printer_devno, 2); + + status = usb_gadget_unregister_driver(&printer_driver); + if (status) + ERROR(dev, "usb_gadget_unregister_driver %x\n", status); + + spin_unlock(&usb_printer_gadget.lock_printer_io); +} +module_exit(cleanup); diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 3173b39f0bf..4402d6f042d 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -24,7 +24,7 @@ * */ -// #define VERBOSE DBG_VERBOSE +/* #define VERBOSE_DEBUG */ #include <linux/device.h> #include <linux/module.h> @@ -38,13 +38,14 @@ #include <linux/timer.h> #include <linux/list.h> #include <linux/interrupt.h> -#include <linux/proc_fs.h> #include <linux/mm.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/irq.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/seq_file.h> +#include <linux/debugfs.h> #include <asm/byteorder.h> #include <asm/dma.h> @@ -127,8 +128,10 @@ static int is_vbus_present(void) { struct pxa2xx_udc_mach_info *mach = the_controller->mach; - if (mach->gpio_vbus) - return gpio_get_value(mach->gpio_vbus); + if (mach->gpio_vbus) { + int value = gpio_get_value(mach->gpio_vbus); + return mach->gpio_vbus_inverted ? !value : value; + } if (mach->udc_is_connected) return mach->udc_is_connected(); return 1; @@ -677,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* kickstart this i/o queue? */ if (list_empty(&ep->queue) && !ep->stopped) { - if (ep->desc == 0 /* ep0 */) { + if (ep->desc == NULL/* ep0 */) { unsigned length = _req->length; switch (dev->ep0state) { @@ -731,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) } /* pio or dma irq handler advances the queue. */ - if (likely (req != 0)) + if (likely(req != NULL)) list_add_tail(&req->queue, &ep->queue); local_irq_restore(flags); @@ -991,45 +994,32 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - -static const char proc_node_name [] = "driver/udc"; +#ifdef CONFIG_USB_GADGET_DEBUG_FS static int -udc_proc_read(char *page, char **start, off_t off, int count, - int *eof, void *_dev) +udc_seq_show(struct seq_file *m, void *d) { - char *buf = page; - struct pxa2xx_udc *dev = _dev; - char *next = buf; - unsigned size = count; + struct pxa2xx_udc *dev = m->private; unsigned long flags; - int i, t; + int i; u32 tmp; - if (off != 0) - return 0; - local_irq_save(flags); /* basic device status */ - t = scnprintf(next, size, DRIVER_DESC "\n" + seq_printf(m, DRIVER_DESC "\n" "%s version: %s\nGadget driver: %s\nHost %s\n\n", driver_name, DRIVER_VERSION SIZE_STR "(pio)", dev->driver ? dev->driver->driver.name : "(none)", is_vbus_present() ? "full speed" : "disconnected"); - size -= t; - next += t; /* registers for device and ep0 */ - t = scnprintf(next, size, + seq_printf(m, "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); - size -= t; - next += t; tmp = UDCCR; - t = scnprintf(next, size, + seq_printf(m, "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, (tmp & UDCCR_REM) ? " rem" : "", (tmp & UDCCR_RSTIR) ? " rstir" : "", @@ -1039,11 +1029,9 @@ udc_proc_read(char *page, char **start, off_t off, int count, (tmp & UDCCR_RSM) ? " rsm" : "", (tmp & UDCCR_UDA) ? " uda" : "", (tmp & UDCCR_UDE) ? " ude" : ""); - size -= t; - next += t; tmp = UDCCS0; - t = scnprintf(next, size, + seq_printf(m, "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, (tmp & UDCCS0_SA) ? " sa" : "", (tmp & UDCCS0_RNE) ? " rne" : "", @@ -1053,28 +1041,22 @@ udc_proc_read(char *page, char **start, off_t off, int count, (tmp & UDCCS0_FTF) ? " ftf" : "", (tmp & UDCCS0_IPR) ? " ipr" : "", (tmp & UDCCS0_OPR) ? " opr" : ""); - size -= t; - next += t; if (dev->has_cfr) { tmp = UDCCFR; - t = scnprintf(next, size, + seq_printf(m, "udccfr %02X =%s%s\n", tmp, (tmp & UDCCFR_AREN) ? " aren" : "", (tmp & UDCCFR_ACM) ? " acm" : ""); - size -= t; - next += t; } if (!is_vbus_present() || !dev->driver) goto done; - t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", + seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", dev->stats.write.bytes, dev->stats.write.ops, dev->stats.read.bytes, dev->stats.read.ops, dev->stats.irqs); - size -= t; - next += t; /* dump endpoint queues */ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { @@ -1082,61 +1064,68 @@ udc_proc_read(char *page, char **start, off_t off, int count, struct pxa2xx_request *req; if (i != 0) { - const struct usb_endpoint_descriptor *d; + const struct usb_endpoint_descriptor *desc; - d = ep->desc; - if (!d) + desc = ep->desc; + if (!desc) continue; tmp = *dev->ep [i].reg_udccs; - t = scnprintf(next, size, + seq_printf(m, "%s max %d %s udccs %02x irqs %lu\n", - ep->ep.name, le16_to_cpu (d->wMaxPacketSize), + ep->ep.name, le16_to_cpu(desc->wMaxPacketSize), "pio", tmp, ep->pio_irqs); /* TODO translate all five groups of udccs bits! */ } else /* ep0 should only have one transfer queued */ - t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n", + seq_printf(m, "ep0 max 16 pio irqs %lu\n", ep->pio_irqs); - if (t <= 0 || t > size) - goto done; - size -= t; - next += t; if (list_empty(&ep->queue)) { - t = scnprintf(next, size, "\t(nothing queued)\n"); - if (t <= 0 || t > size) - goto done; - size -= t; - next += t; + seq_printf(m, "\t(nothing queued)\n"); continue; } list_for_each_entry(req, &ep->queue, queue) { - t = scnprintf(next, size, + seq_printf(m, "\treq %p len %d/%d buf %p\n", &req->req, req->req.actual, req->req.length, req->req.buf); - if (t <= 0 || t > size) - goto done; - size -= t; - next += t; } } done: local_irq_restore(flags); - *eof = 1; - return count - size; + return 0; } -#define create_proc_files() \ - create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) -#define remove_proc_files() \ - remove_proc_entry(proc_node_name, NULL) +static int +udc_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, udc_seq_show, inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = udc_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +#define create_debug_files(dev) \ + do { \ + dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ + S_IRUGO, NULL, dev, &debug_fops); \ + } while (0) +#define remove_debug_files(dev) \ + do { \ + if (dev->debugfs_udc) \ + debugfs_remove(dev->debugfs_udc); \ + } while (0) #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ -#define create_proc_files() do {} while (0) -#define remove_proc_files() do {} while (0) +#define create_debug_files(dev) do {} while (0) +#define remove_debug_files(dev) do {} while (0) #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ @@ -1345,6 +1334,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) local_irq_enable(); driver->unbind(&dev->gadget); + dev->gadget.dev.driver = NULL; dev->driver = NULL; device_del (&dev->gadget.dev); @@ -1397,6 +1387,9 @@ static irqreturn_t udc_vbus_irq(int irq, void *_dev) struct pxa2xx_udc *dev = _dev; int vbus = gpio_get_value(dev->mach->gpio_vbus); + if (dev->mach->gpio_vbus_inverted) + vbus = !vbus; + pxa2xx_udc_vbus_session(&dev->gadget, vbus); return IRQ_HANDLED; } @@ -2099,7 +2092,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) /* insist on Intel/ARM/XScale */ asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { - printk(KERN_ERR "%s: not XScale!\n", driver_name); + pr_err("%s: not XScale!\n", driver_name); return -ENODEV; } @@ -2128,7 +2121,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) break; #endif default: - printk(KERN_ERR "%s: unrecognized processor: %08x\n", + pr_err("%s: unrecognized processor: %08x\n", driver_name, chiprev); /* iop3xx, ixp4xx, ... */ return -ENODEV; @@ -2199,7 +2192,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) retval = request_irq(irq, pxa2xx_udc_irq, IRQF_DISABLED, driver_name, dev); if (retval != 0) { - printk(KERN_ERR "%s: can't get irq %d, err %d\n", + pr_err("%s: can't get irq %d, err %d\n", driver_name, irq, retval); goto err_irq1; } @@ -2212,7 +2205,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) IRQF_DISABLED | IRQF_SAMPLE_RANDOM, driver_name, dev); if (retval != 0) { - printk(KERN_ERR "%s: can't get irq %i, err %d\n", + pr_err("%s: can't get irq %i, err %d\n", driver_name, LUBBOCK_USB_DISC_IRQ, retval); lubbock_fail0: goto err_irq_lub; @@ -2222,7 +2215,7 @@ lubbock_fail0: IRQF_DISABLED | IRQF_SAMPLE_RANDOM, driver_name, dev); if (retval != 0) { - printk(KERN_ERR "%s: can't get irq %i, err %d\n", + pr_err("%s: can't get irq %i, err %d\n", driver_name, LUBBOCK_USB_IRQ, retval); free_irq(LUBBOCK_USB_DISC_IRQ, dev); goto lubbock_fail0; @@ -2235,12 +2228,12 @@ lubbock_fail0: IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, driver_name, dev); if (retval != 0) { - printk(KERN_ERR "%s: can't get irq %i, err %d\n", + pr_err("%s: can't get irq %i, err %d\n", driver_name, vbus_irq, retval); goto err_vbus_irq; } } - create_proc_files(); + create_debug_files(dev); return 0; @@ -2277,7 +2270,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) return -EBUSY; udc_disable(dev); - remove_proc_files(); + remove_debug_files(dev); if (dev->got_irq) { free_irq(platform_get_irq(pdev, 0), dev); @@ -2361,7 +2354,7 @@ static struct platform_driver udc_driver = { static int __init udc_init(void) { - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); + pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); return platform_driver_probe(&udc_driver, pxa2xx_udc_probe); } module_init(udc_init); diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index 1db46d70577..b67e3ff5e4e 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h @@ -129,6 +129,10 @@ struct pxa2xx_udc { struct pxa2xx_udc_mach_info *mach; u64 dma_mask; struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; + +#ifdef CONFIG_USB_GADGET_DEBUG_FS + struct dentry *debugfs_udc; +#endif }; /*-------------------------------------------------------------------------*/ @@ -151,17 +155,19 @@ static struct pxa2xx_udc *the_controller; #define DBG_NOISY 3 /* ... even more: request level */ #define DBG_VERY_NOISY 4 /* ... even more: packet level */ +#define DMSG(stuff...) pr_debug("udc: " stuff) + #ifdef DEBUG +static int is_vbus_present(void); + static const char *state_name[] = { "EP0_IDLE", "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", "EP0_END_XFER", "EP0_STALL" }; -#define DMSG(stuff...) printk(KERN_DEBUG "udc: " stuff) - -#ifdef VERBOSE +#ifdef VERBOSE_DEBUG # define UDC_DEBUG DBG_VERBOSE #else # define UDC_DEBUG DBG_NORMAL @@ -207,7 +213,7 @@ dump_state(struct pxa2xx_udc *dev) unsigned i; DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", - is_usb_connected() ? "host " : "disconnected", + is_vbus_present() ? "host " : "disconnected", state_name[dev->ep0state], UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); dump_udccr("udccr"); @@ -224,7 +230,7 @@ dump_state(struct pxa2xx_udc *dev) } else DMSG("ep0 driver '%s'\n", dev->driver->driver.name); - if (!is_usb_connected()) + if (!is_vbus_present()) return; dump_udccs0 ("udccs0"); @@ -233,7 +239,7 @@ dump_state(struct pxa2xx_udc *dev) dev->stats.read.bytes, dev->stats.read.ops); for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { - if (dev->ep [i].desc == 0) + if (dev->ep [i].desc == NULL) continue; DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); } @@ -241,8 +247,6 @@ dump_state(struct pxa2xx_udc *dev) #else -#define DMSG(stuff...) do{}while(0) - #define dump_udccr(x) do{}while(0) #define dump_udccs0(x) do{}while(0) #define dump_state(x) do{}while(0) @@ -253,8 +257,9 @@ dump_state(struct pxa2xx_udc *dev) #define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) -#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) +#define ERR(stuff...) pr_err("udc: " stuff) +#define WARN(stuff...) pr_warning("udc: " stuff) +#define INFO(stuff...) pr_info("udc: " stuff) #endif /* __LINUX_USB_GADGET_PXA2XX_H */ diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index db1b2bfcee4..3d036647431 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -53,21 +53,18 @@ */ #if 0 -#define DBG(str,args...) do { \ - if (rndis_debug) \ - printk(KERN_DEBUG str , ## args ); \ - } while (0) static int rndis_debug = 0; - module_param (rndis_debug, int, 0); MODULE_PARM_DESC (rndis_debug, "enable debugging"); - #else - #define rndis_debug 0 -#define DBG(str,args...) do{}while(0) #endif +#define DBG(str,args...) do { \ + if (rndis_debug) \ + pr_debug(str , ## args); \ + } while (0) + #define RNDIS_MAX_CONFIGS 1 @@ -679,7 +676,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, #endif default: - printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", + pr_warning("%s: query unknown OID 0x%08X\n", __FUNCTION__, OID); } if (retval < 0) @@ -804,7 +801,7 @@ update_linkstate: #endif /* RNDIS_PM */ default: - printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", + pr_warning("%s: set unknown OID 0x%08X, size %d\n", __FUNCTION__, OID, buf_len); } @@ -1126,8 +1123,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) * In one case those messages seemed to relate to the host * suspending itself. */ - printk (KERN_WARNING - "%s: unknown RNDIS message 0x%08X len %d\n", + pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", __FUNCTION__ , MsgType, MsgLength); { unsigned i; diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index e3e90f8a75e..aadc4204d6f 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -52,10 +52,10 @@ #include <asm/arch/irqs.h> #include <asm/arch/hardware.h> -#include <asm/arch/regs-clock.h> #include <asm/arch/regs-gpio.h> -#include <asm/arch/regs-udc.h> -#include <asm/arch/udc.h> + +#include <asm/plat-s3c24xx/regs-udc.h> +#include <asm/plat-s3c24xx/udc.h> #include <asm/mach-types.h> @@ -893,7 +893,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) /* * s3c2410_udc_irq - interrupt handler */ -static irqreturn_t s3c2410_udc_irq(int irq, void *_dev) +static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev) { struct s3c2410_udc *dev = _dev; int usb_status; @@ -1016,7 +1016,7 @@ static irqreturn_t s3c2410_udc_irq(int irq, void *_dev) } } - dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", irq); + dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", IRQ_USBD); /* Restore old index */ udc_write(idx, S3C2410_UDC_INDEX_REG); @@ -1511,7 +1511,11 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) unsigned int value; dprintk(DEBUG_NORMAL, "%s()\n", __func__); + + /* some cpus cannot read from an line configured to IRQ! */ + s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_INPUT); value = s3c2410_gpio_getpin(udc_info->vbus_pin); + s3c2410_gpio_cfgpin(udc_info->vbus_pin, S3C2410_GPIO_SFN2); if (udc_info->vbus_pin_inverted) value = !value; @@ -1872,9 +1876,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev) if (udc_info && udc_info->vbus_pin > 0) { irq = s3c2410_gpio_getirq(udc_info->vbus_pin); retval = request_irq(irq, s3c2410_udc_vbus_irq, - IRQF_DISABLED | IRQF_TRIGGER_RISING - | IRQF_TRIGGER_FALLING, - gadget_name, udc); + IRQF_DISABLED | IRQF_TRIGGER_RISING + | IRQF_TRIGGER_FALLING | IRQF_SHARED, + gadget_name, udc); if (retval != 0) { dev_err(dev, "can't get vbus irq %i, err %d\n", diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f5738eb8e76..f5c3896b1d9 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -89,9 +89,9 @@ static int debug = 1; #endif #define gs_debug(format, arg...) \ - do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) + do { if (debug) pr_debug(format, ## arg); } while (0) #define gs_debug_level(level, format, arg...) \ - do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) + do { if (debug >= level) pr_debug(format, ## arg); } while (0) /* Thanks to NetChip Technologies for donating this product ID. @@ -553,7 +553,8 @@ static int __init gs_module_init(void) retval = usb_gadget_register_driver(&gs_gadget_driver); if (retval) { - printk(KERN_ERR "gs_module_init: cannot register gadget driver, ret=%d\n", retval); + pr_err("gs_module_init: cannot register gadget driver, " + "ret=%d\n", retval); return retval; } @@ -579,11 +580,13 @@ static int __init gs_module_init(void) if (retval) { usb_gadget_unregister_driver(&gs_gadget_driver); put_tty_driver(gs_tty_driver); - printk(KERN_ERR "gs_module_init: cannot register tty driver, ret=%d\n", retval); + pr_err("gs_module_init: cannot register tty driver, " + "ret=%d\n", retval); return retval; } - printk(KERN_INFO "gs_module_init: %s %s loaded\n", GS_LONG_NAME, GS_VERSION_STR); + pr_info("gs_module_init: %s %s loaded\n", + GS_LONG_NAME, GS_VERSION_STR); return 0; } @@ -598,7 +601,8 @@ static void __exit gs_module_exit(void) put_tty_driver(gs_tty_driver); usb_gadget_unregister_driver(&gs_gadget_driver); - printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME, GS_VERSION_STR); + pr_info("gs_module_exit: %s %s unloaded\n", + GS_LONG_NAME, GS_VERSION_STR); } /* TTY Driver */ @@ -621,7 +625,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file); if (port_num < 0 || port_num >= GS_NUM_PORTS) { - printk(KERN_ERR "gs_open: (%d,%p,%p) invalid port number\n", + pr_err("gs_open: (%d,%p,%p) invalid port number\n", port_num, tty, file); return -ENODEV; } @@ -629,15 +633,14 @@ static int gs_open(struct tty_struct *tty, struct file *file) dev = gs_device; if (dev == NULL) { - printk(KERN_ERR "gs_open: (%d,%p,%p) NULL device pointer\n", + pr_err("gs_open: (%d,%p,%p) NULL device pointer\n", port_num, tty, file); return -ENODEV; } mtx = &gs_open_close_lock[port_num]; if (mutex_lock_interruptible(mtx)) { - printk(KERN_ERR - "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", + pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n", port_num, tty, file); return -ERESTARTSYS; } @@ -645,8 +648,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) spin_lock_irqsave(&dev->dev_lock, flags); if (dev->dev_config == GS_NO_CONFIG_ID) { - printk(KERN_ERR - "gs_open: (%d,%p,%p) device is not connected\n", + pr_err("gs_open: (%d,%p,%p) device is not connected\n", port_num, tty, file); ret = -ENODEV; goto exit_unlock_dev; @@ -655,7 +657,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) port = dev->dev_port[port_num]; if (port == NULL) { - printk(KERN_ERR "gs_open: (%d,%p,%p) NULL port pointer\n", + pr_err("gs_open: (%d,%p,%p) NULL port pointer\n", port_num, tty, file); ret = -ENODEV; goto exit_unlock_dev; @@ -665,7 +667,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) spin_unlock(&dev->dev_lock); if (port->port_dev == NULL) { - printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (1)\n", + pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n", port_num, tty, file); ret = -EIO; goto exit_unlock_port; @@ -692,8 +694,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) /* might have been disconnected while asleep, check */ if (port->port_dev == NULL) { - printk(KERN_ERR - "gs_open: (%d,%p,%p) port disconnected (2)\n", + pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n", port_num, tty, file); port->port_in_use = 0; ret = -EIO; @@ -701,7 +702,8 @@ static int gs_open(struct tty_struct *tty, struct file *file) } if ((port->port_write_buf=buf) == NULL) { - printk(KERN_ERR "gs_open: (%d,%p,%p) cannot allocate port write buffer\n", + pr_err("gs_open: (%d,%p,%p) cannot allocate " + "port write buffer\n", port_num, tty, file); port->port_in_use = 0; ret = -ENOMEM; @@ -714,7 +716,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) /* might have been disconnected while asleep, check */ if (port->port_dev == NULL) { - printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (3)\n", + pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n", port_num, tty, file); port->port_in_use = 0; ret = -EIO; @@ -762,7 +764,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) struct mutex *mtx; if (port == NULL) { - printk(KERN_ERR "gs_close: NULL port pointer\n"); + pr_err("gs_close: NULL port pointer\n"); return; } @@ -774,8 +776,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) spin_lock_irq(&port->port_lock); if (port->port_open_count == 0) { - printk(KERN_ERR - "gs_close: (%d,%p,%p) port is already closed\n", + pr_err("gs_close: (%d,%p,%p) port is already closed\n", port->port_num, tty, file); goto exit; } @@ -837,7 +838,7 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) int ret; if (port == NULL) { - printk(KERN_ERR "gs_write: NULL port pointer\n"); + pr_err("gs_write: NULL port pointer\n"); return -EIO; } @@ -850,14 +851,14 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) spin_lock_irqsave(&port->port_lock, flags); if (port->port_dev == NULL) { - printk(KERN_ERR "gs_write: (%d,%p) port is not connected\n", + pr_err("gs_write: (%d,%p) port is not connected\n", port->port_num, tty); ret = -EIO; goto exit; } if (port->port_open_count == 0) { - printk(KERN_ERR "gs_write: (%d,%p) port is closed\n", + pr_err("gs_write: (%d,%p) port is closed\n", port->port_num, tty); ret = -EBADF; goto exit; @@ -888,7 +889,7 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) struct gs_port *port = tty->driver_data; if (port == NULL) { - printk(KERN_ERR "gs_put_char: NULL port pointer\n"); + pr_err("gs_put_char: NULL port pointer\n"); return; } @@ -898,13 +899,13 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) spin_lock_irqsave(&port->port_lock, flags); if (port->port_dev == NULL) { - printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n", + pr_err("gs_put_char: (%d,%p) port is not connected\n", port->port_num, tty); goto exit; } if (port->port_open_count == 0) { - printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n", + pr_err("gs_put_char: (%d,%p) port is closed\n", port->port_num, tty); goto exit; } @@ -924,7 +925,7 @@ static void gs_flush_chars(struct tty_struct *tty) struct gs_port *port = tty->driver_data; if (port == NULL) { - printk(KERN_ERR "gs_flush_chars: NULL port pointer\n"); + pr_err("gs_flush_chars: NULL port pointer\n"); return; } @@ -933,14 +934,13 @@ static void gs_flush_chars(struct tty_struct *tty) spin_lock_irqsave(&port->port_lock, flags); if (port->port_dev == NULL) { - printk(KERN_ERR - "gs_flush_chars: (%d,%p) port is not connected\n", + pr_err("gs_flush_chars: (%d,%p) port is not connected\n", port->port_num, tty); goto exit; } if (port->port_open_count == 0) { - printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n", + pr_err("gs_flush_chars: (%d,%p) port is closed\n", port->port_num, tty); goto exit; } @@ -1038,7 +1038,7 @@ static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, struct gs_port *port = tty->driver_data; if (port == NULL) { - printk(KERN_ERR "gs_ioctl: NULL port pointer\n"); + pr_err("gs_ioctl: NULL port pointer\n"); return -EIO; } @@ -1076,7 +1076,7 @@ static int gs_send(struct gs_dev *dev) struct gs_req_entry *req_entry; if (dev == NULL) { - printk(KERN_ERR "gs_send: NULL device pointer\n"); + pr_err("gs_send: NULL device pointer\n"); return -ENODEV; } @@ -1103,7 +1103,7 @@ static int gs_send(struct gs_dev *dev) req->length = len; spin_unlock_irqrestore(&dev->dev_lock, flags); if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { - printk(KERN_ERR + pr_err( "gs_send: cannot queue read request, ret=%d\n", ret); spin_lock_irqsave(&dev->dev_lock, flags); @@ -1144,9 +1144,7 @@ static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size) port = dev->dev_port[0]; if (port == NULL) { - printk(KERN_ERR - "gs_send_packet: port=%d, NULL port pointer\n", - 0); + pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0); return -EIO; } @@ -1193,7 +1191,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) port = dev->dev_port[0]; if (port == NULL) { - printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n", + pr_err("gs_recv_packet: port=%d, NULL port pointer\n", port->port_num); return -EIO; } @@ -1201,7 +1199,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) spin_lock(&port->port_lock); if (port->port_open_count == 0) { - printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n", + pr_err("gs_recv_packet: port=%d, port is closed\n", port->port_num); ret = -EIO; goto exit; @@ -1211,14 +1209,14 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) tty = port->port_tty; if (tty == NULL) { - printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", + pr_err("gs_recv_packet: port=%d, NULL tty pointer\n", port->port_num); ret = -EIO; goto exit; } if (port->port_tty->magic != TTY_MAGIC) { - printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n", + pr_err("gs_recv_packet: port=%d, bad tty magic\n", port->port_num); ret = -EIO; goto exit; @@ -1245,7 +1243,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) struct gs_dev *dev = ep->driver_data; if (dev == NULL) { - printk(KERN_ERR "gs_read_complete: NULL device pointer\n"); + pr_err("gs_read_complete: NULL device pointer\n"); return; } @@ -1256,7 +1254,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) requeue: req->length = ep->maxpacket; if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { - printk(KERN_ERR + pr_err( "gs_read_complete: cannot queue read request, ret=%d\n", ret); } @@ -1270,7 +1268,7 @@ requeue: default: /* unexpected */ - printk(KERN_ERR + pr_err( "gs_read_complete: unexpected status error, status=%d\n", req->status); goto requeue; @@ -1287,7 +1285,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) struct gs_req_entry *gs_req = req->context; if (dev == NULL) { - printk(KERN_ERR "gs_write_complete: NULL device pointer\n"); + pr_err("gs_write_complete: NULL device pointer\n"); return; } @@ -1296,8 +1294,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) /* normal completion */ requeue: if (gs_req == NULL) { - printk(KERN_ERR - "gs_write_complete: NULL request pointer\n"); + pr_err("gs_write_complete: NULL request pointer\n"); return; } @@ -1316,7 +1313,7 @@ requeue: break; default: - printk(KERN_ERR + pr_err( "gs_write_complete: unexpected status error, status=%d\n", req->status); goto requeue; @@ -1351,7 +1348,7 @@ static int __init gs_bind(struct usb_gadget *gadget) gs_device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum); else { - printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n", + pr_warning("gs_bind: controller '%s' not recognized\n", gadget->name); /* unrecognized, but safe unless bulk is REALLY quirky */ gs_device_desc.bcdDevice = @@ -1375,7 +1372,7 @@ static int __init gs_bind(struct usb_gadget *gadget) if (use_acm) { ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); if (!ep) { - printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name); + pr_err("gs_bind: cannot run ACM on %s\n", gadget->name); goto autoconf_fail; } gs_device_desc.idProduct = __constant_cpu_to_le16( @@ -1425,7 +1422,7 @@ static int __init gs_bind(struct usb_gadget *gadget) set_gadget_data(gadget, dev); if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) { - printk(KERN_ERR "gs_bind: cannot allocate ports\n"); + pr_err("gs_bind: cannot allocate ports\n"); gs_unbind(gadget); return ret; } @@ -1441,13 +1438,13 @@ static int __init gs_bind(struct usb_gadget *gadget) gadget->ep0->driver_data = dev; - printk(KERN_INFO "gs_bind: %s %s bound\n", + pr_info("gs_bind: %s %s bound\n", GS_LONG_NAME, GS_VERSION_STR); return 0; autoconf_fail: - printk(KERN_ERR "gs_bind: cannot autoconfigure on %s\n", gadget->name); + pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); return -ENODEV; } @@ -1480,7 +1477,7 @@ static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) set_gadget_data(gadget, NULL); } - printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME, + pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, GS_VERSION_STR); } @@ -1513,7 +1510,8 @@ static int gs_setup(struct usb_gadget *gadget, break; default: - printk(KERN_ERR "gs_setup: unknown request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", + pr_err("gs_setup: unknown request, type=%02x, request=%02x, " + "value=%04x, index=%04x, length=%d\n", ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); break; @@ -1526,7 +1524,7 @@ static int gs_setup(struct usb_gadget *gadget, && (ret % gadget->ep0->maxpacket) == 0; ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (ret < 0) { - printk(KERN_ERR "gs_setup: cannot queue response, ret=%d\n", + pr_err("gs_setup: cannot queue response, ret=%d\n", ret); req->status = 0; gs_setup_complete(gadget->ep0, req); @@ -1656,7 +1654,8 @@ set_interface_done: break; default: - printk(KERN_ERR "gs_setup: unknown standard request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", + pr_err("gs_setup: unknown standard request, type=%02x, " + "request=%02x, value=%04x, index=%04x, length=%d\n", ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); break; @@ -1682,7 +1681,7 @@ static int gs_setup_class(struct usb_gadget *gadget, * handler copy that data to port->port_line_coding (iff * it's valid) and maybe pass it on. Until then, fail. */ - printk(KERN_WARNING "gs_setup: set_line_coding " + pr_warning("gs_setup: set_line_coding " "unuspported\n"); break; @@ -1702,12 +1701,12 @@ static int gs_setup_class(struct usb_gadget *gadget, * handler use that to set the state (iff it's valid) and * maybe pass it on. Until then, fail. */ - printk(KERN_WARNING "gs_setup: set_control_line_state " + pr_warning("gs_setup: set_control_line_state " "unuspported\n"); break; default: - printk(KERN_ERR "gs_setup: unknown class request, " + pr_err("gs_setup: unknown class request, " "type=%02x, request=%02x, value=%04x, " "index=%04x, length=%d\n", ctrl->bRequestType, ctrl->bRequest, @@ -1724,7 +1723,8 @@ static int gs_setup_class(struct usb_gadget *gadget, static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) { if (req->status || req->actual != req->length) { - printk(KERN_ERR "gs_setup_complete: status error, status=%d, actual=%d, length=%d\n", + pr_err("gs_setup_complete: status error, status=%d, " + "actual=%d, length=%d\n", req->status, req->actual, req->length); } } @@ -1751,11 +1751,11 @@ static void gs_disconnect(struct usb_gadget *gadget) /* re-allocate ports for the next connection */ if (gs_alloc_ports(dev, GFP_ATOMIC) != 0) - printk(KERN_ERR "gs_disconnect: cannot re-allocate ports\n"); + pr_err("gs_disconnect: cannot re-allocate ports\n"); spin_unlock_irqrestore(&dev->dev_lock, flags); - printk(KERN_INFO "gs_disconnect: %s disconnected\n", GS_LONG_NAME); + pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); } /* @@ -1778,7 +1778,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) struct gs_req_entry *req_entry; if (dev == NULL) { - printk(KERN_ERR "gs_set_config: NULL device pointer\n"); + pr_err("gs_set_config: NULL device pointer\n"); return 0; } @@ -1823,7 +1823,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) dev->dev_notify_ep = ep; dev->dev_notify_ep_desc = ep_desc; } else { - printk(KERN_ERR "gs_set_config: cannot enable notify endpoint %s, ret=%d\n", + pr_err("gs_set_config: cannot enable NOTIFY " + "endpoint %s, ret=%d\n", ep->name, ret); goto exit_reset_config; } @@ -1839,7 +1840,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) dev->dev_in_ep = ep; dev->dev_in_ep_desc = ep_desc; } else { - printk(KERN_ERR "gs_set_config: cannot enable in endpoint %s, ret=%d\n", + pr_err("gs_set_config: cannot enable IN " + "endpoint %s, ret=%d\n", ep->name, ret); goto exit_reset_config; } @@ -1855,7 +1857,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) dev->dev_out_ep = ep; dev->dev_out_ep_desc = ep_desc; } else { - printk(KERN_ERR "gs_set_config: cannot enable out endpoint %s, ret=%d\n", + pr_err("gs_set_config: cannot enable OUT " + "endpoint %s, ret=%d\n", ep->name, ret); goto exit_reset_config; } @@ -1865,7 +1868,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { - printk(KERN_ERR "gs_set_config: cannot find endpoints\n"); + pr_err("gs_set_config: cannot find endpoints\n"); ret = -ENODEV; goto exit_reset_config; } @@ -1876,11 +1879,12 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) { req->complete = gs_read_complete; if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { - printk(KERN_ERR "gs_set_config: cannot queue read request, ret=%d\n", - ret); + pr_err("gs_set_config: cannot queue read " + "request, ret=%d\n", ret); } } else { - printk(KERN_ERR "gs_set_config: cannot allocate read requests\n"); + pr_err("gs_set_config: cannot allocate " + "read requests\n"); ret = -ENOMEM; goto exit_reset_config; } @@ -1893,13 +1897,14 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) req_entry->re_req->complete = gs_write_complete; list_add(&req_entry->re_entry, &dev->dev_req_list); } else { - printk(KERN_ERR "gs_set_config: cannot allocate write requests\n"); + pr_err("gs_set_config: cannot allocate " + "write requests\n"); ret = -ENOMEM; goto exit_reset_config; } } - printk(KERN_INFO "gs_set_config: %s configured, %s speed %s config\n", + pr_info("gs_set_config: %s configured, %s speed %s config\n", GS_LONG_NAME, gadget->speed == USB_SPEED_HIGH ? "high" : "full", config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM"); @@ -1926,7 +1931,7 @@ static void gs_reset_config(struct gs_dev *dev) struct gs_req_entry *req_entry; if (dev == NULL) { - printk(KERN_ERR "gs_reset_config: NULL device pointer\n"); + pr_err("gs_reset_config: NULL device pointer\n"); return; } diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index fcde5d9c87d..d3d4f4048e6 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -1115,7 +1115,7 @@ zero_bind (struct usb_gadget *gadget) ep = usb_ep_autoconfig (gadget, &fs_source_desc); if (!ep) { autoconf_fail: - printk (KERN_ERR "%s: can't autoconfigure on %s\n", + pr_err("%s: can't autoconfigure on %s\n", shortname, gadget->name); return -ENODEV; } @@ -1139,7 +1139,7 @@ autoconf_fail: * things like configuration and altsetting numbering * can need hardware-specific attention though. */ - printk (KERN_WARNING "%s: controller '%s' not recognized\n", + pr_warning("%s: controller '%s' not recognized\n", shortname, gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); } |