1
0

Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus

This commit is contained in:
Dmitry Torokhov
2006-08-04 22:50:27 -04:00
1758 changed files with 35022 additions and 16948 deletions

View File

@@ -23,7 +23,8 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_LH7A404
default y if ARCH_S3C2410
default y if PXA27x
default y if ARCH_AT91RM9200
default y if ARCH_EP93XX
default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx

View File

@@ -48,7 +48,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_CY7C63) += misc/
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/

View File

@@ -291,13 +291,13 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
struct acm_ru *rcv = urb->context;
struct acm *acm = rcv->instance;
int status = urb->status;
dbg("Entering acm_read_bulk with status %d\n", urb->status);
dbg("Entering acm_read_bulk with status %d", urb->status);
if (!ACM_READY(acm))
return;
if (status)
dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
dev_dbg(&acm->data->dev, "bulk rx status %d", status);
buf = rcv->buffer;
buf->size = urb->actual_length;
@@ -343,7 +343,7 @@ next_buffer:
list_del(&buf->list);
spin_unlock(&acm->read_lock);
dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
tty_buffer_request_room(tty, buf->size);
if (!acm->throttle)
@@ -394,7 +394,7 @@ urbs:
rcv->urb->transfer_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
/* This shouldn't kill the driver as unsuccessful URBs are returned to the
free-urbs-pool and resubmited ASAP */
@@ -413,7 +413,7 @@ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
{
struct acm *acm = (struct acm *)urb->context;
dbg("Entering acm_write_bulk with status %d\n", urb->status);
dbg("Entering acm_write_bulk with status %d", urb->status);
acm_write_done(acm);
acm_write_start(acm);
@@ -424,7 +424,7 @@ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
static void acm_softint(void *private)
{
struct acm *acm = private;
dbg("Entering acm_softint.\n");
dbg("Entering acm_softint.");
if (!ACM_READY(acm))
return;
@@ -440,7 +440,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
struct acm *acm;
int rv = -EINVAL;
int i;
dbg("Entering acm_tty_open.\n");
dbg("Entering acm_tty_open.");
mutex_lock(&open_mutex);
@@ -541,7 +541,7 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
int wbn;
struct acm_wb *wb;
dbg("Entering acm_tty_write to write %d bytes,\n", count);
dbg("Entering acm_tty_write to write %d bytes,", count);
if (!ACM_READY(acm))
return -EINVAL;
@@ -793,7 +793,7 @@ static int acm_probe (struct usb_interface *intf,
if (!buflen) {
if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
buflen = intf->cur_altsetting->endpoint->extralen;
buffer = intf->cur_altsetting->endpoint->extra;
} else {
@@ -842,24 +842,24 @@ next_desc:
if (!union_header) {
if (call_interface_num > 0) {
dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
dev_dbg(&intf->dev,"No union descriptor, using call management descriptor");
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
control_interface = intf;
} else {
dev_dbg(&intf->dev,"No union descriptor, giving up\n");
dev_dbg(&intf->dev,"No union descriptor, giving up");
return -ENODEV;
}
} else {
control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
if (!control_interface || !data_interface) {
dev_dbg(&intf->dev,"no interfaces\n");
dev_dbg(&intf->dev,"no interfaces");
return -ENODEV;
}
}
if (data_interface_num != call_interface_num)
dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
skip_normal_probe:
@@ -867,7 +867,7 @@ skip_normal_probe:
if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
struct usb_interface *t;
dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
dev_dbg(&intf->dev,"Your device has switched interfaces.");
t = control_interface;
control_interface = data_interface;
@@ -878,7 +878,7 @@ skip_normal_probe:
}
if (usb_interface_claimed(data_interface)) { /* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available\n");
dev_dbg(&intf->dev,"The data interface isn't available");
return -EBUSY;
}
@@ -895,7 +895,7 @@ skip_normal_probe:
if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
/* descriptors are swapped */
struct usb_endpoint_descriptor *t;
dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
dev_dbg(&intf->dev,"The data interface has switched endpoints");
t = epread;
epread = epwrite;
@@ -910,7 +910,7 @@ skip_normal_probe:
}
if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
dev_dbg(&intf->dev, "out of memory (acm kzalloc)");
goto alloc_fail;
}
@@ -936,26 +936,26 @@ skip_normal_probe:
buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)");
goto alloc_fail2;
}
acm->ctrl_buffer = buf;
if (acm_write_buffers_alloc(acm) < 0) {
dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
dev_dbg(&intf->dev, "out of memory (write buffer alloc)");
goto alloc_fail4;
}
acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->ctrlurb) {
dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
goto alloc_fail5;
}
for (i = 0; i < num_rx_buf; i++) {
struct acm_ru *rcv = &(acm->ru[i]);
if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
goto alloc_fail7;
}
@@ -966,13 +966,13 @@ skip_normal_probe:
struct acm_rb *buf = &(acm->rb[i]);
if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)");
goto alloc_fail7;
}
}
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->writeurb) {
dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
goto alloc_fail7;
}
@@ -1086,6 +1086,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
.driver_info = SINGLE_RX_URB, /* firmware bug */
},
{ USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
.driver_info = SINGLE_RX_URB, /* firmware bug */
},
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_V25TER) },

View File

@@ -31,9 +31,6 @@ config USB_DEVICEFS
For the format of the various /proc/bus/usb/ files, please read
<file:Documentation/usb/proc_usb_info.txt>.
Please note that this code is completely unrelated to devfs, the
"/dev file system support".
Most users want to say Y here.
config USB_BANDWIDTH

View File

@@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
static struct usb_device *usbdev_lookup_minor(int minor)
{
struct device *device;
struct usb_device *udev = NULL;
struct class_device *class_dev;
struct usb_device *dev = NULL;
down(&usb_device_class->sem);
list_for_each_entry(device, &usb_device_class->devices, node) {
if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
udev = device->platform_data;
list_for_each_entry(class_dev, &usb_device_class->children, node) {
if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
dev = class_dev->class_data;
break;
}
}
up(&usb_device_class->sem);
return udev;
return dev;
};
/*
@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev)
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
dev->usbfs_dev = device_create(usb_device_class, &dev->dev,
MKDEV(USB_DEVICE_MAJOR, minor),
dev->class_dev = class_device_create(usb_device_class, NULL,
MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
"usbdev%d.%d", dev->bus->busnum, dev->devnum);
dev->usbfs_dev->platform_data = dev;
dev->class_dev->class_data = dev;
}
static void usbdev_remove(struct usb_device *dev)
{
device_unregister(dev->usbfs_dev);
class_device_unregister(dev->class_dev);
}
static int usbdev_notify(struct notifier_block *self, unsigned long action,

View File

@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
intf->usb_dev = device_create(usb_class->class, &intf->dev,
MKDEV(USB_MAJOR, minor), "%s", temp);
if (IS_ERR(intf->usb_dev)) {
intf->class_dev = class_device_create(usb_class->class, NULL,
MKDEV(USB_MAJOR, minor),
&intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
spin_unlock (&minor_lock);
retval = PTR_ERR(intf->usb_dev);
retval = PTR_ERR(intf->class_dev);
}
exit:
return retval;
@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf,
spin_unlock (&minor_lock);
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->usb_dev = NULL;
class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->class_dev = NULL;
intf->minor = -1;
destroy_usb_class();
}

View File

@@ -1790,7 +1790,10 @@ static int finish_device_resume(struct usb_device *udev)
* and device drivers will know about any resume quirks.
*/
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
if (status < 2)
if (status >= 0)
status = (status == 2 ? 0 : -ENODEV);
if (status)
dev_dbg(&udev->dev,
"gone after usb resume? status %d\n",
status);
@@ -1879,7 +1882,12 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
port1, portchange, devstatus, status);
if (status >= 0)
status = -ENODEV;
} else {
if (portchange & USB_PORT_STAT_C_SUSPEND)
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_SUSPEND);
/* TRSMRCY = 10 msec */
msleep(10);
if (udev)

View File

