Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

+551 -76
+11
drivers/usb/host/Kconfig
··· 124 To compile this driver as a module, choose M here: the 125 module will be called sl811-hcd. 126
··· 124 To compile this driver as a module, choose M here: the 125 module will be called sl811-hcd. 126 127 + config USB_SL811_CS 128 + tristate "CF/PCMCIA support for SL811HS HCD" 129 + depends on USB_SL811_HCD && PCMCIA 130 + default N 131 + help 132 + Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC 133 + REX-CFU1U CF card (often used with PDAs). If unsure, say N. 134 + 135 + To compile this driver as a module, choose M here: the 136 + module will be called "sl811_cs". 137 +
+1
drivers/usb/host/Makefile
··· 7 obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o 8 obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o 9 obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o 10 obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o
··· 7 obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o 8 obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o 9 obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o 10 + obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o 11 obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o
+82 -66
drivers/usb/host/sl811-hcd.c
··· 2 * SL811HS HCD (Host Controller Driver) for USB. 3 * 4 * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) 5 - * Copyright (C) 2004 David Brownell 6 - * 7 * Periodic scheduling is based on Roman's OHCI code 8 * Copyright (C) 1999 Roman Weissgaerber 9 * ··· 15 * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" 16 * document (providing significant pieces missing from that spec); plus 17 * the SL811S spec if you want peripheral side info. 18 - */ 19 20 /* 21 * Status: Passed basic stress testing, works with hubs, mice, keyboards, ··· 67 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); 68 MODULE_LICENSE("GPL"); 69 70 - #define DRIVER_VERSION "15 Dec 2004" 71 72 73 #ifndef DEBUG ··· 121 /* reset as thoroughly as we can */ 122 if (sl811->board && sl811->board->reset) 123 sl811->board->reset(hcd->self.controller); 124 125 sl811_write(sl811, SL11H_IRQ_ENABLE, 0); 126 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); ··· 447 spin_lock(&urb->lock); 448 if (urb->status == -EINPROGRESS) 449 urb->status = status; 450 spin_unlock(&urb->lock); 451 452 spin_unlock(&sl811->lock); ··· 477 if (*prev) 478 *prev = ep->next; 479 sl811->load[i] -= ep->load; 480 - } 481 ep->branch = PERIODIC_SIZE; 482 sl811->periodic_count--; 483 sl811_to_hcd(sl811)->self.bandwidth_allocated ··· 666 667 #ifdef QUIRK2 668 /* this may no longer be necessary ... */ 669 - if (irqstat == 0 && ret == IRQ_NONE) { 670 irqstat = checkdone(sl811); 671 - if (irqstat /* && irq != ~0 */ ) 672 sl811->stat_lost++; 673 } 674 #endif ··· 727 if (sl811->active_a) { 728 sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); 729 finish_request(sl811, sl811->active_a, 730 - container_of(sl811->active_a->hep->urb_list.next, 731 struct urb, urb_list), 732 NULL, -ESHUTDOWN); 733 sl811->active_a = NULL; ··· 737 if (sl811->active_b) { 738 sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); 739 finish_request(sl811, sl811->active_b, 740 - container_of(sl811->active_b->hep->urb_list.next, 741 struct urb, urb_list), 742 NULL, -ESHUTDOWN); 743 sl811->active_b = NULL; ··· 768 goto retry; 769 } 770 771 - if (sl811->periodic_count == 0 && list_empty(&sl811->async)) 772 sofirq_off(sl811); 773 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); 774 ··· 803 } 804 if (j < PERIODIC_SIZE) 805 continue; 806 - branch = i; 807 } 808 } 809 return branch; ··· 897 break; 898 } 899 900 hep->hcpriv = ep; 901 } 902 ··· 969 static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 970 { 971 struct sl811 *sl811 = hcd_to_sl811(hcd); 972 - struct usb_host_endpoint *hep = urb->hcpriv; 973 unsigned long flags; 974 struct sl811h_ep *ep; 975 int retval = 0; 976 977 - if (!hep) 978 - return -EINVAL; 979 - 980 spin_lock_irqsave(&sl811->lock, flags); 981 ep = hep->hcpriv; 982 if (ep) { 983 /* finish right away if this urb can't be active ... ··· 1026 VDBG("dequeue, urb %p active %s; wait4irq\n", urb, 1027 (sl811->active_a == ep) ? "A" : "B"); 1028 } else 1029 retval = -EINVAL; 1030 spin_unlock_irqrestore(&sl811->lock, flags); 1031 return retval; ··· 1586 if (sl811->board && sl811->board->power) 1587 hub_set_power_budget(udev, sl811->board->power * 2); 1588 1589 return 0; 1590 } 1591 ··· 1631 1632 /*-------------------------------------------------------------------------*/ 1633 1634 - static int __init_or_module 1635 sl811h_remove(struct device *dev) 1636 { 1637 struct usb_hcd *hcd = dev_get_drvdata(dev); ··· 1644 remove_debug_file(sl811); 1645 usb_remove_hcd(hcd); 1646 1647 - iounmap(sl811->data_reg); 1648 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1649 - release_mem_region(res->start, 1); 1650 1651 - iounmap(sl811->addr_reg); 1652 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1653 - release_mem_region(res->start, 1); 1654 1655 usb_put_hcd(hcd); 1656 return 0; 1657 } 1658 1659 - #define resource_len(r) (((r)->end - (r)->start) + 1) 1660 - 1661 - static int __init 1662 sl811h_probe(struct device *dev) 1663 { 1664 struct usb_hcd *hcd; ··· 1668 void __iomem *addr_reg; 1669 void __iomem *data_reg; 1670 int retval; 1671 - u8 tmp; 1672 1673 /* basic sanity checks first. board-specific init logic should 1674 * have initialized these three resources and probably board ··· 1676 * minimal sanity checking. 1677 */ 1678 pdev = container_of(dev, struct platform_device, dev); 1679 - if (pdev->num_resources < 3) 1680 - return -ENODEV; 1681 - 1682 - addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1683 - data = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1684 irq = platform_get_irq(pdev, 0); 1685 - if (!addr || !data || irq < 0) 1686 return -ENODEV; 1687 1688 /* refuse to confuse usbcore */ ··· 1686 return -EINVAL; 1687 } 1688 1689 - if (!request_mem_region(addr->start, 1, hcd_name)) { 1690 - retval = -EBUSY; 1691 - goto err1; 1692 - } 1693 - addr_reg = ioremap(addr->start, resource_len(addr)); 1694 - if (addr_reg == NULL) { 1695 - retval = -ENOMEM; 1696 - goto err2; 1697 - } 1698 1699 - if (!request_mem_region(data->start, 1, hcd_name)) { 1700 - retval = -EBUSY; 1701 - goto err3; 1702 - } 1703 - data_reg = ioremap(data->start, resource_len(addr)); 1704 - if (data_reg == NULL) { 1705 - retval = -ENOMEM; 1706 - goto err4; 1707 } 1708 1709 /* allocate and initialize hcd */ ··· 1751 goto err6; 1752 } 1753 1754 - /* sl811s would need a different handler for this irq */ 1755 - #ifdef CONFIG_ARM 1756 - /* Cypress docs say the IRQ is IRQT_HIGH ... */ 1757 - set_irq_type(irq, IRQT_RISING); 1758 - #endif 1759 - retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); 1760 if (retval != 0) 1761 goto err6; 1762 ··· 1768 err6: 1769 usb_put_hcd(hcd); 1770 err5: 1771 - iounmap(data_reg); 1772 err4: 1773 - release_mem_region(data->start, 1); 1774 - err3: 1775 - iounmap(addr_reg); 1776 err2: 1777 - release_mem_region(addr->start, 1); 1778 - err1: 1779 DBG("init error, %d\n", retval); 1780 return retval; 1781 } ··· 1781 #ifdef CONFIG_PM 1782 1783 /* for this device there's no useful distinction between the controller 1784 - * and its root hub, except that the root hub only gets direct PM calls 1785 * when CONFIG_USB_SUSPEND is enabled. 1786 */ 1787 ··· 1835 #endif 1836 1837 1838 - static struct device_driver sl811h_driver = { 1839 .name = (char *) hcd_name, 1840 .bus = &platform_bus_type, 1841 1842 .probe = sl811h_probe, 1843 - .remove = sl811h_remove, 1844 1845 .suspend = sl811h_suspend, 1846 .resume = sl811h_resume, 1847 }; 1848 1849 /*-------------------------------------------------------------------------*/ 1850 - 1851 - static int __init sl811h_init(void) 1852 { 1853 if (usb_disabled()) 1854 return -ENODEV; ··· 1860 } 1861 module_init(sl811h_init); 1862 1863 - static void __exit sl811h_cleanup(void) 1864 - { 1865 driver_unregister(&sl811h_driver); 1866 } 1867 module_exit(sl811h_cleanup);
··· 2 * SL811HS HCD (Host Controller Driver) for USB. 3 * 4 * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) 5 + * Copyright (C) 2004-2005 David Brownell 6 + * 7 * Periodic scheduling is based on Roman's OHCI code 8 * Copyright (C) 1999 Roman Weissgaerber 9 * ··· 15 * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" 16 * document (providing significant pieces missing from that spec); plus 17 * the SL811S spec if you want peripheral side info. 18 + */ 19 20 /* 21 * Status: Passed basic stress testing, works with hubs, mice, keyboards, ··· 67 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); 68 MODULE_LICENSE("GPL"); 69 70 + #define DRIVER_VERSION "19 May 2005" 71 72 73 #ifndef DEBUG ··· 121 /* reset as thoroughly as we can */ 122 if (sl811->board && sl811->board->reset) 123 sl811->board->reset(hcd->self.controller); 124 + else { 125 + sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); 126 + mdelay(20); 127 + } 128 129 sl811_write(sl811, SL11H_IRQ_ENABLE, 0); 130 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); ··· 443 spin_lock(&urb->lock); 444 if (urb->status == -EINPROGRESS) 445 urb->status = status; 446 + urb->hcpriv = NULL; 447 spin_unlock(&urb->lock); 448 449 spin_unlock(&sl811->lock); ··· 472 if (*prev) 473 *prev = ep->next; 474 sl811->load[i] -= ep->load; 475 + } 476 ep->branch = PERIODIC_SIZE; 477 sl811->periodic_count--; 478 sl811_to_hcd(sl811)->self.bandwidth_allocated ··· 661 662 #ifdef QUIRK2 663 /* this may no longer be necessary ... */ 664 + if (irqstat == 0) { 665 irqstat = checkdone(sl811); 666 + if (irqstat) 667 sl811->stat_lost++; 668 } 669 #endif ··· 722 if (sl811->active_a) { 723 sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); 724 finish_request(sl811, sl811->active_a, 725 + container_of(sl811->active_a 726 + ->hep->urb_list.next, 727 struct urb, urb_list), 728 NULL, -ESHUTDOWN); 729 sl811->active_a = NULL; ··· 731 if (sl811->active_b) { 732 sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); 733 finish_request(sl811, sl811->active_b, 734 + container_of(sl811->active_b 735 + ->hep->urb_list.next, 736 struct urb, urb_list), 737 NULL, -ESHUTDOWN); 738 sl811->active_b = NULL; ··· 761 goto retry; 762 } 763 764 + if (sl811->periodic_count == 0 && list_empty(&sl811->async)) 765 sofirq_off(sl811); 766 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); 767 ··· 796 } 797 if (j < PERIODIC_SIZE) 798 continue; 799 + branch = i; 800 } 801 } 802 return branch; ··· 890 break; 891 } 892 893 + ep->hep = hep; 894 hep->hcpriv = ep; 895 } 896 ··· 961 static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 962 { 963 struct sl811 *sl811 = hcd_to_sl811(hcd); 964 + struct usb_host_endpoint *hep; 965 unsigned long flags; 966 struct sl811h_ep *ep; 967 int retval = 0; 968 969 spin_lock_irqsave(&sl811->lock, flags); 970 + hep = urb->hcpriv; 971 + if (!hep) 972 + goto fail; 973 + 974 ep = hep->hcpriv; 975 if (ep) { 976 /* finish right away if this urb can't be active ... ··· 1017 VDBG("dequeue, urb %p active %s; wait4irq\n", urb, 1018 (sl811->active_a == ep) ? "A" : "B"); 1019 } else 1020 + fail: 1021 retval = -EINVAL; 1022 spin_unlock_irqrestore(&sl811->lock, flags); 1023 return retval; ··· 1576 if (sl811->board && sl811->board->power) 1577 hub_set_power_budget(udev, sl811->board->power * 2); 1578 1579 + /* enable power and interupts */ 1580 + port_power(sl811, 1); 1581 + 1582 return 0; 1583 } 1584 ··· 1618 1619 /*-------------------------------------------------------------------------*/ 1620 1621 + static int __devexit 1622 sl811h_remove(struct device *dev) 1623 { 1624 struct usb_hcd *hcd = dev_get_drvdata(dev); ··· 1631 remove_debug_file(sl811); 1632 usb_remove_hcd(hcd); 1633 1634 + /* some platforms may use IORESOURCE_IO */ 1635 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1636 + if (res) 1637 + iounmap(sl811->data_reg); 1638 1639 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1640 + if (res) 1641 + iounmap(sl811->addr_reg); 1642 1643 usb_put_hcd(hcd); 1644 return 0; 1645 } 1646 1647 + static int __devinit 1648 sl811h_probe(struct device *dev) 1649 { 1650 struct usb_hcd *hcd; ··· 1656 void __iomem *addr_reg; 1657 void __iomem *data_reg; 1658 int retval; 1659 + u8 tmp, ioaddr = 0; 1660 1661 /* basic sanity checks first. board-specific init logic should 1662 * have initialized these three resources and probably board ··· 1664 * minimal sanity checking. 1665 */ 1666 pdev = container_of(dev, struct platform_device, dev); 1667 irq = platform_get_irq(pdev, 0); 1668 + if (pdev->num_resources < 3 || irq < 0) 1669 return -ENODEV; 1670 1671 /* refuse to confuse usbcore */ ··· 1679 return -EINVAL; 1680 } 1681 1682 + /* the chip may be wired for either kind of addressing */ 1683 + addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1684 + data = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1685 + retval = -EBUSY; 1686 + if (!addr || !data) { 1687 + addr = platform_get_resource(pdev, IORESOURCE_IO, 0); 1688 + data = platform_get_resource(pdev, IORESOURCE_IO, 1); 1689 + if (!addr || !data) 1690 + return -ENODEV; 1691 + ioaddr = 1; 1692 1693 + addr_reg = (void __iomem *) addr->start; 1694 + data_reg = (void __iomem *) data->start; 1695 + } else { 1696 + addr_reg = ioremap(addr->start, 1); 1697 + if (addr_reg == NULL) { 1698 + retval = -ENOMEM; 1699 + goto err2; 1700 + } 1701 + 1702 + data_reg = ioremap(data->start, 1); 1703 + if (data_reg == NULL) { 1704 + retval = -ENOMEM; 1705 + goto err4; 1706 + } 1707 } 1708 1709 /* allocate and initialize hcd */ ··· 1737 goto err6; 1738 } 1739 1740 + /* The chip's IRQ is level triggered, active high. A requirement 1741 + * for platform device setup is to cope with things like signal 1742 + * inverters (e.g. CF is active low) or working only with edge 1743 + * triggers (e.g. most ARM CPUs). Initial driver stress testing 1744 + * was on a system with single edge triggering, so most sorts of 1745 + * triggering arrangement should work. 1746 + */ 1747 + retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); 1748 if (retval != 0) 1749 goto err6; 1750 ··· 1752 err6: 1753 usb_put_hcd(hcd); 1754 err5: 1755 + if (!ioaddr) 1756 + iounmap(data_reg); 1757 err4: 1758 + if (!ioaddr) 1759 + iounmap(addr_reg); 1760 err2: 1761 DBG("init error, %d\n", retval); 1762 return retval; 1763 } ··· 1767 #ifdef CONFIG_PM 1768 1769 /* for this device there's no useful distinction between the controller 1770 + * and its root hub, except that the root hub only gets direct PM calls 1771 * when CONFIG_USB_SUSPEND is enabled. 1772 */ 1773 ··· 1821 #endif 1822 1823 1824 + /* this driver is exported so sl811_cs can depend on it */ 1825 + struct device_driver sl811h_driver = { 1826 .name = (char *) hcd_name, 1827 .bus = &platform_bus_type, 1828 1829 .probe = sl811h_probe, 1830 + .remove = __devexit_p(sl811h_remove), 1831 1832 .suspend = sl811h_suspend, 1833 .resume = sl811h_resume, 1834 }; 1835 + EXPORT_SYMBOL(sl811h_driver); 1836 1837 /*-------------------------------------------------------------------------*/ 1838 + 1839 + static int __init sl811h_init(void) 1840 { 1841 if (usb_disabled()) 1842 return -ENODEV; ··· 1844 } 1845 module_init(sl811h_init); 1846 1847 + static void __exit sl811h_cleanup(void) 1848 + { 1849 driver_unregister(&sl811h_driver); 1850 } 1851 module_exit(sl811h_cleanup);
+442
drivers/usb/host/sl811_cs.c
···
··· 1 + /* 2 + * PCMCIA driver for SL811HS (as found in REX-CFU1U) 3 + * Filename: sl811_cs.c 4 + * Author: Yukio Yamamoto 5 + * 6 + * Port to sl811-hcd and 2.6.x by 7 + * Botond Botyanszki <boti@rocketmail.com> 8 + * Simon Pickering 9 + * 10 + * Last update: 2005-05-12 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/init.h> 16 + #include <linux/sched.h> 17 + #include <linux/ptrace.h> 18 + #include <linux/slab.h> 19 + #include <linux/string.h> 20 + #include <linux/timer.h> 21 + #include <linux/ioport.h> 22 + 23 + #include <pcmcia/version.h> 24 + #include <pcmcia/cs_types.h> 25 + #include <pcmcia/cs.h> 26 + #include <pcmcia/cistpl.h> 27 + #include <pcmcia/cisreg.h> 28 + #include <pcmcia/ds.h> 29 + 30 + #include <linux/usb_sl811.h> 31 + 32 + MODULE_AUTHOR("Botond Botyanszki"); 33 + MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); 34 + MODULE_LICENSE("GPL"); 35 + 36 + 37 + /*====================================================================*/ 38 + /* MACROS */ 39 + /*====================================================================*/ 40 + 41 + #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) 42 + 43 + static int pc_debug = 0; 44 + module_param(pc_debug, int, 0644); 45 + 46 + #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) 47 + 48 + #else 49 + #define DBG(n, args...) do{}while(0) 50 + #endif /* no debugging */ 51 + 52 + #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) 53 + 54 + #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) 55 + 56 + #define CS_CHECK(fn, ret) \ 57 + do { \ 58 + last_fn = (fn); \ 59 + if ((last_ret = (ret)) != 0) \ 60 + goto cs_failed; \ 61 + } while (0) 62 + 63 + /*====================================================================*/ 64 + /* VARIABLES */ 65 + /*====================================================================*/ 66 + 67 + static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; 68 + 69 + static dev_link_t *dev_list = NULL; 70 + 71 + static int irq_list[4] = { -1 }; 72 + static int irq_list_count; 73 + 74 + module_param_array(irq_list, int, &irq_list_count, 0444); 75 + 76 + INT_MODULE_PARM(irq_mask, 0xdeb8); 77 + 78 + typedef struct local_info_t { 79 + dev_link_t link; 80 + dev_node_t node; 81 + } local_info_t; 82 + 83 + /*====================================================================*/ 84 + 85 + static void release_platform_dev(struct device * dev) 86 + { 87 + DBG(0, "sl811_cs platform_dev release\n"); 88 + dev->parent = NULL; 89 + } 90 + 91 + static struct sl811_platform_data platform_data = { 92 + .potpg = 100, 93 + .power = 50, /* == 100mA */ 94 + // .reset = ... FIXME: invoke CF reset on the card 95 + }; 96 + 97 + static struct resource resources[] = { 98 + [0] = { 99 + .flags = IORESOURCE_IRQ, 100 + }, 101 + [1] = { 102 + // .name = "address", 103 + .flags = IORESOURCE_IO, 104 + }, 105 + [2] = { 106 + // .name = "data", 107 + .flags = IORESOURCE_IO, 108 + }, 109 + }; 110 + 111 + extern struct device_driver sl811h_driver; 112 + 113 + static struct platform_device platform_dev = { 114 + .id = -1, 115 + .dev = { 116 + .platform_data = &platform_data, 117 + .release = release_platform_dev, 118 + }, 119 + .resource = resources, 120 + .num_resources = ARRAY_SIZE(resources), 121 + }; 122 + 123 + static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) 124 + { 125 + if (platform_dev.dev.parent) 126 + return -EBUSY; 127 + platform_dev.dev.parent = parent; 128 + 129 + /* finish seting up the platform device */ 130 + resources[0].start = irq; 131 + 132 + resources[1].start = base_addr; 133 + resources[1].end = base_addr; 134 + 135 + resources[2].start = base_addr + 1; 136 + resources[2].end = base_addr + 1; 137 + 138 + /* The driver core will probe for us. We know sl811-hcd has been 139 + * initialized already because of the link order dependency. 140 + */ 141 + platform_dev.name = sl811h_driver.name; 142 + return platform_device_register(&platform_dev); 143 + } 144 + 145 + /*====================================================================*/ 146 + 147 + static void sl811_cs_detach(dev_link_t *link) 148 + { 149 + dev_link_t **linkp; 150 + 151 + DBG(0, "sl811_cs_detach(0x%p)\n", link); 152 + 153 + /* Locate device structure */ 154 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 155 + if (*linkp == link) 156 + break; 157 + } 158 + if (*linkp == NULL) 159 + return; 160 + 161 + /* Break the link with Card Services */ 162 + if (link->handle) 163 + pcmcia_deregister_client(link->handle); 164 + 165 + /* Unlink device structure, and free it */ 166 + *linkp = link->next; 167 + /* This points to the parent local_info_t struct */ 168 + kfree(link->priv); 169 + } 170 + 171 + static void sl811_cs_release(dev_link_t * link) 172 + { 173 + 174 + DBG(0, "sl811_cs_release(0x%p)\n", link); 175 + 176 + if (link->open) { 177 + DBG(1, "sl811_cs: release postponed, '%s' still open\n", 178 + link->dev->dev_name); 179 + link->state |= DEV_STALE_CONFIG; 180 + return; 181 + } 182 + 183 + /* Unlink the device chain */ 184 + link->dev = NULL; 185 + 186 + platform_device_unregister(&platform_dev); 187 + pcmcia_release_configuration(link->handle); 188 + if (link->io.NumPorts1) 189 + pcmcia_release_io(link->handle, &link->io); 190 + if (link->irq.AssignedIRQ) 191 + pcmcia_release_irq(link->handle, &link->irq); 192 + link->state &= ~DEV_CONFIG; 193 + 194 + if (link->state & DEV_STALE_LINK) 195 + sl811_cs_detach(link); 196 + } 197 + 198 + static void sl811_cs_config(dev_link_t *link) 199 + { 200 + client_handle_t handle = link->handle; 201 + struct device *parent = &handle_to_dev(handle); 202 + local_info_t *dev = link->priv; 203 + tuple_t tuple; 204 + cisparse_t parse; 205 + int last_fn, last_ret; 206 + u_char buf[64]; 207 + config_info_t conf; 208 + cistpl_cftable_entry_t dflt = { 0 }; 209 + 210 + DBG(0, "sl811_cs_config(0x%p)\n", link); 211 + 212 + tuple.DesiredTuple = CISTPL_CONFIG; 213 + tuple.Attributes = 0; 214 + tuple.TupleData = buf; 215 + tuple.TupleDataMax = sizeof(buf); 216 + tuple.TupleOffset = 0; 217 + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 218 + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 219 + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 220 + link->conf.ConfigBase = parse.config.base; 221 + link->conf.Present = parse.config.rmask[0]; 222 + 223 + /* Configure card */ 224 + link->state |= DEV_CONFIG; 225 + 226 + /* Look up the current Vcc */ 227 + CS_CHECK(GetConfigurationInfo, 228 + pcmcia_get_configuration_info(handle, &conf)); 229 + link->conf.Vcc = conf.Vcc; 230 + 231 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 232 + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 233 + while (1) { 234 + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 235 + 236 + if (pcmcia_get_tuple_data(handle, &tuple) != 0 237 + || pcmcia_parse_tuple(handle, &tuple, &parse) 238 + != 0) 239 + goto next_entry; 240 + 241 + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { 242 + dflt = *cfg; 243 + } 244 + 245 + if (cfg->index == 0) 246 + goto next_entry; 247 + 248 + link->conf.ConfigIndex = cfg->index; 249 + 250 + /* Use power settings for Vcc and Vpp if present */ 251 + /* Note that the CIS values need to be rescaled */ 252 + if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { 253 + if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 254 + != conf.Vcc) 255 + goto next_entry; 256 + } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { 257 + if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 258 + != conf.Vcc) 259 + goto next_entry; 260 + } 261 + 262 + if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 263 + link->conf.Vpp1 = link->conf.Vpp2 = 264 + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 265 + else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 266 + link->conf.Vpp1 = link->conf.Vpp2 = 267 + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; 268 + 269 + /* we need an interrupt */ 270 + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 271 + link->conf.Attributes |= CONF_ENABLE_IRQ; 272 + 273 + /* IO window settings */ 274 + link->io.NumPorts1 = link->io.NumPorts2 = 0; 275 + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 276 + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 277 + 278 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 279 + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 280 + link->io.BasePort1 = io->win[0].base; 281 + link->io.NumPorts1 = io->win[0].len; 282 + 283 + if (pcmcia_request_io(link->handle, &link->io) != 0) 284 + goto next_entry; 285 + } 286 + break; 287 + 288 + next_entry: 289 + if (link->io.NumPorts1) 290 + pcmcia_release_io(link->handle, &link->io); 291 + last_ret = pcmcia_get_next_tuple(handle, &tuple); 292 + } 293 + 294 + /* require an IRQ and two registers */ 295 + if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) 296 + goto cs_failed; 297 + if (link->conf.Attributes & CONF_ENABLE_IRQ) 298 + CS_CHECK(RequestIRQ, 299 + pcmcia_request_irq(link->handle, &link->irq)); 300 + else 301 + goto cs_failed; 302 + 303 + CS_CHECK(RequestConfiguration, 304 + pcmcia_request_configuration(link->handle, &link->conf)); 305 + 306 + sprintf(dev->node.dev_name, driver_name); 307 + dev->node.major = dev->node.minor = 0; 308 + link->dev = &dev->node; 309 + 310 + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 311 + dev->node.dev_name, link->conf.ConfigIndex, 312 + link->conf.Vcc/10, link->conf.Vcc%10); 313 + if (link->conf.Vpp1) 314 + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); 315 + printk(", irq %d", link->irq.AssignedIRQ); 316 + printk(", io 0x%04x-0x%04x", link->io.BasePort1, 317 + link->io.BasePort1+link->io.NumPorts1-1); 318 + printk("\n"); 319 + 320 + link->state &= ~DEV_CONFIG_PENDING; 321 + 322 + if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) 323 + < 0) { 324 + cs_failed: 325 + printk("sl811_cs_config failed\n"); 326 + cs_error(link->handle, last_fn, last_ret); 327 + sl811_cs_release(link); 328 + link->state &= ~DEV_CONFIG_PENDING; 329 + } 330 + } 331 + 332 + static int 333 + sl811_cs_event(event_t event, int priority, event_callback_args_t *args) 334 + { 335 + dev_link_t *link = args->client_data; 336 + 337 + DBG(1, "sl811_cs_event(0x%06x)\n", event); 338 + 339 + switch (event) { 340 + case CS_EVENT_CARD_REMOVAL: 341 + link->state &= ~DEV_PRESENT; 342 + if (link->state & DEV_CONFIG) 343 + sl811_cs_release(link); 344 + break; 345 + 346 + case CS_EVENT_CARD_INSERTION: 347 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 348 + sl811_cs_config(link); 349 + break; 350 + 351 + case CS_EVENT_PM_SUSPEND: 352 + link->state |= DEV_SUSPEND; 353 + /* Fall through... */ 354 + case CS_EVENT_RESET_PHYSICAL: 355 + if (link->state & DEV_CONFIG) 356 + pcmcia_release_configuration(link->handle); 357 + break; 358 + 359 + case CS_EVENT_PM_RESUME: 360 + link->state &= ~DEV_SUSPEND; 361 + /* Fall through... */ 362 + case CS_EVENT_CARD_RESET: 363 + if (link->state & DEV_CONFIG) 364 + pcmcia_request_configuration(link->handle, &link->conf); 365 + DBG(0, "reset sl811-hcd here?\n"); 366 + break; 367 + } 368 + return 0; 369 + } 370 + 371 + static dev_link_t *sl811_cs_attach(void) 372 + { 373 + local_info_t *local; 374 + dev_link_t *link; 375 + client_reg_t client_reg; 376 + int ret, i; 377 + 378 + local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 379 + if (!local) 380 + return NULL; 381 + memset(local, 0, sizeof(local_info_t)); 382 + link = &local->link; 383 + link->priv = local; 384 + 385 + /* Initialize */ 386 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 387 + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; 388 + if (irq_list[0] == -1) 389 + link->irq.IRQInfo2 = irq_mask; 390 + else 391 + for (i = 0; i < irq_list_count; i++) 392 + link->irq.IRQInfo2 |= 1 << irq_list[i]; 393 + link->irq.Handler = NULL; 394 + 395 + link->conf.Attributes = 0; 396 + link->conf.Vcc = 33; 397 + link->conf.IntType = INT_MEMORY_AND_IO; 398 + 399 + /* Register with Card Services */ 400 + link->next = dev_list; 401 + dev_list = link; 402 + client_reg.dev_info = (dev_info_t *) &driver_name; 403 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; 404 + client_reg.EventMask = 405 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | 406 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | 407 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; 408 + client_reg.event_handler = &sl811_cs_event; 409 + client_reg.Version = 0x0210; 410 + client_reg.event_callback_args.client_data = link; 411 + ret = pcmcia_register_client(&link->handle, &client_reg); 412 + if (ret != CS_SUCCESS) { 413 + cs_error(link->handle, RegisterClient, ret); 414 + sl811_cs_detach(link); 415 + return NULL; 416 + } 417 + 418 + return link; 419 + } 420 + 421 + static struct pcmcia_driver sl811_cs_driver = { 422 + .owner = THIS_MODULE, 423 + .drv = { 424 + .name = (char *)driver_name, 425 + }, 426 + .attach = sl811_cs_attach, 427 + .detach = sl811_cs_detach, 428 + }; 429 + 430 + /*====================================================================*/ 431 + 432 + static int __init init_sl811_cs(void) 433 + { 434 + return pcmcia_register_driver(&sl811_cs_driver); 435 + } 436 + module_init(init_sl811_cs); 437 + 438 + static void __exit exit_sl811_cs(void) 439 + { 440 + pcmcia_unregister_driver(&sl811_cs_driver); 441 + } 442 + module_exit(exit_sl811_cs);
+3
drivers/usb/serial/ftdi_sio.c
··· 364 { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, 365 { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, 366 { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, 367 { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, 368 { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, 369 { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, ··· 476 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, 477 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, 478 { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, 479 { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, 480 { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, 481 { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, ··· 620 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, 621 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, 622 { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, 623 { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, 624 { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, 625 { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
··· 364 { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, 365 { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, 366 { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, 367 + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, 368 { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, 369 { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, 370 { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, ··· 475 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, 476 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, 477 { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, 478 + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, 479 { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, 480 { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, 481 { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, ··· 618 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, 619 { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, 620 { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, 621 + { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, 622 { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, 623 { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, 624 { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
+2
drivers/usb/serial/ftdi_sio.h
··· 144 145 /* ELV USB Module UO100 (PID sent by Stefan Frings) */ 146 #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ 147 148 /* 149 * Definitions for ID TECH (www.idt-net.com) devices
··· 144 145 /* ELV USB Module UO100 (PID sent by Stefan Frings) */ 146 #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ 147 + /* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ 148 + #define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ 149 150 /* 151 * Definitions for ID TECH (www.idt-net.com) devices
+10 -10
drivers/usb/serial/usb-serial.c
··· 1297 goto exit_bus; 1298 } 1299 1300 - /* register the generic driver, if we should */ 1301 - result = usb_serial_generic_register(debug); 1302 - if (result < 0) { 1303 - err("%s - registering generic driver failed", __FUNCTION__); 1304 - goto exit_generic; 1305 - } 1306 - 1307 usb_serial_tty_driver->owner = THIS_MODULE; 1308 usb_serial_tty_driver->driver_name = "usbserial"; 1309 usb_serial_tty_driver->devfs_name = "usb/tts/"; ··· 1322 goto exit_tty; 1323 } 1324 1325 info(DRIVER_DESC " " DRIVER_VERSION); 1326 1327 return result; 1328 1329 exit_tty: 1330 tty_unregister_driver(usb_serial_tty_driver); 1331 1332 exit_reg_driver: 1333 - usb_serial_generic_deregister(); 1334 - 1335 - exit_generic: 1336 bus_unregister(&usb_serial_bus_type); 1337 1338 exit_bus:
··· 1297 goto exit_bus; 1298 } 1299 1300 usb_serial_tty_driver->owner = THIS_MODULE; 1301 usb_serial_tty_driver->driver_name = "usbserial"; 1302 usb_serial_tty_driver->devfs_name = "usb/tts/"; ··· 1329 goto exit_tty; 1330 } 1331 1332 + /* register the generic driver, if we should */ 1333 + result = usb_serial_generic_register(debug); 1334 + if (result < 0) { 1335 + err("%s - registering generic driver failed", __FUNCTION__); 1336 + goto exit_generic; 1337 + } 1338 + 1339 info(DRIVER_DESC " " DRIVER_VERSION); 1340 1341 return result; 1342 + 1343 + exit_generic: 1344 + usb_deregister(&usb_serial_driver); 1345 1346 exit_tty: 1347 tty_unregister_driver(usb_serial_tty_driver); 1348 1349 exit_reg_driver: 1350 bus_unregister(&usb_serial_bus_type); 1351 1352 exit_bus: