Loading drivers/usb/host/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -124,3 +124,14 @@ config USB_SL811_HCD To compile this driver as a module, choose M here: the module will be called sl811-hcd. config USB_SL811_CS tristate "CF/PCMCIA support for SL811HS HCD" depends on USB_SL811_HCD && PCMCIA default N help Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC REX-CFU1U CF card (often used with PDAs). If unsure, say N. To compile this driver as a module, choose M here: the module will be called "sl811_cs". drivers/usb/host/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o drivers/usb/host/sl811-hcd.c +81 −65 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * SL811HS HCD (Host Controller Driver) for USB. * * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) * Copyright (C) 2004 David Brownell * Copyright (C) 2004-2005 David Brownell * * Periodic scheduling is based on Roman's OHCI code * Copyright (C) 1999 Roman Weissgaerber Loading Loading @@ -67,7 +67,7 @@ MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); MODULE_LICENSE("GPL"); #define DRIVER_VERSION "15 Dec 2004" #define DRIVER_VERSION "19 May 2005" #ifndef DEBUG Loading Loading @@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) /* reset as thoroughly as we can */ if (sl811->board && sl811->board->reset) sl811->board->reset(hcd->self.controller); else { sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); mdelay(20); } sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); Loading Loading @@ -443,6 +447,7 @@ static void finish_request( spin_lock(&urb->lock); if (urb->status == -EINPROGRESS) urb->status = status; urb->hcpriv = NULL; spin_unlock(&urb->lock); spin_unlock(&sl811->lock); Loading Loading @@ -661,9 +666,9 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) #ifdef QUIRK2 /* this may no longer be necessary ... */ if (irqstat == 0 && ret == IRQ_NONE) { if (irqstat == 0) { irqstat = checkdone(sl811); if (irqstat /* && irq != ~0 */ ) if (irqstat) sl811->stat_lost++; } #endif Loading Loading @@ -722,7 +727,8 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) if (sl811->active_a) { sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_a, container_of(sl811->active_a->hep->urb_list.next, container_of(sl811->active_a ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_a = NULL; Loading @@ -731,7 +737,8 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) if (sl811->active_b) { sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_b, container_of(sl811->active_b->hep->urb_list.next, container_of(sl811->active_b ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_b = NULL; Loading Loading @@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( break; } ep->hep = hep; hep->hcpriv = ep; } Loading Loading @@ -961,15 +969,16 @@ static int sl811h_urb_enqueue( static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) { struct sl811 *sl811 = hcd_to_sl811(hcd); struct usb_host_endpoint *hep = urb->hcpriv; struct usb_host_endpoint *hep; unsigned long flags; struct sl811h_ep *ep; int retval = 0; spin_lock_irqsave(&sl811->lock, flags); hep = urb->hcpriv; if (!hep) return -EINVAL; goto fail; spin_lock_irqsave(&sl811->lock, flags); ep = hep->hcpriv; if (ep) { /* finish right away if this urb can't be active ... Loading Loading @@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) VDBG("dequeue, urb %p active %s; wait4irq\n", urb, (sl811->active_a == ep) ? "A" : "B"); } else fail: retval = -EINVAL; spin_unlock_irqrestore(&sl811->lock, flags); return retval; Loading Loading @@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) if (sl811->board && sl811->board->power) hub_set_power_budget(udev, sl811->board->power * 2); /* enable power and interupts */ port_power(sl811, 1); return 0; } Loading Loading @@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { /*-------------------------------------------------------------------------*/ static int __init_or_module static int __devexit sl811h_remove(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); Loading @@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) remove_debug_file(sl811); usb_remove_hcd(hcd); iounmap(sl811->data_reg); /* some platforms may use IORESOURCE_IO */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); release_mem_region(res->start, 1); if (res) iounmap(sl811->data_reg); iounmap(sl811->addr_reg); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, 1); if (res) iounmap(sl811->addr_reg); usb_put_hcd(hcd); return 0; } #define resource_len(r) (((r)->end - (r)->start) + 1) static int __init static int __devinit sl811h_probe(struct device *dev) { struct usb_hcd *hcd; Loading @@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) void __iomem *addr_reg; void __iomem *data_reg; int retval; u8 tmp; u8 tmp, ioaddr = 0; /* basic sanity checks first. board-specific init logic should * have initialized these three resources and probably board Loading @@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) * minimal sanity checking. */ pdev = container_of(dev, struct platform_device, dev); if (pdev->num_resources < 3) return -ENODEV; addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); data = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq = platform_get_irq(pdev, 0); if (!addr || !data || irq < 0) if (pdev->num_resources < 3 || irq < 0) return -ENODEV; /* refuse to confuse usbcore */ Loading @@ -1679,25 +1686,32 @@ sl811h_probe(struct device *dev) return -EINVAL; } if (!request_mem_region(addr->start, 1, hcd_name)) { /* the chip may be wired for either kind of addressing */ addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); data = platform_get_resource(pdev, IORESOURCE_MEM, 1); retval = -EBUSY; goto err1; } addr_reg = ioremap(addr->start, resource_len(addr)); if (!addr || !data) { addr = platform_get_resource(pdev, IORESOURCE_IO, 0); data = platform_get_resource(pdev, IORESOURCE_IO, 1); if (!addr || !data) return -ENODEV; ioaddr = 1; addr_reg = (void __iomem *) addr->start; data_reg = (void __iomem *) data->start; } else { addr_reg = ioremap(addr->start, 1); if (addr_reg == NULL) { retval = -ENOMEM; goto err2; } if (!request_mem_region(data->start, 1, hcd_name)) { retval = -EBUSY; goto err3; } data_reg = ioremap(data->start, resource_len(addr)); data_reg = ioremap(data->start, 1); if (data_reg == NULL) { retval = -ENOMEM; goto err4; } } /* allocate and initialize hcd */ hcd = usb_create_hcd(&sl811h_hc_driver, dev, dev->bus_id); Loading Loading @@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) goto err6; } /* sl811s would need a different handler for this irq */ #ifdef CONFIG_ARM /* Cypress docs say the IRQ is IRQT_HIGH ... */ set_irq_type(irq, IRQT_RISING); #endif retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); /* The chip's IRQ is level triggered, active high. A requirement * for platform device setup is to cope with things like signal * inverters (e.g. CF is active low) or working only with edge * triggers (e.g. most ARM CPUs). Initial driver stress testing * was on a system with single edge triggering, so most sorts of * triggering arrangement should work. */ retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); if (retval != 0) goto err6; Loading @@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) err6: usb_put_hcd(hcd); err5: if (!ioaddr) iounmap(data_reg); err4: release_mem_region(data->start, 1); err3: if (!ioaddr) iounmap(addr_reg); err2: release_mem_region(addr->start, 1); err1: DBG("init error, %d\n", retval); return retval; } Loading Loading @@ -1821,16 +1835,18 @@ sl811h_resume(struct device *dev, u32 phase) #endif static struct device_driver sl811h_driver = { /* this driver is exported so sl811_cs can depend on it */ struct device_driver sl811h_driver = { .name = (char *) hcd_name, .bus = &platform_bus_type, .probe = sl811h_probe, .remove = sl811h_remove, .remove = __devexit_p(sl811h_remove), .suspend = sl811h_suspend, .resume = sl811h_resume, }; EXPORT_SYMBOL(sl811h_driver); /*-------------------------------------------------------------------------*/ Loading drivers/usb/host/sl811_cs.c 0 → 100644 +442 −0 Original line number Diff line number Diff line /* * PCMCIA driver for SL811HS (as found in REX-CFU1U) * Filename: sl811_cs.c * Author: Yukio Yamamoto * * Port to sl811-hcd and 2.6.x by * Botond Botyanszki <boti@rocketmail.com> * Simon Pickering * * Last update: 2005-05-12 */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/timer.h> #include <linux/ioport.h> #include <pcmcia/version.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> #include <linux/usb_sl811.h> MODULE_AUTHOR("Botond Botyanszki"); MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); MODULE_LICENSE("GPL"); /*====================================================================*/ /* MACROS */ /*====================================================================*/ #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) static int pc_debug = 0; module_param(pc_debug, int, 0644); #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) #else #define DBG(n, args...) do{}while(0) #endif /* no debugging */ #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) #define CS_CHECK(fn, ret) \ do { \ last_fn = (fn); \ if ((last_ret = (ret)) != 0) \ goto cs_failed; \ } while (0) /*====================================================================*/ /* VARIABLES */ /*====================================================================*/ static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; static dev_link_t *dev_list = NULL; static int irq_list[4] = { -1 }; static int irq_list_count; module_param_array(irq_list, int, &irq_list_count, 0444); INT_MODULE_PARM(irq_mask, 0xdeb8); typedef struct local_info_t { dev_link_t link; dev_node_t node; } local_info_t; /*====================================================================*/ static void release_platform_dev(struct device * dev) { DBG(0, "sl811_cs platform_dev release\n"); dev->parent = NULL; } static struct sl811_platform_data platform_data = { .potpg = 100, .power = 50, /* == 100mA */ // .reset = ... FIXME: invoke CF reset on the card }; static struct resource resources[] = { [0] = { .flags = IORESOURCE_IRQ, }, [1] = { // .name = "address", .flags = IORESOURCE_IO, }, [2] = { // .name = "data", .flags = IORESOURCE_IO, }, }; extern struct device_driver sl811h_driver; static struct platform_device platform_dev = { .id = -1, .dev = { .platform_data = &platform_data, .release = release_platform_dev, }, .resource = resources, .num_resources = ARRAY_SIZE(resources), }; static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) { if (platform_dev.dev.parent) return -EBUSY; platform_dev.dev.parent = parent; /* finish seting up the platform device */ resources[0].start = irq; resources[1].start = base_addr; resources[1].end = base_addr; resources[2].start = base_addr + 1; resources[2].end = base_addr + 1; /* The driver core will probe for us. We know sl811-hcd has been * initialized already because of the link order dependency. */ platform_dev.name = sl811h_driver.name; return platform_device_register(&platform_dev); } /*====================================================================*/ static void sl811_cs_detach(dev_link_t *link) { dev_link_t **linkp; DBG(0, "sl811_cs_detach(0x%p)\n", link); /* Locate device structure */ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { if (*linkp == link) break; } if (*linkp == NULL) return; /* Break the link with Card Services */ if (link->handle) pcmcia_deregister_client(link->handle); /* Unlink device structure, and free it */ *linkp = link->next; /* This points to the parent local_info_t struct */ kfree(link->priv); } static void sl811_cs_release(dev_link_t * link) { DBG(0, "sl811_cs_release(0x%p)\n", link); if (link->open) { DBG(1, "sl811_cs: release postponed, '%s' still open\n", link->dev->dev_name); link->state |= DEV_STALE_CONFIG; return; } /* Unlink the device chain */ link->dev = NULL; platform_device_unregister(&platform_dev); pcmcia_release_configuration(link->handle); if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; if (link->state & DEV_STALE_LINK) sl811_cs_detach(link); } static void sl811_cs_config(dev_link_t *link) { client_handle_t handle = link->handle; struct device *parent = &handle_to_dev(handle); local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; config_info_t conf; cistpl_cftable_entry_t dflt = { 0 }; DBG(0, "sl811_cs_config(0x%p)\n", link); tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); link->conf.Vcc = conf.Vcc; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); if (pcmcia_get_tuple_data(handle, &tuple) != 0 || pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } if (cfg->index == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ link->io.NumPorts1 = link->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } break; next_entry: if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); last_ret = pcmcia_get_next_tuple(handle, &tuple); } /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); else goto cs_failed; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; link->dev = &dev->node; printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: printk("sl811_cs_config failed\n"); cs_error(link->handle, last_fn, last_ret); sl811_cs_release(link); link->state &= ~DEV_CONFIG_PENDING; } } static int sl811_cs_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; DBG(1, "sl811_cs_event(0x%06x)\n", event); switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) sl811_cs_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; sl811_cs_config(link); break; case CS_EVENT_PM_SUSPEND: link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: if (link->state & DEV_CONFIG) pcmcia_release_configuration(link->handle); break; case CS_EVENT_PM_RESUME: link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); DBG(0, "reset sl811-hcd here?\n"); break; } return 0; } static dev_link_t *sl811_cs_attach(void) { local_info_t *local; dev_link_t *link; client_reg_t client_reg; int ret, i; local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return NULL; memset(local, 0, sizeof(local_info_t)); link = &local->link; link->priv = local; /* Initialize */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; if (irq_list[0] == -1) link->irq.IRQInfo2 = irq_mask; else for (i = 0; i < irq_list_count; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = NULL; link->conf.Attributes = 0; link->conf.Vcc = 33; link->conf.IntType = INT_MEMORY_AND_IO; /* Register with Card Services */ link->next = dev_list; dev_list = link; client_reg.dev_info = (dev_info_t *) &driver_name; client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; client_reg.event_handler = &sl811_cs_event; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); sl811_cs_detach(link); return NULL; } return link; } static struct pcmcia_driver sl811_cs_driver = { .owner = THIS_MODULE, .drv = { .name = (char *)driver_name, }, .attach = sl811_cs_attach, .detach = sl811_cs_detach, }; /*====================================================================*/ static int __init init_sl811_cs(void) { return pcmcia_register_driver(&sl811_cs_driver); } module_init(init_sl811_cs); static void __exit exit_sl811_cs(void) { pcmcia_unregister_driver(&sl811_cs_driver); } module_exit(exit_sl811_cs); drivers/usb/serial/ftdi_sio.c +3 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, Loading Loading @@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, Loading Loading @@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, Loading Loading
drivers/usb/host/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -124,3 +124,14 @@ config USB_SL811_HCD To compile this driver as a module, choose M here: the module will be called sl811-hcd. config USB_SL811_CS tristate "CF/PCMCIA support for SL811HS HCD" depends on USB_SL811_HCD && PCMCIA default N help Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC REX-CFU1U CF card (often used with PDAs). If unsure, say N. To compile this driver as a module, choose M here: the module will be called "sl811_cs".
drivers/usb/host/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o
drivers/usb/host/sl811-hcd.c +81 −65 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * SL811HS HCD (Host Controller Driver) for USB. * * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) * Copyright (C) 2004 David Brownell * Copyright (C) 2004-2005 David Brownell * * Periodic scheduling is based on Roman's OHCI code * Copyright (C) 1999 Roman Weissgaerber Loading Loading @@ -67,7 +67,7 @@ MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); MODULE_LICENSE("GPL"); #define DRIVER_VERSION "15 Dec 2004" #define DRIVER_VERSION "19 May 2005" #ifndef DEBUG Loading Loading @@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) /* reset as thoroughly as we can */ if (sl811->board && sl811->board->reset) sl811->board->reset(hcd->self.controller); else { sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); mdelay(20); } sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); Loading Loading @@ -443,6 +447,7 @@ static void finish_request( spin_lock(&urb->lock); if (urb->status == -EINPROGRESS) urb->status = status; urb->hcpriv = NULL; spin_unlock(&urb->lock); spin_unlock(&sl811->lock); Loading Loading @@ -661,9 +666,9 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) #ifdef QUIRK2 /* this may no longer be necessary ... */ if (irqstat == 0 && ret == IRQ_NONE) { if (irqstat == 0) { irqstat = checkdone(sl811); if (irqstat /* && irq != ~0 */ ) if (irqstat) sl811->stat_lost++; } #endif Loading Loading @@ -722,7 +727,8 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) if (sl811->active_a) { sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_a, container_of(sl811->active_a->hep->urb_list.next, container_of(sl811->active_a ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_a = NULL; Loading @@ -731,7 +737,8 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) if (sl811->active_b) { sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_b, container_of(sl811->active_b->hep->urb_list.next, container_of(sl811->active_b ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_b = NULL; Loading Loading @@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( break; } ep->hep = hep; hep->hcpriv = ep; } Loading Loading @@ -961,15 +969,16 @@ static int sl811h_urb_enqueue( static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) { struct sl811 *sl811 = hcd_to_sl811(hcd); struct usb_host_endpoint *hep = urb->hcpriv; struct usb_host_endpoint *hep; unsigned long flags; struct sl811h_ep *ep; int retval = 0; spin_lock_irqsave(&sl811->lock, flags); hep = urb->hcpriv; if (!hep) return -EINVAL; goto fail; spin_lock_irqsave(&sl811->lock, flags); ep = hep->hcpriv; if (ep) { /* finish right away if this urb can't be active ... Loading Loading @@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) VDBG("dequeue, urb %p active %s; wait4irq\n", urb, (sl811->active_a == ep) ? "A" : "B"); } else fail: retval = -EINVAL; spin_unlock_irqrestore(&sl811->lock, flags); return retval; Loading Loading @@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) if (sl811->board && sl811->board->power) hub_set_power_budget(udev, sl811->board->power * 2); /* enable power and interupts */ port_power(sl811, 1); return 0; } Loading Loading @@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { /*-------------------------------------------------------------------------*/ static int __init_or_module static int __devexit sl811h_remove(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); Loading @@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) remove_debug_file(sl811); usb_remove_hcd(hcd); iounmap(sl811->data_reg); /* some platforms may use IORESOURCE_IO */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); release_mem_region(res->start, 1); if (res) iounmap(sl811->data_reg); iounmap(sl811->addr_reg); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, 1); if (res) iounmap(sl811->addr_reg); usb_put_hcd(hcd); return 0; } #define resource_len(r) (((r)->end - (r)->start) + 1) static int __init static int __devinit sl811h_probe(struct device *dev) { struct usb_hcd *hcd; Loading @@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) void __iomem *addr_reg; void __iomem *data_reg; int retval; u8 tmp; u8 tmp, ioaddr = 0; /* basic sanity checks first. board-specific init logic should * have initialized these three resources and probably board Loading @@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) * minimal sanity checking. */ pdev = container_of(dev, struct platform_device, dev); if (pdev->num_resources < 3) return -ENODEV; addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); data = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq = platform_get_irq(pdev, 0); if (!addr || !data || irq < 0) if (pdev->num_resources < 3 || irq < 0) return -ENODEV; /* refuse to confuse usbcore */ Loading @@ -1679,25 +1686,32 @@ sl811h_probe(struct device *dev) return -EINVAL; } if (!request_mem_region(addr->start, 1, hcd_name)) { /* the chip may be wired for either kind of addressing */ addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); data = platform_get_resource(pdev, IORESOURCE_MEM, 1); retval = -EBUSY; goto err1; } addr_reg = ioremap(addr->start, resource_len(addr)); if (!addr || !data) { addr = platform_get_resource(pdev, IORESOURCE_IO, 0); data = platform_get_resource(pdev, IORESOURCE_IO, 1); if (!addr || !data) return -ENODEV; ioaddr = 1; addr_reg = (void __iomem *) addr->start; data_reg = (void __iomem *) data->start; } else { addr_reg = ioremap(addr->start, 1); if (addr_reg == NULL) { retval = -ENOMEM; goto err2; } if (!request_mem_region(data->start, 1, hcd_name)) { retval = -EBUSY; goto err3; } data_reg = ioremap(data->start, resource_len(addr)); data_reg = ioremap(data->start, 1); if (data_reg == NULL) { retval = -ENOMEM; goto err4; } } /* allocate and initialize hcd */ hcd = usb_create_hcd(&sl811h_hc_driver, dev, dev->bus_id); Loading Loading @@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) goto err6; } /* sl811s would need a different handler for this irq */ #ifdef CONFIG_ARM /* Cypress docs say the IRQ is IRQT_HIGH ... */ set_irq_type(irq, IRQT_RISING); #endif retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); /* The chip's IRQ is level triggered, active high. A requirement * for platform device setup is to cope with things like signal * inverters (e.g. CF is active low) or working only with edge * triggers (e.g. most ARM CPUs). Initial driver stress testing * was on a system with single edge triggering, so most sorts of * triggering arrangement should work. */ retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); if (retval != 0) goto err6; Loading @@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) err6: usb_put_hcd(hcd); err5: if (!ioaddr) iounmap(data_reg); err4: release_mem_region(data->start, 1); err3: if (!ioaddr) iounmap(addr_reg); err2: release_mem_region(addr->start, 1); err1: DBG("init error, %d\n", retval); return retval; } Loading Loading @@ -1821,16 +1835,18 @@ sl811h_resume(struct device *dev, u32 phase) #endif static struct device_driver sl811h_driver = { /* this driver is exported so sl811_cs can depend on it */ struct device_driver sl811h_driver = { .name = (char *) hcd_name, .bus = &platform_bus_type, .probe = sl811h_probe, .remove = sl811h_remove, .remove = __devexit_p(sl811h_remove), .suspend = sl811h_suspend, .resume = sl811h_resume, }; EXPORT_SYMBOL(sl811h_driver); /*-------------------------------------------------------------------------*/ Loading
drivers/usb/host/sl811_cs.c 0 → 100644 +442 −0 Original line number Diff line number Diff line /* * PCMCIA driver for SL811HS (as found in REX-CFU1U) * Filename: sl811_cs.c * Author: Yukio Yamamoto * * Port to sl811-hcd and 2.6.x by * Botond Botyanszki <boti@rocketmail.com> * Simon Pickering * * Last update: 2005-05-12 */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/timer.h> #include <linux/ioport.h> #include <pcmcia/version.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> #include <linux/usb_sl811.h> MODULE_AUTHOR("Botond Botyanszki"); MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); MODULE_LICENSE("GPL"); /*====================================================================*/ /* MACROS */ /*====================================================================*/ #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) static int pc_debug = 0; module_param(pc_debug, int, 0644); #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) #else #define DBG(n, args...) do{}while(0) #endif /* no debugging */ #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) #define CS_CHECK(fn, ret) \ do { \ last_fn = (fn); \ if ((last_ret = (ret)) != 0) \ goto cs_failed; \ } while (0) /*====================================================================*/ /* VARIABLES */ /*====================================================================*/ static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; static dev_link_t *dev_list = NULL; static int irq_list[4] = { -1 }; static int irq_list_count; module_param_array(irq_list, int, &irq_list_count, 0444); INT_MODULE_PARM(irq_mask, 0xdeb8); typedef struct local_info_t { dev_link_t link; dev_node_t node; } local_info_t; /*====================================================================*/ static void release_platform_dev(struct device * dev) { DBG(0, "sl811_cs platform_dev release\n"); dev->parent = NULL; } static struct sl811_platform_data platform_data = { .potpg = 100, .power = 50, /* == 100mA */ // .reset = ... FIXME: invoke CF reset on the card }; static struct resource resources[] = { [0] = { .flags = IORESOURCE_IRQ, }, [1] = { // .name = "address", .flags = IORESOURCE_IO, }, [2] = { // .name = "data", .flags = IORESOURCE_IO, }, }; extern struct device_driver sl811h_driver; static struct platform_device platform_dev = { .id = -1, .dev = { .platform_data = &platform_data, .release = release_platform_dev, }, .resource = resources, .num_resources = ARRAY_SIZE(resources), }; static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) { if (platform_dev.dev.parent) return -EBUSY; platform_dev.dev.parent = parent; /* finish seting up the platform device */ resources[0].start = irq; resources[1].start = base_addr; resources[1].end = base_addr; resources[2].start = base_addr + 1; resources[2].end = base_addr + 1; /* The driver core will probe for us. We know sl811-hcd has been * initialized already because of the link order dependency. */ platform_dev.name = sl811h_driver.name; return platform_device_register(&platform_dev); } /*====================================================================*/ static void sl811_cs_detach(dev_link_t *link) { dev_link_t **linkp; DBG(0, "sl811_cs_detach(0x%p)\n", link); /* Locate device structure */ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { if (*linkp == link) break; } if (*linkp == NULL) return; /* Break the link with Card Services */ if (link->handle) pcmcia_deregister_client(link->handle); /* Unlink device structure, and free it */ *linkp = link->next; /* This points to the parent local_info_t struct */ kfree(link->priv); } static void sl811_cs_release(dev_link_t * link) { DBG(0, "sl811_cs_release(0x%p)\n", link); if (link->open) { DBG(1, "sl811_cs: release postponed, '%s' still open\n", link->dev->dev_name); link->state |= DEV_STALE_CONFIG; return; } /* Unlink the device chain */ link->dev = NULL; platform_device_unregister(&platform_dev); pcmcia_release_configuration(link->handle); if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; if (link->state & DEV_STALE_LINK) sl811_cs_detach(link); } static void sl811_cs_config(dev_link_t *link) { client_handle_t handle = link->handle; struct device *parent = &handle_to_dev(handle); local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; config_info_t conf; cistpl_cftable_entry_t dflt = { 0 }; DBG(0, "sl811_cs_config(0x%p)\n", link); tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); link->conf.Vcc = conf.Vcc; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); if (pcmcia_get_tuple_data(handle, &tuple) != 0 || pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } if (cfg->index == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ link->io.NumPorts1 = link->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } break; next_entry: if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); last_ret = pcmcia_get_next_tuple(handle, &tuple); } /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); else goto cs_failed; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; link->dev = &dev->node; printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: printk("sl811_cs_config failed\n"); cs_error(link->handle, last_fn, last_ret); sl811_cs_release(link); link->state &= ~DEV_CONFIG_PENDING; } } static int sl811_cs_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; DBG(1, "sl811_cs_event(0x%06x)\n", event); switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) sl811_cs_release(link); break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; sl811_cs_config(link); break; case CS_EVENT_PM_SUSPEND: link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: if (link->state & DEV_CONFIG) pcmcia_release_configuration(link->handle); break; case CS_EVENT_PM_RESUME: link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); DBG(0, "reset sl811-hcd here?\n"); break; } return 0; } static dev_link_t *sl811_cs_attach(void) { local_info_t *local; dev_link_t *link; client_reg_t client_reg; int ret, i; local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return NULL; memset(local, 0, sizeof(local_info_t)); link = &local->link; link->priv = local; /* Initialize */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; if (irq_list[0] == -1) link->irq.IRQInfo2 = irq_mask; else for (i = 0; i < irq_list_count; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = NULL; link->conf.Attributes = 0; link->conf.Vcc = 33; link->conf.IntType = INT_MEMORY_AND_IO; /* Register with Card Services */ link->next = dev_list; dev_list = link; client_reg.dev_info = (dev_info_t *) &driver_name; client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; client_reg.event_handler = &sl811_cs_event; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); sl811_cs_detach(link); return NULL; } return link; } static struct pcmcia_driver sl811_cs_driver = { .owner = THIS_MODULE, .drv = { .name = (char *)driver_name, }, .attach = sl811_cs_attach, .detach = sl811_cs_detach, }; /*====================================================================*/ static int __init init_sl811_cs(void) { return pcmcia_register_driver(&sl811_cs_driver); } module_init(init_sl811_cs); static void __exit exit_sl811_cs(void) { pcmcia_unregister_driver(&sl811_cs_driver); } module_exit(exit_sl811_cs);
drivers/usb/serial/ftdi_sio.c +3 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, Loading Loading @@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, Loading Loading @@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, Loading