@@ -695,7 +695,7 @@ static void usbfs_remove_device(struct usb_device *dev)
wake_up_all(&ds->wait);
list_del_init(&ds->list);
if (ds->discsignr) {
sinfo.si_signo = SIGPIPE;
sinfo.si_signo = ds->discsignr;
sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = ds->disccontext;

View File

@@ -207,7 +207,7 @@ config USB_AT91
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
depends on USB && EXPERIMENTAL
depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
select USB_GADGET_DUALSPEED
help
This host controller driver emulates USB, looping all data transfer

View File

@@ -57,19 +57,23 @@
/*
* This controller is simple and PIO-only. It's used in many AT91-series
* ARMv4T controllers, including the at91rm9200 (arm920T, with MMU),
* at91sam9261 (arm926ejs, with MMU), and several no-mmu versions.
* full speed USB controllers, including the at91rm9200 (arm920T, with MMU),
* at91sam926x (arm926ejs, with MMU), and several no-mmu versions.
*
* This driver expects the board has been wired with two GPIOs suppporting
* a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the
* testing hasn't covered such cases.) The pullup is most important; it
* testing hasn't covered such cases.)
*
* The pullup is most important (so it's integrated on sam926x parts). It
* provides software control over whether the host enumerates the device.
*
* The VBUS sensing helps during enumeration, and allows both USB clocks
* (and the transceiver) to stay gated off until they're necessary, saving
* power. During USB suspend, the 48 MHz clock is gated off.
* power. During USB suspend, the 48 MHz clock is gated off in hardware;
* it may also be gated off by software during some Linux sleep states.
*/
#define DRIVER_VERSION "8 March 2005"
#define DRIVER_VERSION "3 May 2006"
static const char driver_name [] = "at91_udc";
static const char ep0name[] = "ep0";
@@ -316,9 +320,15 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status)
*
* There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE
* that shouldn't normally be changed.
*
* NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains,
* implying a need to wait for one write to complete (test relevant bits)
* before starting the next write. This shouldn't be an issue given how
* infrequently we write, except maybe for write-then-read idioms.
*/
#define SET_FX (AT91_UDP_TXPKTRDY)
#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \
| AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
/* pull OUT packet data from the endpoint's fifo */
static int read_fifo (struct at91_ep *ep, struct at91_request *req)
@@ -472,7 +482,8 @@ static void nuke(struct at91_ep *ep, int status)
/*-------------------------------------------------------------------------*/
static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
static int at91_ep_enable(struct usb_ep *_ep,
const struct usb_endpoint_descriptor *desc)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
struct at91_udc *dev = ep->udc;
@@ -582,11 +593,12 @@ static int at91_ep_disable (struct usb_ep * _ep)
* interesting for request or buffer allocation.
*/
static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags)
static struct usb_request *
at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
{
struct at91_request *req;
req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
if (!req)
return NULL;
@@ -862,6 +874,7 @@ static void stop_activity(struct at91_udc *udc)
if (udc->gadget.speed == USB_SPEED_UNKNOWN)
driver = NULL;
udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->suspended = 0;
for (i = 0; i < NUM_ENDPOINTS; i++) {
struct at91_ep *ep = &udc->ep[i];
@@ -889,8 +902,8 @@ static void clk_off(struct at91_udc *udc)
return;
udc->clocked = 0;
udc->gadget.speed = USB_SPEED_UNKNOWN;
clk_disable(udc->iclk);
clk_disable(udc->fclk);
clk_disable(udc->iclk);
}
/*
@@ -911,9 +924,6 @@ static void pullup(struct at91_udc *udc, int is_on)
at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_set_gpio_value(udc->board.pullup_pin, 0);
clk_off(udc);
// REVISIT: with transceiver disabled, will D- float
// so that a host would falsely detect a device?
}
}
@@ -1290,7 +1300,8 @@ static void handle_ep0(struct at91_udc *udc)
if (udc->wait_for_addr_ack) {
u32 tmp;
at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr);
at91_udp_write(AT91_UDP_FADDR,
AT91_UDP_FEN | udc->addr);
tmp = at91_udp_read(AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_FADDEN;
if (udc->addr)
@@ -1361,9 +1372,10 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
u32 rescans = 5;
while (rescans--) {
u32 status = at91_udp_read(AT91_UDP_ISR);
u32 status;
status &= at91_udp_read(AT91_UDP_IMR);
status = at91_udp_read(AT91_UDP_ISR)
& at91_udp_read(AT91_UDP_IMR);
if (!status)
break;
@@ -1379,18 +1391,17 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
stop_activity(udc);
/* enable ep0 */
at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
at91_udp_write(AT91_UDP_CSR(0),
AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
udc->gadget.speed = USB_SPEED_FULL;
udc->suspended = 0;
at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
/*
* NOTE: this driver keeps clocks off unless the
* USB host is present. That saves power, and also
* eliminates IRQs (reset, resume, suspend) that can
* otherwise flood from the controller. If your
* board doesn't support VBUS detection, suspend and
* resume irq logic may need more attention...
* USB host is present. That saves power, but for
* boards that don't support VBUS detection, both
* clocks need to be active most of the time.
*/
/* host initiated suspend (3+ms bus idle) */
@@ -1452,13 +1463,19 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
/*-------------------------------------------------------------------------*/
static void nop_release(struct device *dev)
{
/* nothing to free */
}
static struct at91_udc controller = {
.gadget = {
.ops = &at91_udc_ops,
.ep0 = &controller.ep[0].ep,
.name = driver_name,
.dev = {
.bus_id = "gadget"
.ops = &at91_udc_ops,
.ep0 = &controller.ep[0].ep,
.name = driver_name,
.dev = {
.bus_id = "gadget",
.release = nop_release,
}
},
.ep[0] = {
@@ -1468,7 +1485,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(0)),
.int_mask = 1 << 0,
},
.ep[1] = {
@@ -1479,7 +1497,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(1)),
.int_mask = 1 << 1,
},
.ep[2] = {
@@ -1490,7 +1509,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(2)),
.int_mask = 1 << 2,
},
.ep[3] = {
@@ -1501,7 +1521,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(3)),
.int_mask = 1 << 3,
},
.ep[4] = {
@@ -1512,7 +1533,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(4)),
.int_mask = 1 << 4,
},
.ep[5] = {
@@ -1523,10 +1545,11 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(5)),
.int_mask = 1 << 5,
},
/* ep6 and ep7 are also reserved */
/* ep6 and ep7 are also reserved (custom silicon might use them) */
};
static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
@@ -1593,6 +1616,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
local_irq_disable();
udc->enabled = 0;
at91_udp_write(AT91_UDP_IDR, ~0);
pullup(udc, 0);
local_irq_enable();
@@ -1624,6 +1648,16 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
return -ENODEV;
}
if (pdev->num_resources != 2) {
DBG("invalid num_resources");
return -ENODEV;
}
if ((pdev->resource[0].flags != IORESOURCE_MEM)
|| (pdev->resource[1].flags != IORESOURCE_IRQ)) {
DBG("invalid resource type");
return -ENODEV;
}
if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
DBG("someone's using UDC memory\n");
return -EBUSY;
@@ -1649,19 +1683,26 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
if (retval < 0)
goto fail0;
/* disable everything until there's a gadget driver and vbus */
pullup(udc, 0);
/* don't do anything until we have both gadget driver and VBUS */
clk_enable(udc->iclk);
at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_udp_write(AT91_UDP_IDR, 0xffffffff);
clk_disable(udc->iclk);
/* request UDC and maybe VBUS irqs */
if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) {
DBG("request irq %d failed\n", AT91_ID_UDP);
udc->udp_irq = platform_get_irq(pdev, 0);
if (request_irq(udc->udp_irq, at91_udc_irq,
IRQF_DISABLED, driver_name, udc)) {
DBG("request irq %d failed\n", udc->udp_irq);
retval = -EBUSY;
goto fail1;
}
if (udc->board.vbus_pin > 0) {
if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) {
DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
free_irq(AT91_ID_UDP, udc);
if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
IRQF_DISABLED, driver_name, udc)) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
free_irq(udc->udp_irq, udc);
retval = -EBUSY;
goto fail1;
}
@@ -1670,6 +1711,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
udc->vbus = 1;
}
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
@@ -1678,14 +1720,14 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
fail1:
device_unregister(&udc->gadget.dev);
fail0:
release_mem_region(AT91_VA_BASE_UDP, SZ_16K);
release_mem_region(AT91_BASE_UDP, SZ_16K);
DBG("%s probe failed, %d\n", driver_name, retval);
return retval;
}
static int __devexit at91udc_remove(struct platform_device *dev)
static int __devexit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
DBG("remove\n");
@@ -1694,10 +1736,11 @@ static int __devexit at91udc_remove(struct platform_device *dev)
if (udc->driver != 0)
usb_gadget_unregister_driver(udc->driver);
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
if (udc->board.vbus_pin > 0)
free_irq(udc->board.vbus_pin, udc);
free_irq(AT91_ID_UDP, udc);
free_irq(udc->udp_irq, udc);
device_unregister(&udc->gadget.dev);
release_mem_region(AT91_BASE_UDP, SZ_16K);
@@ -1708,31 +1751,36 @@ static int __devexit at91udc_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg)
static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
int wake = udc->driver && device_may_wakeup(&pdev->dev);
/*
* The "safe" suspend transitions are opportunistic ... e.g. when
* the USB link is suspended (48MHz clock autogated off), or when
* it's disconnected (programmatically gated off, elsewhere).
* Then we can suspend, and the chip can enter slow clock mode.
*
* The problem case is some component (user mode?) suspending this
* device while it's active, with the 48 MHz clock in use. There
* are two basic approaches: (a) veto suspend levels involving slow
* clock mode, (b) disconnect, so 48 MHz will no longer be in use
* and we can enter slow clock mode. This uses (b) for now, since
* it's simplest until AT91 PM exists and supports the other option.
/* Unless we can act normally to the host (letting it wake us up
* whenever it has work for us) force disconnect. Wakeup requires
* PLLB for USB events (signaling for reset, wakeup, or incoming
* tokens) and VBUS irqs (on systems which support them).
*/
if (udc->vbus && !udc->suspended)
if ((!udc->suspended && udc->addr)
|| !wake
|| at91_suspend_entering_slow_clock()) {
pullup(udc, 0);
disable_irq_wake(udc->udp_irq);
} else
enable_irq_wake(udc->udp_irq);
if (udc->board.vbus_pin > 0) {
if (wake)
enable_irq_wake(udc->board.vbus_pin);
else
disable_irq_wake(udc->board.vbus_pin);
}
return 0;
}
static int at91udc_resume(struct platform_device *dev)
static int at91udc_resume(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
/* maybe reconnect to host; if so, clocks on */
pullup(udc, 1);
@@ -1748,7 +1796,7 @@ static struct platform_driver at91_udc = {
.remove = __devexit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
.suspend = at91udc_suspend,
.resume = at91udc_resume,
.resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
@@ -1767,6 +1815,6 @@ static void __devexit udc_exit_module(void)
}
module_exit(udc_exit_module);
MODULE_DESCRIPTION("AT91RM9200 udc driver");
MODULE_DESCRIPTION("AT91 udc driver");
MODULE_AUTHOR("Thomas Rathbone, David Brownell");
MODULE_LICENSE("GPL");

View File

@@ -141,6 +141,7 @@ struct at91_udc {
struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
int udp_irq;
};
static inline struct at91_udc *to_udc(struct usb_gadget *g)

View File

@@ -609,7 +609,8 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
if (!dum->driver)
return -ESHUTDOWN;
spin_lock_irqsave (&dum->lock, flags);
local_irq_save (flags);
spin_lock (&dum->lock);
list_for_each_entry (req, &ep->queue, queue) {
if (&req->req == _req) {
list_del_init (&req->queue);
@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
break;
}
}
spin_unlock_irqrestore (&dum->lock, flags);
spin_unlock (&dum->lock);
if (retval == 0) {
dev_dbg (udc_dev(dum),
@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
req, _ep->name, _req->length, _req->buf);
_req->complete (_ep, _req);
}
local_irq_restore (flags);
return retval;
}

View File

