From 950ee4c8f094feecd3add994a2cf4fd335ca509b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 19 Mar 2006 20:49:14 +0100 Subject: [PATCH] USB: net2282 and net2280 software compatibility Below is a patch to gadgets/net2280.[ch] which adds support for the net2282 controller. The original code was kindly provided by PLX Technology, I just merged it with the current net2280 driver in the kernel. Tested on 2.6.15.6, but only with 2282. I did the merge, so that the behaviour for the 2280 is unaffected (except for short delays for extra checks). Signed-off-by: G. Liakhovetski Signed-off-by: Greg Kroah-Hartman Support for net2282 in net2280 driver. --- drivers/usb/gadget/Kconfig | 4 +- drivers/usb/gadget/net2280.c | 90 +++++++++++++++++++++++++++++++++----------- drivers/usb/gadget/net2280.h | 2 + 3 files changed, 73 insertions(+), 23 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d80f71877d6..363b2ad74ae 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -69,11 +69,11 @@ choice often need board-specific hooks. config USB_GADGET_NET2280 - boolean "NetChip 2280" + boolean "NetChip 228x" depends on PCI select USB_GADGET_DUALSPEED help - NetChip 2280 is a PCI based USB peripheral controller which + NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers. It has six configurable endpoints, as well as endpoint zero diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index fb73dc10053..7682c07035b 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -26,6 +26,8 @@ * Copyright (C) 2003 David Brownell * Copyright (C) 2003-2005 PLX Technology, Inc. * + * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip + * * 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 @@ -71,8 +73,8 @@ #include -#define DRIVER_DESC "PLX NET2280 USB Peripheral Controller" -#define DRIVER_VERSION "2005 Feb 03" +#define DRIVER_DESC "PLX NET228x USB Peripheral Controller" +#define DRIVER_VERSION "2005 Sept 27" #define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ @@ -118,7 +120,7 @@ module_param (fifo_mode, ushort, 0644); /* enable_suspend -- When enabled, the driver will respond to * USB suspend requests by powering down the NET2280. Otherwise, * USB suspend requests will be ignored. This is acceptible for - * self-powered devices, and helps avoid some quirks. + * self-powered devices */ static int enable_suspend = 0; @@ -223,6 +225,11 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) ep->is_in = (tmp & USB_DIR_IN) != 0; if (!ep->is_in) writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); + else if (dev->pdev->device != 0x2280) { + /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */ + writel ((1 << CLEAR_NAK_OUT_PACKETS) + | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); + } writel (tmp, &ep->regs->ep_cfg); @@ -232,8 +239,9 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) writel (tmp, &dev->regs->pciirqenb0); tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) - | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE) - | readl (&ep->regs->ep_irqenb); + | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); + if (dev->pdev->device == 0x2280) + tmp |= readl (&ep->regs->ep_irqenb); writel (tmp, &ep->regs->ep_irqenb); } else { /* dma, per-request */ tmp = (1 << (8 + ep->num)); /* completion */ @@ -314,10 +322,18 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) /* init to our chosen defaults, notably so that we NAK OUT * packets until the driver queues a read (+note erratum 0112) */ - tmp = (1 << SET_NAK_OUT_PACKETS_MODE) + if (!ep->is_in || ep->dev->pdev->device == 0x2280) { + tmp = (1 << SET_NAK_OUT_PACKETS_MODE) | (1 << SET_NAK_OUT_PACKETS) | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | (1 << CLEAR_INTERRUPT_MODE); + } else { + /* added for 2282 */ + tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) + | (1 << CLEAR_NAK_OUT_PACKETS) + | (1 << CLEAR_EP_HIDE_STATUS_PHASE) + | (1 << CLEAR_INTERRUPT_MODE); + } if (ep->num != 0) { tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) @@ -326,14 +342,18 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) writel (tmp, &ep->regs->ep_rsp); /* scrub most status bits, and flush any fifo state */ - writel ( (1 << TIMEOUT) + if (ep->dev->pdev->device == 0x2280) + tmp = (1 << FIFO_OVERFLOW) + | (1 << FIFO_UNDERFLOW); + else + tmp = 0; + + writel (tmp | (1 << TIMEOUT) | (1 << USB_STALL_SENT) | (1 << USB_IN_NAK_SENT) | (1 << USB_IN_ACK_RCVD) | (1 << USB_OUT_PING_NAK_SENT) | (1 << USB_OUT_ACK_SENT) - | (1 << FIFO_OVERFLOW) - | (1 << FIFO_UNDERFLOW) | (1 << FIFO_FLUSH) | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) @@ -718,7 +738,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) */ if (ep->is_in) dmacount |= (1 << DMA_DIRECTION); - else if ((dmacount % ep->ep.maxpacket) != 0) + if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280) dmacount |= (1 << END_OF_CHAIN); req->valid = valid; @@ -760,9 +780,12 @@ static inline void stop_dma (struct net2280_dma_regs __iomem *dma) static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) { struct net2280_dma_regs __iomem *dma = ep->dma; + unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); - writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION), - &dma->dmacount); + if (ep->dev->pdev->device != 0x2280) + tmp |= (1 << END_OF_CHAIN); + + writel (tmp, &dma->dmacount); writel (readl (&dma->dmastat), &dma->dmastat); writel (td_dma, &dma->dmadesc); @@ -2110,7 +2133,11 @@ static void handle_ep_small (struct net2280_ep *ep) VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", ep->ep.name, t, req ? &req->req : 0); #endif - writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); + if (!ep->is_in || ep->dev->pdev->device == 0x2280) + writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); + else + /* Added for 2282 */ + writel (t, &ep->regs->ep_stat); /* for ep0, monitor token irqs to catch data stage length errors * and to synchronize on status. @@ -2337,7 +2364,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) u32 raw [2]; struct usb_ctrlrequest r; } u; - int tmp = 0; + int tmp; struct net2280_request *req; if (dev->gadget.speed == USB_SPEED_UNKNOWN) { @@ -2364,14 +2391,19 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) } ep->stopped = 0; dev->protocol_stall = 0; - writel ( (1 << TIMEOUT) + + if (ep->dev->pdev->device == 0x2280) + tmp = (1 << FIFO_OVERFLOW) + | (1 << FIFO_UNDERFLOW); + else + tmp = 0; + + writel (tmp | (1 << TIMEOUT) | (1 << USB_STALL_SENT) | (1 << USB_IN_NAK_SENT) | (1 << USB_IN_ACK_RCVD) | (1 << USB_OUT_PING_NAK_SENT) | (1 << USB_OUT_ACK_SENT) - | (1 << FIFO_OVERFLOW) - | (1 << FIFO_UNDERFLOW) | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | (1 << DATA_PACKET_RECEIVED_INTERRUPT) @@ -2385,6 +2417,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) cpu_to_le32s (&u.raw [0]); cpu_to_le32s (&u.raw [1]); + tmp = 0; + #define w_value le16_to_cpup (&u.r.wValue) #define w_index le16_to_cpup (&u.r.wIndex) #define w_length le16_to_cpup (&u.r.wLength) @@ -2594,10 +2628,17 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) writel (stat, &dev->regs->irqstat1); /* some status we can just ignore */ - stat &= ~((1 << CONTROL_STATUS_INTERRUPT) - | (1 << SUSPEND_REQUEST_INTERRUPT) - | (1 << RESUME_INTERRUPT) - | (1 << SOF_INTERRUPT)); + if (dev->pdev->device == 0x2280) + stat &= ~((1 << CONTROL_STATUS_INTERRUPT) + | (1 << SUSPEND_REQUEST_INTERRUPT) + | (1 << RESUME_INTERRUPT) + | (1 << SOF_INTERRUPT)); + else + stat &= ~((1 << CONTROL_STATUS_INTERRUPT) + | (1 << RESUME_INTERRUPT) + | (1 << SOF_DOWN_INTERRUPT) + | (1 << SOF_INTERRUPT)); + if (!stat) return; // DEBUG (dev, "irqstat1 %08x\n", stat); @@ -2939,6 +2980,13 @@ static struct pci_device_id pci_ids [] = { { .device = 0x2280, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, +}, { + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class_mask = ~0, + .vendor = 0x17cc, + .device = 0x2282, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index fff4509cf34..e195abec8d7 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -179,6 +179,7 @@ struct net2280_regs { #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 #define PCI_RETRY_ABORT_INTERRUPT 17 #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 +#define SOF_DOWN_INTERRUPT 14 #define GPIO_INTERRUPT 13 #define DMA_D_INTERRUPT 12 #define DMA_C_INTERRUPT 11 @@ -346,6 +347,7 @@ struct net2280_dma_regs { /* [11.7] */ #define DMA_ENABLE 1 #define DMA_ADDRESS_HOLD 0 u32 dmastat; +#define DMA_ABORT_DONE_INTERRUPT 27 #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 #define DMA_TRANSACTION_DONE_INTERRUPT 24 #define DMA_ABORT 1 -- cgit v1.2.3 From f096e0434c717d7a2aa1614e0be0d1b7c64bec29 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 21 Mar 2006 22:54:47 +0000 Subject: [PATCH] USB: cleanups for ohci-s3c2410.c Fix compile errors due to functions not being defined static Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-s3c2410.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 682bf221566..b27669fe9f0 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -37,7 +37,7 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); /* conversion functions */ -struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) +static struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) { return hcd->self.controller->platform_data; } @@ -316,7 +316,8 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) * */ -void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) +static void +usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) { usb_remove_hcd(hcd); s3c2410_stop_hc(dev); @@ -334,8 +335,8 @@ void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) * through the hotplug entry's driver_data. * */ -int usb_hcd_s3c2410_probe (const struct hc_driver *driver, - struct platform_device *dev) +static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, + struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; -- cgit v1.2.3 From 7e1c0b86aca9d42fa4de3fdad17c57bb462fe1e2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 21 Mar 2006 14:55:20 +0000 Subject: [PATCH] USB: ftdi_sio: add support for Eclo COM to 1-Wire USB adapter This patch adds support for the Eclo COM to 1-Wire USB adapter to the ftdi_sio driver's device ID table. Details were provided by Martin Grill on the ftdi-sio-usb-devel mailing list and I (Ian Abbott) confirmed it matched the INF file in the Eclo's Windows driver package. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f3af81b4dd2..67793d9ca5f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -489,6 +489,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8da773c2744..18bcc3ab4d2 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -399,6 +399,12 @@ #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ +/* + * Eclo (http://www.eclo.pt/) product IDs. + * PID 0xEA90 submitted by Martin Grill. + */ +#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ -- cgit v1.2.3 From 70ffe6e14d7c5db84b92841471ce6fd0200010cd Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 23 Mar 2006 15:05:16 -0500 Subject: [PATCH] USB: g_file_storage: Set short_not_ok for bulk-out transfers I'm told that some UDC hardware may work better if it knows that receiving a short packet should always cause an error. Accordingly, this patch (as663) sets the short_not_ok flag for bulk-out transfers in g_file_storage. Oddly enough, there are no circumstances where that driver can legally receive a shorter-than-expected bulk-out packet. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index cf3be299e35..eb2821542b7 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1795,6 +1795,7 @@ static int do_write(struct fsg_dev *fsg) * the bulk-out maxpacket size */ bh->outreq->length = bh->bulk_out_intended_length = amount; + bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); fsg->next_buffhd_to_fill = bh->next; @@ -2398,6 +2399,7 @@ static int throw_away_data(struct fsg_dev *fsg) * the bulk-out maxpacket size */ bh->outreq->length = bh->bulk_out_intended_length = amount; + bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); fsg->next_buffhd_to_fill = bh->next; @@ -3029,6 +3031,7 @@ static int get_next_command(struct fsg_dev *fsg) /* Queue a request to read a Bulk-only CBW */ set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); + bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); -- cgit v1.2.3 From 14cd5f8e85e90c9dead2393377b9a2c23131e0ce Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 23 Mar 2006 15:07:25 -0500 Subject: [PATCH] USB: g_file_storage: add comment about buffer allocation This patch (as664) adds a comment to file_storage.c, noting that the driver is slightly non-portable because it assumes that a buffer allocated for a bulk-in endpoint will also be useable for a bulk-out endpoint. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index eb2821542b7..b6d920f349e 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -71,6 +71,12 @@ * requirement amounts to two 16K buffers, size configurable by a parameter. * Support is included for both full-speed and high-speed operation. * + * Note that the driver is slightly non-portable in that it assumes a + * single memory/DMA buffer will be useable for bulk-in, bulk-out, and + * interrupt-in endpoints. With most device controllers this isn't an + * issue, but there may be some with hardware restrictions that prevent + * a buffer from being used by more than one endpoint. + * * Module options: * * file=filename[,filename...] @@ -3956,6 +3962,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < NUM_BUFFERS; ++i) { struct fsg_buffhd *bh = &fsg->buffhds[i]; + /* Allocate for the bulk-in endpoint. We assume that + * the buffer will also work with the bulk-out (and + * interrupt-in) endpoint. */ bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, &bh->dma, GFP_KERNEL); if (!bh->buf) -- cgit v1.2.3 From 1ce7dd26e0f0e34bb75ec56f7f546151af34fcf9 Mon Sep 17 00:00:00 2001 From: Luiz Fernando Capitulino Date: Fri, 24 Mar 2006 17:12:31 -0300 Subject: [PATCH] USB serial: Converts port semaphore to mutexes. The usbserial's port semaphore used to synchronize serial_open() and serial_close() are strict mutexes, convert them to the mutex implementation. Signed-off-by: Luiz Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 16 ++++++++-------- drivers/usb/serial/usb-serial.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 097f4e8488f..071f86a59c0 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -27,10 +27,10 @@ #include #include #include +#include #include #include #include -#include #include #include "usb-serial.h" #include "pl2303.h" @@ -192,7 +192,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) if (!port) return -ENODEV; - if (down_interruptible(&port->sem)) + if (mutex_lock_interruptible(&port->mutex)) return -ERESTARTSYS; ++port->open_count; @@ -219,7 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) goto bailout_module_put; } - up(&port->sem); + mutex_unlock(&port->mutex); return 0; bailout_module_put: @@ -227,7 +227,7 @@ bailout_module_put: bailout_kref_put: kref_put(&serial->kref, destroy_serial); port->open_count = 0; - up(&port->sem); + mutex_unlock(&port->mutex); return retval; } @@ -240,10 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) dbg("%s - port %d", __FUNCTION__, port->number); - down(&port->sem); + mutex_lock(&port->mutex); if (port->open_count == 0) { - up(&port->sem); + mutex_unlock(&port->mutex); return; } @@ -262,7 +262,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) module_put(port->serial->type->driver.owner); } - up(&port->sem); + mutex_unlock(&port->mutex); kref_put(&port->serial->kref, destroy_serial); } @@ -783,7 +783,7 @@ int usb_serial_probe(struct usb_interface *interface, port->number = i + serial->minor; port->serial = serial; spin_lock_init(&port->lock); - sema_init(&port->sem, 1); + mutex_init(&port->mutex); INIT_WORK(&port->work, usb_serial_port_softint, port); serial->port[i] = port; } diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index d7d27c3385b..dc89d871046 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -16,7 +16,7 @@ #include #include -#include +#include #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ @@ -31,7 +31,7 @@ * @serial: pointer back to the struct usb_serial owner of this port. * @tty: pointer to the corresponding tty for this port. * @lock: spinlock to grab when updating portions of this structure. - * @sem: semaphore used to synchronize serial_open() and serial_close() + * @mutex: mutex used to synchronize serial_open() and serial_close() * access for this port. * @number: the number of the port (the minor number). * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. @@ -63,7 +63,7 @@ struct usb_serial_port { struct usb_serial * serial; struct tty_struct * tty; spinlock_t lock; - struct semaphore sem; + struct mutex mutex; unsigned char number; unsigned char * interrupt_in_buffer; -- cgit v1.2.3 From 75e2df603de69dba67dd64ab34a2313fdc52a4dd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 25 Mar 2006 18:01:53 +0100 Subject: [PATCH] USB: pci-quirks.c: proper prototypes This patch adds a header file with proper prototypes for two functions in drivers/usb/host/pci-quirks.c. Signed-off-by: Adrian Bunk Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 1 + drivers/usb/host/pci-quirks.h | 7 +++++++ drivers/usb/host/uhci-hcd.c | 4 +--- 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/host/pci-quirks.h (limited to 'drivers/usb') diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 9e81c26313f..1045f846fbe 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -15,6 +15,7 @@ #include #include #include +#include "pci-quirks.h" #define UHCI_USBLEGSUP 0xc0 /* legacy support */ diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h new file mode 100644 index 00000000000..1564edfff6f --- /dev/null +++ b/drivers/usb/host/pci-quirks.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_USB_PCI_QUIRKS_H +#define __LINUX_USB_PCI_QUIRKS_H + +void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); +int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); + +#endif /* __LINUX_USB_PCI_QUIRKS_H */ diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4edb8330c44..3d511690c9b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -50,6 +50,7 @@ #include "../core/hcd.h" #include "uhci-hcd.h" +#include "pci-quirks.h" /* * Version Information @@ -100,9 +101,6 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); #include "uhci-q.c" #include "uhci-hub.c" -extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); -extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); - /* * Finish up a host controller reset and update the recorded state. */ -- cgit v1.2.3 From fb9ac9bda9aee5a42d44f4b503bdbd7c414ac201 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 25 Mar 2006 18:03:38 +0100 Subject: [PATCH] USB: input/: proper prototypes This patch adds proper prototypes in a header file for some global functions. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-ff.c | 6 ------ drivers/usb/input/hid.h | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index 72e698658b5..d5c91ee6799 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c @@ -34,12 +34,6 @@ #include "hid.h" -/* Drivers' initializing functions */ -extern int hid_lgff_init(struct hid_device* hid); -extern int hid_lg3d_init(struct hid_device* hid); -extern int hid_pid_init(struct hid_device* hid); -extern int hid_tmff_init(struct hid_device* hid); - /* * This table contains pointers to initializers. To add support for new * devices, you need to add the USB vendor and product ids here. diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 4e1b784fe52..9c62837b5b8 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -533,3 +533,8 @@ static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input, return hid->ff_event(hid, input, type, code, value); return -ENOSYS; } + +int hid_lgff_init(struct hid_device* hid); +int hid_tmff_init(struct hid_device* hid); +int hid_pid_init(struct hid_device* hid); + -- cgit v1.2.3 From 62a13db346bb6ef80c112d373733d3e873dad90b Mon Sep 17 00:00:00 2001 From: Folkert van Heusden Date: Tue, 28 Mar 2006 20:41:26 +0900 Subject: [PATCH] USB: add support for Papouch TMU (USB thermometer) This patch adds support for new vendor (papouch) and one of their devices - TMU (a USB thermometer). More information: vendor homepage: http://www.papouch.com/en/ product homepage (Polish): http://www.papouch.com/shop/scripts/_detail.asp?katcislo=0188 This patch is based on the submission from Folkert van Heusden [1]. Then reviseted by Kalin KOZHUHAROV [2] and retested by Folkert. [1] http://article.gmane.org/gmane.linux.kernel/392970 [2] http://article.gmane.org/gmane.linux.kernel/393386 Signed-off-by: Folkert van Heusden Signed-off-by: Kalin KOZHUHAROV Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 67793d9ca5f..f5851db67f5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -494,6 +494,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 18bcc3ab4d2..2155f0e4a37 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -405,6 +405,15 @@ */ #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ +/* + * Papouch products (http://www.papouch.com/) + * Submitted by Folkert van Heusden + */ + +#define PAPOUCH_VID 0x5050 /* Vendor ID */ +#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ + + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ -- cgit v1.2.3 From 1d3e20236d7a5678d44602171bbd153c57c8c4bc Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Wed, 29 Mar 2006 22:41:07 +0200 Subject: [PATCH] USB: usbtouchscreen: unified USB touchscreen driver A new single driver for various USB touchscreen devices. It currently supports: - eGalax TouchKit - PanJit TouchSet - 3M/Microtouch - ITM Touchscreens Support for the diffent devices can be enabled/disable when CONFIG_EMBEDDED is set. Sizes for comparision: text data bss dec hex filename 2942 724 4 3670 e56 touchkitusb.ko 2647 660 0 3307 ceb mtouchusb.ko 2448 628 0 3076 c04 itmtouch.ko 4145 1012 12 5169 1431 usbtouchscreen.ko Signed-off-by: Daniel Ritz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/Kconfig | 42 ++- drivers/usb/input/Makefile | 1 + drivers/usb/input/hid-core.c | 7 + drivers/usb/input/usbtouchscreen.c | 605 +++++++++++++++++++++++++++++++++++++ 4 files changed, 652 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/input/usbtouchscreen.c (limited to 'drivers/usb') diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 5246b35301d..83b90be7fa0 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -200,9 +200,45 @@ config USB_POWERMATE To compile this driver as a module, choose M here: the module will be called powermate. +config USB_TOUCHSCREEN + tristate "USB Touchscreen Driver" + depends on USB && INPUT + ---help--- + USB Touchscreen driver for: + - eGalax Touchkit USB + - PanJit TouchSet USB + - 3M MicroTouch USB + - ITM + + Have a look at for + a usage description and the required user-space stuff. + + To compile this driver as a module, choose M here: the + module will be called usbtouchscreen. + +config USB_TOUCHSCREEN_EGALAX + default y + bool "eGalax device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_PANJIT + default y + bool "PanJit device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_3M + default y + bool "3M/Microtouch device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_ITM + default y + bool "ITM device support" if EMBEDDED + depends on USB_TOUCHSCREEN + config USB_MTOUCH tristate "MicroTouch USB Touchscreen Driver" - depends on USB && INPUT + depends on USB && INPUT && !USB_TOUCHSCREEN_3M ---help--- Say Y here if you want to use a MicroTouch (Now 3M) USB Touchscreen controller. @@ -214,7 +250,7 @@ config USB_MTOUCH config USB_ITMTOUCH tristate "ITM Touch USB Touchscreen Driver" - depends on USB && INPUT + depends on USB && INPUT && !USB_TOUCHSCREEN_ITM ---help--- Say Y here if you want to use a ITM Touch USB Touchscreen controller. @@ -226,7 +262,7 @@ config USB_ITMTOUCH config USB_EGALAX tristate "eGalax TouchKit USB Touchscreen Driver" - depends on USB && INPUT + depends on USB && INPUT && !USB_TOUCHSCREEN_EGALAX ---help--- Say Y here if you want to use a eGalax TouchKit USB Touchscreen controller. diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index d512d9f488f..764114529c5 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_USB_MOUSE) += usbmouse.o obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o obj-$(CONFIG_USB_EGALAX) += touchkitusb.o +obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o obj-$(CONFIG_USB_POWERMATE) += powermate.o obj-$(CONFIG_USB_WACOM) += wacom.o obj-$(CONFIG_USB_ACECAD) += acecad.o diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index d4bf1701046..1d979d6e0c8 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1372,6 +1372,8 @@ void hid_close(struct hid_device *hid) usb_kill_urb(hid->urbin); } +#define USB_VENDOR_ID_PANJIT 0x134c + /* * Initialize all reports */ @@ -1701,6 +1703,11 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, + { 0, 0 } }; diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c new file mode 100644 index 00000000000..e9a07c1e905 --- /dev/null +++ b/drivers/usb/input/usbtouchscreen.c @@ -0,0 +1,605 @@ +/****************************************************************************** + * usbtouchscreen.c + * Driver for USB Touchscreens, supporting those devices: + * - eGalax Touchkit + * - 3M/Microtouch + * - ITM + * - PanJit TouchSet + * + * Copyright (C) 2004-2006 by Daniel Ritz + * Copyright (C) by Todd E. Johnson (mtouchusb.c) + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Driver is based on touchkitusb.c + * - ITM parts are from itmtouch.c + * - 3M parts are from mtouchusb.c + * - PanJit parts are from an unmerged driver by Lanslott Gish + * + *****************************************************************************/ + +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_VERSION "v0.3" +#define DRIVER_AUTHOR "Daniel Ritz " +#define DRIVER_DESC "USB Touchscreen Driver" + +static int swap_xy; +module_param(swap_xy, bool, 0644); +MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); + +/* device specifc data/functions */ +struct usbtouch_usb; +struct usbtouch_device_info { + int min_xc, max_xc; + int min_yc, max_yc; + int min_press, max_press; + int rept_size; + int flags; + + void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len); + int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); + int (*init) (struct usbtouch_usb *usbtouch); +}; + +#define USBTOUCH_FLG_BUFFER 0x01 + + +/* a usbtouch device */ +struct usbtouch_usb { + unsigned char *data; + dma_addr_t data_dma; + unsigned char *buffer; + int buf_len; + struct urb *irq; + struct usb_device *udev; + struct input_dev *input; + struct usbtouch_device_info *type; + char name[128]; + char phys[64]; +}; + +static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, + struct pt_regs *regs, unsigned char *pkt, int len); + +/* device types */ +enum { + DEVTPYE_DUMMY = -1, + DEVTYPE_EGALAX, + DEVTYPE_PANJIT, + DEVTYPE_3M, + DEVTYPE_ITM, +}; + +static struct usb_device_id usbtouch_devices[] = { +#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX + {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, + {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, + {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, + {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT + {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT}, + {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT}, + {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT}, + {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT}, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_3M + {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M}, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_ITM + {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, +#endif + + {} +}; + + +/***************************************************************************** + * eGalax part + */ + +#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX + +#define EGALAX_PKT_TYPE_MASK 0xFE +#define EGALAX_PKT_TYPE_REPT 0x80 +#define EGALAX_PKT_TYPE_DIAG 0x0A + +static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +{ + if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) + return 0; + + *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); + *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); + *touch = pkt[0] & 0x01; + + return 1; + +} + +static int egalax_get_pkt_len(unsigned char *buf) +{ + switch (buf[0] & EGALAX_PKT_TYPE_MASK) { + case EGALAX_PKT_TYPE_REPT: + return 5; + + case EGALAX_PKT_TYPE_DIAG: + return buf[1] + 2; + } + + return 0; +} + +static void egalax_process(struct usbtouch_usb *usbtouch, struct pt_regs *regs, + unsigned char *pkt, int len) +{ + unsigned char *buffer; + int pkt_len, buf_len, pos; + + /* if the buffer contains data, append */ + if (unlikely(usbtouch->buf_len)) { + int tmp; + + /* if only 1 byte in buffer, add another one to get length */ + if (usbtouch->buf_len == 1) + usbtouch->buffer[1] = pkt[0]; + + pkt_len = egalax_get_pkt_len(usbtouch->buffer); + + /* unknown packet: drop everything */ + if (!pkt_len) + return; + + /* append, process */ + tmp = pkt_len - usbtouch->buf_len; + memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); + usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len); + + buffer = pkt + tmp; + buf_len = len - tmp; + } else { + buffer = pkt; + buf_len = len; + } + + /* only one byte left in buffer */ + if (unlikely(buf_len == 1)) { + usbtouch->buffer[0] = buffer[0]; + usbtouch->buf_len = 1; + return; + } + + /* loop over the buffer */ + pos = 0; + while (pos < buf_len) { + /* get packet len */ + pkt_len = egalax_get_pkt_len(buffer + pos); + + /* unknown packet: drop everything */ + if (unlikely(!pkt_len)) + return; + + /* full packet: process */ + if (likely(pkt_len <= buf_len)) { + usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len); + } else { + /* incomplete packet: save in buffer */ + memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); + usbtouch->buf_len = buf_len - pos; + } + pos += pkt_len; + } +} +#endif + + +/***************************************************************************** + * PanJit Part + */ +#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT +static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +{ + *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; + *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; + *touch = pkt[0] & 0x01; + + return 1; +} +#endif + + +/***************************************************************************** + * 3M/Microtouch Part + */ +#ifdef CONFIG_USB_TOUCHSCREEN_3M + +#define MTOUCHUSB_ASYNC_REPORT 1 +#define MTOUCHUSB_RESET 7 +#define MTOUCHUSB_REQ_CTRLLR_ID 10 + +static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +{ + *x = (pkt[8] << 8) | pkt[7]; + *y = (pkt[10] << 8) | pkt[9]; + *touch = (pkt[2] & 0x40) ? 1 : 0; + + return 1; +} + +static int mtouch_init(struct usbtouch_usb *usbtouch) +{ + int ret; + + ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), + MTOUCHUSB_RESET, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", + __FUNCTION__, ret); + if (ret < 0) + return ret; + + ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), + MTOUCHUSB_ASYNC_REPORT, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); + dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", + __FUNCTION__, ret); + if (ret < 0) + return ret; + + return 0; +} +#endif + + +/***************************************************************************** + * ITM Part + */ +#ifdef CONFIG_USB_TOUCHSCREEN_ITM +static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +{ + *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); + *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); + *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F); + *touch = ~pkt[7] & 0x20; + + return 1; +} +#endif + + +/***************************************************************************** + * the different device descriptors + */ +static struct usbtouch_device_info usbtouch_dev_info[] = { +#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX + [DEVTYPE_EGALAX] = { + .min_xc = 0x0, + .max_xc = 0x07ff, + .min_yc = 0x0, + .max_yc = 0x07ff, + .rept_size = 16, + .flags = USBTOUCH_FLG_BUFFER, + .process_pkt = egalax_process, + .read_data = egalax_read_data, + }, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT + [DEVTYPE_PANJIT] = { + .min_xc = 0x0, + .max_xc = 0x0fff, + .min_yc = 0x0, + .max_yc = 0x0fff, + .rept_size = 8, + .read_data = panjit_read_data, + }, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_3M + [DEVTYPE_3M] = { + .min_xc = 0x0, + .max_xc = 0x4000, + .min_yc = 0x0, + .max_yc = 0x4000, + .rept_size = 11, + .read_data = mtouch_read_data, + .init = mtouch_init, + }, +#endif + +#ifdef CONFIG_USB_TOUCHSCREEN_ITM + [DEVTYPE_ITM] = { + .min_xc = 0x0, + .max_xc = 0x0fff, + .min_yc = 0x0, + .max_yc = 0x0fff, + .max_press = 0xff, + .rept_size = 8, + .read_data = itm_read_data, + }, +#endif +}; + + +/***************************************************************************** + * Generic Part + */ +static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, + struct pt_regs *regs, unsigned char *pkt, int len) +{ + int x, y, touch, press; + struct usbtouch_device_info *type = usbtouch->type; + + if (!type->read_data(pkt, &x, &y, &touch, &press)) + return; + + input_regs(usbtouch->input, regs); + input_report_key(usbtouch->input, BTN_TOUCH, touch); + + if (swap_xy) { + input_report_abs(usbtouch->input, ABS_X, y); + input_report_abs(usbtouch->input, ABS_Y, x); + } else { + input_report_abs(usbtouch->input, ABS_X, x); + input_report_abs(usbtouch->input, ABS_Y, y); + } + if (type->max_press) + input_report_abs(usbtouch->input, ABS_PRESSURE, press); + input_sync(usbtouch->input); +} + + +static void usbtouch_irq(struct urb *urb, struct pt_regs *regs) +{ + struct usbtouch_usb *usbtouch = urb->context; + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ETIMEDOUT: + /* this urb is timing out */ + dbg("%s - urb timed out - was the device unplugged?", + __FUNCTION__); + return; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length); + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result: %d", + __FUNCTION__, retval); +} + +static int usbtouch_open(struct input_dev *input) +{ + struct usbtouch_usb *usbtouch = input->private; + + usbtouch->irq->dev = usbtouch->udev; + + if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) + return -EIO; + + return 0; +} + +static void usbtouch_close(struct input_dev *input) +{ + struct usbtouch_usb *usbtouch = input->private; + + usb_kill_urb(usbtouch->irq); +} + + +static void usbtouch_free_buffers(struct usb_device *udev, + struct usbtouch_usb *usbtouch) +{ + if (usbtouch->data) + usb_buffer_free(udev, usbtouch->type->rept_size, + usbtouch->data, usbtouch->data_dma); + kfree(usbtouch->buffer); +} + + +static int usbtouch_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usbtouch_usb *usbtouch; + struct input_dev *input_dev; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev = interface_to_usbdev(intf); + struct usbtouch_device_info *type; + int err; + + interface = intf->cur_altsetting; + endpoint = &interface->endpoint[0].desc; + + usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!usbtouch || !input_dev) + goto out_free; + + type = &usbtouch_dev_info[id->driver_info]; + usbtouch->type = type; + if (!type->process_pkt) + type->process_pkt = usbtouch_process_pkt; + + usbtouch->data = usb_buffer_alloc(udev, type->rept_size, + SLAB_KERNEL, &usbtouch->data_dma); + if (!usbtouch->data) + goto out_free; + + if (type->flags & USBTOUCH_FLG_BUFFER) { + usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); + if (!usbtouch->buffer) + goto out_free_buffers; + } + + usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); + if (!usbtouch->irq) { + dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); + goto out_free_buffers; + } + + usbtouch->udev = udev; + usbtouch->input = input_dev; + + if (udev->manufacturer) + strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(usbtouch->name, " ", sizeof(usbtouch->name)); + strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name)); + } + + if (!strlen(usbtouch->name)) + snprintf(usbtouch->name, sizeof(usbtouch->name), + "USB Touchscreen %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys)); + strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys)); + + input_dev->name = usbtouch->name; + input_dev->phys = usbtouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = usbtouch; + input_dev->open = usbtouch_open; + input_dev->close = usbtouch_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); + input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); + if (type->max_press) + input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, + type->max_press, 0, 0); + + usb_fill_int_urb(usbtouch->irq, usbtouch->udev, + usb_rcvintpipe(usbtouch->udev, 0x81), + usbtouch->data, type->rept_size, + usbtouch_irq, usbtouch, endpoint->bInterval); + + usbtouch->irq->transfer_dma = usbtouch->data_dma; + usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + /* device specific init */ + if (type->init) { + err = type->init(usbtouch); + if (err) { + dbg("%s - type->init() failed, err: %d", __FUNCTION__, err); + goto out_free_buffers; + } + } + + err = input_register_device(usbtouch->input); + if (err) { + dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err); + goto out_free_buffers; + } + + usb_set_intfdata(intf, usbtouch); + + return 0; + +out_free_buffers: + usbtouch_free_buffers(udev, usbtouch); +out_free: + input_free_device(input_dev); + kfree(usbtouch); + return -ENOMEM; +} + +static void usbtouch_disconnect(struct usb_interface *intf) +{ + struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); + + dbg("%s - called", __FUNCTION__); + + if (!usbtouch) + return; + + dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__); + usb_set_intfdata(intf, NULL); + usb_kill_urb(usbtouch->irq); + input_unregister_device(usbtouch->input); + usb_free_urb(usbtouch->irq); + usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); + kfree(usbtouch); +} + +MODULE_DEVICE_TABLE(usb, usbtouch_devices); + +static struct usb_driver usbtouch_driver = { + .name = "usbtouchscreen", + .probe = usbtouch_probe, + .disconnect = usbtouch_disconnect, + .id_table = usbtouch_devices, +}; + +static int __init usbtouch_init(void) +{ + return usb_register(&usbtouch_driver); +} + +static void __exit usbtouch_cleanup(void) +{ + usb_deregister(&usbtouch_driver); +} + +module_init(usbtouch_init); +module_exit(usbtouch_cleanup); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +MODULE_ALIAS("touchkitusb"); +MODULE_ALIAS("itmtouch"); +MODULE_ALIAS("mtouchusb"); -- cgit v1.2.3 From 5e32b5767fca231e1c84b84e877a26766c27510f Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Sat, 1 Apr 2006 18:19:28 +0200 Subject: [PATCH] usb/input: remove Kconfig entries of old touchscreen drivers in favour of usbtouchscreen Signed-off-by: Daniel Ritz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/Kconfig | 40 ---------------------------------------- 1 file changed, 40 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 83b90be7fa0..650103bc961 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -236,46 +236,6 @@ config USB_TOUCHSCREEN_ITM bool "ITM device support" if EMBEDDED depends on USB_TOUCHSCREEN -config USB_MTOUCH - tristate "MicroTouch USB Touchscreen Driver" - depends on USB && INPUT && !USB_TOUCHSCREEN_3M - ---help--- - Say Y here if you want to use a MicroTouch (Now 3M) USB - Touchscreen controller. - - See for additional information. - - To compile this driver as a module, choose M here: the - module will be called mtouchusb. - -config USB_ITMTOUCH - tristate "ITM Touch USB Touchscreen Driver" - depends on USB && INPUT && !USB_TOUCHSCREEN_ITM - ---help--- - Say Y here if you want to use a ITM Touch USB - Touchscreen controller. - - This touchscreen is used in LG 1510SF monitors. - - To compile this driver as a module, choose M here: the - module will be called itmtouch. - -config USB_EGALAX - tristate "eGalax TouchKit USB Touchscreen Driver" - depends on USB && INPUT && !USB_TOUCHSCREEN_EGALAX - ---help--- - Say Y here if you want to use a eGalax TouchKit USB - Touchscreen controller. - - The driver has been tested on a Xenarc 700TSV monitor - with eGalax touchscreen. - - Have a look at for - a usage description and the required user-space stuff. - - To compile this driver as a module, choose M here: the - module will be called touchkitusb. - config USB_YEALINK tristate "Yealink usb-p1k voip phone" depends on USB && INPUT && EXPERIMENTAL -- cgit v1.2.3 From aafe5bd6ec341edfaf3233d272febbb8862a7251 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 31 Mar 2006 11:46:43 -0500 Subject: [PATCH] USB: g_file_storage: use module_param_array_named macro Randy Dunlap pointed out that there now is a module_param_array_named macro available. This patch (as666) updates g_file_storage to make use of it. It also adds a comment listing the specifications documents used in the design of the driver's SCSI operation (at Pat LaVarre's request). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index b6d920f349e..6f887478b14 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -114,6 +114,14 @@ * setting are not allowed when the medium is loaded. * * This gadget driver is heavily based on "Gadget Zero" by David Brownell. + * The driver's SCSI command interface was based on the "Information + * technology - Small Computer System Interface - 2" document from + * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at + * . The single exception + * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the + * "Universal Serial Bus Mass Storage Class UFI Command Specification" + * document, Revision 1.0, December 14, 1998, available at + * . */ @@ -340,11 +348,9 @@ MODULE_LICENSE("Dual BSD/GPL"); #define MAX_LUNS 8 - /* Arggh! There should be a module_param_array_named macro! */ -static char *file[MAX_LUNS]; -static int ro[MAX_LUNS]; - static struct { + char *file[MAX_LUNS]; + int ro[MAX_LUNS]; int num_filenames; int num_ros; unsigned int nluns; @@ -376,10 +382,11 @@ static struct { }; -module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO); +module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, + S_IRUGO); MODULE_PARM_DESC(file, "names of backing files or devices"); -module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO); +module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); MODULE_PARM_DESC(ro, "true to force read-only"); module_param_named(luns, mod_data.nluns, uint, S_IRUGO); @@ -3868,7 +3875,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; - curlun->ro = ro[i]; + curlun->ro = mod_data.ro[i]; curlun->dev.parent = &gadget->dev; curlun->dev.driver = &fsg_driver.driver; dev_set_drvdata(&curlun->dev, fsg); @@ -3885,8 +3892,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) kref_get(&fsg->ref); } - if (file[i] && *file[i]) { - if ((rc = open_backing_file(curlun, file[i])) != 0) + if (mod_data.file[i] && *mod_data.file[i]) { + if ((rc = open_backing_file(curlun, + mod_data.file[i])) != 0) goto out; } else if (!mod_data.removable) { ERROR(fsg, "no file given for LUN%d\n", i); -- cgit v1.2.3 From 7d3fe085f9cdd3d3eea0154ea02e2f6b4a8f3974 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Wed, 29 Mar 2006 16:33:49 -0800 Subject: [PATCH] USB: wacom tablet driver update This patch adds support for DTF 521, Intuos3 12x12, and 12x19; fixes minor data report bugs. Signed-off-by: Ping Cheng Acked-by: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/wacom.c | 136 +++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 49 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index d3e15df9e81..cf84c6096f2 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -9,7 +9,7 @@ * Copyright (c) 2000 Daniel Egger * Copyright (c) 2001 Frederic Lepied * Copyright (c) 2004 Panagiotis Issaris - * Copyright (c) 2002-2005 Ping Cheng + * Copyright (c) 2002-2006 Ping Cheng * * ChangeLog: * v0.1 (vp) - Initial release @@ -56,6 +56,8 @@ * - Merged wacom_intuos3_irq into wacom_intuos_irq * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. * - Report Device IDs + * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 + * - Minor data report fix */ /* @@ -78,7 +80,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.44" +#define DRIVER_VERSION "v1.45" #define DRIVER_AUTHOR "Vojtech Pavlik " #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" #define DRIVER_LICENSE "GPL" @@ -99,6 +101,8 @@ enum { PL, INTUOS, INTUOS3, + INTUOS312, + INTUOS319, CINTIQ, MAX_TYPE }; @@ -127,7 +131,19 @@ struct wacom { char phys[32]; }; +#define USB_REQ_GET_REPORT 0x01 #define USB_REQ_SET_REPORT 0x09 + +static int usb_get_report(struct usb_interface *intf, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(interface_to_usbdev(intf), + usb_rcvctrlpipe(interface_to_usbdev(intf), 0), + USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, + buf, size, 100); +} + static int usb_set_report(struct usb_interface *intf, unsigned char type, unsigned char id, void *buf, int size) { @@ -206,7 +222,8 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) wacom->tool[1] = BTN_TOOL_PEN; id = STYLUS_DEVICE_ID; } - input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */ + input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ + input_report_abs(dev, ABS_MISC, id); /* report tool id */ input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); input_report_abs(dev, ABS_PRESSURE, pressure); @@ -239,7 +256,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; - int retval; + int retval, id; switch (urb->status) { case 0: @@ -263,12 +280,15 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) input_regs(dev, regs); if (data[1] & 0x04) { - input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0); + input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); input_report_key(dev, BTN_TOUCH, data[1] & 0x08); + id = ERASER_DEVICE_ID; } else { - input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0); + input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); input_report_key(dev, BTN_TOUCH, data[1] & 0x01); + id = STYLUS_DEVICE_ID; } + input_report_abs(dev, ABS_MISC, id); /* report tool id */ input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); @@ -312,7 +332,8 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) } input_regs(dev, regs); - input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID); + input_report_key(dev, BTN_TOOL_PEN, 1); + input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); @@ -350,6 +371,8 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) goto exit; } + if (data[0] == 99) return; /* for Volito tablets */ + if (data[0] != 2) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); goto exit; @@ -374,10 +397,10 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) case 2: /* Mouse with wheel */ input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); if (wacom->features->type == WACOM_G4) { - rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); - input_report_rel(dev, REL_WHEEL, rw); + rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); + input_report_rel(dev, REL_WHEEL, -rw); } else - input_report_rel(dev, REL_WHEEL, (signed char) data[6]); + input_report_rel(dev, REL_WHEEL, -(signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ @@ -406,39 +429,27 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) } } - input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0); + if (data[1] & 0x10) + input_report_abs(dev, ABS_MISC, id); /* report tool id */ + else + input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ + input_report_key(dev, wacom->tool[0], data[1] & 0x10); input_sync(dev); /* send pad data */ if (wacom->features->type == WACOM_G4) { - /* fist time sending pad data */ - if (wacom->tool[1] != BTN_TOOL_FINGER) { - wacom->id[1] = 0; - wacom->serial[1] = (data[7] & 0x38) >> 2; - } - if (data[7] & 0xf8) { + if ((wacom->serial[1] & 0xc0) != (data[7] & 0xf8)) { + wacom->id[1] = 1; + wacom->serial[1] = (data[7] & 0xf8); input_report_key(dev, BTN_0, (data[7] & 0x40)); input_report_key(dev, BTN_4, (data[7] & 0x80)); - if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e)) - /* alter REL_WHEEL value so X apps can get it */ - wacom->serial[1] += (wacom->serial[1] & 0x01) ? -1 : 1; - else - wacom->serial[1] = (data[7] & 0x38 ) >> 2; - - /* don't alter the value when there is no wheel event */ - if (wacom->serial[1] == 1) - wacom->serial[1] = 0; - rw = wacom->serial[1]; - rw = (rw & 0x08) ? -(rw & 0x07) : (rw & 0x07); + rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); input_report_rel(dev, REL_WHEEL, rw); - wacom->tool[1] = BTN_TOOL_FINGER; - wacom->id[1] = data[7] & 0xf8; - input_report_key(dev, wacom->tool[1], 0xf0); + input_report_key(dev, BTN_TOOL_FINGER, 0xf0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } else if (wacom->id[1]) { wacom->id[1] = 0; - wacom->serial[1] = 0; - input_report_key(dev, wacom->tool[1], 0); + input_report_key(dev, BTN_TOOL_FINGER, 0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } input_sync(dev); @@ -516,21 +527,31 @@ static int wacom_intuos_inout(struct urb *urb) default: /* Unknown tool */ wacom->tool[idx] = BTN_TOOL_PEN; } - input_report_key(dev, wacom->tool[idx], wacom->id[idx]); - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); + if(!((wacom->tool[idx] == BTN_TOOL_LENS) && + ((wacom->features->type == INTUOS312) + || (wacom->features->type == INTUOS319)))) { + input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ + input_report_key(dev, wacom->tool[idx], 1); + input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); + input_sync(dev); + } return 1; } /* Exit report */ if ((data[1] & 0xfe) == 0x80) { input_report_key(dev, wacom->tool[idx], 0); + input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); return 1; } - return 0; + if((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS312) + || (wacom->features->type == INTUOS319))) + return 1; + else + return 0; } static void wacom_intuos_general(struct urb *urb) @@ -600,10 +621,9 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) /* pad packets. Works as a second tool and is always in prox */ if (data[0] == 12) { /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) { + if (wacom->tool[1] != BTN_TOOL_FINGER) wacom->tool[1] = BTN_TOOL_FINGER; - input_report_key(dev, wacom->tool[1], 1); - } + input_report_key(dev, BTN_0, (data[5] & 0x01)); input_report_key(dev, BTN_1, (data[5] & 0x02)); input_report_key(dev, BTN_2, (data[5] & 0x04)); @@ -614,6 +634,11 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) input_report_key(dev, BTN_7, (data[6] & 0x08)); input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); + + if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2]) + input_report_key(dev, wacom->tool[1], 1); + else + input_report_key(dev, wacom->tool[1], 0); input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); input_sync(dev); goto exit; @@ -676,8 +701,8 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) input_report_key(dev, BTN_LEFT, data[8] & 0x04); input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); input_report_key(dev, BTN_RIGHT, data[8] & 0x10); - input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1) - - (data[8] & 0x01)); + input_report_rel(dev, REL_WHEEL, (data[8] & 0x01) + - ((data[8] & 0x02) >> 1)); /* I3 2D mouse side buttons */ if (wacom->features->type == INTUOS3) { @@ -695,7 +720,8 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) } } - input_report_key(dev, wacom->tool[idx], wacom->id[idx]); + input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ + input_report_key(dev, wacom->tool[idx], 1); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); @@ -733,7 +759,8 @@ static struct wacom_features wacom_features[] = { { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq }, { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, - { "Wacom PL710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, + { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq }, + { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq }, { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq }, { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, @@ -744,6 +771,8 @@ static struct wacom_features wacom_features[] = { { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, + { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS312, wacom_intuos_irq }, + { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS319, wacom_intuos_irq }, { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq }, { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, @@ -779,6 +808,7 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC3) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, @@ -788,6 +818,8 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, @@ -820,7 +852,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct input_dev *input_dev; - char rep_data[2] = {0x02, 0x02}; + char rep_data[2], limit = 0; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); input_dev = input_allocate_device(); @@ -857,6 +889,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); + input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); switch (wacom->features->type) { case WACOM_G4: @@ -875,6 +908,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i break; case INTUOS3: + case INTUOS312: + case INTUOS319: case CINTIQ: input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); @@ -916,10 +951,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_register_device(wacom->dev); - /* ask the tablet to report tablet data */ - usb_set_report(intf, 3, 2, rep_data, 2); - /* repeat once (not sure why the first call often fails) */ - usb_set_report(intf, 3, 2, rep_data, 2); + /* Ask the tablet to report tablet data. Repeat until it succeeds */ + do { + rep_data[0] = 2; + rep_data[1] = 2; + usb_set_report(intf, 3, 2, rep_data, 2); + usb_get_report(intf, 3, 2, rep_data, 2); + } while (rep_data[1] != 2 && limit++ < 5); usb_set_intfdata(intf, wacom); return 0; -- cgit v1.2.3 From 999a6a6a2a24cf2e9fafc9b47ee263835f59b4a1 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Wed, 29 Mar 2006 16:34:16 -0800 Subject: [PATCH] USB: add new wacom devices to usb hid-core list This patch adds support for DTF 521, Intuos3 12x12 and 12x19 Signed-off-by: Ping Cheng Acked-by: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 1d979d6e0c8..f2225d1ddb0 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1657,9 +1657,12 @@ static const struct hid_blacklist { { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 4, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, -- cgit v1.2.3 From 016534cffc5847e2a75b25d10f8c52edec6c8cb7 Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Thu, 30 Mar 2006 09:59:22 +0300 Subject: [PATCH] USB: pegasus driver bugfix Attached is a patch that fixes nasty bug, which i am afraid was there for a long time. It was spotted by Andre Draszik . From: Petko Manolov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/pegasus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 5b667568456..2deb4c01539 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -262,7 +262,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, - &tmp, 1, ctrl_callback, pegasus); + tmp, 1, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); -- cgit v1.2.3 From 87ed0aeba8d59fe5d68df8d10ba469d63b254914 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 4 Apr 2006 09:56:04 +0200 Subject: [PATCH] USB: drivers/usb/core/: remove unused exports This patch removes the following unused EXPORT_SYMBOL's: - hub.c: usb_set_device_state - usb.c: usb_alloc_dev - usb.c: usb_disconnect Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 1 - drivers/usb/core/usb.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8e65f7a237e..3c76f7e17c0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1022,7 +1022,6 @@ void usb_set_device_state(struct usb_device *udev, recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); } -EXPORT_SYMBOL(usb_set_device_state); #ifdef CONFIG_PM diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index d7352aa73b5..b7fdc1cd134 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1194,7 +1194,6 @@ EXPORT_SYMBOL(usb_disabled); EXPORT_SYMBOL_GPL(usb_get_intf); EXPORT_SYMBOL_GPL(usb_put_intf); -EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_put_dev); EXPORT_SYMBOL(usb_get_dev); EXPORT_SYMBOL(usb_hub_tt_clear_buffer); @@ -1208,7 +1207,6 @@ EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_altnum_to_altsetting); EXPORT_SYMBOL(usb_reset_device); -EXPORT_SYMBOL(usb_disconnect); EXPORT_SYMBOL(__usb_get_extra_descriptor); -- cgit v1.2.3 From 2a99b50719d3bff0a090fa8daf56d519c338296c Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Sun, 2 Apr 2006 18:43:53 +0200 Subject: [PATCH] USB: UEAGLE : cosmetic - improve debug trace in order to make easy to solve user problems. - indent some code - increase version number Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 830d2c98267..8ec9e031e0d 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -68,7 +68,7 @@ #include "usbatm.h" -#define EAGLEUSBVERSION "ueagle 1.2" +#define EAGLEUSBVERSION "ueagle 1.3" /* @@ -314,6 +314,10 @@ struct cmv { ((d) & 0xff) << 16 | \ ((a) & 0xff) << 8 | \ ((b) & 0xff)) +#define GETSA1(a) ((a >> 8) & 0xff) +#define GETSA2(a) (a & 0xff) +#define GETSA3(a) ((a >> 24) & 0xff) +#define GETSA4(a) ((a >> 16) & 0xff) #define SA_CNTL MAKESA('C', 'N', 'T', 'L') #define SA_DIAG MAKESA('D', 'I', 'A', 'G') @@ -728,11 +732,12 @@ bad2: uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); return; bad1: - uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); + uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); } static inline void wake_up_cmv_ack(struct uea_softc *sc) { + BUG_ON(sc->cmv_ack); sc->cmv_ack = 1; wake_up(&sc->cmv_ack_wait); } @@ -743,6 +748,9 @@ static inline int wait_cmv_ack(struct uea_softc *sc) sc->cmv_ack, ACK_TIMEOUT); sc->cmv_ack = 0; + uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", + jiffies_to_msecs(ret)); + if (ret < 0) return ret; @@ -791,6 +799,12 @@ static int uea_cmv(struct uea_softc *sc, struct cmv cmv; int ret; + uea_enters(INS_TO_USBDEV(sc)); + uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " + "offset : 0x%04x, data : 0x%08x\n", + FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), + GETSA1(address), GETSA2(address), GETSA3(address), + GETSA4(address), offset, data); /* we send a request, but we expect a reply */ sc->cmv_function = function | 0x2; sc->cmv_idx++; @@ -808,7 +822,9 @@ static int uea_cmv(struct uea_softc *sc, ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); if (ret < 0) return ret; - return wait_cmv_ack(sc); + ret = wait_cmv_ack(sc); + uea_leaves(INS_TO_USBDEV(sc)); + return ret; } static inline int uea_read_cmv(struct uea_softc *sc, @@ -922,7 +938,7 @@ static int uea_stat(struct uea_softc *sc) * we check the status again in order to detect the failure earlier */ if (sc->stats.phy.flags) { - uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", + uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", sc->stats.phy.flags); return 0; } @@ -1101,6 +1117,8 @@ static int uea_start_reset(struct uea_softc *sc) if (ret < 0) return ret; + uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); + /* Enter in R-IDLE (cmv) until instructed otherwise */ ret = uea_write_cmv(sc, SA_CNTL, 0, 1); if (ret < 0) @@ -1121,6 +1139,7 @@ static int uea_start_reset(struct uea_softc *sc) } /* Enter in R-ACT-REQ */ ret = uea_write_cmv(sc, SA_CNTL, 0, 2); + uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); out: release_firmware(cmvs_fw); sc->reset = 0; @@ -1235,6 +1254,7 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { wake_up_cmv_ack(sc); + uea_leaves(INS_TO_USBDEV(sc)); return; } @@ -1249,6 +1269,7 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) sc->data = sc->data << 16 | sc->data >> 16; wake_up_cmv_ack(sc); + uea_leaves(INS_TO_USBDEV(sc)); return; bad2: @@ -1256,12 +1277,14 @@ bad2: "Function : %d, Subfunction : %d\n", FUNCTION_TYPE(cmv->bFunction), FUNCTION_SUBTYPE(cmv->bFunction)); + uea_leaves(INS_TO_USBDEV(sc)); return; bad1: uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " "wPreamble %d, bDirection %d\n", le16_to_cpu(cmv->wPreamble), cmv->bDirection); + uea_leaves(INS_TO_USBDEV(sc)); } /* @@ -1508,7 +1531,7 @@ static ssize_t read_##name(struct device *dev, \ int ret = -ENODEV; \ struct uea_softc *sc; \ \ - mutex_lock(&uea_mutex); \ + mutex_lock(&uea_mutex); \ sc = dev_to_uea(dev); \ if (!sc) \ goto out; \ @@ -1516,7 +1539,7 @@ static ssize_t read_##name(struct device *dev, \ if (reset) \ sc->stats.phy.name = 0; \ out: \ - mutex_unlock(&uea_mutex); \ + mutex_unlock(&uea_mutex); \ return ret; \ } \ \ -- cgit v1.2.3 From 22fcceb546227a4c557d1844c1796c13a5086c9f Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Sun, 2 Apr 2006 18:44:20 +0200 Subject: [PATCH] USB: UEAGLE : support geode - increase ack timeout for slow system (geode 233MHz where HZ=100) - reset the cmv ack flag when rebooting Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 8ec9e031e0d..602be5488c9 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -243,7 +243,7 @@ enum { #define BULK_TIMEOUT 300 #define CTRL_TIMEOUT 1000 -#define ACK_TIMEOUT msecs_to_jiffies(1500) +#define ACK_TIMEOUT msecs_to_jiffies(3000) #define UEA_INTR_IFACE_NO 0 #define UEA_US_IFACE_NO 1 @@ -1079,7 +1079,13 @@ static int uea_start_reset(struct uea_softc *sc) uea_enters(INS_TO_USBDEV(sc)); uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); + /* mask interrupt */ sc->booting = 1; + /* We need to set this here because, a ack timeout could have occured, + * but before we start the reboot, the ack occurs and set this to 1. + * So we will failed to wait Ready CMV. + */ + sc->cmv_ack = 0; UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); /* reset statistics */ @@ -1105,6 +1111,7 @@ static int uea_start_reset(struct uea_softc *sc) msleep(1000); sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); + /* demask interrupt */ sc->booting = 0; /* start loading DSP */ -- cgit v1.2.3 From 584958c3d2985396bdb6f96ae632971b43f6f984 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Sun, 2 Apr 2006 18:44:48 +0200 Subject: [PATCH] USB: UEAGLE : null pointer dereference fix this patch fix potential null pointer dereference. Found by the Coverity checker. Signed-off-by: Duncan Sands Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 602be5488c9..047fb4ea2fa 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1673,7 +1673,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); if (!sc) { - uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); + uea_err(usb, "uea_init: not enough memory !\n"); return -ENOMEM; } -- cgit v1.2.3 From 4d45e21867bee51e3bb42e95bc2929231d7c8192 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Sun, 2 Apr 2006 18:45:46 +0200 Subject: [PATCH] USB: UEAGLE : memory leack fix this patch fix leak of memory allocated to intr if allocation of sc->urb_int fails. Found by the Coverity checker. Signed-off-by: Duncan Sands Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 047fb4ea2fa..b38990adf1c 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1376,7 +1376,7 @@ static int uea_boot(struct uea_softc *sc) if (ret < 0) { uea_err(INS_TO_USBDEV(sc), "urb submition failed with error %d\n", ret); - goto err1; + goto err; } sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); @@ -1390,10 +1390,10 @@ static int uea_boot(struct uea_softc *sc) err2: usb_kill_urb(sc->urb_int); -err1: - kfree(intr); err: usb_free_urb(sc->urb_int); + sc->urb_int = NULL; + kfree(intr); uea_leaves(INS_TO_USBDEV(sc)); return -ENOMEM; } -- cgit v1.2.3 From 89ccbdc91bc5a433fa256c0136fbe181d7c5d474 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:18:09 -0800 Subject: [PATCH] USB: otg hub support is optional USB OTG devices are not required to support external hubs. This adds a configuration option to disable that support. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 7 +++++++ drivers/usb/core/hub.c | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index ff03184da40..a08787e253a 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -99,4 +99,11 @@ config USB_OTG_WHITELIST normal Linux-USB hosts do (other than the warning), and is convenient for many stages of product development. +config USB_OTG_BLACKLIST_HUB + bool "Disable external hubs" + depends on USB_OTG + help + If you say Y here, then Linux will refuse to enumerate + external hubs. OTG hosts are allowed to reduce hardware + and software costs by not supporting external hubs. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3c76f7e17c0..0c87f73f293 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -836,6 +836,13 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); +#ifdef CONFIG_USB_OTG_BLACKLIST_HUB + if (hdev->parent) { + dev_warn(&intf->dev, "ignoring external hub\n"); + return -ENODEV; + } +#endif + /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((desc->desc.bInterfaceSubClass != 0) && -- cgit v1.2.3 From 42795410c325108d59d0b1e750657197a7374c04 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:18:34 -0800 Subject: [PATCH] USB: fix gadget_is_musbhdrc() I submitted the wrong version of the patch teaching about the driver for Mentor's Highspeed Dual Role Controller (HDRC), whoops! This uses the right name for that driver. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/gadget_chips.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index c4081407171..aa80f091072 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -100,9 +100,9 @@ #define gadget_is_musbhsfc(g) 0 #endif -/* Mentor high speed "dual role" controller, peripheral mode */ -#ifdef CONFIG_USB_GADGET_MUSBHDRC -#define gadget_is_musbhdrc(g) !strcmp("musbhdrc_udc", (g)->name) +/* Mentor high speed "dual role" controller, in peripheral role */ +#ifdef CONFIG_USB_GADGET_MUSB_HDRC +#define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) #else #define gadget_is_musbhdrc(g) 0 #endif -- cgit v1.2.3 From 68dcc688d1f042842a8fb523e4a584b3211181d1 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:18:53 -0800 Subject: [PATCH] USB: net2280 short rx status fix Some patch broke short-OUT packet handling for net2280, making it report illegal status values. This updates the status code so it's correct. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 7682c07035b..6a4b93ad108 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2241,7 +2241,8 @@ static void handle_ep_small (struct net2280_ep *ep) if (likely (req)) { req->td->dmacount = 0; t = readl (&ep->regs->ep_avail); - dma_done (ep, req, count, t); + dma_done (ep, req, count, + (ep->out_overflow || t) ? -EOVERFLOW : 0); } /* also flush to prevent erratum 0106 trouble */ -- cgit v1.2.3 From 51400f1d6ef7ca871b584117527f7c6b12bf182b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:19:08 -0800 Subject: [PATCH] USB: rndis_host whitespace/comment updates This adds a "avoid proprietary protocols" warnoff, identifying several of the known deficiencies in Microsoft's excuse-for-specification, and fixes some whitespace bugs. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/rndis_host.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index 49991ac1bf3..94ddfe16fdd 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c @@ -39,6 +39,20 @@ * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of * course ACM was intended for modems, not Ethernet links! USB's standard * for Ethernet links is "CDC Ethernet", which is significantly simpler. + * + * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues + * include: + * - Power management in particular relies on information that's scattered + * through other documentation, and which is incomplete or incorrect even + * there. + * - There are various undocumented protocol requirements, such as the + * need to send unused garbage in control-OUT messages. + * - In some cases, MS-Windows will emit undocumented requests; this + * matters more to peripheral implementations than host ones. + * + * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in + * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and + * currently rare) "Ethernet Emulation Model" (EEM). */ /* @@ -72,17 +86,17 @@ struct rndis_msg_hdr { */ #define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */ #define RNDIS_MSG_INIT ccpu2(0x00000002) -#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_HALT ccpu2(0x00000003) #define RNDIS_MSG_QUERY ccpu2(0x00000004) -#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_SET ccpu2(0x00000005) -#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_RESET ccpu2(0x00000006) -#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) #define RNDIS_MSG_INDICATE ccpu2(0x00000007) #define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008) -#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) /* codes for "status" field of completion messages */ #define RNDIS_STATUS_SUCCESS ccpu2(0x00000000) @@ -596,13 +610,13 @@ static struct usb_driver rndis_driver = { static int __init rndis_init(void) { - return usb_register(&rndis_driver); + return usb_register(&rndis_driver); } module_init(rndis_init); static void __exit rndis_exit(void) { - usb_deregister(&rndis_driver); + usb_deregister(&rndis_driver); } module_exit(rndis_exit); -- cgit v1.2.3 From 984163338a24198863116ccf3e7762fd1fc3c663 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:19:23 -0800 Subject: [PATCH] USB: gadgetfs highspeed bugfix This catches up to a change in the Kconfig support for highspeed modes; the change predated 2.6.10, and anyone using gadgetfs on a highspeed device would see the kernel wrongly reject the alternate descriptors. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/inode.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3f618ce6998..42b457030b0 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -810,7 +810,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (value == 0) data->state = STATE_EP_ENABLED; break; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH: /* fails if caller didn't provide that descriptor... */ value = usb_ep_enable (ep, &data->hs_desc); @@ -982,7 +982,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* assume that was SET_CONFIGURATION */ if (dev->current_config) { unsigned power; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED if (dev->gadget->speed == USB_SPEED_HIGH) power = dev->hs_config->bMaxPower; else @@ -1262,7 +1262,7 @@ static struct file_operations ep0_io_operations = { * Unrecognized ep0 requests may be handled in user space. */ -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) { struct usb_qualifier_descriptor qual; @@ -1291,7 +1291,7 @@ static int config_buf (struct dev_data *dev, u8 type, unsigned index) { int len; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED int hs; #endif @@ -1299,7 +1299,7 @@ config_buf (struct dev_data *dev, u8 type, unsigned index) if (index > 0) return -EINVAL; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED hs = (dev->gadget->speed == USB_SPEED_HIGH); if (type == USB_DT_OTHER_SPEED_CONFIG) hs = !hs; @@ -1335,12 +1335,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->state = STATE_CONNECTED; dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { ERROR (dev, "no high speed config??\n"); return -EINVAL; } -#endif /* HIGHSPEED */ +#endif /* CONFIG_USB_GADGET_DUALSPEED */ INFO (dev, "connected\n"); event = next_event (dev, GADGETFS_CONNECT); @@ -1352,11 +1352,11 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) /* ... down_trylock (&data->lock) ... */ if (data->state != STATE_EP_DEFER_ENABLE) continue; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED if (gadget->speed == USB_SPEED_HIGH) value = usb_ep_enable (ep, &data->hs_desc); else -#endif /* HIGHSPEED */ +#endif /* CONFIG_USB_GADGET_DUALSPEED */ value = usb_ep_enable (ep, &data->desc); if (value) { ERROR (dev, "deferred %s enable --> %d\n", @@ -1391,7 +1391,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value = min (w_length, (u16) sizeof *dev->dev); req->buf = dev->dev; break; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER: if (!dev->hs_config) break; @@ -1428,7 +1428,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) // user mode expected to disable endpoints } else { u8 config, power; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED if (gadget->speed == USB_SPEED_HIGH) { config = dev->hs_config->bConfigurationValue; power = dev->hs_config->bMaxPower; @@ -1728,7 +1728,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) } static struct usb_gadget_driver gadgetfs_driver = { -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED .speed = USB_SPEED_HIGH, #else .speed = USB_SPEED_FULL, -- cgit v1.2.3 From 35fcca442aca1a8d927b697e7e15d3f655958bd7 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:19:43 -0800 Subject: [PATCH] USB: gadget zero poisons OUT buffers Fill OUT buffers with 0x55 before RX, so that controller driver bugs that mangle data can be more readily detected during testing. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/zero.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 51424f66a76..68e3d8f5da8 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -572,9 +572,10 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) switch (status) { case 0: /* normal completion? */ - if (ep == dev->out_ep) + if (ep == dev->out_ep) { check_read_data (dev, ep, req); - else + memset (req->buf, 0x55, req->length); + } else reinit_write_data (dev, ep, req); break; @@ -626,6 +627,8 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) if (strcmp (ep->name, EP_IN_NAME) == 0) reinit_write_data (ep->driver_data, ep, req); + else + memset (req->buf, 0x55, req->length); status = usb_ep_queue (ep, req, gfp_flags); if (status) { -- cgit v1.2.3 From 68ba61b89c10b3412c7ee05cd649303ba5a588d1 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 20:26:21 -0800 Subject: [PATCH] USB: at91 usb driver supend/resume fixes AT91: the two USB drivers (OHCI, UDC) got out of sync with various usbcore and driver model PM updates; fix. Also minor fixes to ohci: whitespace/style, MODULE_ALIAS so coldplug works using /sys/.../modalias, and turn off _both_ clocks during suspend. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/at91_udc.c | 4 ++-- drivers/usb/host/ohci-at91.c | 35 +++++++++++++++++------------------ 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 865858cfd1c..b8d0b7825bf 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1709,7 +1709,7 @@ static int __devexit at91udc_remove(struct platform_device *dev) } #ifdef CONFIG_PM -static int at91udc_suspend(struct platform_device *dev, u32 state, u32 level) +static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg) { struct at91_udc *udc = platform_get_drvdata(dev); @@ -1731,7 +1731,7 @@ static int at91udc_suspend(struct platform_device *dev, u32 state, u32 level) return 0; } -static int at91udc_resume(struct platform_device *dev, u32 level) +static int at91udc_resume(struct platform_device *dev) { struct at91_udc *udc = platform_get_drvdata(dev); diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 980030d684d..6b7350b5241 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -20,7 +20,7 @@ #include #ifndef CONFIG_ARCH_AT91RM9200 -#error "This file is AT91RM9200 bus glue. CONFIG_ARCH_AT91RM9200 must be defined." +#error "CONFIG_ARCH_AT91RM9200 must be defined." #endif /* interface and function clocks */ @@ -84,8 +84,6 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. - * - * Store this function in the HCD's struct pci_driver as probe(). */ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) { @@ -148,7 +146,6 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * } -/* may be called without controller electrically present */ /* may be called with controller, bus, and devices active */ /** @@ -166,11 +163,11 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde usb_remove_hcd(hcd); at91_stop_hc(pdev); iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - clk_put(fclk); - clk_put(iclk); - fclk = iclk = NULL; + clk_put(fclk); + clk_put(iclk); + fclk = iclk = NULL; dev_set_drvdata(&pdev->dev, NULL); return 0; @@ -235,8 +232,8 @@ static const struct hc_driver ohci_at91_hc_driver = { .hub_control = ohci_hub_control, #ifdef CONFIG_PM - .hub_suspend = ohci_hub_suspend, - .hub_resume = ohci_hub_resume, + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, #endif .start_port_reset = ohci_start_port_reset, }; @@ -254,21 +251,21 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *dev) } #ifdef CONFIG_PM -static int ohci_hcd_at91_drv_suspend(struct platform_device *dev, u32 state, u32 level) -{ - printk("%s(%s:%d): not implemented yet\n", - __func__, __FILE__, __LINE__); +/* REVISIT suspend/resume look "too" simple here */ + +static int +ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) +{ clk_disable(fclk); + clk_disable(iclk); return 0; } -static int ohci_hcd_at91_drv_resume(struct platform_device *dev, u32 state) +static int ohci_hcd_at91_drv_resume(struct platform_device *dev) { - printk("%s(%s:%d): not implemented yet\n", - __func__, __FILE__, __LINE__); - + clk_enable(iclk); clk_enable(fclk); return 0; @@ -278,6 +275,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev, u32 state) #define ohci_hcd_at91_drv_resume NULL #endif +MODULE_ALIAS("at91rm9200-ohci"); + static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, .remove = ohci_hcd_at91_drv_remove, -- cgit v1.2.3 From 8b5249019352eecd49fb00004d583904e891e7b1 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:20:15 -0800 Subject: [PATCH] USB: usbtest: scatterlist OUT data pattern testing Previously, scatterlist tests didn't write patterned data. Given how many corner cases are addresed by them, this was a significant gap in Linux-USB test coverage. Moreover, when peripherals checked for correct data patterns, false error reports would drown out the true ones. This adds the pattern on the way OUT from the host, so scatterlist tests can now be used to uncover bugs like host TX or peripheral RX paths failing for back-to-back short packets. It's easy enough to get an error there with at least one of the {DMA,PIO}{RX,TX} code paths, or run into hardware races that need to be defended against. Note this patch doesn't add checking for correct data patterns on the way IN from peripherals, just a FIXME for later. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 9d59b901841..ccc5e8238bd 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -381,6 +381,7 @@ alloc_sglist (int nents, int max, int vary) for (i = 0; i < nents; i++) { char *buf; + unsigned j; buf = kzalloc (size, SLAB_KERNEL); if (!buf) { @@ -391,6 +392,16 @@ alloc_sglist (int nents, int max, int vary) /* kmalloc pages are always physically contiguous! */ sg_init_one(&sg[i], buf, size); + switch (pattern) { + case 0: + /* already zeroed */ + break; + case 1: + for (j = 0; j < size; j++) + *buf++ = (u8) (j % 63); + break; + } + if (vary) { size += vary; size %= max; @@ -425,6 +436,8 @@ static int perform_sglist ( usb_sg_wait (req); retval = req->status; + /* FIXME check resulting data pattern */ + /* FIXME if endpoint halted, clear halt (and log) */ } -- cgit v1.2.3 From e1394b49ee70bd8686acaf969e4d61b57da1c263 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 2 Apr 2006 10:20:43 -0800 Subject: [PATCH] USB: g_ether, highspeed conformance fix Be sure to record the peripheral's ep0 maxpacket size BEFORE using that to initialize the (high speed) device qualifier; that helps a lot with USBCV testing. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ether.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index c3d8e5c5bf2..9c4422ac9de 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2338,6 +2338,9 @@ autoconf_fail: hs_subset_descriptors(); } + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; + usb_gadget_set_selfpowered (gadget); + /* For now RNDIS is always a second config */ if (rndis) device_desc.bNumConfigurations = 2; @@ -2361,9 +2364,6 @@ autoconf_fail: #endif #endif /* DUALSPEED */ - device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; - usb_gadget_set_selfpowered (gadget); - if (gadget->is_otg) { otg_descriptor.bmAttributes |= USB_OTG_HNP, eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; -- cgit v1.2.3 From 9fc4831cc3e063019079581ff5062f9790d9b0c7 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Sun, 2 Apr 2006 10:21:26 -0800 Subject: [PATCH] USB: linux/usb/net2280.h common definitions Move common definitions for NET2280 to , so that I can use them in prism54usb (it is not merged yet, but I plan to do it soon). Signed-off-by: Pete Zaitcev Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.h | 417 +------------------------------------------ 1 file changed, 1 insertion(+), 416 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index e195abec8d7..957d6df3401 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -22,422 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/*-------------------------------------------------------------------------*/ - -/* NET2280 MEMORY MAPPED REGISTERS - * - * The register layout came from the chip documentation, and the bit - * number definitions were extracted from chip specification. - * - * Use the shift operator ('<<') to build bit masks, with readl/writel - * to access the registers through PCI. - */ - -/* main registers, BAR0 + 0x0000 */ -struct net2280_regs { - // offset 0x0000 - u32 devinit; -#define LOCAL_CLOCK_FREQUENCY 8 -#define FORCE_PCI_RESET 7 -#define PCI_ID 6 -#define PCI_ENABLE 5 -#define FIFO_SOFT_RESET 4 -#define CFG_SOFT_RESET 3 -#define PCI_SOFT_RESET 2 -#define USB_SOFT_RESET 1 -#define M8051_RESET 0 - u32 eectl; -#define EEPROM_ADDRESS_WIDTH 23 -#define EEPROM_CHIP_SELECT_ACTIVE 22 -#define EEPROM_PRESENT 21 -#define EEPROM_VALID 20 -#define EEPROM_BUSY 19 -#define EEPROM_CHIP_SELECT_ENABLE 18 -#define EEPROM_BYTE_READ_START 17 -#define EEPROM_BYTE_WRITE_START 16 -#define EEPROM_READ_DATA 8 -#define EEPROM_WRITE_DATA 0 - u32 eeclkfreq; - u32 _unused0; - // offset 0x0010 - - u32 pciirqenb0; /* interrupt PCI master ... */ -#define SETUP_PACKET_INTERRUPT_ENABLE 7 -#define ENDPOINT_F_INTERRUPT_ENABLE 6 -#define ENDPOINT_E_INTERRUPT_ENABLE 5 -#define ENDPOINT_D_INTERRUPT_ENABLE 4 -#define ENDPOINT_C_INTERRUPT_ENABLE 3 -#define ENDPOINT_B_INTERRUPT_ENABLE 2 -#define ENDPOINT_A_INTERRUPT_ENABLE 1 -#define ENDPOINT_0_INTERRUPT_ENABLE 0 - u32 pciirqenb1; -#define PCI_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - u32 cpu_irqenb0; /* ... or onboard 8051 */ -#define SETUP_PACKET_INTERRUPT_ENABLE 7 -#define ENDPOINT_F_INTERRUPT_ENABLE 6 -#define ENDPOINT_E_INTERRUPT_ENABLE 5 -#define ENDPOINT_D_INTERRUPT_ENABLE 4 -#define ENDPOINT_C_INTERRUPT_ENABLE 3 -#define ENDPOINT_B_INTERRUPT_ENABLE 2 -#define ENDPOINT_A_INTERRUPT_ENABLE 1 -#define ENDPOINT_0_INTERRUPT_ENABLE 0 - u32 cpu_irqenb1; -#define CPU_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_INTA_INTERRUPT_ENABLE 24 -#define PCI_PME_INTERRUPT_ENABLE 23 -#define PCI_SERR_INTERRUPT_ENABLE 22 -#define PCI_PERR_INTERRUPT_ENABLE 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - - // offset 0x0020 - u32 _unused1; - u32 usbirqenb1; -#define USB_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_INTA_INTERRUPT_ENABLE 24 -#define PCI_PME_INTERRUPT_ENABLE 23 -#define PCI_SERR_INTERRUPT_ENABLE 22 -#define PCI_PERR_INTERRUPT_ENABLE 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - u32 irqstat0; -#define INTA_ASSERTED 12 -#define SETUP_PACKET_INTERRUPT 7 -#define ENDPOINT_F_INTERRUPT 6 -#define ENDPOINT_E_INTERRUPT 5 -#define ENDPOINT_D_INTERRUPT 4 -#define ENDPOINT_C_INTERRUPT 3 -#define ENDPOINT_B_INTERRUPT 2 -#define ENDPOINT_A_INTERRUPT 1 -#define ENDPOINT_0_INTERRUPT 0 - u32 irqstat1; -#define POWER_STATE_CHANGE_INTERRUPT 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT 26 -#define PCI_PARITY_ERROR_INTERRUPT 25 -#define PCI_INTA_INTERRUPT 24 -#define PCI_PME_INTERRUPT 23 -#define PCI_SERR_INTERRUPT 22 -#define PCI_PERR_INTERRUPT 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 -#define PCI_RETRY_ABORT_INTERRUPT 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 -#define SOF_DOWN_INTERRUPT 14 -#define GPIO_INTERRUPT 13 -#define DMA_D_INTERRUPT 12 -#define DMA_C_INTERRUPT 11 -#define DMA_B_INTERRUPT 10 -#define DMA_A_INTERRUPT 9 -#define EEPROM_DONE_INTERRUPT 8 -#define VBUS_INTERRUPT 7 -#define CONTROL_STATUS_INTERRUPT 6 -#define ROOT_PORT_RESET_INTERRUPT 4 -#define SUSPEND_REQUEST_INTERRUPT 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 -#define RESUME_INTERRUPT 1 -#define SOF_INTERRUPT 0 - // offset 0x0030 - u32 idxaddr; - u32 idxdata; - u32 fifoctl; -#define PCI_BASE2_RANGE 16 -#define IGNORE_FIFO_AVAILABILITY 3 -#define PCI_BASE2_SELECT 2 -#define FIFO_CONFIGURATION_SELECT 0 - u32 _unused2; - // offset 0x0040 - u32 memaddr; -#define START 28 -#define DIRECTION 27 -#define FIFO_DIAGNOSTIC_SELECT 24 -#define MEMORY_ADDRESS 0 - u32 memdata0; - u32 memdata1; - u32 _unused3; - // offset 0x0050 - u32 gpioctl; -#define GPIO3_LED_SELECT 12 -#define GPIO3_INTERRUPT_ENABLE 11 -#define GPIO2_INTERRUPT_ENABLE 10 -#define GPIO1_INTERRUPT_ENABLE 9 -#define GPIO0_INTERRUPT_ENABLE 8 -#define GPIO3_OUTPUT_ENABLE 7 -#define GPIO2_OUTPUT_ENABLE 6 -#define GPIO1_OUTPUT_ENABLE 5 -#define GPIO0_OUTPUT_ENABLE 4 -#define GPIO3_DATA 3 -#define GPIO2_DATA 2 -#define GPIO1_DATA 1 -#define GPIO0_DATA 0 - u32 gpiostat; -#define GPIO3_INTERRUPT 3 -#define GPIO2_INTERRUPT 2 -#define GPIO1_INTERRUPT 1 -#define GPIO0_INTERRUPT 0 -} __attribute__ ((packed)); - -/* usb control, BAR0 + 0x0080 */ -struct net2280_usb_regs { - // offset 0x0080 - u32 stdrsp; -#define STALL_UNSUPPORTED_REQUESTS 31 -#define SET_TEST_MODE 16 -#define GET_OTHER_SPEED_CONFIGURATION 15 -#define GET_DEVICE_QUALIFIER 14 -#define SET_ADDRESS 13 -#define ENDPOINT_SET_CLEAR_HALT 12 -#define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11 -#define GET_STRING_DESCRIPTOR_2 10 -#define GET_STRING_DESCRIPTOR_1 9 -#define GET_STRING_DESCRIPTOR_0 8 -#define GET_SET_INTERFACE 6 -#define GET_SET_CONFIGURATION 5 -#define GET_CONFIGURATION_DESCRIPTOR 4 -#define GET_DEVICE_DESCRIPTOR 3 -#define GET_ENDPOINT_STATUS 2 -#define GET_INTERFACE_STATUS 1 -#define GET_DEVICE_STATUS 0 - u32 prodvendid; -#define PRODUCT_ID 16 -#define VENDOR_ID 0 - u32 relnum; - u32 usbctl; -#define SERIAL_NUMBER_INDEX 16 -#define PRODUCT_ID_STRING_ENABLE 13 -#define VENDOR_ID_STRING_ENABLE 12 -#define USB_ROOT_PORT_WAKEUP_ENABLE 11 -#define VBUS_PIN 10 -#define TIMED_DISCONNECT 9 -#define SUSPEND_IMMEDIATELY 7 -#define SELF_POWERED_USB_DEVICE 6 -#define REMOTE_WAKEUP_SUPPORT 5 -#define PME_POLARITY 4 -#define USB_DETECT_ENABLE 3 -#define PME_WAKEUP_ENABLE 2 -#define DEVICE_REMOTE_WAKEUP_ENABLE 1 -#define SELF_POWERED_STATUS 0 - // offset 0x0090 - u32 usbstat; -#define HIGH_SPEED 7 -#define FULL_SPEED 6 -#define GENERATE_RESUME 5 -#define GENERATE_DEVICE_REMOTE_WAKEUP 4 - u32 xcvrdiag; -#define FORCE_HIGH_SPEED_MODE 31 -#define FORCE_FULL_SPEED_MODE 30 -#define USB_TEST_MODE 24 -#define LINE_STATE 16 -#define TRANSCEIVER_OPERATION_MODE 2 -#define TRANSCEIVER_SELECT 1 -#define TERMINATION_SELECT 0 - u32 setup0123; - u32 setup4567; - // offset 0x0090 - u32 _unused0; - u32 ouraddr; -#define FORCE_IMMEDIATE 7 -#define OUR_USB_ADDRESS 0 - u32 ourconfig; -} __attribute__ ((packed)); - -/* pci control, BAR0 + 0x0100 */ -struct net2280_pci_regs { - // offset 0x0100 - u32 pcimstctl; -#define PCI_ARBITER_PARK_SELECT 13 -#define PCI_MULTI LEVEL_ARBITER 12 -#define PCI_RETRY_ABORT_ENABLE 11 -#define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10 -#define DMA_READ_MULTIPLE_ENABLE 9 -#define DMA_READ_LINE_ENABLE 8 -#define PCI_MASTER_COMMAND_SELECT 6 -#define MEM_READ_OR_WRITE 0 -#define IO_READ_OR_WRITE 1 -#define CFG_READ_OR_WRITE 2 -#define PCI_MASTER_START 5 -#define PCI_MASTER_READ_WRITE 4 -#define PCI_MASTER_WRITE 0 -#define PCI_MASTER_READ 1 -#define PCI_MASTER_BYTE_WRITE_ENABLES 0 - u32 pcimstaddr; - u32 pcimstdata; - u32 pcimststat; -#define PCI_ARBITER_CLEAR 2 -#define PCI_EXTERNAL_ARBITER 1 -#define PCI_HOST_MODE 0 -} __attribute__ ((packed)); - -/* dma control, BAR0 + 0x0180 ... array of four structs like this, - * for channels 0..3. see also struct net2280_dma: descriptor - * that can be loaded into some of these registers. - */ -struct net2280_dma_regs { /* [11.7] */ - // offset 0x0180, 0x01a0, 0x01c0, 0x01e0, - u32 dmactl; -#define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 -#define DMA_CLEAR_COUNT_ENABLE 21 -#define DESCRIPTOR_POLLING_RATE 19 -#define POLL_CONTINUOUS 0 -#define POLL_1_USEC 1 -#define POLL_100_USEC 2 -#define POLL_1_MSEC 3 -#define DMA_VALID_BIT_POLLING_ENABLE 18 -#define DMA_VALID_BIT_ENABLE 17 -#define DMA_SCATTER_GATHER_ENABLE 16 -#define DMA_OUT_AUTO_START_ENABLE 4 -#define DMA_PREEMPT_ENABLE 3 -#define DMA_FIFO_VALIDATE 2 -#define DMA_ENABLE 1 -#define DMA_ADDRESS_HOLD 0 - u32 dmastat; -#define DMA_ABORT_DONE_INTERRUPT 27 -#define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 -#define DMA_TRANSACTION_DONE_INTERRUPT 24 -#define DMA_ABORT 1 -#define DMA_START 0 - u32 _unused0 [2]; - // offset 0x0190, 0x01b0, 0x01d0, 0x01f0, - u32 dmacount; -#define VALID_BIT 31 -#define DMA_DIRECTION 30 -#define DMA_DONE_INTERRUPT_ENABLE 29 -#define END_OF_CHAIN 28 -#define DMA_BYTE_COUNT_MASK ((1<<24)-1) -#define DMA_BYTE_COUNT 0 - u32 dmaaddr; - u32 dmadesc; - u32 _unused1; -} __attribute__ ((packed)); - -/* dedicated endpoint registers, BAR0 + 0x0200 */ - -struct net2280_dep_regs { /* [11.8] */ - // offset 0x0200, 0x0210, 0x220, 0x230, 0x240 - u32 dep_cfg; - // offset 0x0204, 0x0214, 0x224, 0x234, 0x244 - u32 dep_rsp; - u32 _unused [2]; -} __attribute__ ((packed)); - -/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs - * like this, for ep0 then the configurable endpoints A..F - * ep0 reserved for control; E and F have only 64 bytes of fifo - */ -struct net2280_ep_regs { /* [11.9] */ - // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 - u32 ep_cfg; -#define ENDPOINT_BYTE_COUNT 16 -#define ENDPOINT_ENABLE 10 -#define ENDPOINT_TYPE 8 -#define ENDPOINT_DIRECTION 7 -#define ENDPOINT_NUMBER 0 - u32 ep_rsp; -#define SET_NAK_OUT_PACKETS 15 -#define SET_EP_HIDE_STATUS_PHASE 14 -#define SET_EP_FORCE_CRC_ERROR 13 -#define SET_INTERRUPT_MODE 12 -#define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 -#define SET_NAK_OUT_PACKETS_MODE 10 -#define SET_ENDPOINT_TOGGLE 9 -#define SET_ENDPOINT_HALT 8 -#define CLEAR_NAK_OUT_PACKETS 7 -#define CLEAR_EP_HIDE_STATUS_PHASE 6 -#define CLEAR_EP_FORCE_CRC_ERROR 5 -#define CLEAR_INTERRUPT_MODE 4 -#define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 -#define CLEAR_NAK_OUT_PACKETS_MODE 2 -#define CLEAR_ENDPOINT_TOGGLE 1 -#define CLEAR_ENDPOINT_HALT 0 - u32 ep_irqenb; -#define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6 -#define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5 -#define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3 -#define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2 -#define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1 -#define DATA_IN_TOKEN_INTERRUPT_ENABLE 0 - u32 ep_stat; -#define FIFO_VALID_COUNT 24 -#define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22 -#define TIMEOUT 21 -#define USB_STALL_SENT 20 -#define USB_IN_NAK_SENT 19 -#define USB_IN_ACK_RCVD 18 -#define USB_OUT_PING_NAK_SENT 17 -#define USB_OUT_ACK_SENT 16 -#define FIFO_OVERFLOW 13 -#define FIFO_UNDERFLOW 12 -#define FIFO_FULL 11 -#define FIFO_EMPTY 10 -#define FIFO_FLUSH 9 -#define SHORT_PACKET_OUT_DONE_INTERRUPT 6 -#define SHORT_PACKET_TRANSFERRED_INTERRUPT 5 -#define NAK_OUT_PACKETS 4 -#define DATA_PACKET_RECEIVED_INTERRUPT 3 -#define DATA_PACKET_TRANSMITTED_INTERRUPT 2 -#define DATA_OUT_PING_TOKEN_INTERRUPT 1 -#define DATA_IN_TOKEN_INTERRUPT 0 - // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 - u32 ep_avail; - u32 ep_data; - u32 _unused0 [2]; -} __attribute__ ((packed)); +#include /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 48b1be6ac080c3bb5ad3e529d8816953507790ab Mon Sep 17 00:00:00 2001 From: David Hollis Date: Tue, 28 Mar 2006 20:15:42 -0500 Subject: [PATCH] USB: Rename ax8817x_func() to asix_func() and add utility functions to reduce bloat Now that the ASIX code is supporting more than just the AX88172 devices, make the utility function names more generic: ax8817x_func -> asix_func. Functions that are chip specific now indicate as such: ax88772_func. Additionally, pull some common routines used in initialization and such into simple functions to reduce the verbosity of certain functions such as the bind() routines and to make the error handling consistent across the board. Signed-off-by: David Hollis Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/asix.c | 327 ++++++++++++++++++++++++------------------------- 1 file changed, 163 insertions(+), 164 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 3094970615c..12b599a0b53 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c @@ -37,7 +37,6 @@ #include "usbnet.h" - /* ASIX AX8817X based USB 2.0 Ethernet Devices */ #define AX_CMD_SET_SW_MII 0x06 @@ -109,7 +108,7 @@ #define AX_EEPROM_MAGIC 0xdeadbeef /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ -struct ax8817x_data { +struct asix_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; }; @@ -121,7 +120,7 @@ struct ax88172_int_data { u16 res3; } __attribute__ ((packed)); -static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, +static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { return usb_control_msg( @@ -136,7 +135,7 @@ static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, USB_CTRL_GET_TIMEOUT); } -static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, +static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { return usb_control_msg( @@ -151,19 +150,80 @@ static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, USB_CTRL_SET_TIMEOUT); } -static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs) +static void asix_async_cmd_callback(struct urb *urb, struct pt_regs *regs) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; if (urb->status < 0) - printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d", + printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", urb->status); kfree(req); usb_free_urb(urb); } -static void ax8817x_status(struct usbnet *dev, struct urb *urb) +static inline int asix_set_sw_mii(struct usbnet *dev) +{ + int ret; + ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); + if (ret < 0) + devdbg(dev, "Failed to enable software MII access"); + return ret; +} + +static inline int asix_set_hw_mii(struct usbnet *dev) +{ + int ret; + ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); + if (ret < 0) + devdbg(dev, "Failed to enable hardware MII access"); + return ret; +} + +static inline int asix_get_phyid(struct usbnet *dev) +{ + int ret = 0; + void *buf; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + goto out1; + + if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, + 0, 0, 2, buf)) < 2) { + devdbg(dev, "Error reading PHYID register: %02x", ret); + goto out2; + } + ret = *((u8 *)buf + 1); +out2: + kfree(buf); +out1: + return ret; +} + +static int asix_sw_reset(struct usbnet *dev, u8 flags) +{ + int ret; + + ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); + if (ret < 0) + devdbg(dev,"Failed to send software reset: %02x", ret); + + return ret; +} + +static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) +{ + int ret; + + ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); + if (ret < 0) + devdbg(dev, "Failed to write RX_CTL mode: %02x", ret); + + return ret; +} + +static void asix_status(struct usbnet *dev, struct urb *urb) { struct ax88172_int_data *event; int link; @@ -179,12 +239,12 @@ static void ax8817x_status(struct usbnet *dev, struct urb *urb) usbnet_defer_kevent (dev, EVENT_LINK_RESET ); } else netif_carrier_off(dev->net); - devdbg(dev, "ax8817x - Link Status is: %d", link); + devdbg(dev, "Link Status is: %d", link); } } static void -ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, +asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { struct usb_ctrlrequest *req; @@ -211,7 +271,7 @@ ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (void *)req, data, size, - ax8817x_async_cmd_callback, req); + asix_async_cmd_callback, req); if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { deverr(dev, "Error submitting the control message: status=%d", @@ -221,10 +281,10 @@ ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, } } -static void ax8817x_set_multicast(struct net_device *net) +static void asix_set_multicast(struct net_device *net) { struct usbnet *dev = netdev_priv(net); - struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; + struct asix_data *data = (struct asix_data *)&dev->data; u8 rx_ctl = 0x8c; if (net->flags & IFF_PROMISC) { @@ -255,53 +315,51 @@ static void ax8817x_set_multicast(struct net_device *net) mc_list = mc_list->next; } - ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, + asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, AX_MCAST_FILTER_SIZE, data->multi_filter); rx_ctl |= 0x10; } - ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); + asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); } -static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) +static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); u16 res; - u8 buf[1]; - ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); - ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, + asix_set_sw_mii(dev); + asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); - ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); + asix_set_hw_mii(dev); return res & 0xffff; } /* same as above, but converts resulting value to cpu byte order */ -static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc) +static int asix_mdio_read_le(struct net_device *netdev, int phy_id, int loc) { - return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc)); + return le16_to_cpu(asix_mdio_read(netdev,phy_id, loc)); } static void -ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); u16 res = val; - u8 buf[1]; - ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); - ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, + asix_set_sw_mii(dev); + asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); - ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); + asix_set_hw_mii(dev); } /* same as above, but converts new value to le16 byte order before writing */ static void -ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) +asix_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) { - ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); + asix_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); } static int ax88172_link_reset(struct usbnet *dev) @@ -312,23 +370,23 @@ static int ax88172_link_reset(struct usbnet *dev) u8 mode; mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN; - lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); - adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); + lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); + adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); res = mii_nway_result(lpa|adv); if (res & LPA_DUPLEX) mode |= AX_MEDIUM_FULL_DUPLEX; - ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); return 0; } static void -ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); u8 opt; - if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { + if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { wolinfo->supported = 0; wolinfo->wolopts = 0; return; @@ -344,7 +402,7 @@ ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) } static int -ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); u8 opt = 0; @@ -357,19 +415,19 @@ ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) if (opt != 0) opt |= AX_MONITOR_MODE; - if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, + if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, opt, 0, 0, &buf) < 0) return -EINVAL; return 0; } -static int ax8817x_get_eeprom_len(struct net_device *net) +static int asix_get_eeprom_len(struct net_device *net) { return AX_EEPROM_LEN; } -static int ax8817x_get_eeprom(struct net_device *net, +static int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) { struct usbnet *dev = netdev_priv(net); @@ -386,14 +444,14 @@ static int ax8817x_get_eeprom(struct net_device *net, /* ax8817x returns 2 bytes from eeprom on read */ for (i=0; i < eeprom->len / 2; i++) { - if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, + if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, eeprom->offset + i, 0, 2, &ebuf[i]) < 0) return -EINVAL; } return 0; } -static void ax8817x_get_drvinfo (struct net_device *net, +static void asix_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { /* Inherit standard device info */ @@ -401,14 +459,14 @@ static void ax8817x_get_drvinfo (struct net_device *net, info->eedump_len = 0x3e; } -static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) +static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); return mii_ethtool_gset(&dev->mii,cmd); } -static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) +static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); @@ -418,27 +476,27 @@ static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) /* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */ -static struct ethtool_ops ax8817x_ethtool_ops = { - .get_drvinfo = ax8817x_get_drvinfo, +static struct ethtool_ops ax88172_ethtool_ops = { + .get_drvinfo = asix_get_drvinfo, .get_link = ethtool_op_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, - .get_wol = ax8817x_get_wol, - .set_wol = ax8817x_set_wol, - .get_eeprom_len = ax8817x_get_eeprom_len, - .get_eeprom = ax8817x_get_eeprom, - .get_settings = ax8817x_get_settings, - .set_settings = ax8817x_set_settings, + .get_wol = asix_get_wol, + .set_wol = asix_set_wol, + .get_eeprom_len = asix_get_eeprom_len, + .get_eeprom = asix_get_eeprom, + .get_settings = asix_get_settings, + .set_settings = asix_set_settings, }; -static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd) +static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) { struct usbnet *dev = netdev_priv(net); return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } -static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) +static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) { int ret = 0; void *buf; @@ -455,55 +513,39 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) /* Toggle the GPIOs in a manufacturer/model specific way */ for (i = 2; i >= 0; i--) { - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, + if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, (gpio_bits >> (i * 8)) & 0xff, 0, 0, buf)) < 0) goto out2; msleep(5); } - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, - 0x80, 0, 0, buf)) < 0) { - dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret); + if ((ret = asix_write_rx_ctl(dev,0x80)) < 0) goto out2; - } /* Get the MAC address */ memset(buf, 0, ETH_ALEN); - if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, + if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) { dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); goto out2; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); - /* Get the PHY id */ - if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, - 0, 0, 2, buf)) < 0) { - dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret); - goto out2; - } else if (ret < 2) { - /* this should always return 2 bytes */ - dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", - ret); - ret = -EIO; - goto out2; - } - /* Initialize MII structure */ dev->mii.dev = dev->net; - dev->mii.mdio_read = ax8817x_mdio_read; - dev->mii.mdio_write = ax8817x_mdio_write; + dev->mii.mdio_read = asix_mdio_read; + dev->mii.mdio_write = asix_mdio_write; dev->mii.phy_id_mask = 0x3f; dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = *((u8 *)buf + 1); - dev->net->do_ioctl = ax8817x_ioctl; + dev->mii.phy_id = asix_get_phyid(dev); + dev->net->do_ioctl = asix_ioctl; - dev->net->set_multicast_list = ax8817x_set_multicast; - dev->net->ethtool_ops = &ax8817x_ethtool_ops; + dev->net->set_multicast_list = asix_set_multicast; + dev->net->ethtool_ops = &ax88172_ethtool_ops; - ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, + asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); mii_nway_restart(&dev->mii); @@ -515,16 +557,16 @@ out1: } static struct ethtool_ops ax88772_ethtool_ops = { - .get_drvinfo = ax8817x_get_drvinfo, + .get_drvinfo = asix_get_drvinfo, .get_link = ethtool_op_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, - .get_wol = ax8817x_get_wol, - .set_wol = ax8817x_set_wol, - .get_eeprom_len = ax8817x_get_eeprom_len, - .get_eeprom = ax8817x_get_eeprom, - .get_settings = ax8817x_get_settings, - .set_settings = ax8817x_set_settings, + .get_wol = asix_get_wol, + .set_wol = asix_set_wol, + .get_eeprom_len = asix_get_eeprom_len, + .get_eeprom = asix_get_eeprom, + .get_settings = asix_get_settings, + .set_settings = asix_set_settings, }; static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) @@ -541,62 +583,45 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) goto out1; } - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, + if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, 0x00B0, 0, 0, buf)) < 0) goto out2; msleep(5); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, + if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) { dbg("Select PHY #1 failed: %d", ret); goto out2; } - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, - 0, 0, buf)) < 0) { - dbg("Failed to power down internal PHY: %d", ret); + if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD)) < 0) goto out2; - } msleep(150); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, - 0, 0, buf)) < 0) { - dbg("Failed to perform software reset: %d", ret); + if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) goto out2; - } msleep(150); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, - AX_SWRESET_IPRL | AX_SWRESET_PRL, - 0, 0, buf)) < 0) { - dbg("Failed to set Internal/External PHY reset control: %d", - ret); + if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) goto out2; - } msleep(150); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, - 0x0000, 0, 0, buf)) < 0) { - dbg("Failed to reset RX_CTL: %d", ret); + if ((ret = asix_write_rx_ctl(dev, 0x00)) < 0) goto out2; - } /* Get the MAC address */ memset(buf, 0, ETH_ALEN); - if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, + if ((ret = asix_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) { dbg("Failed to read MAC address: %d", ret); goto out2; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, - 0, 0, 0, buf)) < 0) { - dbg("Enabling software MII failed: %d", ret); + if ((ret = asix_set_sw_mii(dev)) < 0) goto out2; - } - if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, + if (((ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0) || (*((u16 *)buf) != 0x003b)) { dbg("Read PHY register 2 must be 0x3b00: %d", ret); @@ -605,74 +630,49 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) /* Initialize MII structure */ dev->mii.dev = dev->net; - dev->mii.mdio_read = ax8817x_mdio_read; - dev->mii.mdio_write = ax8817x_mdio_write; + dev->mii.mdio_read = asix_mdio_read; + dev->mii.mdio_write = asix_mdio_write; dev->mii.phy_id_mask = 0xff; dev->mii.reg_num_mask = 0xff; - dev->net->do_ioctl = ax8817x_ioctl; + dev->net->do_ioctl = asix_ioctl; + dev->mii.phy_id = asix_get_phyid(dev); - /* Get the PHY id */ - if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, - 0, 0, 2, buf)) < 0) { - dbg("Error reading PHY ID: %02x", ret); + if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) goto out2; - } else if (ret < 2) { - /* this should always return 2 bytes */ - dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", - ret); - ret = -EIO; - goto out2; - } - dev->mii.phy_id = *((u8 *)buf + 1); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, - 0, 0, buf)) < 0) { - dbg("Set external PHY reset pin level: %d", ret); - goto out2; - } msleep(150); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, - AX_SWRESET_IPRL | AX_SWRESET_PRL, - 0, 0, buf)) < 0) { - dbg("Set Internal/External PHY reset control: %d", ret); + + if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) goto out2; - } - msleep(150); + msleep(150); - dev->net->set_multicast_list = ax8817x_set_multicast; + dev->net->set_multicast_list = asix_set_multicast; dev->net->ethtool_ops = &ax88772_ethtool_ops; - ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, + asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + asix_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA); mii_nway_restart(&dev->mii); - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, + if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) { dbg("Write medium mode register: %d", ret); goto out2; } - if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, + if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, AX88772_IPG2_DEFAULT, 0, buf)) < 0) { dbg("Write IPG,IPG1,IPG2 failed: %d", ret); goto out2; } - if ((ret = - ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) { - dbg("Failed to set hardware MII: %02x", ret); + if ((ret = asix_set_hw_mii(dev)) < 0) goto out2; - } /* Set RX_CTL to default values with 2k buffer, and enable cactus */ - if ((ret = - ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0, - buf)) < 0) { - dbg("Reset RX_CTL failed: %d", ret); + if ((ret = asix_write_rx_ctl(dev, 0x0088)) < 0) goto out2; - } kfree(buf); @@ -794,23 +794,23 @@ static int ax88772_link_reset(struct usbnet *dev) u16 mode; mode = AX88772_MEDIUM_DEFAULT; - lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); - adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); + lpa = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); + adv = asix_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); res = mii_nway_result(lpa|adv); if ((res & LPA_DUPLEX) == 0) mode &= ~AX88772_MEDIUM_FULL_DUPLEX; if ((res & LPA_100) == 0) mode &= ~AX88772_MEDIUM_100MB; - ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); return 0; } static const struct driver_info ax8817x_info = { .description = "ASIX AX8817x USB 2.0 Ethernet", - .bind = ax8817x_bind, - .status = ax8817x_status, + .bind = ax88172_bind, + .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -819,8 +819,8 @@ static const struct driver_info ax8817x_info = { static const struct driver_info dlink_dub_e100_info = { .description = "DLink DUB-E100 USB Ethernet", - .bind = ax8817x_bind, - .status = ax8817x_status, + .bind = ax88172_bind, + .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -829,8 +829,8 @@ static const struct driver_info dlink_dub_e100_info = { static const struct driver_info netgear_fa120_info = { .description = "Netgear FA-120 USB Ethernet", - .bind = ax8817x_bind, - .status = ax8817x_status, + .bind = ax88172_bind, + .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -839,8 +839,8 @@ static const struct driver_info netgear_fa120_info = { static const struct driver_info hawking_uf200_info = { .description = "Hawking UF200 USB Ethernet", - .bind = ax8817x_bind, - .status = ax8817x_status, + .bind = ax88172_bind, + .status = asix_status, .link_reset = ax88172_link_reset, .reset = ax88172_link_reset, .flags = FLAG_ETHER, @@ -850,13 +850,12 @@ static const struct driver_info hawking_uf200_info = { static const struct driver_info ax88772_info = { .description = "ASIX AX88772 USB 2.0 Ethernet", .bind = ax88772_bind, - .status = ax8817x_status, + .status = asix_status, .link_reset = ax88772_link_reset, .reset = ax88772_link_reset, .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88772_rx_fixup, .tx_fixup = ax88772_tx_fixup, - .data = 0x00130103, }; static const struct usb_device_id products [] = { -- cgit v1.2.3 From 01e89506351b84ac6f39eb70f99c71483768ca60 Mon Sep 17 00:00:00 2001 From: Michael Downey Date: Mon, 3 Apr 2006 08:58:07 -0600 Subject: [PATCH] USB: keyspan-remote bugfix Signed-off-by: Michael Downey Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/keyspan_remote.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index b4a051b549d..3d911976f37 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c @@ -297,6 +297,8 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) remote->data.bits_left -= 6; } else { err("%s - Error in message, invalid toggle.\n", __FUNCTION__); + remote->stage = 0; + return; } keyspan_load_tester(remote, 5); -- cgit v1.2.3 From 8e32640672bdcb01e0d83f087f09dd65fcbc3275 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 4 Apr 2006 14:47:44 -0400 Subject: [PATCH] USB: UHCI: don't track suspended ports Someone recently posted a bug report where it turned out that uhci-hcd was disagreeing with the UHCI controller over whether or not a port was suspended: The driver thought it wasn't and the hardware thought it was. This patch (as665) fixes the problem and simplifies the driver by removing the internal state-tracking completely. Now the driver just asks the hardware whether a port is suspended. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 3 +-- drivers/usb/host/uhci-hcd.h | 1 - drivers/usb/host/uhci-hub.c | 18 +++++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 3d511690c9b..c0c4db78b59 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -115,8 +115,7 @@ static void finish_reset(struct uhci_hcd *uhci) for (port = 0; port < uhci->rh_numports; ++port) outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); - uhci->port_c_suspend = uhci->suspended_ports = - uhci->resuming_ports = 0; + uhci->port_c_suspend = uhci->resuming_ports = 0; uhci->rh_state = UHCI_RH_RESET; uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->state = HC_STATE_HALT; diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 4a69c7eb09b..d5c8f4d9282 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -415,7 +415,6 @@ struct uhci_hcd { /* Support for port suspend/resume/reset */ unsigned long port_c_suspend; /* Bit-arrays of ports */ - unsigned long suspended_ports; unsigned long resuming_ports; unsigned long ports_timeout; /* Time to stop signalling */ diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 152971d1676..c8451d9578f 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -85,11 +85,10 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, { int status; - if (test_bit(port, &uhci->suspended_ports)) { + if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) { CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); - clear_bit(port, &uhci->suspended_ports); - clear_bit(port, &uhci->resuming_ports); - set_bit(port, &uhci->port_c_suspend); + if (test_bit(port, &uhci->resuming_ports)) + set_bit(port, &uhci->port_c_suspend); /* The controller won't actually turn off the RD bit until * it has had a chance to send a low-speed EOP sequence, @@ -97,6 +96,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, * slightly longer for good luck. */ udelay(4); } + clear_bit(port, &uhci->resuming_ports); } /* Wait for the UHCI controller in HP's iLO2 server management chip. @@ -265,8 +265,6 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, wPortChange |= USB_PORT_STAT_C_SUSPEND; lstatus |= 1; } - if (test_bit(port, &uhci->suspended_ports)) - lstatus |= 2; if (test_bit(port, &uhci->resuming_ports)) lstatus |= 4; @@ -309,7 +307,6 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, switch (wValue) { case USB_PORT_FEAT_SUSPEND: - set_bit(port, &uhci->suspended_ports); SET_RH_PORTSTAT(USBPORTSC_SUSP); OK(0); case USB_PORT_FEAT_RESET: @@ -343,8 +340,11 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, CLR_RH_PORTSTAT(USBPORTSC_PEC); OK(0); case USB_PORT_FEAT_SUSPEND: - if (test_bit(port, &uhci->suspended_ports) && - !test_and_set_bit(port, + if (!(inw(port_addr) & USBPORTSC_SUSP)) { + + /* Make certain the port isn't suspended */ + uhci_finish_suspend(uhci, port, port_addr); + } else if (!test_and_set_bit(port, &uhci->resuming_ports)) { SET_RH_PORTSTAT(USBPORTSC_RD); -- cgit v1.2.3 From bfb25849f00d0b8453191ee12125738b5f5c9146 Mon Sep 17 00:00:00 2001 From: Jeffrey Vandenbroucke sign Date: Tue, 28 Mar 2006 15:21:36 -0800 Subject: [PATCH] hid-core.c: fix "input irq status -32 received" for Silvercrest USB Keyboard When not using this patch, the kernel will continuously return "input irq status -32 received", while making the keyboard unusable. This can be easely resolved using HID_QUIRK_NOGET. Vendor-ID and Device-ID should be applied to hid-core.c, and making an entry to make use of it. Signed-off-by: Jeffrey Vandenbroucke Cc: Alan Stern Cc: Greg KH Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index f2225d1ddb0..f419bd82ab7 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1374,6 +1374,9 @@ void hid_close(struct hid_device *hid) #define USB_VENDOR_ID_PANJIT 0x134c +#define USB_VENDOR_ID_SILVERCREST 0x062a +#define USB_DEVICE_ID_SILVERCREST_KB 0x0201 + /* * Initialize all reports */ @@ -1680,6 +1683,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, -- cgit v1.2.3 From 3799c40189570133f9bb3176be24f0edb0e823c6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Sun, 2 Apr 2006 01:45:00 +0100 Subject: [PATCH] USB: S3C2410: use clk_enable() to ensure 48MHz to OHCI core Get the "usb-bus" clock and ensure it is enabled when the OHCI core is in use. It seems that a few bootloaders do not enable the UPLL at startup, which stops the OHCI core having a 48MHz bus clock. The improvements to the clock framework for the s3c24xx now allow the USB PLL to be started and stopped when being used. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-s3c2410.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index b27669fe9f0..1da5de573a6 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -30,6 +30,7 @@ /* clock device associated with the hcd */ static struct clk *clk; +static struct clk *usb_clk; /* forward definitions */ @@ -47,6 +48,10 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) struct s3c2410_hcd_info *info = dev->dev.platform_data; dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); + + clk_enable(usb_clk); + mdelay(2); /* let the bus clock stabilise */ + clk_enable(clk); if (info != NULL) { @@ -75,6 +80,7 @@ static void s3c2410_stop_hc(struct platform_device *dev) } clk_disable(clk); + clk_disable(usb_clk); } /* ohci_s3c2410_hub_status_data @@ -354,14 +360,21 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed"); retval = -EBUSY; - goto err0; + goto err_put; } - clk = clk_get(NULL, "usb-host"); + clk = clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; - goto err1; + goto err_mem; + } + + usb_clk = clk_get(&dev->dev, "upll"); + if (IS_ERR(usb_clk)) { + dev_err(&dev->dev, "cannot get usb-host clock\n"); + retval = -ENOENT; + goto err_clk; } s3c2410_start_hc(dev, hcd); @@ -370,26 +383,29 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; - goto err2; + goto err_ioremap; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); if (retval != 0) - goto err2; + goto err_ioremap; return 0; - err2: + err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); + clk_put(usb_clk); + + err_clk: clk_put(clk); - err1: + err_mem: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err0: + err_put: usb_put_hcd(hcd); return retval; } -- cgit v1.2.3 From e853bf4af372afdae732c48be04a6b154f2de3d4 Mon Sep 17 00:00:00 2001 From: Tomasz Kazmierczak Date: Thu, 6 Apr 2006 22:07:12 +0200 Subject: [PATCH] USB: pl2303: added support for OTi's DKU-5 clone cable This patch adds support for a clone of Nokia DKU-5 cable made by Ours Technology Inc for Nokia phones with PopPort (Nokia 3100 and others). The cable uses PL2303 USB-to-serial converter from Prolific Technology Inc. Signed-off-by: Tomasz Kazmierczak Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b3014fda645..ccf746b27d4 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -78,6 +78,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, + { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 77901d14397..09f379b19e9 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -79,3 +79,7 @@ /* USB GSM cable from Speed Dragon Multimedia, Ltd */ #define SPEEDDRAGON_VENDOR_ID 0x0e55 #define SPEEDDRAGON_PRODUCT_ID 0x110b + +/* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */ +#define OTI_VENDOR_ID 0x0ea0 +#define OTI_PRODUCT_ID 0x6858 -- cgit v1.2.3 From 69a4bf7c9525e5c92c0ecda0db0373f30162b28f Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Wed, 12 Apr 2006 23:41:59 +0200 Subject: [PATCH] USB: remove __init from usb_console_setup This prevents an Oops if booted with "console=ttyUSB0" but without a USB-serial dongle, and plugged one in afterwards. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 167f8ec5613..8023bb7279b 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -54,7 +54,7 @@ static struct console usbcons; * serial.c code, except that the specifier is "ttyUSB" instead * of "ttyS". */ -static int __init usb_console_setup(struct console *co, char *options) +static int usb_console_setup(struct console *co, char *options) { struct usbcons_info *info = &usbcons_info; int baud = 9600; -- cgit v1.2.3 From f9814802dfec8feaf51ba873d7eac1a05ee65842 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Apr 2006 08:09:52 -0700 Subject: [PATCH] USB: add driver for funsoft usb serial device Cc: David Clare Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 9 ++++++ drivers/usb/serial/Makefile | 1 + drivers/usb/serial/funsoft.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 drivers/usb/serial/funsoft.c (limited to 'drivers/usb') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 5a8a2c91c2b..f96b73f54bf 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -158,6 +158,15 @@ config USB_SERIAL_FTDI_SIO To compile this driver as a module, choose M here: the module will be called ftdi_sio. +config USB_SERIAL_FUNSOFT + tristate "USB Fundamental Software Dongle Driver" + depends on USB_SERIAL + ---help--- + Say Y here if you want to use the Fundamental Software dongle. + + To compile this driver as a module, choose M here: the + module will be called funsoft. + config USB_SERIAL_VISOR tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index f7fe4172efe..93c21245b1a 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o +obj-$(CONFIG_USB_SERIAL_FUNSOFT) += funsoft.o obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c new file mode 100644 index 00000000000..803721b97e2 --- /dev/null +++ b/drivers/usb/serial/funsoft.c @@ -0,0 +1,65 @@ +/* + * Funsoft Serial USB driver + * + * Copyright (C) 2006 Greg Kroah-Hartman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include "usb-serial.h" + +static struct usb_device_id id_table [] = { + { USB_DEVICE(0x1404, 0xcddc) }, + { }, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +static struct usb_driver funsoft_driver = { + .name = "funsoft", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + +static struct usb_serial_driver funsoft_device = { + .driver = { + .owner = THIS_MODULE, + .name = "funsoft", + }, + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, +}; + +static int __init funsoft_init(void) +{ + int retval; + + retval = usb_serial_register(&funsoft_device); + if (retval) + return retval; + retval = usb_register(&funsoft_driver); + if (retval) + usb_serial_deregister(&funsoft_device); + return retval; +} + +static void __exit funsoft_exit(void) +{ + usb_deregister(&funsoft_driver); + usb_serial_deregister(&funsoft_device); +} + +module_init(funsoft_init); +module_exit(funsoft_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 026694920579590c73b5c56705d543568ed5ad41 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 23 Mar 2006 01:38:34 -0800 Subject: [PATCH] pm: print name of failed suspend function Print more diagnostic info to help identify the source of power management suspend failures. Example: usb_hcd_pci_suspend(): pci_set_power_state+0x0/0x1af() returns -22 pci_device_suspend(): usb_hcd_pci_suspend+0x0/0x11b() returns -22 suspend_device(): pci_device_suspend+0x0/0x34() returns -22 Work-in-progress. It needs lots more suspend_report_result() calls sprinkled everywhere. Cc: Patrick Mochel Cc: Pavel Machek Cc: Nigel Cunningham Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 0d2193b6923..66b78404ab3 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -213,11 +213,9 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) if (hcd->driver->suspend) { retval = hcd->driver->suspend(hcd, message); - if (retval) { - dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", - retval); + suspend_report_result(hcd->driver->suspend, retval); + if (retval) goto done; - } } synchronize_irq(dev->irq); @@ -263,6 +261,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) * some device state (e.g. as part of clock reinit). */ retval = pci_set_power_state (dev, PCI_D3hot); + suspend_report_result(pci_set_power_state, retval); if (retval == 0) { int wake = device_can_wakeup(&hcd->self.root_hub->dev); -- cgit v1.2.3 From 66e0a9888b774af625ce544f7c6597c7506d07db Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 5 Apr 2006 12:03:45 -0700 Subject: [PATCH] isd200: limit to BLK_DEV_IDE Limit USB_STORAGE_ISD200 to whatever BLK_DEV_IDE and USB_STORAGE are set to (y, m) since isd200 calls ide_fix_driveid() in the BLK_DEV_IDE code. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 92be101feba..be9eec22574 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -48,7 +48,8 @@ config USB_STORAGE_FREECOM config USB_STORAGE_ISD200 bool "ISD-200 USB/ATA Bridge support" - depends on USB_STORAGE && BLK_DEV_IDE + depends on USB_STORAGE + depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE ---help--- Say Y here if you want to use USB Mass Store devices based on the In-Systems Design ISD-200 USB/ATA bridge. -- cgit v1.2.3 From c82ffb07cd1aa356c599999c4f0dc5155a91d318 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 26 Apr 2006 07:20:48 +0100 Subject: [PATCH] fix leak in activate_ep_files() Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/gadget/inode.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 42b457030b0..0eb010a3f5b 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1614,6 +1614,7 @@ static int activate_ep_files (struct dev_data *dev) data, &ep_config_operations, &data->dentry); if (!data->inode) { + usb_ep_free_request(ep, data->req); kfree (data); goto enomem; } -- cgit v1.2.3 From 67ca0284f69992ad71ac12dc375f2b158d9d703d Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 23 Apr 2006 19:59:23 +0200 Subject: [PATCH] USB: Resource leak fix for whiteheat driver We may return from drivers/usb/serial/whiteheat.c::whiteheat_attach() without freeing `result' if we leave via the no_firmware: label. Spotted by the coverity checker as #670 Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/whiteheat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 557411c6e7c..f806553cd9a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -508,6 +508,7 @@ no_firmware: err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description); err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description); err("%s: please contact support@connecttech.com\n", serial->type->description); + kfree(result); return -ENODEV; no_command_private: -- cgit v1.2.3 From 58381719845d9ee19a321c2eb69cfa9b7886be9a Mon Sep 17 00:00:00 2001 From: Wang Jun Date: Wed, 19 Apr 2006 16:32:07 +0800 Subject: [PATCH] USB: add new iTegno usb CDMA 1x card support for pl2303 Add new iTegno usb CDMA 1x card (usbid '0eba:2080') support to pl2303 driver Signed-off-by: Wang Jun Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ccf746b27d4..c96714bb1cb 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -61,6 +61,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) }, { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, + { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 09f379b19e9..7f29e81d3e3 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -26,6 +26,7 @@ #define ITEGNO_VENDOR_ID 0x0eba #define ITEGNO_PRODUCT_ID 0x1080 +#define ITEGNO_PRODUCT_ID_2080 0x2080 #define MA620_VENDOR_ID 0x0df7 #define MA620_PRODUCT_ID 0x0620 -- cgit v1.2.3 From 2120638354a6881b9c442b10fc21f28ecadc7402 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sun, 16 Apr 2006 19:18:36 -0700 Subject: [PATCH] USB: Storage: unusual devs update This patch removes the Protocol portion of the Iomega Click! device as it's not needed. Not-needed message reported by Kenneth Crudup Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c4a9dcff5f2..55cce575f6b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -411,7 +411,7 @@ UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, "Iomega", "USB Clik! 40", - US_SC_8070, US_PR_BULK, NULL, + US_SC_8070, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), /* Yakumo Mega Image 37 -- cgit v1.2.3 From f430c405ca23dd5a9389d1f62dcdeb1fd6ce6024 Mon Sep 17 00:00:00 2001 From: Olivier Blondeau Date: Sun, 16 Apr 2006 19:19:25 -0700 Subject: [PATCH] USB: storage: atmel unusual dev update Originally submitted by Olivier Blondeau , with re-diffing by me. Adds a new atmel unusual_dev entry. Signed-off-by: Phil Dibowitz --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 55cce575f6b..aec5ea8682d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -773,6 +773,13 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Olivier Blondeau */ +UNUSUAL_DEV( 0x0727, 0x0306, 0x0100, 0x0100, + "ATMEL", + "SND1 Storage", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE), + /* Submitted by Roman Hodek */ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk", -- cgit v1.2.3 From a29fccd7993a3d411674e148cb0759a017be3e21 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 14 Apr 2006 16:40:00 -0400 Subject: [PATCH] USB: net2280: Handle STALLs for 0-length control-IN requests This patch (as668) fixes a typo in net2280. The handler for 0-length control-IN requests should check that the endpoint _isn't_ halted before sending a 0-length packet. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 6a4b93ad108..2d5cededcbd 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2166,7 +2166,7 @@ static void handle_ep_small (struct net2280_ep *ep) ep->stopped = 1; set_halt (ep); mode = 2; - } else if (!req && ep->stopped) + } else if (!req && !ep->stopped) write_fifo (ep, NULL); } } else { -- cgit v1.2.3 From 317e83b842ba39776054219ae29844127876416a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 14 Apr 2006 16:42:03 -0400 Subject: [PATCH] USB: net2280: send 0-length packets for ep0 This patch (as669) fixes a bug in the net2280 driver. Now it will properly send zero-length packets on ep0 until the control status stage occurs. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 2d5cededcbd..c842b194cf0 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2280,9 +2280,7 @@ static void handle_ep_small (struct net2280_ep *ep) /* if we wrote it all, we're usually done */ if (req->req.actual == req->req.length) { if (ep->num == 0) { - /* wait for control status */ - if (mode != 2) - req = NULL; + /* send zlps until the status stage */ } else if (!req->req.zero || len != ep->ep.maxpacket) mode = 2; } -- cgit v1.2.3 From 658ad5e001a17be5fadaa8d57d1aa7f7c62628c1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 14 Apr 2006 16:44:11 -0400 Subject: [PATCH] USB: net2280: check for shared IRQs This patch (as670) adds a check for whether a shared IRQ was actually generated by the net2280 device. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c842b194cf0..b2d507f16b8 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2742,6 +2742,10 @@ static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r) { struct net2280 *dev = _dev; + /* shared interrupt, not ours */ + if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED))) + return IRQ_NONE; + spin_lock (&dev->lock); /* handle disconnect, dma, and more */ -- cgit v1.2.3 From 9fb81ce63671f9743517f628dac935269f2581a9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 14 Apr 2006 16:46:28 -0400 Subject: [PATCH] USB: net2280: set driver data before it is used This patch (as671) fixes a bug in the error pathway for the net2280 probe routine. A failure during probe will cause the driver to call pci_get_drvdata before the corresponding pci_set_drvdata has been set. The patch also does a kzalloc conversion. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/net2280.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index b2d507f16b8..0b929349395 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2833,13 +2833,13 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) } /* alloc, and start init */ - dev = kmalloc (sizeof *dev, SLAB_KERNEL); + dev = kzalloc (sizeof *dev, SLAB_KERNEL); if (dev == NULL){ retval = -ENOMEM; goto done; } - memset (dev, 0, sizeof *dev); + pci_set_drvdata (pdev, dev); spin_lock_init (&dev->lock); dev->pdev = pdev; dev->gadget.ops = &net2280_ops; @@ -2952,7 +2952,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff; /* done */ - pci_set_drvdata (pdev, dev); INFO (dev, "%s\n", driver_desc); INFO (dev, "irq %s, pci mem %p, chip rev %04x\n", bufp, base, dev->chiprev); -- cgit v1.2.3 From c67808eee61a01c3128298c5972426a1a67b9093 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 9 Apr 2006 20:07:35 +0200 Subject: [PATCH] USB: Use new PCI_CLASS_SERIAL_USB_* defines We could use the recently added PCI_CLASS_SERIAL_USB_UHCI, PCI_CLASS_SERIAL_USB_OHCI and PCI_CLASS_SERIAL_USB_EHCI defines in more places, for slightly shorter and clearer code. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-pci.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- drivers/usb/host/uhci-hcd.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 1e03f1a5a5f..a1bd2bea6de 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -350,7 +350,7 @@ static const struct hc_driver ehci_pci_hc_driver = { /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { /* end: all zeroes */ } diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 1bfe96f4d04..b268537e389 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -206,7 +206,7 @@ static const struct hc_driver ohci_pci_hc_driver = { static const struct pci_device_id pci_ids [] = { { /* handle any USB OHCI controller */ - PCI_DEVICE_CLASS((PCI_CLASS_SERIAL_USB << 8) | 0x10, ~0), + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* end: all zeroes */ } }; diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index c0c4db78b59..d225e11f405 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -858,7 +858,7 @@ static const struct hc_driver uhci_driver = { static const struct pci_device_id uhci_pci_ids[] = { { /* handle any USB UHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x00), ~0), + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), .driver_data = (unsigned long) &uhci_driver, }, { /* end: all zeroes */ } }; -- cgit v1.2.3 From cdd3b1565a8d563ed84cf1c2af6cabf461f3c317 Mon Sep 17 00:00:00 2001 From: Nathan Bronson Date: Mon, 10 Apr 2006 00:05:09 -0400 Subject: [PATCH] USB: ftdi_sio vendor code for RR-CirKits LocoBuffer USB This patch adds recognition of the RR-CirKits LocoBuffer USB to the existing FTDI driver. http://www.rr-cirkits.com Signed-off-by: Nathan Bronson Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f5851db67f5..5eb646ee097 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -493,6 +493,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, { }, /* Optional parameter entry */ diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 2155f0e4a37..b6c50a16ef8 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -399,6 +399,11 @@ #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ +/* + * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) + */ +#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ + /* * Eclo (http://www.eclo.pt/) product IDs. * PID 0xEA90 submitted by Martin Grill. -- cgit v1.2.3 From 69737dfaacd000b10fc4a1e9eb518b630b43c3ad Mon Sep 17 00:00:00 2001 From: "Luiz Fernando N. Capitulino" Date: Tue, 11 Apr 2006 15:52:41 -0300 Subject: [PATCH] USB: ftdi_sio: Adds support for iPlus device. Adds support in ftdi_sio usbserial driver for USB modems sold by Plus GSM Company in Poland. Signed-off-by: Luiz Fernando Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5eb646ee097..20a9846e7b1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -308,6 +308,7 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index b6c50a16ef8..7c31d59bf63 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -39,6 +39,9 @@ /* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ #define FTDI_TTUSB_PID 0xFF20 /* Product Id */ +/* iPlus device */ +#define FTDI_IPLUS_PID 0xD070 /* Product Id */ + /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -- cgit v1.2.3 From 7e0258fd28762c09b997edb56849ecfa29284b79 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 12 Apr 2006 15:20:35 +0100 Subject: [PATCH] USB: ftdi_sio: add support for ASK RDR 400 series card reader This patch adds support for an ASK RDR 400 series contactless card reader to the ftdi_sio driver's device ID table. The product ID was supplied by Adriano Couto on the ftdi-usb-sio-devel list. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 20a9846e7b1..82151207d81 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -495,6 +495,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, { }, /* Optional parameter entry */ diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 7c31d59bf63..2c55a5ea9c9 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -155,6 +155,11 @@ #define ICOM_ID1_VID 0x0C26 #define ICOM_ID1_PID 0x0004 +/* + * ASK.fr devices + */ +#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ + /* * DSS-20 Sync Station for Sony Ericsson P800 */ -- cgit v1.2.3 From 839ab1d4ce4dfd7e6c189391a82c584292488b41 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 26 Apr 2006 14:39:11 -0700 Subject: [PATCH] USB: fix bug in ohci-hcd.c ohci_restart() A loop on a power-lost resume path used the wrong index. I suspect khubd has been working around such bugs. Noticed by Andreas Mohr . Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 544f7589912..73f5a379d9b 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -863,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci) i = ohci->num_ports; while (i--) ohci_writel (ohci, RH_PS_PSS, - &ohci->regs->roothub.portstatus [temp]); + &ohci->regs->roothub.portstatus [i]); ohci_dbg (ohci, "restart complete\n"); } return 0; -- cgit v1.2.3 From 67c752b41a4238c1a2d7eebcd061ff8c1127d3e9 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 28 Apr 2006 18:44:06 +0200 Subject: [PATCH] USBATM: change the default speedtouch iso altsetting The maximum possible bandwidth for a speedtouch modem is about 7Mbaud. You can only get this by using isochronous urbs (enable_isoc=1) and altsetting 3. With the current default altsetting of 2, the modem maxes out at about 4Mbaud. So change the default altsetting to 3 when using isochronous urbs. It would be nice to base the altsetting on the detected line speed, but that's hard given the current design. Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/speedtch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 7860c8a5800..956b7a1e8af 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -69,7 +69,7 @@ static const char speedtch_driver_name[] = "speedtch"; #define RESUBMIT_DELAY 1000 /* milliseconds */ #define DEFAULT_BULK_ALTSETTING 1 -#define DEFAULT_ISOC_ALTSETTING 2 +#define DEFAULT_ISOC_ALTSETTING 3 #define DEFAULT_DL_512_FIRST 0 #define DEFAULT_ENABLE_ISOC 0 #define DEFAULT_SW_BUFFERING 0 -- cgit v1.2.3 From 6275cdfa0fe032208937a3567ebb8bcfd42d20b1 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 28 Apr 2006 18:52:16 +0200 Subject: [PATCH] USBATM: fix modinfo output Because of the way stringify works, using an expression like 64 * 1024 for UDSL_MAX_BUF_SIZE results in 64 * 1024 turning up in the modinfo output instead of 65536. So use 65536 directly (this was the only way I found of fixing this). Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index c1211fc037d..546249843b8 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -99,11 +99,11 @@ static const char usbatm_driver_name[] = "usbatm"; #define UDSL_MAX_RCV_URBS 16 #define UDSL_MAX_SND_URBS 16 -#define UDSL_MAX_BUF_SIZE 64 * 1024 /* bytes */ +#define UDSL_MAX_BUF_SIZE 65536 #define UDSL_DEFAULT_RCV_URBS 4 #define UDSL_DEFAULT_SND_URBS 4 -#define UDSL_DEFAULT_RCV_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ -#define UDSL_DEFAULT_SND_BUF_SIZE 64 * ATM_CELL_SIZE /* bytes */ +#define UDSL_DEFAULT_RCV_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ +#define UDSL_DEFAULT_SND_BUF_SIZE 3392 /* 64 * ATM_CELL_SIZE */ #define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) @@ -135,7 +135,7 @@ MODULE_PARM_DESC(rcv_buf_bytes, module_param(snd_buf_bytes, uint, S_IRUGO); MODULE_PARM_DESC(snd_buf_bytes, "Size of the buffers used for transmission, in bytes (range: 1-" - __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: " + __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: " __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")"); -- cgit v1.2.3 From 7e713b825610de9a9584c189c72e2d9f2326359c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 1 May 2006 14:02:45 -0700 Subject: [PATCH] USB: pegasus fixes (logstorm, suspend) Teach "pegasus" to handle a few of the disconnect fault paths without hundreds of usless syslog messages. Handle the carrier check workqueue entry even if the driver has not been opened. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/pegasus.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 2deb4c01539..7683926a1b6 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -318,6 +318,8 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) set_register(pegasus, PhyCtrl, (indx | PHY_READ)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); + if (ret == -ESHUTDOWN) + goto fail; if (data[0] & PHY_DONE) break; } @@ -326,6 +328,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) *regd = le16_to_cpu(regdi); return ret; } +fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); @@ -354,12 +357,15 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, PhyCtrl, 1, data); + if (ret == -ESHUTDOWN) + goto fail; if (data[0] & PHY_DONE) break; } if (i < REG_TIMEOUT) return ret; +fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -387,6 +393,8 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) ret = get_registers(pegasus, EpromCtrl, 1, &tmp); if (tmp & EPROM_DONE) break; + if (ret == -ESHUTDOWN) + goto fail; } if (i < REG_TIMEOUT) { ret = get_registers(pegasus, EpromData, 2, &retdatai); @@ -394,6 +402,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) return ret; } +fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -433,12 +442,15 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, EpromCtrl, 1, &tmp); + if (ret == -ESHUTDOWN) + goto fail; if (tmp & EPROM_DONE) break; } disable_eprom_write(pegasus); if (i < REG_TIMEOUT) return ret; +fail: if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); return -ETIMEDOUT; @@ -1378,9 +1390,8 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) struct pegasus *pegasus = usb_get_intfdata(intf); netif_device_detach (pegasus->net); + cancel_delayed_work(&pegasus->carrier_check); if (netif_running(pegasus->net)) { - cancel_delayed_work(&pegasus->carrier_check); - usb_kill_urb(pegasus->rx_urb); usb_kill_urb(pegasus->intr_urb); } @@ -1400,10 +1411,9 @@ static int pegasus_resume (struct usb_interface *intf) pegasus->intr_urb->status = 0; pegasus->intr_urb->actual_length = 0; intr_callback(pegasus->intr_urb, NULL); - - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, - CARRIER_CHECK_DELAY); } + queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, + CARRIER_CHECK_DELAY); return 0; } -- cgit v1.2.3 From db4cefaaea4c6d67cdaebfd315abc791c5c9d22f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 1 May 2006 22:07:13 -0700 Subject: [PATCH] USB: fix OHCI PM regression This fixes a small regression in USB controller power usage for many OHCI controllers, notably including every non-PCI version of OHCI: on those systems, the runtime autosuspend mechanism is no longer enabled. The change moves to saner defaults. All root hubs are expected to handle remote wakeup (and hence autosuspend), although drivers for buggy silicon may override that default. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index fbd938d4ea5..e2e00ba4e1e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1805,6 +1805,12 @@ int usb_add_hcd(struct usb_hcd *hcd, USB_SPEED_FULL; hcd->self.root_hub = rhdev; + /* wakeup flag init defaults to "everything works" for root hubs, + * but drivers can override it in reset() if needed, along with + * recording the overall controller's system wakeup capability. + */ + device_init_wakeup(&rhdev->dev, 1); + /* "reset" is misnamed; its role is now one-time init. the controller * should already have been reset (and boot firmware kicked off etc). */ @@ -1813,13 +1819,6 @@ int usb_add_hcd(struct usb_hcd *hcd, goto err_hcd_driver_setup; } - /* wakeup flag init is in transition; for now we can't rely on PCI to - * initialize these bits properly, so we let reset() override it. - * This init should _precede_ the reset() once PCI behaves. - */ - device_init_wakeup(&rhdev->dev, - device_can_wakeup(hcd->self.controller)); - /* NOTE: root hub and controller capabilities may not be the same */ if (device_can_wakeup(hcd->self.controller) && device_can_wakeup(&hcd->self.root_hub->dev)) -- cgit v1.2.3 From 436f5762bcd4929825a0725d4bc78337e6fc0d8f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 2 May 2006 15:22:41 -0400 Subject: [PATCH] USB: usbcore: don't check the device's power source The choose_configuration() routine contains code the determine the device's power source, so that configurations requiring external power can be ruled out if the device is running on bus power. Unfortunately it turns out that some devices have errors in their config descriptors and other devices don't like the GET_DEVICE_STATUS request. Since that information wasn't used for anything else, this patch (as673) removes the code, leaving only a comment. It fixes bugzilla entry #6448. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0c87f73f293..90b8d43c6b3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1168,19 +1168,9 @@ static inline const char *plural(int n) static int choose_configuration(struct usb_device *udev) { int i; - u16 devstatus; - int bus_powered; int num_configs; struct usb_host_config *c, *best; - /* If this fails, assume the device is bus-powered */ - devstatus = 0; - usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); - le16_to_cpus(&devstatus); - bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); - dev_dbg(&udev->dev, "device is %s-powered\n", - bus_powered ? "bus" : "self"); - best = NULL; c = udev->config; num_configs = udev->descriptor.bNumConfigurations; @@ -1197,6 +1187,19 @@ static int choose_configuration(struct usb_device *udev) * similar errors in their descriptors. If the next test * were allowed to execute, such configurations would always * be rejected and the devices would not work as expected. + * In the meantime, we run the risk of selecting a config + * that requires external power at a time when that power + * isn't available. It seems to be the lesser of two evils. + * + * Bugzilla #6448 reports a device that appears to crash + * when it receives a GET_DEVICE_STATUS request! We don't + * have any other way to tell whether a device is self-powered, + * but since we don't use that information anywhere but here, + * the call has been removed. + * + * Maybe the GET_DEVICE_STATUS call and the test below can + * be reinstated when device firmwares become more reliable. + * Don't hold your breath. */ #if 0 /* Rule out self-powered configs for a bus-powered device */ -- cgit v1.2.3 From 20a0f47e18c646bcc772282512fc59e56b2fc968 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 4 May 2006 11:34:25 +0100 Subject: [PATCH] USB: ftdi_sio: Add support for HCG HF Dual ISO RFID Reader This patch adds support for ACG Identification Technologies GmbH's HF Dual ISO Reader (an RFID tag reader) to the ftdi_sio driver's device ID table. The product ID was supplied by anotonios (anton at goto10 dot org) on the ftdi-usb-sio-devel list and subsequently verified by myself (Ian Abbott). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 82151207d81..9498da46103 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -498,6 +498,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 2c55a5ea9c9..3e4123f09e0 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -426,6 +426,11 @@ #define PAPOUCH_VID 0x5050 /* Vendor ID */ #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +/* + * ACG Identification Technologies GmbH products (http://www.acg.de/). + * Submitted by anton -at- goto10 -dot- org. + */ +#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ -- cgit v1.2.3 From 72a9f958421a519e69b3e7b409948c3a294f4a32 Mon Sep 17 00:00:00 2001 From: Razvan Gavril Date: Thu, 4 May 2006 11:35:49 +0300 Subject: [PATCH] USB: ftdi_sio: add device id for ACT Solutions HomePro ZWave interface Signed-off-by: Razvan Gavril Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9498da46103..986d7622273 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -307,6 +307,7 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 3e4123f09e0..d69a917e768 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -32,6 +32,10 @@ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ +/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ +#define FTDI_ACTZWAVE_PID 0xF2D0 + + /* www.irtrans.de device */ #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ -- cgit v1.2.3 From b68f7de02ae380ddb4e5e457e3fe945ddfd0aa08 Mon Sep 17 00:00:00 2001 From: Ken Brush Date: Mon, 8 May 2006 20:24:12 -0500 Subject: [PATCH] USB: Add Sieraa Wireless 580 evdo card to airprime.c This adds the Sierra Wireless card to airprime.c. I tested this on my laptop. Signed-off-by: Ken Brush Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index dbf1f063098..694b205f9b7 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,6 +18,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.2.3 From 332bbf613868a5d5938ad9fb7436b2beae72d53d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 5 May 2006 11:07:21 +0200 Subject: [PATCH] USB: add an IBM USB keyboard to the HID_QUIRK_NOGET blacklist After recent changes, the USB keyboard as shipped with IBM pSeries systems does not work anymore, unless the keyboard is replugged after reboot. Adding this model to the blacklist fixes it. Signed-off-by: Olaf Hering Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index f419bd82ab7..435273e7c85 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1557,6 +1557,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_HP 0x03f0 #define USB_DEVICE_ID_HP_USBHUB_KB 0x020c +#define USB_VENDOR_ID_IBM 0x04b3 +#define USB_DEVICE_ID_IBM_USBHUB_KB 0x3005 + #define USB_VENDOR_ID_CREATIVELABS 0x062a #define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201 @@ -1681,6 +1684,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET }, { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, -- cgit v1.2.3 From 16c23f7d88cbcce491f9370b2846fad66e8ef319 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 9 May 2006 12:37:22 -0700 Subject: [PATCH] USB: Emagic USB firmware loading fixes It's become apparent as machines get faster that the emagic kernel firmware loaders (based on the ezusb loader) have a reset race. a 400MHz TiBook never tripped it, but a 2GHz Pentium M seems to hit it about 30% of the time. The bug is seen as a hung USB box and the kernel error: drivers/usb/misc/emi62.c: emi62_load_firmware - error loading firmware: error = -110 The patch below inserts a delay after deasserting reset to allow the box to settle before a new command is issued. This affects only device startup. Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/emi26.c | 4 ++++ drivers/usb/misc/emi62.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 3824df33094..1fd9cb85f4c 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -15,6 +15,7 @@ #include #include #include +#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -114,6 +115,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); + msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -150,6 +152,7 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } } + msleep(250); /* let device settle */ /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); @@ -192,6 +195,7 @@ static int emi26_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } + msleep(250); /* let device settle */ /* return 1 to fail the driver inialization * and give real driver change to load */ diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 52fea2e08db..fe351371f27 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -15,6 +15,7 @@ #include #include #include +#include #define MAX_INTEL_HEX_RECORD_LENGTH 16 typedef struct _INTEL_HEX_RECORD @@ -123,6 +124,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); + msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with @@ -166,6 +168,7 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } + msleep(250); /* let device settle */ /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ @@ -228,6 +231,7 @@ static int emi62_load_firmware (struct usb_device *dev) err("%s - error loading firmware: error = %d", __FUNCTION__, err); goto wraperr; } + msleep(250); /* let device settle */ kfree(buf); -- cgit v1.2.3 From 704936a25bda9bb12e35bb222d5e3f26186dc279 Mon Sep 17 00:00:00 2001 From: Luiz Fernando Capitulino Date: Thu, 11 May 2006 22:34:17 -0300 Subject: [PATCH] usbserial: Fixes use-after-free in serial_open(). If the device is disconnected while serial_open() is executing and either try_module_get() or the device specific open function fails, the kref_put() call in the 'bailout_kref_put' label will free the memory pointed out by 'port'. The subsequent dereferences in the 'bailout_kref_put' label will be invalid. The fix is just to assure kref_put() is called after any 'port' usage. Signed-off-by: Luiz Fernando N. Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 071f86a59c0..d9dceb4f57b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -225,9 +225,9 @@ static int serial_open (struct tty_struct *tty, struct file * filp) bailout_module_put: module_put(serial->type->driver.owner); bailout_kref_put: - kref_put(&serial->kref, destroy_serial); port->open_count = 0; mutex_unlock(&port->mutex); + kref_put(&serial->kref, destroy_serial); return retval; } -- cgit v1.2.3 From 71a84163ca6b4e36744978385e94150af32f9d75 Mon Sep 17 00:00:00 2001 From: Luiz Fernando Capitulino Date: Thu, 11 May 2006 22:34:24 -0300 Subject: [PATCH] usbserial: Fixes leak in serial_open() error path. If serial_open() fails at the port assignment or mutex_lock_interruptible() is interrupted, the 'serial' object will never be freed. We should call kref_put() when those errors happens. Signed-off-by: Luiz Fernando N. Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index d9dceb4f57b..9c36f0ece20 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -189,11 +189,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp) portNumber = tty->index - serial->minor; port = serial->port[portNumber]; - if (!port) - return -ENODEV; + if (!port) { + retval = -ENODEV; + goto bailout_kref_put; + } - if (mutex_lock_interruptible(&port->mutex)) - return -ERESTARTSYS; + if (mutex_lock_interruptible(&port->mutex)) { + retval = -ERESTARTSYS; + goto bailout_kref_put; + } ++port->open_count; @@ -209,7 +213,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) * safe because we are called with BKL held */ if (!try_module_get(serial->type->driver.owner)) { retval = -ENODEV; - goto bailout_kref_put; + goto bailout_mutex_unlock; } /* only call the device specific open if this @@ -224,9 +228,10 @@ static int serial_open (struct tty_struct *tty, struct file * filp) bailout_module_put: module_put(serial->type->driver.owner); -bailout_kref_put: +bailout_mutex_unlock: port->open_count = 0; mutex_unlock(&port->mutex); +bailout_kref_put: kref_put(&serial->kref, destroy_serial); return retval; } -- cgit v1.2.3 From 815ddc99dd8108908d14c699a37d0f5974da6def Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 May 2006 11:05:29 -0700 Subject: [PATCH] USB: add ark3116 usb to serial driver Based on Simon's original driver, with some minor code cleanups and tidying by me. Cc: Simon Schulz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 10 + drivers/usb/serial/Makefile | 1 + drivers/usb/serial/ark3116.c | 465 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/serial/generic.c | 1 + 4 files changed, 477 insertions(+) create mode 100644 drivers/usb/serial/ark3116.c (limited to 'drivers/usb') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index f96b73f54bf..5c60be52156 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -71,6 +71,16 @@ config USB_SERIAL_ANYDATA To compile this driver as a module, choose M here: the module will be called anydata. +config USB_SERIAL_ARK3116 + tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" + depends on USB_SERIAL && EXPERIMENTAL + help + Say Y here if you want to use a ARK Micro 3116 USB to Serial + device. + + To compile this driver as a module, choose M here: the + module will be called ark3116 + config USB_SERIAL_BELKIN tristate "USB Belkin and Peracom Single Port Serial Driver" depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 93c21245b1a..5a0960fc9d3 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -13,6 +13,7 @@ usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o +obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c new file mode 100644 index 00000000000..8dec796222a --- /dev/null +++ b/drivers/usb/serial/ark3116.c @@ -0,0 +1,465 @@ +/* + * ark3116 + * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, + * productid=0x0232) (used in a datacable called KQ-U8A) + * + * - based on code by krisfx -> thanks !! + * (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457) + * + * - based on logs created by usbsnoopy + * + * Author : Simon Schulz [ark3116_driverauctionant.de] + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "usb-serial.h" + + +static int debug; + +static struct usb_device_id id_table [] = { + { USB_DEVICE(0x6547, 0x0232) }, + { }, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +struct ark3116_private { + spinlock_t lock; + u8 termios_initialized; +}; + +static inline void ARK3116_SND(struct usb_serial *serial, int seq, + __u8 request, __u8 requesttype, + __u16 value, __u16 index) +{ + int result; + result = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev,0), + request, requesttype, value, index, + NULL,0x00, 1000); + dbg("%03d > ok",seq); +} + +static inline void ARK3116_RCV(struct usb_serial *serial, int seq, + __u8 request, __u8 requesttype, + __u16 value, __u16 index, __u8 expected, + char *buf) +{ + int result; + result = usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev,0), + request, requesttype, value, index, + buf, 0x0000001, 1000); + if (result) + dbg("%03d < %d bytes [0x%02X]",seq, result, buf[0]); + else + dbg("%03d < 0 bytes", seq); +} + + +static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, + __u8 request, __u8 requesttype, + __u16 value, __u16 index, char *buf) +{ + usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev,0), + request, requesttype, value, index, + buf, 0x0000001, 1000); +} + + +static int ark3116_attach(struct usb_serial *serial) +{ + char *buf; + struct ark3116_private *priv; + int i; + + for (i = 0; i < serial->num_ports; ++i) { + priv = kmalloc (sizeof (struct ark3116_private), GFP_KERNEL); + if (!priv) + goto cleanup; + memset (priv, 0x00, sizeof (struct ark3116_private)); + spin_lock_init(&priv->lock); + + usb_set_serial_port_data(serial->port[i], priv); + } + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) { + dbg("error kmalloc -> out of mem ?"); + goto cleanup; + } + + /* 3 */ + ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002); + ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001); + ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008); + ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B); + + /* <-- seq7 */ + ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf); + ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003); + ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000); + ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001); + ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003); + + /* <-- seq12 */ + ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf); + ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004); + + /* 14 */ + ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf); + ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004); + + /* 16 */ + ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf); + /* --> seq17 */ + ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004); + + /* <-- seq18 */ + ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf); + + /* --> seq19 */ + ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004); + + + /* <-- seq20 */ + /* seems like serial port status info (RTS, CTS,...) */ + /* returns modem control line status ?! */ + ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); + + /* set 9600 baud & do some init ?! */ + ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); + ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000); + ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001); + ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); + ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); + ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); + ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); + ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003); + + kfree(buf); + return(0); + +cleanup: + for (--i; i>=0; --i) + usb_set_serial_port_data(serial->port[i], NULL); + return -ENOMEM; +} + +static void ark3116_set_termios(struct usb_serial_port *port, + struct termios *old_termios) +{ + struct usb_serial *serial = port->serial; + struct ark3116_private *priv = usb_get_serial_port_data(port); + unsigned int cflag = port->tty->termios->c_cflag; + unsigned long flags; + int baud; + int ark3116_baud; + char *buf; + char config; + + config = 0; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if ((!port->tty) || (!port->tty->termios)) { + dbg("%s - no tty structures", __FUNCTION__); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + if (!priv->termios_initialized) { + *(port->tty->termios) = tty_std_termios; + port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + priv->termios_initialized = 1; + } + spin_unlock_irqrestore(&priv->lock, flags); + + cflag = port->tty->termios->c_cflag; + + /* check that they really want us to change something: */ + if (old_termios) { + if ((cflag == old_termios->c_cflag) && + (RELEVANT_IFLAG(port->tty->termios->c_iflag) == + RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg("%s - nothing to change...", __FUNCTION__); + return; + } + } + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) { + dbg("error kmalloc"); + return; + } + + /* set data bit count (8/7/6/5) */ + if (cflag & CSIZE){ + switch (cflag & CSIZE){ + case CS5: + config |= 0x00; + dbg("setting CS5"); + break; + case CS6: + config |= 0x01; + dbg("setting CS6"); + break; + case CS7: + config |= 0x02; + dbg("setting CS7"); + break; + default: + err ("CSIZE was set but not CS5-CS8, using CS8!"); + case CS8: + config |= 0x03; + dbg("setting CS8"); + break; + } + } + + /* set parity (NONE,EVEN,ODD) */ + if (cflag & PARENB){ + if (cflag & PARODD) { + config |= 0x08; + dbg("setting parity to ODD"); + } else { + config |= 0x18; + dbg("setting parity to EVEN"); + } + } else { + dbg("setting parity to NONE"); + } + + /* SET STOPBIT (1/2) */ + if (cflag & CSTOPB) { + config |= 0x04; + dbg ("setting 2 stop bits"); + } else { + dbg ("setting 1 stop bit"); + } + + + /* set baudrate: */ + baud = 0; + switch (cflag & CBAUD){ + case B0: + err("can't set 0baud, using 9600 instead"); + break; + case B75: baud = 75; break; + case B150: baud = 150; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + default: + dbg("does not support the baudrate requested (fix it)"); + break; + } + + /* set 9600 as default (if given baudrate is invalid for example) */ + if (baud == 0) + baud = 9600; + + /* + * found by try'n'error, be careful, maybe there are other options + * for multiplicator etc! + */ + if (baud == 460800) + /* strange, for 460800 the formula is wrong + * (dont use round(), then 9600baud is wrong) */ + ark3116_baud = 7; + else + ark3116_baud = 3000000 / baud; + + /* ? */ + ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf); + /* offset = buf[0]; */ + /* offset = 0x03; */ + /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */ + + + /* set baudrate */ + dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud); + ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); + ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); + ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); + ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); + + /* ? */ + ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); + ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); + + /* set data bit count, stop bit count & parity: */ + dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); + ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); + ARK3116_SND(serial,154,0xFE,0x40,config,0x0003); + + if (cflag & CRTSCTS) + dbg("CRTSCTS not supported by chipset ?!"); + + /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */ + + kfree(buf); + return; +} + +static int ark3116_open(struct usb_serial_port *port, struct file *filp) +{ + struct termios tmp_termios; + struct usb_serial *serial = port->serial; + char *buf; + int result = 0; + + dbg("%s - port %d", __FUNCTION__, port->number); + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) { + dbg("error kmalloc -> out of mem ?"); + return -ENOMEM; + } + + result = usb_serial_generic_open(port, filp); + if (result) + return result; + + /* open */ + ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf); + + ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003); + ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000); + ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001); + ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003); + + ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf); + ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004); + + ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf); + ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004); + + ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf); + + ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004); + + ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf); + + ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004); + + /* returns different values (control lines ?!) */ + ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); + + /* initialise termios: */ + if (port->tty) + ark3116_set_termios(port, &tmp_termios); + + kfree(buf); + + return result; + +} + +static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) +{ + dbg("ioctl not supported yet..."); + return -ENOIOCTLCMD; +} + +static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file) +{ + struct usb_serial *serial = port->serial; + char *buf; + char temp; + + /* seems like serial port status info (RTS, CTS,...) is stored + * in reg(?) 0x0006 + * pcb connection point 11 = GND -> sets bit4 of response + * pcb connection point 7 = GND -> sets bit6 of response + */ + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) { + dbg("error kmalloc"); + return -ENOMEM; + } + + /* read register: */ + ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf); + temp = buf[0]; + kfree(buf); + + /* i do not really know if bit4=CTS and bit6=DSR... was just a + * quick guess !! + */ + return (temp & (1<<4) ? TIOCM_CTS : 0) | + (temp & (1<<6) ? TIOCM_DSR : 0); +} + +static struct usb_driver ark3116_driver = { + .name = "ark3116", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + +static struct usb_serial_driver ark3116_device = { + .driver = { + .owner = THIS_MODULE, + .name = "ark3116", + }, + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .attach = ark3116_attach, + .set_termios = ark3116_set_termios, + .ioctl = ark3116_ioctl, + .tiocmget = ark3116_tiocmget, + .open = ark3116_open, +}; + +static int __init ark3116_init(void) +{ + int retval; + + retval = usb_serial_register(&ark3116_device); + if (retval) + return retval; + retval = usb_register(&ark3116_driver); + if (retval) + usb_serial_deregister(&ark3116_device); + return retval; +} + +static void __exit ark3116_exit(void) +{ + usb_deregister(&ark3116_driver); + usb_serial_deregister(&ark3116_device); +} + +module_init(ark3116_init); +module_exit(ark3116_exit); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 476cda107f4..c62cc287651 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -138,6 +138,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) return result; } +EXPORT_SYMBOL_GPL(usb_serial_generic_open); static void generic_cleanup (struct usb_serial_port *port) { -- cgit v1.2.3 From df3fccb14ad02c5fabe095a104a0323c223f2833 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 May 2006 08:44:45 +0200 Subject: [PATCH] USB: fix omninet driver bug I introduced this way back in 2.6.13 when adding the port lock logic. This device talks out through different "ports" all at the same time, so the lock logic was wrong, preventing any data from ever being sent properly. Thanks a lot to Bernhard Reiter for being patient and helping with debugging this. Cc: Bernhard Reiter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/omninet.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 4d40704dea2..238033a8709 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -257,14 +257,14 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf return (0); } - spin_lock(&port->lock); - if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_lock(&wport->lock); + if (wport->write_urb_busy) { + spin_unlock(&wport->lock); dbg("%s - already writing", __FUNCTION__); return 0; } - port->write_urb_busy = 1; - spin_unlock(&port->lock); + wport->write_urb_busy = 1; + spin_unlock(&wport->lock); count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; @@ -283,7 +283,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf wport->write_urb->dev = serial->dev; result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { - port->write_urb_busy = 0; + wport->write_urb_busy = 0; err("%s - failed submitting write urb, error %d", __FUNCTION__, result); } else result = count; -- cgit v1.2.3 From 48d705522da4fa04bb0169a7ca3c9ab92e28b613 Mon Sep 17 00:00:00 2001 From: "Micon, David" Date: Sat, 20 May 2006 14:59:59 -0700 Subject: [PATCH] HID read busywait fix Make a read of a HID device block until data is available. Without it, the read goes into a busy-wait loop until data is available. Cc: Greg KH Acked-by: Vojtech Pavlik Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/input/hiddev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 6dd66669617..c4670e1d465 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -317,6 +317,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun } schedule(); + set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); -- cgit v1.2.3