diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2006-12-08 01:07:56 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2006-12-08 01:07:56 -0500 |
commit | bef986502fa398b1785a3979b1aa17cd902d3527 (patch) | |
tree | b59c1afe7b1dfcc001b86e54863f550d7ddc8c34 /drivers/usb/input/hid-core.c | |
parent | 4bdbd2807deeccc0793d57fb5120d7a53f2c0b3c (diff) | |
parent | c99767974ebd2a719d849fdeaaa1674456f5283f (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/hid.h
Diffstat (limited to 'drivers/usb/input/hid-core.c')
-rw-r--r-- | drivers/usb/input/hid-core.c | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 6095d9cedb7..0811c39bd14 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -968,20 +968,30 @@ static void hid_retry_timeout(unsigned long _hid) | |||
968 | hid_io_error(hid); | 968 | hid_io_error(hid); |
969 | } | 969 | } |
970 | 970 | ||
971 | /* Workqueue routine to reset the device */ | 971 | /* Workqueue routine to reset the device or clear a halt */ |
972 | static void hid_reset(void *_hid) | 972 | static void hid_reset(struct work_struct *work) |
973 | { | 973 | { |
974 | struct hid_device *hid = (struct hid_device *) _hid; | 974 | struct hid_device *hid = |
975 | int rc_lock, rc; | 975 | container_of(work, struct hid_device, reset_work); |
976 | 976 | int rc_lock, rc = 0; | |
977 | dev_dbg(&hid->intf->dev, "resetting device\n"); | 977 | |
978 | rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); | 978 | if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { |
979 | if (rc_lock >= 0) { | 979 | dev_dbg(&hid->intf->dev, "clear halt\n"); |
980 | rc = usb_reset_composite_device(hid->dev, hid->intf); | 980 | rc = usb_clear_halt(hid->dev, hid->urbin->pipe); |
981 | if (rc_lock) | 981 | clear_bit(HID_CLEAR_HALT, &hid->iofl); |
982 | usb_unlock_device(hid->dev); | 982 | hid_start_in(hid); |
983 | } | ||
984 | |||
985 | else if (test_bit(HID_RESET_PENDING, &hid->iofl)) { | ||
986 | dev_dbg(&hid->intf->dev, "resetting device\n"); | ||
987 | rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); | ||
988 | if (rc_lock >= 0) { | ||
989 | rc = usb_reset_composite_device(hid->dev, hid->intf); | ||
990 | if (rc_lock) | ||
991 | usb_unlock_device(hid->dev); | ||
992 | } | ||
993 | clear_bit(HID_RESET_PENDING, &hid->iofl); | ||
983 | } | 994 | } |
984 | clear_bit(HID_RESET_PENDING, &hid->iofl); | ||
985 | 995 | ||
986 | switch (rc) { | 996 | switch (rc) { |
987 | case 0: | 997 | case 0: |
@@ -1023,9 +1033,8 @@ static void hid_io_error(struct hid_device *hid) | |||
1023 | 1033 | ||
1024 | /* Retries failed, so do a port reset */ | 1034 | /* Retries failed, so do a port reset */ |
1025 | if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { | 1035 | if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { |
1026 | if (schedule_work(&hid->reset_work)) | 1036 | schedule_work(&hid->reset_work); |
1027 | goto done; | 1037 | goto done; |
1028 | clear_bit(HID_RESET_PENDING, &hid->iofl); | ||
1029 | } | 1038 | } |
1030 | } | 1039 | } |
1031 | 1040 | ||
@@ -1049,6 +1058,11 @@ static void hid_irq_in(struct urb *urb) | |||
1049 | hid->retry_delay = 0; | 1058 | hid->retry_delay = 0; |
1050 | hid_input_report(HID_INPUT_REPORT, urb, 1); | 1059 | hid_input_report(HID_INPUT_REPORT, urb, 1); |
1051 | break; | 1060 | break; |
1061 | case -EPIPE: /* stall */ | ||
1062 | clear_bit(HID_IN_RUNNING, &hid->iofl); | ||
1063 | set_bit(HID_CLEAR_HALT, &hid->iofl); | ||
1064 | schedule_work(&hid->reset_work); | ||
1065 | return; | ||
1052 | case -ECONNRESET: /* unlink */ | 1066 | case -ECONNRESET: /* unlink */ |
1053 | case -ENOENT: | 1067 | case -ENOENT: |
1054 | case -ESHUTDOWN: /* unplug */ | 1068 | case -ESHUTDOWN: /* unplug */ |
@@ -1065,7 +1079,7 @@ static void hid_irq_in(struct urb *urb) | |||
1065 | warn("input irq status %d received", urb->status); | 1079 | warn("input irq status %d received", urb->status); |
1066 | } | 1080 | } |
1067 | 1081 | ||
1068 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 1082 | status = usb_submit_urb(urb, GFP_ATOMIC); |
1069 | if (status) { | 1083 | if (status) { |
1070 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 1084 | clear_bit(HID_IN_RUNNING, &hid->iofl); |
1071 | if (status != -EPERM) { | 1085 | if (status != -EPERM) { |
@@ -1627,6 +1641,19 @@ void hid_init_reports(struct hid_device *hid) | |||
1627 | 1641 | ||
1628 | #define USB_VENDOR_ID_APPLE 0x05ac | 1642 | #define USB_VENDOR_ID_APPLE 0x05ac |
1629 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 | 1643 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 |
1644 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e | ||
1645 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f | ||
1646 | #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 | ||
1647 | #define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 | ||
1648 | #define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 | ||
1649 | #define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 | ||
1650 | #define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 | ||
1651 | #define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 | ||
1652 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a | ||
1653 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b | ||
1654 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c | ||
1655 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | ||
1656 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | ||
1630 | 1657 | ||
1631 | #define USB_VENDOR_ID_CHERRY 0x046a | 1658 | #define USB_VENDOR_ID_CHERRY 0x046a |
1632 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 | 1659 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 |
@@ -1797,16 +1824,19 @@ static const struct hid_blacklist { | |||
1797 | 1824 | ||
1798 | { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, | 1825 | { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, |
1799 | 1826 | ||
1800 | { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, | 1827 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, |
1801 | { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, | 1828 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, |
1802 | { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, | 1829 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, |
1803 | { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, | 1830 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1804 | { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, | 1831 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, |
1805 | { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, | 1832 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, |
1806 | { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN }, | 1833 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1807 | { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, | 1834 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, |
1808 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, | 1835 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, |
1809 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, | 1836 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, |
1837 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
1838 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
1839 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
1810 | 1840 | ||
1811 | { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, | 1841 | { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, |
1812 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, | 1842 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, |
@@ -1839,13 +1869,13 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int * | |||
1839 | 1869 | ||
1840 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | 1870 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) |
1841 | { | 1871 | { |
1842 | if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) | 1872 | if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma))) |
1843 | return -1; | 1873 | return -1; |
1844 | if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) | 1874 | if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma))) |
1845 | return -1; | 1875 | return -1; |
1846 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) | 1876 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma))) |
1847 | return -1; | 1877 | return -1; |
1848 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) | 1878 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma))) |
1849 | return -1; | 1879 | return -1; |
1850 | 1880 | ||
1851 | return 0; | 1881 | return 0; |
@@ -1989,7 +2019,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1989 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) | 2019 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) |
1990 | interval = hid_mousepoll_interval; | 2020 | interval = hid_mousepoll_interval; |
1991 | 2021 | ||
1992 | if (endpoint->bEndpointAddress & USB_DIR_IN) { | 2022 | if (usb_endpoint_dir_in(endpoint)) { |
1993 | if (hid->urbin) | 2023 | if (hid->urbin) |
1994 | continue; | 2024 | continue; |
1995 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) | 2025 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) |
@@ -2019,7 +2049,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2019 | 2049 | ||
2020 | init_waitqueue_head(&hid->wait); | 2050 | init_waitqueue_head(&hid->wait); |
2021 | 2051 | ||
2022 | INIT_WORK(&hid->reset_work, hid_reset, hid); | 2052 | INIT_WORK(&hid->reset_work, hid_reset); |
2023 | setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); | 2053 | setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); |
2024 | 2054 | ||
2025 | spin_lock_init(&hid->inlock); | 2055 | spin_lock_init(&hid->inlock); |
@@ -2071,13 +2101,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2071 | return hid; | 2101 | return hid; |
2072 | 2102 | ||
2073 | fail: | 2103 | fail: |
2074 | 2104 | usb_free_urb(hid->urbin); | |
2075 | if (hid->urbin) | 2105 | usb_free_urb(hid->urbout); |
2076 | usb_free_urb(hid->urbin); | 2106 | usb_free_urb(hid->urbctrl); |
2077 | if (hid->urbout) | ||
2078 | usb_free_urb(hid->urbout); | ||
2079 | if (hid->urbctrl) | ||
2080 | usb_free_urb(hid->urbctrl); | ||
2081 | hid_free_buffers(dev, hid); | 2107 | hid_free_buffers(dev, hid); |
2082 | hid_free_device(hid); | 2108 | hid_free_device(hid); |
2083 | 2109 | ||
@@ -2108,8 +2134,7 @@ static void hid_disconnect(struct usb_interface *intf) | |||
2108 | 2134 | ||
2109 | usb_free_urb(hid->urbin); | 2135 | usb_free_urb(hid->urbin); |
2110 | usb_free_urb(hid->urbctrl); | 2136 | usb_free_urb(hid->urbctrl); |
2111 | if (hid->urbout) | 2137 | usb_free_urb(hid->urbout); |
2112 | usb_free_urb(hid->urbout); | ||
2113 | 2138 | ||
2114 | hid_free_buffers(hid->dev, hid); | 2139 | hid_free_buffers(hid->dev, hid); |
2115 | hid_free_device(hid); | 2140 | hid_free_device(hid); |