@@ -34,12 +34,12 @@
/* we must assign addresses for configurable endpoints (like net2280) */
static __initdata unsigned epnum;
static __devinitdata unsigned epnum;
// #define MANY_ENDPOINTS
#ifdef MANY_ENDPOINTS
/* more than 15 configurable endpoints */
static __initdata unsigned in_epnum;
static __devinitdata unsigned in_epnum;
#endif
@@ -59,7 +59,7 @@ static __initdata unsigned in_epnum;
* NOTE: each endpoint is unidirectional, as specified by its USB
* descriptor; and isn't specific to a configuration or altsetting.
*/
static int __init
static int __devinit
ep_matches (
struct usb_gadget *gadget,
struct usb_ep *ep,
@@ -73,7 +73,7 @@ ep_matches (
/* endpoint already claimed? */
if (0 != ep->driver_data)
return 0;
/* only support ep0 for portable CONTROL traffic */
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
if (USB_ENDPOINT_XFER_CONTROL == type)
@@ -186,7 +186,7 @@ ep_matches (
return 1;
}
static struct usb_ep * __init
static struct usb_ep * __devinit
find_ep (struct usb_gadget *gadget, const char *name)
{
struct usb_ep *ep;
@@ -228,7 +228,7 @@ find_ep (struct usb_gadget *gadget, const char *name)
*
* On failure, this returns a null endpoint descriptor.
*/
struct usb_ep * __init usb_ep_autoconfig (
struct usb_ep * __devinit usb_ep_autoconfig (
struct usb_gadget *gadget,
struct usb_endpoint_descriptor *desc
)
@@ -276,7 +276,7 @@ struct usb_ep * __init usb_ep_autoconfig (
return ep;
}
/* Second, look at endpoints until an unclaimed one looks usable */
/* Second, look at endpoints until an unclaimed one looks usable */
list_for_each_entry (ep, &gadget->ep_list, ep_list) {
if (ep_matches (gadget, ep, desc))
return ep;
@@ -295,7 +295,7 @@ struct usb_ep * __init usb_ep_autoconfig (
* state such as ep->driver_data and the record of assigned endpoints
* used by usb_ep_autoconfig().
*/
void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
void __devinit usb_ep_autoconfig_reset (struct usb_gadget *gadget)
{
struct usb_ep *ep;

View File

@@ -2131,7 +2131,7 @@ eth_req_free (struct usb_ep *ep, struct usb_request *req)
}
static void __exit
static void /* __init_or_exit */
eth_unbind (struct usb_gadget *gadget)
{
struct eth_dev *dev = get_gadget_data (gadget);
@@ -2158,7 +2158,7 @@ eth_unbind (struct usb_gadget *gadget)
set_gadget_data (gadget, NULL);
}
static u8 __init nibble (unsigned char c)
static u8 __devinit nibble (unsigned char c)
{
if (likely (isdigit (c)))
return c - '0';
@@ -2168,7 +2168,7 @@ static u8 __init nibble (unsigned char c)
return 0;
}
static int __init get_ether_addr(const char *str, u8 *dev_addr)
static int __devinit get_ether_addr(const char *str, u8 *dev_addr)
{
if (str) {
unsigned i;
@@ -2189,7 +2189,7 @@ static int __init get_ether_addr(const char *str, u8 *dev_addr)
return 1;
}
static int __init
static int __devinit
eth_bind (struct usb_gadget *gadget)
{
struct eth_dev *dev;

View File

@@ -3691,7 +3691,7 @@ static void lun_release(struct device *dev)
kref_put(&fsg->ref, fsg_release);
}
static void __exit fsg_unbind(struct usb_gadget *gadget)
static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
{
struct fsg_dev *fsg = get_gadget_data(gadget);
int i;

View File

@@ -1398,7 +1398,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
int __init rndis_init (void)
int __devinit rndis_init (void)
{
u8 i;

View File

@@ -264,7 +264,7 @@ int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);
int __init rndis_init (void);
int __devinit rndis_init (void);
void rndis_exit (void);
#endif /* _LINUX_RNDIS_H */

View File

@@ -1473,7 +1473,7 @@ autoconf_fail:
* Called on module unload. Frees the control request and device
* structure.
*/
static void __exit gs_unbind(struct usb_gadget *gadget)
static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
{
struct gs_dev *dev = get_gadget_data(gadget);

View File

@@ -1121,7 +1121,7 @@ zero_autoresume (unsigned long _dev)
/*-------------------------------------------------------------------------*/
static void __exit
static void /* __init_or_exit */
zero_unbind (struct usb_gadget *gadget)
{
struct zero_dev *dev = get_gadget_data (gadget);

View File

@@ -41,8 +41,6 @@
#endif
#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
#endif /* Au1200 */
extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
@@ -107,9 +105,9 @@ int usb_ehci_au1xxx_probe(const struct hc_driver *driver,
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
pr_info("%s: this is chip revision AB!\n", dev->dev.name);
pr_info("%s: this is chip revision AB!\n", dev->name);
pr_info("%s: update your board or re-configure the kernel\n",
dev->dev.name);
dev->name);
return -ENODEV;
}
#endif
@@ -228,9 +226,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
/*-------------------------------------------------------------------------*/
static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
{
struct platform_device *pdev = to_platform_device(dev);
struct usb_hcd *hcd = NULL;
int ret;
@@ -243,10 +240,9 @@ static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
return ret;
}
static int ehci_hcd_au1xxx_drv_remove(struct device *dev)
static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
{
struct platform_device *pdev = to_platform_device(dev);
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_ehci_au1xxx_remove(hcd, pdev);
return 0;
@@ -269,12 +265,13 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
}
*/
MODULE_ALIAS("au1xxx-ehci");
/* FIXME use "struct platform_driver" */
static struct device_driver ehci_hcd_au1xxx_driver = {
.name = "au1xxx-ehci",
.bus = &platform_bus_type,
static struct platform_driver ehci_hcd_au1xxx_driver = {
.probe = ehci_hcd_au1xxx_drv_probe,
.remove = ehci_hcd_au1xxx_drv_remove,
/*.suspend = ehci_hcd_au1xxx_drv_suspend, */
/*.resume = ehci_hcd_au1xxx_drv_resume, */
.driver = {
.name = "au1xxx-ehci",
.bus = &platform_bus_type
}
};

View File

@@ -625,10 +625,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
writel (status | CMD_RUN, &ehci->regs->command);
while (i--) {
status = readl (&ehci->regs->port_status [i]);
if (status & PORT_OWNER)
int pstatus = readl (&ehci->regs->port_status [i]);
if (pstatus & PORT_OWNER)
continue;
if (!(status & PORT_RESUME)
if (!(pstatus & PORT_RESUME)
|| ehci->reset_done [i] != 0)
continue;
@@ -891,7 +892,7 @@ MODULE_LICENSE ("GPL");
#define PCI_DRIVER ehci_pci_driver
#endif
#ifdef CONFIG_PPC_83xx
#ifdef CONFIG_MPC834x
#include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver
#endif

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2004 SAN People (Pty) Ltd.
* Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
*
* AT91RM9200 Bus Glue
* AT91 Bus Glue
*
* Based on fragments of 2.4 driver by Rick Bronson.
* Based on ohci-omap.c
@@ -19,12 +19,13 @@
#include <asm/hardware.h>
#include <asm/arch/board.h>
#ifndef CONFIG_ARCH_AT91RM9200
#error "CONFIG_ARCH_AT91RM9200 must be defined."
#ifndef CONFIG_ARCH_AT91
#error "CONFIG_ARCH_AT91 must be defined."
#endif
/* interface and function clocks */
static struct clk *iclk, *fclk;
static int clocked;
extern int usb_disabled(void);
@@ -35,13 +36,14 @@ static void at91_start_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs;
dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n");
dev_dbg(&pdev->dev, "start\n");
/*
* Start the USB clocks.
*/
clk_enable(iclk);
clk_enable(fclk);
clocked = 1;
/*
* The USB host controller must remain in reset.
@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs;
dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n");
dev_dbg(&pdev->dev, "stop\n");
/*
* Put the USB host controller into reset.
@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform_device *pdev)
*/
clk_disable(fclk);
clk_disable(iclk);
clocked = 0;
}
@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/**
* usb_hcd_at91_probe - initialize AT91RM9200-based HCDs
* usb_hcd_at91_probe - initialize AT91-based HCDs
* Context: !in_interrupt()
*
* 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.
*/
int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev)
static int usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
struct usb_hcd *hcd = NULL;
@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *
return -ENODEV;
}
if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
if ((pdev->resource[0].flags != IORESOURCE_MEM)
|| (pdev->resource[1].flags != IORESOURCE_IRQ)) {
pr_debug("hcd probe: invalid resource type\n");
return -ENODEV;
}
hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200");
hcd = usb_create_hcd(driver, &pdev->dev, "at91");
if (!hcd)
return -ENOMEM;
hcd->rsrc_start = pdev->resource[0].start;
@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *
/* may be called with controller, bus, and devices active */
/**
* usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs
* usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
* @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_at91_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
* context, "rmmod" or something similar.
*
*/
static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev)
static int usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
at91_stop_hc(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
disable_irq_wake(hcd->irq);
clk_put(fclk);
clk_put(iclk);
@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde
static int __devinit
ohci_at91_start (struct usb_hcd *hcd)
{
// struct at91_ohci_data *board = hcd->self.controller->platform_data;
struct at91_usbh_data *board = hcd->self.controller->platform_data;
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct usb_device *root = hcd->self.root_hub;
int ret;
if ((ret = ohci_init(ohci)) < 0)
return ret;
root->maxchild = board->ports;
if ((ret = ohci_run(ohci)) < 0) {
err("can't start %s", hcd->self.bus_name);
ohci_stop(hcd);
return ret;
}
// hcd->self.root_hub->maxchild = board->ports;
return 0;
}
@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd)
static const struct hc_driver ohci_at91_hc_driver = {
.description = hcd_name,
.product_desc = "AT91RM9200 OHCI",
.product_desc = "AT91 OHCI",
.hcd_priv_size = sizeof(struct ohci_hcd),
/*
@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_hc_driver = {
/*-------------------------------------------------------------------------*/
static int ohci_hcd_at91_drv_probe(struct platform_device *dev)
static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev);
device_init_wakeup(&pdev->dev, 1);
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
static int ohci_hcd_at91_drv_remove(struct platform_device *dev)
static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
return usb_hcd_at91_remove(platform_get_drvdata(dev), dev);
device_init_wakeup(&pdev->dev, 0);
return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
}
#ifdef CONFIG_PM
/* REVISIT suspend/resume look "too" simple here */
static int
ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg)
ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
{
clk_disable(fclk);
clk_disable(iclk);
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(hcd->irq);
else
disable_irq_wake(hcd->irq);
/*
* The integrated transceivers seem unable to notice disconnect,
* reconnect, or wakeup without the 48 MHz clock active. so for
* correctness, always discard connection state (using reset).
*
* REVISIT: some boards will be able to turn VBUS off...
*/
if (at91_suspend_entering_slow_clock()) {
ohci_usb_reset (ohci);
clk_disable(fclk);
clk_disable(iclk);
clocked = 0;
}
return 0;
}
static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
{
clk_enable(iclk);
clk_enable(fclk);
if (!clocked) {
clk_enable(iclk);
clk_enable(fclk);
}
return 0;
}
@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
#define ohci_hcd_at91_drv_resume NULL
#endif
MODULE_ALIAS("at91rm9200-ohci");
MODULE_ALIAS("at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_at91_driver = {
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
.driver = {
.name = "at91rm9200-ohci",
.name = "at91_ohci",
.owner = THIS_MODULE,
},
};

View File

@@ -101,13 +101,16 @@ static void au1xxx_start_ohc(struct platform_device *dev)
#endif /* Au1200 */
#ifndef CONFIG_SOC_AU1200
/* wait for reset complete (read register twice; see au1500 errata) */
while (au_readl(USB_HOST_CONFIG),
!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
#endif
udelay(1000);
printk(KERN_DEBUG __FILE__
": Clock to USB host has been enabled \n");
#endif
}
static void au1xxx_stop_ohc(struct platform_device *dev)
@@ -157,9 +160,9 @@ static int usb_ohci_au1xxx_probe(const struct hc_driver *driver,
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
pr_info("%s: this is chip revision AB !!\n",
dev->dev.name);
dev->name);
pr_info("%s: update your board or re-configure the kernel\n",
dev->dev.name);
dev->name);
return -ENODEV;
}
#endif

View File

@@ -0,0 +1,225 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
* (C) Copyright 2002 Hewlett-Packard Company
*
* Bus Glue for ep93xx.
*
* Written by Christopher Hoover <ch@hpl.hp.com>
* Based on fragments of previous driver by Russell King et al.
*
* Modified for LH7A404 from ohci-sa1111.c
* by Durgesh Pattamatta <pattamattad@sharpsec.com>
*
* Modified for pxa27x from ohci-lh7a404.c
* by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
*
* Modified for ep93xx from ohci-pxa27x.c
* by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
* Based on an earlier driver by Ray Lehtiniemi
*
* This file is licenced under the GPL.
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/signal.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
static struct clk *usb_host_clock;
static void ep93xx_start_hc(struct device *dev)
{
clk_enable(usb_host_clock);
}
static void ep93xx_stop_hc(struct device *dev)
{
clk_disable(usb_host_clock);
}
static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
struct usb_hcd *hcd;
if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ");
return -ENOMEM;
}
hcd = usb_create_hcd(driver, &pdev->dev, "ep93xx");
if (hcd == NULL)
return -ENOMEM;
hcd->rsrc_start = pdev->resource[0].start;
hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
usb_put_hcd(hcd);
retval = -EBUSY;
goto err1;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
pr_debug("ioremap failed");
retval = -ENOMEM;
goto err2;
}
usb_host_clock = clk_get(&pdev->dev, "usb_host");
ep93xx_start_hc(&pdev->dev);
ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
if (retval == 0)
return retval;
ep93xx_stop_hc(&pdev->dev);
iounmap(hcd->regs);
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
usb_put_hcd(hcd);
return retval;
}
static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
ep93xx_stop_hc(&pdev->dev);
clk_put(usb_host_clock);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
if ((ret = ohci_init(ohci)) < 0)
return ret;
if ((ret = ohci_run(ohci)) < 0) {
err("can't start %s", hcd->self.bus_name);
ohci_stop(hcd);
return ret;
}
return 0;
}
static struct hc_driver ohci_ep93xx_hc_driver = {
.description = hcd_name,
.product_desc = "EP93xx OHCI",
.hcd_priv_size = sizeof(struct ohci_hcd),
.irq = ohci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.start = ohci_ep93xx_start,
.stop = ohci_stop,
.urb_enqueue = ohci_urb_enqueue,
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
.get_frame_number = ohci_get_frame,
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
#ifdef CONFIG_PM
.bus_suspend = ohci_bus_suspend,
.bus_resume = ohci_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
extern int usb_disabled(void);
static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
{
int ret;
ret = -ENODEV;
if (!usb_disabled())
ret = usb_hcd_ep93xx_probe(&ohci_ep93xx_hc_driver, pdev);
return ret;
}
static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_hcd_ep93xx_remove(hcd, pdev);
return 0;
}
#ifdef CONFIG_PM
static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ochi_hcd *ohci = hcd_to_ohci(hcd);
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
ep93xx_stop_hc(&pdev->dev);
hcd->state = HC_STATE_SUSPENDED;
pdev->dev.power.power_state = PMSG_SUSPEND;
return 0;
}
static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int status;
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
ep93xx_start_hc(&pdev->dev);
pdev->dev.power.power_state = PMSG_ON;
usb_hcd_resume_root_hub(hcd);
return 0;
}
#endif
static struct platform_driver ohci_hcd_ep93xx_driver = {
.probe = ohci_hcd_ep93xx_drv_probe,
.remove = ohci_hcd_ep93xx_drv_remove,
#ifdef CONFIG_PM
.suspend = ohci_hcd_ep93xx_drv_suspend,
.resume = ohci_hcd_ep93xx_drv_resume,
#endif
.driver = {
.name = "ep93xx-ohci",
},
};
static int __init ohci_hcd_ep93xx_init(void)
{
return platform_driver_register(&ohci_hcd_ep93xx_driver);
}
static void __exit ohci_hcd_ep93xx_cleanup(void)
{
platform_driver_unregister(&ohci_hcd_ep93xx_driver);
}
module_init(ohci_hcd_ep93xx_init);
module_exit(ohci_hcd_ep93xx_cleanup);

View File

@@ -901,6 +901,10 @@ MODULE_LICENSE ("GPL");
#include "ohci-pxa27x.c"
#endif
#ifdef CONFIG_ARCH_EP93XX
#include "ohci-ep93xx.c"
#endif
#ifdef CONFIG_SOC_AU1X00
#include "ohci-au1xxx.c"
#endif
@@ -909,7 +913,7 @@ MODULE_LICENSE ("GPL");
#include "ohci-ppc-soc.c"
#endif
#ifdef CONFIG_ARCH_AT91RM9200
#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
#include "ohci-at91.c"
#endif
@@ -919,9 +923,11 @@ MODULE_LICENSE ("GPL");
|| defined(CONFIG_ARCH_OMAP) \
|| defined (CONFIG_ARCH_LH7A404) \
|| defined (CONFIG_PXA27x) \
|| defined (CONFIG_ARCH_EP93XX) \
|| defined (CONFIG_SOC_AU1X00) \
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|| defined (CONFIG_ARCH_AT91RM9200) \
|| defined (CONFIG_ARCH_AT91SAM9261) \
)
#error "missing bus glue for ohci-hcd"
#endif

View File

@@ -581,14 +581,14 @@ static int ohci_hub_control (
break;
case GetHubStatus:
temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
*(__le32 *) buf = cpu_to_le32 (temp);
put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
temp = roothub_portstatus (ohci, wIndex);
*(__le32 *) buf = cpu_to_le32 (temp);
put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */

View File

@@ -167,8 +167,6 @@ static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
{
void __iomem *base;
int wait_time;
u32 control;
if (!mmio_resource_enabled(pdev, 0))
return;
@@ -179,9 +177,10 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
#ifndef __hppa__
control = readl(base + OHCI_CONTROL);
{
u32 control = readl(base + OHCI_CONTROL);
if (control & OHCI_CTRL_IR) {
wait_time = 500; /* arbitrary; 5 seconds */
int wait_time = 500; /* arbitrary; 5 seconds */
writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
writel(OHCI_OCR, base + OHCI_CMDSTATUS);
while (wait_time > 0 &&
@@ -198,6 +197,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
/* reset controller, preserving RWC */
writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
}
}
#endif
/*

View File

@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
/* We received a short packet */
if (urb->transfer_flags & URB_SHORT_NOT_OK)
ret = -EREMOTEIO;
else if (ctrlstat & TD_CTRL_SPD)
/* Fixup needed only if this isn't the URB's last TD */
else if (&td->list != urbp->td_list.prev)
ret = 1;
}

View File

@@ -152,9 +152,8 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
* events. The hardware generates 5 events for the first keypress
* and we have to take this into account for an accurate repeat
* behaviour.
* (HZ / 20) == 50 ms and works well for me.
*/
#define FILTER_TIME (HZ / 20)
#define FILTER_TIME 60 /* msec */
struct ati_remote {
struct input_dev *idev;
@@ -467,7 +466,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
/* Filter duplicate events which happen "too close" together. */
if ((ati_remote->old_data[0] == data[1]) &&
(ati_remote->old_data[1] == data[2]) &&
time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) {
time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(FILTER_TIME))) {
ati_remote->repeat_count++;
} else {
ati_remote->repeat_count = 0;

View File

@@ -1507,6 +1507,9 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677
#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
#define USB_VENDOR_ID_CODEMERCS 0x07c0
#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
@@ -1670,6 +1673,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },

View File

@@ -88,19 +88,19 @@ config USB_LED
To compile this driver as a module, choose M here: the
module will be called usbled.
config USB_CY7C63
config USB_CYPRESS_CY7C63
tristate "Cypress CY7C63xxx USB driver support"
depends on USB
help
Say Y here if you want to connect a Cypress CY7C63xxx
micro controller to your computer's USB port. This driver
supports the pre-programmed devices (incl. firmware) by
AK Modul-Bus Computer GmbH.
micro controller to your computer's USB port. Currently this
driver supports the pre-programmed devices (incl. firmware)
by AK Modul-Bus Computer GmbH.
Please see: http://www.ak-modul-bus.de/stat/mikrocontroller.html
To compile this driver as a module, choose M here: the
module will be called cy7c63.
module will be called cypress_cy7c63.
config USB_CYTHERM
tristate "Cypress USB thermometer driver support"

View File

@@ -4,7 +4,7 @@
#
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
obj-$(CONFIG_USB_CY7C63) += cy7c63.o
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o
obj-$(CONFIG_USB_EMI26) += emi26.o
obj-$(CONFIG_USB_EMI62) += emi62.o

View File

@@ -1,244 +0,0 @@
/*
* cy7c63.c
*
* Copyright (c) 2006 Oliver Bock (bock@fh-wolfenbuettel.de)
*
* This driver is based on the Cypress Thermometer USB Driver by
* Marcus Maul and the 2.0 version of Greg Kroah-Hartman's
* USB Skeleton driver.
*
* Is is a generic driver for the Cypress CY7C63000 family.
* For the time being it enables you to toggle the single I/O ports
* of the device.
*
* Supported vendors: AK Modul-Bus Computer GmbH
* Supported devices: CY7C63001A-PC (to be continued...)
* Supported functions: Read/Write Ports (to be continued...)
*
* Chipsets families: CY7C63000, CY7C63001, CY7C63100, CY7C63101
*
*
* 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, version 2.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#define DRIVER_AUTHOR "Oliver Bock (bock@fh-wolfenbuettel.de)"
#define DRIVER_DESC "Cypress CY7C63xxx USB driver"
#define CY7C63_VENDOR_ID 0xa2c
#define CY7C63_PRODUCT_ID 0x8
#define CY7C63_READ_PORT 0x4
#define CY7C63_WRITE_PORT 0x5
#define CY7C63_READ_RAM 0x2
#define CY7C63_WRITE_RAM 0x3
#define CY7C63_READ_ROM 0x1
#define CY7C63_READ_PORT_ID0 0
#define CY7C63_WRITE_PORT_ID0 0
#define CY7C63_READ_PORT_ID1 0x2
#define CY7C63_WRITE_PORT_ID1 1
#define CY7C63_MAX_REQSIZE 8
/* table of devices that work with this driver */
static struct usb_device_id cy7c63_table [] = {
{ USB_DEVICE(CY7C63_VENDOR_ID, CY7C63_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, cy7c63_table);
/* structure to hold all of our device specific stuff */
struct cy7c63 {
struct usb_device * udev;
char port0;
char port1;
};
/* used to send usb control messages to device */
int vendor_command(struct cy7c63 *dev, unsigned char request,
unsigned char address, unsigned char data) {
int retval = 0;
unsigned int pipe;
unsigned char *iobuf;
/* allocate some memory for the i/o buffer*/
iobuf = kzalloc(CY7C63_MAX_REQSIZE, GFP_KERNEL);
if (!iobuf) {
dev_err(&dev->udev->dev, "Out of memory!\n");
retval = -ENOMEM;
goto error;
}
dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
/* prepare usb control message and send it upstream */
pipe = usb_rcvctrlpipe(dev->udev, 0);
retval = usb_control_msg(dev->udev, pipe, request,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
address, data, iobuf, CY7C63_MAX_REQSIZE,
USB_CTRL_GET_TIMEOUT);
/* store returned data (more READs to be added!) */
switch (request) {
case CY7C63_READ_PORT:
if (address == CY7C63_READ_PORT_ID0) {
dev->port0 = iobuf[1];
dev_dbg(&dev->udev->dev,
"READ_PORT0 returned: %d\n",dev->port0);
}
else if (address == CY7C63_READ_PORT_ID1) {
dev->port1 = iobuf[1];
dev_dbg(&dev->udev->dev,
"READ_PORT1 returned: %d\n",dev->port1);
}
break;
}
kfree(iobuf);
error:
return retval;
}
#define get_set_port(num,read_id,write_id) \
static ssize_t set_port##num(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) { \
\
int value; \
int result = 0; \
\
struct usb_interface *intf = to_usb_interface(dev); \
struct cy7c63 *cyp = usb_get_intfdata(intf); \
\
dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", num); \
\
/* validate input data */ \
if (sscanf(buf, "%d", &value) < 1) { \
result = -EINVAL; \
goto error; \
} \
if (value>255 || value<0) { \
result = -EINVAL; \
goto error; \
} \
\
result = vendor_command(cyp, CY7C63_WRITE_PORT, write_id, \
(unsigned char)value); \
\
dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n",result); \
error: \
return result < 0 ? result : count; \
} \
\
static ssize_t get_port##num(struct device *dev, \
struct device_attribute *attr, char *buf) { \
\
int result = 0; \
\
struct usb_interface *intf = to_usb_interface(dev); \
struct cy7c63 *cyp = usb_get_intfdata(intf); \
\
dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", num); \
\
result = vendor_command(cyp, CY7C63_READ_PORT, read_id, 0); \
\
dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result); \
\
return sprintf(buf, "%d", cyp->port##num); \
} \
static DEVICE_ATTR(port##num, S_IWUGO | S_IRUGO, get_port##num, set_port##num);
get_set_port(0, CY7C63_READ_PORT_ID0, CY7C63_WRITE_PORT_ID0);
get_set_port(1, CY7C63_READ_PORT_ID1, CY7C63_WRITE_PORT_ID1);
static int cy7c63_probe(struct usb_interface *interface,
const struct usb_device_id *id) {
struct cy7c63 *dev = NULL;
int retval = -ENOMEM;
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&dev->udev->dev, "Out of memory!\n");
goto error;
}
dev->udev = usb_get_dev(interface_to_usbdev(interface));
/* save our data pointer in this interface device */
usb_set_intfdata(interface, dev);
/* create device attribute files */
device_create_file(&interface->dev, &dev_attr_port0);
device_create_file(&interface->dev, &dev_attr_port1);
/* let the user know what node this device is now attached to */
dev_info(&interface->dev,
"Cypress CY7C63xxx device now attached\n");
retval = 0;
error:
return retval;
}
static void cy7c63_disconnect(struct usb_interface *interface) {
struct cy7c63 *dev;
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
/* remove device attribute files */
device_remove_file(&interface->dev, &dev_attr_port0);
device_remove_file(&interface->dev, &dev_attr_port1);
usb_put_dev(dev->udev);
dev_info(&interface->dev,
"Cypress CY7C63xxx device now disconnected\n");
kfree(dev);
}
static struct usb_driver cy7c63_driver = {
.name = "cy7c63",
.probe = cy7c63_probe,
.disconnect = cy7c63_disconnect,
.id_table = cy7c63_table,
};
static int __init cy7c63_init(void) {
int result;
/* register this driver with the USB subsystem */
result = usb_register(&cy7c63_driver);
if (result) {
err("Function usb_register failed! Error number: %d\n", result);
}
return result;
}
static void __exit cy7c63_exit(void) {
/* deregister this driver with the USB subsystem */
usb_deregister(&cy7c63_driver);
}
module_init(cy7c63_init);
module_exit(cy7c63_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,284 @@
/*
* cypress_cy7c63.c
*
* Copyright (c) 2006 Oliver Bock (o.bock@fh-wolfenbuettel.de)
*
* This driver is based on the Cypress USB Driver by Marcus Maul
* (cyport) and the 2.0 version of Greg Kroah-Hartman's
* USB Skeleton driver.
*
* This is a generic driver for the Cypress CY7C63xxx family.
* For the time being it enables you to read from and write to
* the single I/O ports of the device.
*
* Supported vendors: AK Modul-Bus Computer GmbH
* (Firmware "Port-Chip")
*
* Supported devices: CY7C63001A-PC
* CY7C63001C-PXC
* CY7C63001C-SXC
*
* Supported functions: Read/Write Ports
*
*
* 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, version 2.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#define DRIVER_AUTHOR "Oliver Bock (o.bock@fh-wolfenbuettel.de)"
#define DRIVER_DESC "Cypress CY7C63xxx USB driver"
#define CYPRESS_VENDOR_ID 0xa2c
#define CYPRESS_PRODUCT_ID 0x8
#define CYPRESS_READ_PORT 0x4
#define CYPRESS_WRITE_PORT 0x5
#define CYPRESS_READ_RAM 0x2
#define CYPRESS_WRITE_RAM 0x3
#define CYPRESS_READ_ROM 0x1
#define CYPRESS_READ_PORT_ID0 0
#define CYPRESS_WRITE_PORT_ID0 0
#define CYPRESS_READ_PORT_ID1 0x2
#define CYPRESS_WRITE_PORT_ID1 1
#define CYPRESS_MAX_REQSIZE 8
/* table of devices that work with this driver */
static struct usb_device_id cypress_table [] = {
{ USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, cypress_table);
/* structure to hold all of our device specific stuff */
struct cypress {
struct usb_device * udev;
unsigned char port[2];
};
/* used to send usb control messages to device */
static int vendor_command(struct cypress *dev, unsigned char request,
unsigned char address, unsigned char data)
{
int retval = 0;
unsigned int pipe;
unsigned char *iobuf;
/* allocate some memory for the i/o buffer*/
iobuf = kzalloc(CYPRESS_MAX_REQSIZE, GFP_KERNEL);
if (!iobuf) {
dev_err(&dev->udev->dev, "Out of memory!\n");
retval = -ENOMEM;
goto error;
}
dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
/* prepare usb control message and send it upstream */
pipe = usb_rcvctrlpipe(dev->udev, 0);
retval = usb_control_msg(dev->udev, pipe, request,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
address, data, iobuf, CYPRESS_MAX_REQSIZE,
USB_CTRL_GET_TIMEOUT);
/* store returned data (more READs to be added) */
switch (request) {
case CYPRESS_READ_PORT:
if (address == CYPRESS_READ_PORT_ID0) {
dev->port[0] = iobuf[1];
dev_dbg(&dev->udev->dev,
"READ_PORT0 returned: %d\n",
dev->port[0]);
}
else if (address == CYPRESS_READ_PORT_ID1) {
dev->port[1] = iobuf[1];
dev_dbg(&dev->udev->dev,
"READ_PORT1 returned: %d\n",
dev->port[1]);
}
break;
}
kfree(iobuf);
error:
return retval;
}
/* write port value */
static ssize_t write_port(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count,
int port_num, int write_id)
{
int value = -1;
int result = 0;
struct usb_interface *intf = to_usb_interface(dev);
struct cypress *cyp = usb_get_intfdata(intf);
dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", port_num);
/* validate input data */
if (sscanf(buf, "%d", &value) < 1) {
result = -EINVAL;
goto error;
}
if (value < 0 || value > 255) {
result = -EINVAL;
goto error;
}
result = vendor_command(cyp, CYPRESS_WRITE_PORT, write_id,
(unsigned char)value);
dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
error:
return result < 0 ? result : count;
}
/* attribute callback handler (write) */
static ssize_t set_port0_handler(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return write_port(dev, attr, buf, count, 0, CYPRESS_WRITE_PORT_ID0);
}
/* attribute callback handler (write) */
static ssize_t set_port1_handler(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
return write_port(dev, attr, buf, count, 1, CYPRESS_WRITE_PORT_ID1);
}
/* read port value */
static ssize_t read_port(struct device *dev, struct device_attribute *attr,
char *buf, int port_num, int read_id)
{
int result = 0;
struct usb_interface *intf = to_usb_interface(dev);
struct cypress *cyp = usb_get_intfdata(intf);
dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", port_num);
result = vendor_command(cyp, CYPRESS_READ_PORT, read_id, 0);
dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
return sprintf(buf, "%d", cyp->port[port_num]);
}
/* attribute callback handler (read) */
static ssize_t get_port0_handler(struct device *dev,
struct device_attribute *attr, char *buf)
{
return read_port(dev, attr, buf, 0, CYPRESS_READ_PORT_ID0);
}
/* attribute callback handler (read) */
static ssize_t get_port1_handler(struct device *dev,
struct device_attribute *attr, char *buf)
{
return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
}
static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
get_port0_handler, set_port0_handler);
static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
get_port1_handler, set_port1_handler);
static int cypress_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct cypress *dev = NULL;
int retval = -ENOMEM;
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&dev->udev->dev, "Out of memory!\n");
goto error;
}
dev->udev = usb_get_dev(interface_to_usbdev(interface));
/* save our data pointer in this interface device */
usb_set_intfdata(interface, dev);
/* create device attribute files */
device_create_file(&interface->dev, &dev_attr_port0);
device_create_file(&interface->dev, &dev_attr_port1);
/* let the user know that the device is now attached */
dev_info(&interface->dev,
"Cypress CY7C63xxx device now attached\n");
retval = 0;
error:
return retval;
}
static void cypress_disconnect(struct usb_interface *interface)
{
struct cypress *dev;
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
/* remove device attribute files */
device_remove_file(&interface->dev, &dev_attr_port0);
device_remove_file(&interface->dev, &dev_attr_port1);
usb_put_dev(dev->udev);
dev_info(&interface->dev,
"Cypress CY7C63xxx device now disconnected\n");
kfree(dev);
}
static struct usb_driver cypress_driver = {
.name = "cypress_cy7c63",
.probe = cypress_probe,
.disconnect = cypress_disconnect,
.id_table = cypress_table,
};
static int __init cypress_init(void)
{
int result;
/* register this driver with the USB subsystem */
result = usb_register(&cypress_driver);
if (result) {
err("Function usb_register failed! Error number: %d\n", result);
}
return result;
}
static void __exit cypress_exit(void)
{
/* deregister this driver with the USB subsystem */
usb_deregister(&cypress_driver);
}
module_init(cypress_init);
module_exit(cypress_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

View File

@@ -200,10 +200,8 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
/* create a urb, and a buffer for it, and copy the data to the urb */
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
retval = -ENOMEM;
goto error;
}
if (!urb)
return -ENOMEM;
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {

View File

@@ -64,7 +64,6 @@ struct mon_reader_text {
};
static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
static void mon_text_dtor(void *, kmem_cache_t *, unsigned long);
/*
* mon_text_submit
@@ -268,7 +267,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
(long)rp);
rp->e_slab = kmem_cache_create(rp->slab_name,
sizeof(struct mon_event_text), sizeof(long), 0,
mon_text_ctor, mon_text_dtor);
mon_text_ctor, NULL);
if (rp->e_slab == NULL) {
rc = -ENOMEM;
goto err_slab;
@@ -459,7 +458,3 @@ static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
memset(mem, 0xe5, sizeof(struct mon_event_text));
}
static void mon_text_dtor(void *mem, kmem_cache_t *slab, unsigned long sflags)
{
;
}

View File

@@ -128,11 +128,13 @@
#define VENDOR_ID_MELCO 0x0411
#define VENDOR_ID_MICRONET 0x3980
#define VENDOR_ID_LONGSHINE 0x07b8
#define VENDOR_ID_ZYXEL 0x0586
#define PRODUCT_ID_RTL8150 0x8150
#define PRODUCT_ID_LUAKTX 0x0012
#define PRODUCT_ID_LCS8138TX 0x401a
#define PRODUCT_ID_SP128AR 0x0003
#define PRODUCT_ID_PRESTIGE 0x401a
#undef EEPROM_WRITE
@@ -142,6 +144,7 @@ static struct usb_device_id rtl8150_table[] = {
{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
{USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
{USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
{USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
{}
};
@@ -172,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *);
static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
static int rtl8150_resume(struct usb_interface *intf);
static const char driver_name [] = "rtl8150";
@@ -180,6 +185,8 @@ static struct usb_driver rtl8150_driver = {
.probe = rtl8150_probe,
.disconnect = rtl8150_disconnect,
.id_table = rtl8150_table,
.suspend = rtl8150_suspend,
.resume = rtl8150_resume
};
/*
@@ -235,9 +242,11 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
usb_fill_control_urb(dev->ctrl_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
&dev->rx_creg, size, ctrl_callback, dev);
if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC)))
if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
if (ret == -ENODEV)
netif_device_detach(dev->netdev);
err("control request submission failed: %d", ret);
else
} else
set_bit(RX_REG_SET, &dev->flags);
return ret;
@@ -413,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
struct sk_buff *skb;
struct net_device *netdev;
u16 rx_stat;
int status;
dev = urb->context;
if (!dev)
@@ -462,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
goon:
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
if (status == -ENODEV)
netif_device_detach(dev->netdev);
else if (status) {
set_bit(RX_URB_FAIL, &dev->flags);
goto resched;
} else {
@@ -478,6 +491,7 @@ static void rx_fixup(unsigned long data)
{
rtl8150_t *dev;
struct sk_buff *skb;
int status;
dev = (rtl8150_t *)data;
@@ -496,10 +510,13 @@ static void rx_fixup(unsigned long data)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
try_again:
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
if (status == -ENODEV) {
netif_device_detach(dev->netdev);
} else if (status) {
set_bit(RX_URB_FAIL, &dev->flags);
goto tlsched;
} else {
} else {
clear_bit(RX_URB_FAIL, &dev->flags);
}
@@ -571,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
resubmit:
status = usb_submit_urb (urb, SLAB_ATOMIC);
if (status)
if (status == -ENODEV)
netif_device_detach(dev->netdev);
else if (status)
err ("can't resubmit intr, %s-%s/input0, status %d",
dev->udev->bus->bus_name,
dev->udev->devpath, status);
}
static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
{
rtl8150_t *dev = usb_get_intfdata(intf);
netif_device_detach(dev->netdev);
if (netif_running(dev->netdev)) {
usb_kill_urb(dev->rx_urb);
usb_kill_urb(dev->intr_urb);
}
return 0;
}
static int rtl8150_resume(struct usb_interface *intf)
{
rtl8150_t *dev = usb_get_intfdata(intf);
netif_device_attach(dev->netdev);
if (netif_running(dev->netdev)) {
dev->rx_urb->status = 0;
dev->rx_urb->actual_length = 0;
read_bulk_callback(dev->rx_urb, NULL);
dev->intr_urb->status = 0;
dev->intr_urb->actual_length = 0;
intr_callback(dev->intr_urb, NULL);
}
return 0;
}
/*
**
@@ -687,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
skb->data, count, write_bulk_callback, dev);
if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++;
netif_start_queue(netdev);
/* Can we get/handle EPIPE here? */
if (res == -ENODEV)
netif_device_detach(dev->netdev);
else {
warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++;
netif_start_queue(netdev);
}
} else {
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
@@ -726,16 +779,25 @@ static int rtl8150_open(struct net_device *netdev)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL)))
if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
return res;
}
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
dev->intr_buff, INTBUFSIZE, intr_callback,
dev, dev->intr_interval);
if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL)))
if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
netif_start_queue(netdev);
usb_kill_urb(dev->rx_urb);
return res;
}
enable_net_traffic(dev);
set_carrier(netdev);
netif_start_queue(netdev);
return res;
}

View File

@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME
To compile this driver as a module, choose M here: the
module will be called airprime.
config USB_SERIAL_ANYDATA
tristate "USB AnyData CDMA Wireless Driver"
depends on USB_SERIAL
help
Say Y here if you want to use a AnyData CDMA device.
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
@@ -456,6 +447,17 @@ config USB_SERIAL_SAFE_PADDED
bool "USB Secure Encapsulated Driver - Padded"
depends on USB_SERIAL_SAFE
config USB_SERIAL_SIERRAWIRELESS
tristate "USB Sierra Wireless Driver"
depends on USB_SERIAL
help
Say M here if you want to use a Sierra Wireless device (if
using an PC 5220 or AC580 please use the Airprime driver
instead).
To compile this driver as a module, choose M here: the
module will be called sierra.
config USB_SERIAL_TI
tristate "USB TI 3410/5052 Serial Driver"
depends on USB_SERIAL
@@ -491,15 +493,18 @@ config USB_SERIAL_XIRCOM
module will be called keyspan_pda.
config USB_SERIAL_OPTION
tristate "USB driver for GSM modems"
tristate "USB driver for GSM and CDMA modems"
depends on USB_SERIAL
help
Say Y here if you have an "Option" GSM PCMCIA card
(or an OEM version: branded Huawei, Audiovox, or Novatel).
Say Y here if you have a GSM or CDMA modem that's connected to USB.
These cards feature a built-in OHCI-USB adapter and an
internally-connected GSM modem. The USB bus is not
accessible externally.
This driver also supports several PCMCIA cards which have a
built-in OHCI-USB adapter and an internally-connected GSM modem.
The USB bus on these cards is not accessible externally.
Supported devices include (some of?) those made by:
Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or
Anydata.
To compile this driver as a module, choose M here: the
module will be called option.

View File

@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o
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
@@ -39,6 +38,7 @@ obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o

View File

@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */

View File

@@ -1,123 +0,0 @@
/*
* AnyData CDMA Serial USB driver
*
* Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
*
* 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 <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
/* if overridden by the user, then use their value for the size of the
* read and write urbs */
static int buffer_size;
static int debug;
static struct usb_driver anydata_driver = {
.name = "anydata",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
static int anydata_open(struct usb_serial_port *port, struct file *filp)
{
char *buffer;
int result = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
if (buffer_size) {
/* override the default buffer sizes */
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
dev_err(&port->dev, "%s - out of memory.\n",
__FUNCTION__);
return -ENOMEM;
}
kfree (port->read_urb->transfer_buffer);
port->read_urb->transfer_buffer = buffer;
port->read_urb->transfer_buffer_length = buffer_size;
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
dev_err(&port->dev, "%s - out of memory.\n",
__FUNCTION__);
return -ENOMEM;
}
kfree (port->write_urb->transfer_buffer);
port->write_urb->transfer_buffer = buffer;
port->write_urb->transfer_buffer_length = buffer_size;
port->bulk_out_size = buffer_size;
}
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
usb_serial_generic_write_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
dev_err(&port->dev,
"%s - failed submitting read urb, error %d\n",
__FUNCTION__, result);
return result;
}
static struct usb_serial_driver anydata_device = {
.driver = {
.owner = THIS_MODULE,
.name = "anydata",
},
.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,
.open = anydata_open,
};
static int __init anydata_init(void)
{
int retval;
retval = usb_serial_register(&anydata_device);
if (retval)
return retval;
retval = usb_register(&anydata_driver);
if (retval)
usb_serial_deregister(&anydata_device);
return retval;
}
static void __exit anydata_exit(void)
{
usb_deregister(&anydata_driver);
usb_serial_deregister(&anydata_device);
}
module_init(anydata_init);
module_exit(anydata_exit);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(buffer_size, int, 0);
MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");

View File

@@ -21,7 +21,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static int debug;

View File

@@ -74,7 +74,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "belkin_sa.h"
static int debug;

View File

@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
{

View File

@@ -17,11 +17,10 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static int debug;
#include "usb-serial.h"
struct usbcons_info {
int magic;
int break_flag;

View File

@@ -26,7 +26,7 @@
#include <linux/moduleparam.h>
#include <linux/usb.h>
#include <asm/uaccess.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/*
* Version Information

View File

@@ -39,7 +39,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#define CYBERJACK_LOCAL_BUF_SIZE 32

View File

@@ -59,11 +59,11 @@
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include "usb-serial.h"
#include "cypress_m8.h"

View File

@@ -246,7 +246,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/wait.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/* Defines */

View File

@@ -62,7 +62,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static int debug;

View File

@@ -15,7 +15,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
#define CPUCS_REG 0x7F92

View File

@@ -257,7 +257,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/serial.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "ftdi_sio.h"
/*
@@ -313,6 +313,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -336,6 +337,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
@@ -500,6 +502,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
{ USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -548,11 +552,17 @@ struct ftdi_private {
spinlock_t rx_lock; /* spinlock for receive state */
struct work_struct rx_work;
int rx_processed;
unsigned long rx_bytes;
__u16 interface; /* FT2232C port interface (0 for FT232/245) */
int force_baud; /* if non-zero, force the baud rate to this value */
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
spinlock_t tx_lock; /* spinlock for transmit state */
unsigned long tx_bytes;
unsigned long tx_outstanding_bytes;
unsigned long tx_outstanding_urbs;
};
/* Used for TIOCMIWAIT */
@@ -626,6 +636,9 @@ static struct usb_serial_driver ftdi_sio_device = {
#define HIGH 1
#define LOW 0
/* number of outstanding urbs to prevent userspace DoS from happening */
#define URB_UPPER_LIMIT 42
/*
* ***************************************************************************
* Utlity functions
@@ -1156,6 +1169,7 @@ static int ftdi_sio_attach (struct usb_serial *serial)
}
spin_lock_init(&priv->rx_lock);
spin_lock_init(&priv->tx_lock);
init_waitqueue_head(&priv->delta_msr_wait);
/* This will push the characters through immediately rather
than queue a task to deliver them */
@@ -1270,6 +1284,13 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
dbg("%s", __FUNCTION__);
spin_lock_irqsave(&priv->tx_lock, flags);
priv->tx_bytes = 0;
spin_unlock_irqrestore(&priv->tx_lock, flags);
spin_lock_irqsave(&priv->rx_lock, flags);
priv->rx_bytes = 0;
spin_unlock_irqrestore(&priv->rx_lock, flags);
if (port->tty)
port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
@@ -1372,6 +1393,7 @@ static int ftdi_write (struct usb_serial_port *port,
int data_offset ; /* will be 1 for the SIO and 0 otherwise */
int status;
int transfer_size;
unsigned long flags;
dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
@@ -1379,6 +1401,13 @@ static int ftdi_write (struct usb_serial_port *port,
dbg("write request of 0 bytes");
return 0;
}
spin_lock_irqsave(&priv->tx_lock, flags);
if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
spin_unlock_irqrestore(&priv->tx_lock, flags);
dbg("%s - write limit hit\n", __FUNCTION__);
return 0;
}
spin_unlock_irqrestore(&priv->tx_lock, flags);
data_offset = priv->write_offset;
dbg("data_offset set to %d",data_offset);
@@ -1445,6 +1474,12 @@ static int ftdi_write (struct usb_serial_port *port,
err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
count = status;
kfree (buffer);
} else {
spin_lock_irqsave(&priv->tx_lock, flags);
++priv->tx_outstanding_urbs;
priv->tx_outstanding_bytes += count;
priv->tx_bytes += count;
spin_unlock_irqrestore(&priv->tx_lock, flags);
}
/* we are done with this urb, so let the host driver
@@ -1460,7 +1495,11 @@ static int ftdi_write (struct usb_serial_port *port,
static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct ftdi_private *priv;
int data_offset; /* will be 1 for the SIO and 0 otherwise */
unsigned long countback;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
@@ -1472,34 +1511,67 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
return;
}
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
return;
}
/* account for transferred data */
countback = urb->actual_length;
data_offset = priv->write_offset;
if (data_offset > 0) {
/* Subtract the control bytes */
countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
}
spin_lock_irqsave(&priv->tx_lock, flags);
--priv->tx_outstanding_urbs;
priv->tx_outstanding_bytes -= countback;
spin_unlock_irqrestore(&priv->tx_lock, flags);
usb_serial_port_softint(port);
} /* ftdi_write_bulk_callback */
static int ftdi_write_room( struct usb_serial_port *port )
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
int room;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
/*
* We really can take anything the user throws at us
* but let's pick a nice big number to tell the tty
* layer that we have lots of free space
*/
return 2048;
spin_lock_irqsave(&priv->tx_lock, flags);
if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
/*
* We really can take anything the user throws at us
* but let's pick a nice big number to tell the tty
* layer that we have lots of free space
*/
room = 2048;
} else {
room = 0;
}
spin_unlock_irqrestore(&priv->tx_lock, flags);
return room;
} /* ftdi_write_room */
static int ftdi_chars_in_buffer (struct usb_serial_port *port)
{ /* ftdi_chars_in_buffer */
struct ftdi_private *priv = usb_get_serial_port_data(port);
int buffered;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
/*
* We can't really account for how much data we
* have sent out, but hasn't made it through to the
* device, so just tell the tty layer that everything
* is flushed.
*/
return 0;
spin_lock_irqsave(&priv->tx_lock, flags);
buffered = (int)priv->tx_outstanding_bytes;
spin_unlock_irqrestore(&priv->tx_lock, flags);
if (buffered < 0) {
err("%s outstanding tx bytes is negative!", __FUNCTION__);
buffered = 0;
}
return buffered;
} /* ftdi_chars_in_buffer */
@@ -1509,6 +1581,8 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct tty_struct *tty;
struct ftdi_private *priv;
unsigned long countread;
unsigned long flags;
if (urb->number_of_packets > 0) {
err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
@@ -1543,6 +1617,13 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
return;
}
/* count data bytes, but not status bytes */
countread = urb->actual_length;
countread -= 2 * ((countread + (PKTSZ - 1)) / PKTSZ);
spin_lock_irqsave(&priv->rx_lock, flags);
priv->rx_bytes += countread;
spin_unlock_irqrestore(&priv->rx_lock, flags);
ftdi_process_read(port);
} /* ftdi_read_bulk_callback */

View File

@@ -36,6 +36,9 @@
#define FTDI_ACTZWAVE_PID 0xF2D0
/* www.starting-point-systems.com µChameleon device */
#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */
/* www.irtrans.de device */
#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
@@ -179,6 +182,10 @@
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */
#define FTDI_TNC_X_PID 0xEBE0
/*
* ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
* All of these devices use FTDI's vendor ID (0x0403).
@@ -442,6 +449,18 @@
*/
#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */
/*
* ThorLabs USB motor drivers
*/
#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */
/*
* Testo products (http://www.testo.com/)
* Submitted by Colin Leroy
*/
#define TESTO_VID 0x128D
#define TESTO_USB_INTERFACE_PID 0x0001
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */

View File

@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1404, 0xcddc) },

View File

@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
/* the mode to be set when the port ist opened */
static int initial_mode = 1;
@@ -42,8 +43,6 @@ static int initial_mode = 1;
/* debug flag */
static int debug = 0;
#include "usb-serial.h"
#define GARMIN_VENDOR_ID 0x091E
/*

View File

@@ -17,8 +17,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <asm/uaccess.h>
#include "usb-serial.h"
static int debug;
@@ -285,6 +285,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg
if (result)
dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{

View File

@@ -17,7 +17,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/*
* Version Information

View File

@@ -44,7 +44,7 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "io_edgeport.h"
#include "io_ionsp.h" /* info for the iosp messages */
#include "io_16654.h" /* 16654 UART defines */

View File

@@ -39,8 +39,8 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "usb-serial.h"
#include "io_16654.h"
#include "io_usbvend.h"
#include "io_ti.h"

View File

@@ -55,7 +55,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "ipaq.h"
#define KP_RETRIES 100
@@ -70,6 +70,8 @@
static __u16 product, vendor;
static int debug;
static int connect_retries = KP_RETRIES;
static int initial_wait;
/* Function prototypes for an ipaq */
static int ipaq_open (struct usb_serial_port *port, struct file *filp);
@@ -248,6 +250,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
{ USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */
{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
@@ -582,7 +585,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
struct ipaq_private *priv;
struct ipaq_packet *pkt;
int i, result = 0;
int retries = KP_RETRIES;
int retries = connect_retries;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -646,16 +649,12 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
port->read_urb->transfer_buffer_length = URBDATA_SIZE;
port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
msleep(1000*initial_wait);
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
ipaq_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
goto error;
}
/*
* Send out control message observed in win98 sniffs. Not sure what
@@ -670,8 +669,14 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
0x1, 0, NULL, 0, 100);
if (result == 0) {
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
goto error;
}
return 0;
}
msleep(1000);
}
err("%s - failed doing control urb, error %d", __FUNCTION__, result);
goto error;
@@ -854,6 +859,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
if (urb->status) {
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
return;
}
spin_lock_irqsave(&write_list_lock, flags);
@@ -966,3 +972,9 @@ MODULE_PARM_DESC(vendor, "User specified USB idVendor");
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified USB idProduct");
module_param(connect_retries, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(connect_retries, "Maximum number of connect retries (one second each)");
module_param(initial_wait, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(initial_wait, "Time to wait before attempting a connection (in seconds)");

View File

@@ -46,8 +46,8 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <asm/uaccess.h>
#include "usb-serial.h"
/*
* Version Information
@@ -373,6 +373,8 @@ static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s", __FUNCTION__);
port->write_urb_busy = 0;
if (urb->status)
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);

View File

@@ -57,7 +57,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/*
* Version Information

View File

@@ -107,7 +107,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "keyspan.h"
static int debug;

View File

@@ -78,6 +78,7 @@
#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static int debug;
@@ -107,8 +108,6 @@ struct ezusb_hex_record {
#include "xircom_pgs_fw.h"
#endif
#include "usb-serial.h"
/*
* Version Information
*/

View File

@@ -55,7 +55,7 @@
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "kl5kusb105.h"
static int debug;

View File

@@ -46,8 +46,8 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/ioctl.h>
#include "usb-serial.h"
#include "kobil_sct.h"
static int debug;

View File

@@ -75,7 +75,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "mct_u232.h"
/*

View File

@@ -14,7 +14,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static int debug;

View File

@@ -46,7 +46,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
static int debug;

View File

@@ -9,39 +9,14 @@
Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
History:
2005-05-19 v0.1 Initial version, based on incomplete docs
and analysis of misbehavior with the standard driver
2005-05-20 v0.2 Extended the input buffer to avoid losing
random 64-byte chunks of data
2005-05-21 v0.3 implemented chars_in_buffer()
turned on low_latency
simplified the code somewhat
2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
removed some dead code
added sponsor notice
coding style clean-up
2005-06-20 v0.4.1 add missing braces :-/
killed end-of-line whitespace
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard
2005-09-20 v0.4.4 increased recv buffer size: the card sometimes
wants to send >2000 bytes.
2006-04-10 v0.5 fixed two array overrun errors :-/
2006-04-21 v0.5.1 added support for Sierra Wireless MC8755
2006-05-15 v0.6 re-enable multi-port support
2006-06-01 v0.6.1 add COBRA
2006-06-01 v0.6.2 add backwards-compatibility stuff
2006-06-01 v0.6.3 add Novatel Wireless
2006-06-01 v0.7 Option => GSM
History: see the git log.
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
This driver exists because the "normal" serial driver doesn't work too well
with GSM modems. Issues:
- data loss -- one single Receive URB is not nearly enough
- nonstandard flow (Option devices) and multiplex (Sierra) control
- nonstandard flow (Option devices) control
- controlling the baud rate doesn't make sense
This driver is named "option" because the most common device it's
@@ -53,7 +28,7 @@
device features.
*/
#define DRIVER_VERSION "v0.7.0"
#define DRIVER_VERSION "v0.7.1"
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
#define DRIVER_DESC "USB Driver for GSM modems"
@@ -64,7 +39,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
/* Function prototypes */
static int option_open(struct usb_serial_port *port, struct file *filp);
@@ -95,27 +70,29 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D
#define SIERRAWIRELESS_VENDOR_ID 0x1199
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
#define OPTION_PRODUCT_COBRA 0x6500
#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
#define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -124,13 +101,11 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ } /* Terminating entry */
};
static struct usb_device_id option_ids3[] = {
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -147,37 +122,11 @@ static struct usb_driver option_driver = {
/* The card has three separate interfaces, which the serial driver
* recognizes separately, thus num_port=1.
*/
static struct usb_serial_driver option_3port_device = {
.driver = {
.owner = THIS_MODULE,
.name = "option",
},
.description = "GSM modem (3-port)",
.id_table = option_ids3,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 3,
.open = option_open,
.close = option_close,
.write = option_write,
.write_room = option_write_room,
.chars_in_buffer = option_chars_in_buffer,
.throttle = option_rx_throttle,
.unthrottle = option_rx_unthrottle,
.set_termios = option_set_termios,
.break_ctl = option_break_ctl,
.tiocmget = option_tiocmget,
.tiocmset = option_tiocmset,
.attach = option_startup,
.shutdown = option_shutdown,
.read_int_callback = option_instat_callback,
};
static struct usb_serial_driver option_1port_device = {
.driver = {
.owner = THIS_MODULE,
.name = "option",
.name = "option1",
},
.description = "GSM modem (1-port)",
.id_table = option_ids1,
@@ -241,9 +190,6 @@ static int __init option_init(void)
retval = usb_serial_register(&option_1port_device);
if (retval)
goto failed_1port_device_register;
retval = usb_serial_register(&option_3port_device);
if (retval)
goto failed_3port_device_register;
retval = usb_register(&option_driver);
if (retval)
goto failed_driver_register;
@@ -253,8 +199,6 @@ static int __init option_init(void)
return 0;
failed_driver_register:
usb_serial_deregister (&option_3port_device);
failed_3port_device_register:
usb_serial_deregister (&option_1port_device);
failed_1port_device_register:
return retval;
@@ -263,7 +207,6 @@ failed_1port_device_register:
static void __exit option_exit(void)
{
usb_deregister (&option_driver);
usb_serial_deregister (&option_3port_device);
usb_serial_deregister (&option_1port_device);
}
@@ -652,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial)
dbg("%s", __FUNCTION__);
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
portdata = usb_get_serial_port_data(port);

View File

@@ -27,7 +27,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "pl2303.h"
/*
@@ -52,6 +52,7 @@ struct pl2303_buf {
static struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
@@ -79,6 +80,8 @@ static struct usb_device_id id_table [] = {
{ 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) },
{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ } /* Terminating entry */
};

View File

@@ -10,6 +10,7 @@
#define PL2303_VENDOR_ID 0x067b
#define PL2303_PRODUCT_ID 0x2303
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
#define PL2303_PRODUCT_ID_DCU11 0x1234
#define PL2303_PRODUCT_ID_PHAROS 0xaaa0
#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2
@@ -84,3 +85,11 @@
/* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */
#define OTI_VENDOR_ID 0x0ea0
#define OTI_PRODUCT_ID 0x6858
/* DATAPILOT Universal-2 Phone Cable */
#define DATAPILOT_U2_VENDOR_ID 0x0731
#define DATAPILOT_U2_PRODUCT_ID 0x2003
/* Belkin "F5U257" Serial Adapter */
#define BELKIN_VENDOR_ID 0x050d
#define BELKIN_PRODUCT_ID 0x0257

View File

@@ -71,7 +71,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#ifndef CONFIG_USB_SAFE_PADDED

View File

@@ -0,0 +1,75 @@
/*
* Sierra Wireless CDMA Wireless Serial USB driver
*
* Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com>
* Original Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
*
* 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 <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
{ USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
{ USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
/* Following devices are supported in the airprime.c driver */
/* { USB_DEVICE(0x1199, 0x0112) }, */ /* Sierra Wireless AirCard 580 */
/* { USB_DEVICE(0x0F3D, 0x0112) }, */ /* AirPrime/Sierra PC 5220 */
{ }
};
MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver sierra_driver = {
.name = "sierra_wireless",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
};
static struct usb_serial_driver sierra_device = {
.driver = {
.owner = THIS_MODULE,
.name = "Sierra_Wireless",
},
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 3,
};
static int __init sierra_init(void)
{
int retval;
retval = usb_serial_register(&sierra_device);
if (retval)
return retval;
retval = usb_register(&sierra_driver);
if (retval)
usb_serial_deregister(&sierra_device);
return retval;
}
static void __exit sierra_exit(void)
{
usb_deregister(&sierra_driver);
usb_serial_deregister(&sierra_device);
}
module_init(sierra_init);
module_exit(sierra_exit);
MODULE_LICENSE("GPL");

View File

@@ -83,8 +83,8 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "usb-serial.h"
#include "ti_usb_3410_5052.h"
#include "ti_fw_3410.h" /* firmware image for 3410 */
#include "ti_fw_5052.h" /* firmware image for 5052 */

View File

@@ -31,7 +31,7 @@
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "pl2303.h"
/*
@@ -40,6 +40,8 @@
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"
static void port_free(struct usb_serial_port *port);
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.name = "usbserial",
@@ -146,23 +148,10 @@ static void destroy_serial(struct kref *kref)
port = serial->port[i];
if (!port)
continue;
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
usb_kill_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_out_urb);
usb_free_urb(port->interrupt_out_urb);
kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
port_free(port);
}
}
flush_scheduled_work(); /* port->work */
usb_put_dev(serial->dev);
/* free up any memory that we allocated */
@@ -564,6 +553,11 @@ static void port_release(struct device *dev)
struct usb_serial_port *port = to_usb_serial_port(dev);
dbg ("%s - %s", __FUNCTION__, dev->bus_id);
port_free(port);
}
static void port_free(struct usb_serial_port *port)
{
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
usb_kill_urb(port->write_urb);
@@ -576,6 +570,7 @@ static void port_release(struct device *dev)
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
flush_scheduled_work(); /* port->work */
kfree(port);
}

View File

@@ -1,300 +0,0 @@
/*
* USB Serial Converter driver
*
* Copyright (C) 1999 - 2005
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
*/
#ifndef __LINUX_USB_SERIAL_H
#define __LINUX_USB_SERIAL_H
#include <linux/kref.h>
#include <linux/mutex.h>
#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
/* parity check flag */
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
/**
* usb_serial_port: structure for the specific ports of a device.
* @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.
* @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.
* @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
* @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
* for this port.
* @interrupt_out_buffer: pointer to the interrupt out buffer for this port.
* @interrupt_out_size: the size of the interrupt_out_buffer, in bytes.
* @interrupt_out_urb: pointer to the interrupt out struct urb for this port.
* @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
* for this port.
* @bulk_in_buffer: pointer to the bulk in buffer for this port.
* @read_urb: pointer to the bulk in struct urb for this port.
* @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
* port.
* @bulk_out_buffer: pointer to the bulk out buffer for this port.
* @bulk_out_size: the size of the bulk_out_buffer, in bytes.
* @write_urb: pointer to the bulk out struct urb for this port.
* @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
* port.
* @write_wait: a wait_queue_head_t used by the port.
* @work: work queue entry for the line discipline waking up.
* @open_count: number of times this port has been opened.
*
* This structure is used by the usb-serial core and drivers for the specific
* ports of a device.
*/
struct usb_serial_port {
struct usb_serial * serial;
struct tty_struct * tty;
spinlock_t lock;
struct mutex mutex;
unsigned char number;
unsigned char * interrupt_in_buffer;
struct urb * interrupt_in_urb;
__u8 interrupt_in_endpointAddress;
unsigned char * interrupt_out_buffer;
int interrupt_out_size;
struct urb * interrupt_out_urb;
__u8 interrupt_out_endpointAddress;
unsigned char * bulk_in_buffer;
int bulk_in_size;
struct urb * read_urb;
__u8 bulk_in_endpointAddress;
unsigned char * bulk_out_buffer;
int bulk_out_size;
struct urb * write_urb;
int write_urb_busy;
__u8 bulk_out_endpointAddress;
wait_queue_head_t write_wait;
struct work_struct work;
int open_count;
struct device dev;
};
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
/* get and set the port private data pointer helper functions */
static inline void *usb_get_serial_port_data (struct usb_serial_port *port)
{
return dev_get_drvdata(&port->dev);
}
static inline void usb_set_serial_port_data (struct usb_serial_port *port, void *data)
{
dev_set_drvdata(&port->dev, data);
}
/**
* usb_serial - structure used by the usb-serial core for a device
* @dev: pointer to the struct usb_device for this device
* @type: pointer to the struct usb_serial_driver for this device
* @interface: pointer to the struct usb_interface for this device
* @minor: the starting minor number for this device
* @num_ports: the number of ports this device has
* @num_interrupt_in: number of interrupt in endpoints we have
* @num_interrupt_out: number of interrupt out endpoints we have
* @num_bulk_in: number of bulk in endpoints we have
* @num_bulk_out: number of bulk out endpoints we have
* @port: array of struct usb_serial_port structures for the different ports.
* @private: place to put any driver specific information that is needed. The
* usb-serial driver is required to manage this data, the usb-serial core
* will not touch this. Use usb_get_serial_data() and
* usb_set_serial_data() to access this.
*/
struct usb_serial {
struct usb_device * dev;
struct usb_serial_driver * type;
struct usb_interface * interface;
unsigned char minor;
unsigned char num_ports;
unsigned char num_port_pointers;
char num_interrupt_in;
char num_interrupt_out;
char num_bulk_in;
char num_bulk_out;
struct usb_serial_port * port[MAX_NUM_PORTS];
struct kref kref;
void * private;
};
#define to_usb_serial(d) container_of(d, struct usb_serial, kref)
#define NUM_DONT_CARE (-1)
/* get and set the serial private data pointer helper functions */
static inline void *usb_get_serial_data (struct usb_serial *serial)
{
return serial->private;
}
static inline void usb_set_serial_data (struct usb_serial *serial, void *data)
{
serial->private = data;
}
/**
* usb_serial_driver - describes a usb serial driver
* @description: pointer to a string that describes this driver. This string used
* in the syslog messages when a device is inserted or removed.
* @id_table: pointer to a list of usb_device_id structures that define all
* of the devices this structure can support.
* @num_interrupt_in: the number of interrupt in endpoints this device will
* have.
* @num_interrupt_out: the number of interrupt out endpoints this device will
* have.
* @num_bulk_in: the number of bulk in endpoints this device will have.
* @num_bulk_out: the number of bulk out endpoints this device will have.
* @num_ports: the number of different ports this device will have.
* @calc_num_ports: pointer to a function to determine how many ports this
* device has dynamically. It will be called after the probe()
* callback is called, but before attach()
* @probe: pointer to the driver's probe function.
* This will be called when the device is inserted into the system,
* but before the device has been fully initialized by the usb_serial
* subsystem. Use this function to download any firmware to the device,
* or any other early initialization that might be needed.
* Return 0 to continue on with the initialization sequence. Anything
* else will abort it.
* @attach: pointer to the driver's attach function.
* This will be called when the struct usb_serial structure is fully set
* set up. Do any local initialization of the device, or any private
* memory structure allocation at this point in time.
* @shutdown: pointer to the driver's shutdown function. This will be
* called when the device is removed from the system.
*
* This structure is defines a USB Serial driver. It provides all of
* the information that the USB serial core code needs. If the function
* pointers are defined, then the USB serial core code will call them when
* the corresponding tty port functions are called. If they are not
* called, the generic serial function will be used instead.
*
* The driver.owner field should be set to the module owner of this driver.
* The driver.name field should be set to the name of this driver (remember
* it will show up in sysfs, so it needs to be short and to the point.
* Useing the module name is a good idea.)
*/
struct usb_serial_driver {
const char *description;
const struct usb_device_id *id_table;
char num_interrupt_in;
char num_interrupt_out;
char num_bulk_in;
char num_bulk_out;
char num_ports;
struct list_head driver_list;
struct device_driver driver;
int (*probe) (struct usb_serial *serial, const struct usb_device_id *id);
int (*attach) (struct usb_serial *serial);
int (*calc_num_ports) (struct usb_serial *serial);
void (*shutdown) (struct usb_serial *serial);
int (*port_probe) (struct usb_serial_port *port);
int (*port_remove) (struct usb_serial_port *port);
/* serial function calls */
int (*open) (struct usb_serial_port *port, struct file * filp);
void (*close) (struct usb_serial_port *port, struct file * filp);
int (*write) (struct usb_serial_port *port, const unsigned char *buf, int count);
int (*write_room) (struct usb_serial_port *port);
int (*ioctl) (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
void (*set_termios) (struct usb_serial_port *port, struct termios * old);
void (*break_ctl) (struct usb_serial_port *port, int break_state);
int (*chars_in_buffer) (struct usb_serial_port *port);
void (*throttle) (struct usb_serial_port *port);
void (*unthrottle) (struct usb_serial_port *port);
int (*tiocmget) (struct usb_serial_port *port, struct file *file);
int (*tiocmset) (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
void (*write_int_callback)(struct urb *urb, struct pt_regs *regs);
void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
};
#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
extern int usb_serial_register(struct usb_serial_driver *driver);
extern void usb_serial_deregister(struct usb_serial_driver *driver);
extern void usb_serial_port_softint(struct usb_serial_port *port);
extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
extern void usb_serial_disconnect(struct usb_interface *iface);
extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest);
extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
/* USB Serial console functions */
#ifdef CONFIG_USB_SERIAL_CONSOLE
extern void usb_serial_console_init (int debug, int minor);
extern void usb_serial_console_exit (void);
extern void usb_serial_console_disconnect(struct usb_serial *serial);
#else
static inline void usb_serial_console_init (int debug, int minor) { }
static inline void usb_serial_console_exit (void) { }
static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
#endif
/* Functions needed by other parts of the usbserial core */
extern struct usb_serial *usb_serial_get_by_index (unsigned int minor);
extern void usb_serial_put(struct usb_serial *serial);
extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp);
extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count);
extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
extern int usb_serial_generic_write_room (struct usb_serial_port *port);
extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
extern void usb_serial_generic_shutdown (struct usb_serial *serial);
extern int usb_serial_generic_register (int debug);
extern void usb_serial_generic_deregister (void);
extern int usb_serial_bus_register (struct usb_serial_driver *device);
extern void usb_serial_bus_deregister (struct usb_serial_driver *device);
extern struct usb_serial_driver usb_serial_generic_device;
extern struct bus_type usb_serial_bus_type;
extern struct tty_driver *usb_serial_tty_driver;
static inline void usb_serial_debug_data(int debug,
struct device *dev,
const char *function, int size,
const unsigned char *data)
{
int i;
if (debug) {
dev_printk(KERN_DEBUG, dev, "%s - length = %d, data = ", function, size);
for (i = 0; i < size; ++i)
printk ("%.2x ", data[i]);
printk ("\n");
}
}
/* Use our own dbg macro */
#undef dbg
#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg); } while (0)
#endif /* ifdef __LINUX_USB_SERIAL_H */

View File

@@ -25,7 +25,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "visor.h"
/*
@@ -302,7 +302,6 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
spin_lock_irqsave(&priv->lock, flags);
priv->bytes_in = 0;
priv->bytes_out = 0;
priv->outstanding_urbs = 0;
priv->throttled = 0;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -435,13 +434,25 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
static int visor_write_room (struct usb_serial_port *port)
{
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
/*
* We really can take anything the user throws at us
* but let's pick a nice big number to tell the tty
* layer that we have lots of free space
* layer that we have lots of free space, unless we don't.
*/
spin_lock_irqsave(&priv->lock, flags);
if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
spin_unlock_irqrestore(&priv->lock, flags);
dbg("%s - write limit hit\n", __FUNCTION__);
return 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
return 2048;
}
@@ -758,15 +769,22 @@ static int visor_calc_num_ports (struct usb_serial *serial)
static int generic_startup(struct usb_serial *serial)
{
struct usb_serial_port **ports = serial->port;
struct visor_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc (sizeof(*priv), GFP_KERNEL);
if (!priv)
if (!priv) {
while (i-- != 0) {
priv = usb_get_serial_port_data(ports[i]);
usb_set_serial_port_data(ports[i], NULL);
kfree(priv);
}
return -ENOMEM;
}
spin_lock_init(&priv->lock);
usb_set_serial_port_data(serial->port[i], priv);
usb_set_serial_port_data(ports[i], priv);
}
return 0;
}
@@ -876,7 +894,18 @@ static int clie_5_attach (struct usb_serial *serial)
static void visor_shutdown (struct usb_serial *serial)
{
struct visor_private *priv;
int i;
dbg("%s", __FUNCTION__);
for (i = 0; i < serial->num_ports; i++) {
priv = usb_get_serial_port_data(serial->port[i]);
if (priv) {
usb_set_serial_port_data(serial->port[i], NULL);
kfree(priv);
}
}
}
static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)

View File

@@ -79,7 +79,7 @@
#include <linux/usb.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
#include "usb-serial.h"
#include <linux/usb/serial.h>
#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */
#include "whiteheat.h" /* WhiteHEAT specific commands */

View File

@@ -112,13 +112,11 @@ static int slave_configure(struct scsi_device *sdev)
if (sdev->scsi_level < SCSI_2)
sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
/* According to the technical support people at Genesys Logic,
* devices using their chips have problems transferring more than
* 32 KB at a time. In practice people have found that 64 KB
* works okay and that's what Windows does. But we'll be
* conservative; people can always use the sysfs interface to
* increase max_sectors. */
if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS &&
/* Many devices have trouble transfering more than 32KB at a time,
* while others have trouble with more than 64K. At this time we
* are limiting both to 32K (64 sectores).
*/
if ((us->flags & US_FL_MAX_SECTORS_64) &&
sdev->request_queue->max_sectors > 64)
blk_queue_max_sectors(sdev->request_queue, 64);

View File

@@ -180,7 +180,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
if (timeleft <= 0) {
US_DEBUGP("%s -- cancelling URB\n",
timeleft == 0 ? "Timeout" : "Signal");
usb_unlink_urb(us->current_urb);
usb_kill_urb(us->current_urb);
}
/* return the URB status */

View File

@@ -112,6 +112,19 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
/* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100,
"Samsung Info. Systems America, Inc.",
"MP3 Player",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Orgad Shaneh <orgads@gmail.com> */
UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100,
"Samsung", "MP3 Player",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Christian Leber <christian@leber.de> */
UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100,
"TrekStor",
@@ -132,6 +145,21 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Mario Rettig <mariorettig@web.de> */
UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100,
"Nokia",
"Nokia 3250",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
/* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
* Einar Th. Einarsson <einarthered@gmail.com> */
UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100,
"Nokia",
"N91",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
/* Reported by Jiri Slaby <jirislaby@gmail.com> and
* Rene C. Castberg <Rene@Castberg.org> */
UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100,
@@ -140,6 +168,13 @@ UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
/* Reported by Matthew Bloch <matthew@bytemark.co.uk> */
UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100,
"Nokia",
"E61",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
"SMSC",
@@ -473,10 +508,11 @@ UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
US_SC_SCSI, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
/* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0600,
/* Submitted by Lars Jacob <jacob.lars@googlemail.com>
* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0610,
"Sony",
"DSC-T1/T5",
"DSC-T1/T5/H5",
US_SC_8070, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
@@ -598,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Digital Camera EX-20 DSC",
US_SC_8070, US_PR_DEVICE, NULL, 0 ),
/* The entry was here before I took over, and had US_SC_RBC. It turns
* out that isn't needed. Additionally, Torsten Eriksson
* <Torsten.Eriksson@bergianska.se> is able to use his device fine
* without this entry at all - but I don't suspect that will be true
* for all users (the protocol is likely needed), so is staying at
* this time. - Phil Dibowitz <phil@ipom.com>
*/
UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
"LaCie",
"USB Hard Disk",
US_SC_DEVICE, US_PR_CB, NULL, 0 ),
/* Submitted by Joel Bourquard <numlock@freesurf.ch>
* Some versions of this device need the SubClass and Protocol overrides
* while others don't.
@@ -708,18 +732,22 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
* They were originally reported by Alexander Oltu
* <alexander@all-2.com> and Peter Marks <peter.marks@turner.com>
* respectively.
*
* US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz
* <phil@ipom.com> as these flags were made and hard-coded
* special-cases were pulled from scsiglue.c.
*/
UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Optical",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_GO_SLOW ),
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Disk",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_GO_SLOW ),
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
/* Reported by Hanno Boeck <hanno@gmx.de>
* Taken from the Lycoris Kernel */
@@ -1073,7 +1101,15 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
"Optio S/S4",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
/* This is a virtual windows driver CD, which the zd1211rw driver automatically
* converts into a WLAN device. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
"ZyXEL",
"G-220F USB-WLAN Install",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_DEVICE ),
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI",
@@ -1196,6 +1232,14 @@ UNUSUAL_DEV( 0x0ea0, 0x6828, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Benjamin Schiller <sbenni@gmx.de>
* It is also sold by Easylite as DJ 20 */
UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
"Typhoon",
"My DJ 1820",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
/* Reported by Michael Stattmann <michael@stattmann.com> */
UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
"Sony Ericsson",
@@ -1227,6 +1271,15 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
* and Renato Perini <rperini@email.it>
*/
UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001,
"Motorola",
"RAZR V3x",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
/* Reported by Radovan Garabik <garabik@kassiopeia.juls.savba.sk> */
UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
"MPIO",

View File

@@ -55,6 +55,7 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/utsrelease.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -373,8 +374,12 @@ static int usb_stor_control_thread(void * __us)
/* lock access to the state */
scsi_lock(host);
/* did the command already complete because of a disconnect? */
if (!us->srb)
; /* nothing to do */
/* indicate that the command is done */
if (us->srb->result != DID_ABORT << 16) {
else if (us->srb->result != DID_ABORT << 16) {
US_DEBUGP("scsi cmd done, result=0x%x\n",
us->srb->result);
us->srb->scsi_done(us->srb);
@@ -478,7 +483,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
}
/* Get the unusual_devs entries and the string descriptors */
static void get_device_info(struct us_data *us, const struct usb_device_id *id)
static int get_device_info(struct us_data *us, const struct usb_device_id *id)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
@@ -495,6 +500,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
unusual_dev->useTransport;
us->flags = USB_US_ORIG_FLAGS(id->driver_info);
if (us->flags & US_FL_IGNORE_DEVICE) {
printk(KERN_INFO USB_STORAGE "device ignored\n");
return -ENODEV;
}
/*
* This flag is only needed when we're in high-speed, so let's
* disable it if we're in full-speed
@@ -524,7 +534,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
printk(KERN_NOTICE USB_STORAGE "This device "
"(%04x,%04x,%04x S %02x P %02x)"
" has %s in unusual_devs.h\n"
" has %s in unusual_devs.h (kernel"
" %s)\n"
" Please send a copy of this message to "
"<linux-usb-devel@lists.sourceforge.net>\n",
le16_to_cpu(ddesc->idVendor),
@@ -532,8 +543,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
le16_to_cpu(ddesc->bcdDevice),
idesc->bInterfaceSubClass,
idesc->bInterfaceProtocol,
msgs[msg]);
msgs[msg],
UTS_RELEASE);
}
return 0;
}
/* Get the transport settings */
@@ -836,32 +850,34 @@ static void dissociate_dev(struct us_data *us)
* the host */
static void quiesce_and_remove_host(struct us_data *us)
{
struct Scsi_Host *host = us_to_host(us);
/* Prevent new USB transfers, stop the current command, and
* interrupt a SCSI-scan or device-reset delay */
scsi_lock(host);
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
scsi_unlock(host);
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);
/* It doesn't matter if the SCSI-scanning thread is still running.
* The thread will exit when it sees the DISCONNECTING flag. */
/* Wait for the current command to finish, then remove the host */
mutex_lock(&us->dev_mutex);
mutex_unlock(&us->dev_mutex);
/* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
* is such a command pending, complete it with an error. */
mutex_lock(&us->dev_mutex);
if (us->srb) {
us->srb->result = DID_NO_CONNECT << 16;
scsi_lock(us_to_host(us));
scsi_lock(host);
us->srb->scsi_done(us->srb);
us->srb = NULL;
scsi_unlock(us_to_host(us));
scsi_unlock(host);
}
mutex_unlock(&us->dev_mutex);
/* Now we own no commands so it's safe to remove the SCSI host */
scsi_remove_host(us_to_host(us));
scsi_remove_host(host);
}
/* Second stage of disconnect processing: deallocate all resources */
@@ -960,7 +976,9 @@ static int storage_probe(struct usb_interface *intf,
* of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table.
*/
get_device_info(us, id);
result = get_device_info(us, id);
if (result)
goto BadDevice;
/* Get the transport, protocol, and pipe settings */
result = get_transport(us);

View File

@@ -176,8 +176,4 @@ extern void fill_inquiry_response(struct us_data *us,
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
/* Vendor ID list for devices that require special handling */
#define USB_VENDOR_ID_GENESYS 0x05e3 /* Genesys Logic */
#endif