diff options
Diffstat (limited to 'drivers/usb')
105 files changed, 11475 insertions, 1209 deletions
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 516a6400db43..a419c42e880e 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -17,6 +17,8 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ | |||
17 | obj-$(CONFIG_USB_U132_HCD) += host/ | 17 | obj-$(CONFIG_USB_U132_HCD) += host/ |
18 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 18 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
19 | 19 | ||
20 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ | ||
21 | |||
20 | obj-$(CONFIG_USB_ACM) += class/ | 22 | obj-$(CONFIG_USB_ACM) += class/ |
21 | obj-$(CONFIG_USB_PRINTER) += class/ | 23 | obj-$(CONFIG_USB_PRINTER) += class/ |
22 | 24 | ||
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index 86e64035edb0..be0b8daac9c7 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig | |||
@@ -19,7 +19,6 @@ if USB_ATM | |||
19 | 19 | ||
20 | config USB_SPEEDTOUCH | 20 | config USB_SPEEDTOUCH |
21 | tristate "Speedtouch USB support" | 21 | tristate "Speedtouch USB support" |
22 | depends on USB_ATM | ||
23 | select FW_LOADER | 22 | select FW_LOADER |
24 | help | 23 | help |
25 | Say Y here if you have an SpeedTouch USB or SpeedTouch 330 | 24 | Say Y here if you have an SpeedTouch USB or SpeedTouch 330 |
@@ -32,7 +31,6 @@ config USB_SPEEDTOUCH | |||
32 | 31 | ||
33 | config USB_CXACRU | 32 | config USB_CXACRU |
34 | tristate "Conexant AccessRunner USB support" | 33 | tristate "Conexant AccessRunner USB support" |
35 | depends on USB_ATM | ||
36 | select FW_LOADER | 34 | select FW_LOADER |
37 | help | 35 | help |
38 | Say Y here if you have an ADSL USB modem based on the Conexant | 36 | Say Y here if you have an ADSL USB modem based on the Conexant |
@@ -45,7 +43,6 @@ config USB_CXACRU | |||
45 | 43 | ||
46 | config USB_UEAGLEATM | 44 | config USB_UEAGLEATM |
47 | tristate "ADI 930 and eagle USB DSL modem" | 45 | tristate "ADI 930 and eagle USB DSL modem" |
48 | depends on USB_ATM | ||
49 | select FW_LOADER | 46 | select FW_LOADER |
50 | help | 47 | help |
51 | Say Y here if you have an ADSL USB modem based on the ADI 930 | 48 | Say Y here if you have an ADSL USB modem based on the ADI 930 |
@@ -58,7 +55,6 @@ config USB_UEAGLEATM | |||
58 | 55 | ||
59 | config USB_XUSBATM | 56 | config USB_XUSBATM |
60 | tristate "Other USB DSL modem support" | 57 | tristate "Other USB DSL modem support" |
61 | depends on USB_ATM | ||
62 | help | 58 | help |
63 | Say Y here if you have a DSL USB modem not explicitly supported by | 59 | Say Y here if you have a DSL USB modem not explicitly supported by |
64 | another USB DSL drivers. In order to use your modem you will need to | 60 | another USB DSL drivers. In order to use your modem you will need to |
diff --git a/drivers/usb/c67x00/Makefile b/drivers/usb/c67x00/Makefile new file mode 100644 index 000000000000..868bc41b5980 --- /dev/null +++ b/drivers/usb/c67x00/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # | ||
2 | # Makefile for Cypress C67X00 USB Controller | ||
3 | # | ||
4 | |||
5 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | ||
6 | |||
7 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00.o | ||
8 | |||
9 | c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o | ||
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c new file mode 100644 index 000000000000..5633bc5c8bf2 --- /dev/null +++ b/drivers/usb/c67x00/c67x00-drv.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * c67x00-drv.c: Cypress C67X00 USB Common infrastructure | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * This file implements the common infrastructure for using the c67x00. | ||
26 | * It is both the link between the platform configuration and subdrivers and | ||
27 | * the link between the common hardware parts and the subdrivers (e.g. | ||
28 | * interrupt handling). | ||
29 | * | ||
30 | * The c67x00 has 2 SIE's (serial interface engine) wich can be configured | ||
31 | * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG). | ||
32 | * | ||
33 | * Depending on the platform configuration, the SIE's are created and | ||
34 | * the corresponding subdriver is initialized (c67x00_probe_sie). | ||
35 | */ | ||
36 | |||
37 | #include <linux/device.h> | ||
38 | #include <linux/io.h> | ||
39 | #include <linux/list.h> | ||
40 | #include <linux/usb.h> | ||
41 | #include <linux/usb/c67x00.h> | ||
42 | |||
43 | #include "c67x00.h" | ||
44 | #include "c67x00-hcd.h" | ||
45 | |||
46 | static void c67x00_probe_sie(struct c67x00_sie *sie, | ||
47 | struct c67x00_device *dev, int sie_num) | ||
48 | { | ||
49 | spin_lock_init(&sie->lock); | ||
50 | sie->dev = dev; | ||
51 | sie->sie_num = sie_num; | ||
52 | sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num); | ||
53 | |||
54 | switch (sie->mode) { | ||
55 | case C67X00_SIE_HOST: | ||
56 | c67x00_hcd_probe(sie); | ||
57 | break; | ||
58 | |||
59 | case C67X00_SIE_UNUSED: | ||
60 | dev_info(sie_dev(sie), | ||
61 | "Not using SIE %d as requested\n", sie->sie_num); | ||
62 | break; | ||
63 | |||
64 | default: | ||
65 | dev_err(sie_dev(sie), | ||
66 | "Unsupported configuration: 0x%x for SIE %d\n", | ||
67 | sie->mode, sie->sie_num); | ||
68 | break; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | static void c67x00_remove_sie(struct c67x00_sie *sie) | ||
73 | { | ||
74 | switch (sie->mode) { | ||
75 | case C67X00_SIE_HOST: | ||
76 | c67x00_hcd_remove(sie); | ||
77 | break; | ||
78 | |||
79 | default: | ||
80 | break; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static irqreturn_t c67x00_irq(int irq, void *__dev) | ||
85 | { | ||
86 | struct c67x00_device *c67x00 = __dev; | ||
87 | struct c67x00_sie *sie; | ||
88 | u16 msg, int_status; | ||
89 | int i, count = 8; | ||
90 | |||
91 | int_status = c67x00_ll_hpi_status(c67x00); | ||
92 | if (!int_status) | ||
93 | return IRQ_NONE; | ||
94 | |||
95 | while (int_status != 0 && (count-- >= 0)) { | ||
96 | c67x00_ll_irq(c67x00, int_status); | ||
97 | for (i = 0; i < C67X00_SIES; i++) { | ||
98 | sie = &c67x00->sie[i]; | ||
99 | msg = 0; | ||
100 | if (int_status & SIEMSG_FLG(i)) | ||
101 | msg = c67x00_ll_fetch_siemsg(c67x00, i); | ||
102 | if (sie->irq) | ||
103 | sie->irq(sie, int_status, msg); | ||
104 | } | ||
105 | int_status = c67x00_ll_hpi_status(c67x00); | ||
106 | } | ||
107 | |||
108 | if (int_status) | ||
109 | dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! " | ||
110 | "status = 0x%04x\n", int_status); | ||
111 | |||
112 | return IRQ_HANDLED; | ||
113 | } | ||
114 | |||
115 | /* ------------------------------------------------------------------------- */ | ||
116 | |||
117 | static int __devinit c67x00_drv_probe(struct platform_device *pdev) | ||
118 | { | ||
119 | struct c67x00_device *c67x00; | ||
120 | struct c67x00_platform_data *pdata; | ||
121 | struct resource *res, *res2; | ||
122 | int ret, i; | ||
123 | |||
124 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
125 | if (!res) | ||
126 | return -ENODEV; | ||
127 | |||
128 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
129 | if (!res2) | ||
130 | return -ENODEV; | ||
131 | |||
132 | pdata = pdev->dev.platform_data; | ||
133 | if (!pdata) | ||
134 | return -ENODEV; | ||
135 | |||
136 | c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL); | ||
137 | if (!c67x00) | ||
138 | return -ENOMEM; | ||
139 | |||
140 | if (!request_mem_region(res->start, res->end - res->start + 1, | ||
141 | pdev->name)) { | ||
142 | dev_err(&pdev->dev, "Memory region busy\n"); | ||
143 | ret = -EBUSY; | ||
144 | goto request_mem_failed; | ||
145 | } | ||
146 | c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1); | ||
147 | if (!c67x00->hpi.base) { | ||
148 | dev_err(&pdev->dev, "Unable to map HPI registers\n"); | ||
149 | ret = -EIO; | ||
150 | goto map_failed; | ||
151 | } | ||
152 | |||
153 | spin_lock_init(&c67x00->hpi.lock); | ||
154 | c67x00->hpi.regstep = pdata->hpi_regstep; | ||
155 | c67x00->pdata = pdev->dev.platform_data; | ||
156 | c67x00->pdev = pdev; | ||
157 | |||
158 | c67x00_ll_init(c67x00); | ||
159 | c67x00_ll_hpi_reg_init(c67x00); | ||
160 | |||
161 | ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00); | ||
162 | if (ret) { | ||
163 | dev_err(&pdev->dev, "Cannot claim IRQ\n"); | ||
164 | goto request_irq_failed; | ||
165 | } | ||
166 | |||
167 | ret = c67x00_ll_reset(c67x00); | ||
168 | if (ret) { | ||
169 | dev_err(&pdev->dev, "Device reset failed\n"); | ||
170 | goto reset_failed; | ||
171 | } | ||
172 | |||
173 | for (i = 0; i < C67X00_SIES; i++) | ||
174 | c67x00_probe_sie(&c67x00->sie[i], c67x00, i); | ||
175 | |||
176 | platform_set_drvdata(pdev, c67x00); | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | reset_failed: | ||
181 | free_irq(res2->start, c67x00); | ||
182 | request_irq_failed: | ||
183 | iounmap(c67x00->hpi.base); | ||
184 | map_failed: | ||
185 | release_mem_region(res->start, res->end - res->start + 1); | ||
186 | request_mem_failed: | ||
187 | kfree(c67x00); | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int __devexit c67x00_drv_remove(struct platform_device *pdev) | ||
193 | { | ||
194 | struct c67x00_device *c67x00 = platform_get_drvdata(pdev); | ||
195 | struct resource *res; | ||
196 | int i; | ||
197 | |||
198 | for (i = 0; i < C67X00_SIES; i++) | ||
199 | c67x00_remove_sie(&c67x00->sie[i]); | ||
200 | |||
201 | c67x00_ll_release(c67x00); | ||
202 | |||
203 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
204 | if (res) | ||
205 | free_irq(res->start, c67x00); | ||
206 | |||
207 | iounmap(c67x00->hpi.base); | ||
208 | |||
209 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
210 | if (res) | ||
211 | release_mem_region(res->start, res->end - res->start + 1); | ||
212 | |||
213 | kfree(c67x00); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static struct platform_driver c67x00_driver = { | ||
219 | .probe = c67x00_drv_probe, | ||
220 | .remove = __devexit_p(c67x00_drv_remove), | ||
221 | .driver = { | ||
222 | .owner = THIS_MODULE, | ||
223 | .name = "c67x00", | ||
224 | }, | ||
225 | }; | ||
226 | MODULE_ALIAS("platform:c67x00"); | ||
227 | |||
228 | static int __init c67x00_init(void) | ||
229 | { | ||
230 | return platform_driver_register(&c67x00_driver); | ||
231 | } | ||
232 | |||
233 | static void __exit c67x00_exit(void) | ||
234 | { | ||
235 | platform_driver_unregister(&c67x00_driver); | ||
236 | } | ||
237 | |||
238 | module_init(c67x00_init); | ||
239 | module_exit(c67x00_exit); | ||
240 | |||
241 | MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely"); | ||
242 | MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver"); | ||
243 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c new file mode 100644 index 000000000000..a22b887f4e9e --- /dev/null +++ b/drivers/usb/c67x00/c67x00-hcd.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * c67x00-hcd.c: Cypress C67X00 USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/device.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/usb.h> | ||
27 | |||
28 | #include "c67x00.h" | ||
29 | #include "c67x00-hcd.h" | ||
30 | |||
31 | /* -------------------------------------------------------------------------- | ||
32 | * Root Hub Support | ||
33 | */ | ||
34 | |||
35 | static __u8 c67x00_hub_des[] = { | ||
36 | 0x09, /* __u8 bLength; */ | ||
37 | 0x29, /* __u8 bDescriptorType; Hub-descriptor */ | ||
38 | 0x02, /* __u8 bNbrPorts; */ | ||
39 | 0x00, /* __u16 wHubCharacteristics; */ | ||
40 | 0x00, /* (per-port OC, no power switching) */ | ||
41 | 0x32, /* __u8 bPwrOn2pwrGood; 2ms */ | ||
42 | 0x00, /* __u8 bHubContrCurrent; 0 mA */ | ||
43 | 0x00, /* __u8 DeviceRemovable; ** 7 Ports max ** */ | ||
44 | 0xff, /* __u8 PortPwrCtrlMask; ** 7 ports max ** */ | ||
45 | }; | ||
46 | |||
47 | static void c67x00_hub_reset_host_port(struct c67x00_sie *sie, int port) | ||
48 | { | ||
49 | struct c67x00_hcd *c67x00 = sie->private_data; | ||
50 | unsigned long flags; | ||
51 | |||
52 | c67x00_ll_husb_reset(sie, port); | ||
53 | |||
54 | spin_lock_irqsave(&c67x00->lock, flags); | ||
55 | c67x00_ll_husb_reset_port(sie, port); | ||
56 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
57 | |||
58 | c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT); | ||
59 | } | ||
60 | |||
61 | static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
62 | { | ||
63 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
64 | struct c67x00_sie *sie = c67x00->sie; | ||
65 | u16 status; | ||
66 | int i; | ||
67 | |||
68 | *buf = 0; | ||
69 | status = c67x00_ll_usb_get_status(sie); | ||
70 | for (i = 0; i < C67X00_PORTS; i++) | ||
71 | if (status & PORT_CONNECT_CHANGE(i)) | ||
72 | *buf |= (1 << i); | ||
73 | |||
74 | /* bit 0 denotes hub change, b1..n port change */ | ||
75 | *buf <<= 1; | ||
76 | |||
77 | return !!*buf; | ||
78 | } | ||
79 | |||
80 | static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
81 | u16 wIndex, char *buf, u16 wLength) | ||
82 | { | ||
83 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
84 | struct c67x00_sie *sie = c67x00->sie; | ||
85 | u16 status, usb_status; | ||
86 | int len = 0; | ||
87 | unsigned int port = wIndex-1; | ||
88 | u16 wPortChange, wPortStatus; | ||
89 | |||
90 | switch (typeReq) { | ||
91 | |||
92 | case GetHubStatus: | ||
93 | *(__le32 *) buf = cpu_to_le32(0); | ||
94 | len = 4; /* hub power */ | ||
95 | break; | ||
96 | |||
97 | case GetPortStatus: | ||
98 | if (wIndex > C67X00_PORTS) | ||
99 | return -EPIPE; | ||
100 | |||
101 | status = c67x00_ll_usb_get_status(sie); | ||
102 | usb_status = c67x00_ll_get_usb_ctl(sie); | ||
103 | |||
104 | wPortChange = 0; | ||
105 | if (status & PORT_CONNECT_CHANGE(port)) | ||
106 | wPortChange |= USB_PORT_STAT_C_CONNECTION; | ||
107 | |||
108 | wPortStatus = USB_PORT_STAT_POWER; | ||
109 | if (!(status & PORT_SE0_STATUS(port))) | ||
110 | wPortStatus |= USB_PORT_STAT_CONNECTION; | ||
111 | if (usb_status & LOW_SPEED_PORT(port)) { | ||
112 | wPortStatus |= USB_PORT_STAT_LOW_SPEED; | ||
113 | c67x00->low_speed_ports |= (1 << port); | ||
114 | } else | ||
115 | c67x00->low_speed_ports &= ~(1 << port); | ||
116 | |||
117 | if (usb_status & SOF_EOP_EN(port)) | ||
118 | wPortStatus |= USB_PORT_STAT_ENABLE; | ||
119 | |||
120 | *(__le16 *) buf = cpu_to_le16(wPortStatus); | ||
121 | *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange); | ||
122 | len = 4; | ||
123 | break; | ||
124 | |||
125 | case SetHubFeature: /* We don't implement these */ | ||
126 | case ClearHubFeature: | ||
127 | switch (wValue) { | ||
128 | case C_HUB_OVER_CURRENT: | ||
129 | case C_HUB_LOCAL_POWER: | ||
130 | len = 0; | ||
131 | break; | ||
132 | |||
133 | default: | ||
134 | return -EPIPE; | ||
135 | } | ||
136 | break; | ||
137 | |||
138 | case SetPortFeature: | ||
139 | if (wIndex > C67X00_PORTS) | ||
140 | return -EPIPE; | ||
141 | |||
142 | switch (wValue) { | ||
143 | case USB_PORT_FEAT_SUSPEND: | ||
144 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
145 | "SetPortFeature %d (SUSPEND)\n", port); | ||
146 | len = 0; | ||
147 | break; | ||
148 | |||
149 | case USB_PORT_FEAT_RESET: | ||
150 | c67x00_hub_reset_host_port(sie, port); | ||
151 | len = 0; | ||
152 | break; | ||
153 | |||
154 | case USB_PORT_FEAT_POWER: | ||
155 | /* Power always enabled */ | ||
156 | len = 0; | ||
157 | break; | ||
158 | |||
159 | default: | ||
160 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
161 | "%s: SetPortFeature %d (0x%04x) Error!\n", | ||
162 | __func__, port, wValue); | ||
163 | return -EPIPE; | ||
164 | } | ||
165 | break; | ||
166 | |||
167 | case ClearPortFeature: | ||
168 | if (wIndex > C67X00_PORTS) | ||
169 | return -EPIPE; | ||
170 | |||
171 | switch (wValue) { | ||
172 | case USB_PORT_FEAT_ENABLE: | ||
173 | /* Reset the port so that the c67x00 also notices the | ||
174 | * disconnect */ | ||
175 | c67x00_hub_reset_host_port(sie, port); | ||
176 | len = 0; | ||
177 | break; | ||
178 | |||
179 | case USB_PORT_FEAT_C_ENABLE: | ||
180 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
181 | "ClearPortFeature (%d): C_ENABLE\n", port); | ||
182 | len = 0; | ||
183 | break; | ||
184 | |||
185 | case USB_PORT_FEAT_SUSPEND: | ||
186 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
187 | "ClearPortFeature (%d): SUSPEND\n", port); | ||
188 | len = 0; | ||
189 | break; | ||
190 | |||
191 | case USB_PORT_FEAT_C_SUSPEND: | ||
192 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
193 | "ClearPortFeature (%d): C_SUSPEND\n", port); | ||
194 | len = 0; | ||
195 | break; | ||
196 | |||
197 | case USB_PORT_FEAT_POWER: | ||
198 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
199 | "ClearPortFeature (%d): POWER\n", port); | ||
200 | return -EPIPE; | ||
201 | |||
202 | case USB_PORT_FEAT_C_CONNECTION: | ||
203 | c67x00_ll_usb_clear_status(sie, | ||
204 | PORT_CONNECT_CHANGE(port)); | ||
205 | len = 0; | ||
206 | break; | ||
207 | |||
208 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
209 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
210 | "ClearPortFeature (%d): OVER_CURRENT\n", port); | ||
211 | len = 0; | ||
212 | break; | ||
213 | |||
214 | case USB_PORT_FEAT_C_RESET: | ||
215 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
216 | "ClearPortFeature (%d): C_RESET\n", port); | ||
217 | len = 0; | ||
218 | break; | ||
219 | |||
220 | default: | ||
221 | dev_dbg(c67x00_hcd_dev(c67x00), | ||
222 | "%s: ClearPortFeature %d (0x%04x) Error!\n", | ||
223 | __func__, port, wValue); | ||
224 | return -EPIPE; | ||
225 | } | ||
226 | break; | ||
227 | |||
228 | case GetHubDescriptor: | ||
229 | len = min_t(unsigned int, sizeof(c67x00_hub_des), wLength); | ||
230 | memcpy(buf, c67x00_hub_des, len); | ||
231 | break; | ||
232 | |||
233 | default: | ||
234 | dev_dbg(c67x00_hcd_dev(c67x00), "%s: unknown\n", __func__); | ||
235 | return -EPIPE; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /* --------------------------------------------------------------------- | ||
242 | * Main part of host controller driver | ||
243 | */ | ||
244 | |||
245 | /** | ||
246 | * c67x00_hcd_irq | ||
247 | * | ||
248 | * This function is called from the interrupt handler in c67x00-drv.c | ||
249 | */ | ||
250 | static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg) | ||
251 | { | ||
252 | struct c67x00_hcd *c67x00 = sie->private_data; | ||
253 | struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); | ||
254 | |||
255 | /* Handle sie message flags */ | ||
256 | if (msg) { | ||
257 | if (msg & HUSB_TDListDone) | ||
258 | c67x00_sched_kick(c67x00); | ||
259 | else | ||
260 | dev_warn(c67x00_hcd_dev(c67x00), | ||
261 | "Unknown SIE msg flag(s): 0x%04x\n", msg); | ||
262 | } | ||
263 | |||
264 | if (unlikely(hcd->state == HC_STATE_HALT)) | ||
265 | return; | ||
266 | |||
267 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) | ||
268 | return; | ||
269 | |||
270 | /* Handle Start of frame events */ | ||
271 | if (int_status & SOFEOP_FLG(sie->sie_num)) { | ||
272 | c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG); | ||
273 | c67x00_sched_kick(c67x00); | ||
274 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * c67x00_hcd_start: Host controller start hook | ||
280 | */ | ||
281 | static int c67x00_hcd_start(struct usb_hcd *hcd) | ||
282 | { | ||
283 | hcd->uses_new_polling = 1; | ||
284 | hcd->state = HC_STATE_RUNNING; | ||
285 | hcd->poll_rh = 1; | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * c67x00_hcd_stop: Host controller stop hook | ||
292 | */ | ||
293 | static void c67x00_hcd_stop(struct usb_hcd *hcd) | ||
294 | { | ||
295 | /* Nothing to do */ | ||
296 | } | ||
297 | |||
298 | static int c67x00_hcd_get_frame(struct usb_hcd *hcd) | ||
299 | { | ||
300 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
301 | u16 temp_val; | ||
302 | |||
303 | dev_dbg(c67x00_hcd_dev(c67x00), "%s\n", __func__); | ||
304 | temp_val = c67x00_ll_husb_get_frame(c67x00->sie); | ||
305 | temp_val &= HOST_FRAME_MASK; | ||
306 | return temp_val ? (temp_val - 1) : HOST_FRAME_MASK; | ||
307 | } | ||
308 | |||
309 | static struct hc_driver c67x00_hc_driver = { | ||
310 | .description = "c67x00-hcd", | ||
311 | .product_desc = "Cypress C67X00 Host Controller", | ||
312 | .hcd_priv_size = sizeof(struct c67x00_hcd), | ||
313 | .flags = HCD_USB11 | HCD_MEMORY, | ||
314 | |||
315 | /* | ||
316 | * basic lifecycle operations | ||
317 | */ | ||
318 | .start = c67x00_hcd_start, | ||
319 | .stop = c67x00_hcd_stop, | ||
320 | |||
321 | /* | ||
322 | * managing i/o requests and associated device resources | ||
323 | */ | ||
324 | .urb_enqueue = c67x00_urb_enqueue, | ||
325 | .urb_dequeue = c67x00_urb_dequeue, | ||
326 | .endpoint_disable = c67x00_endpoint_disable, | ||
327 | |||
328 | /* | ||
329 | * scheduling support | ||
330 | */ | ||
331 | .get_frame_number = c67x00_hcd_get_frame, | ||
332 | |||
333 | /* | ||
334 | * root hub support | ||
335 | */ | ||
336 | .hub_status_data = c67x00_hub_status_data, | ||
337 | .hub_control = c67x00_hub_control, | ||
338 | }; | ||
339 | |||
340 | /* --------------------------------------------------------------------- | ||
341 | * Setup/Teardown routines | ||
342 | */ | ||
343 | |||
344 | int c67x00_hcd_probe(struct c67x00_sie *sie) | ||
345 | { | ||
346 | struct c67x00_hcd *c67x00; | ||
347 | struct usb_hcd *hcd; | ||
348 | unsigned long flags; | ||
349 | int retval; | ||
350 | |||
351 | if (usb_disabled()) | ||
352 | return -ENODEV; | ||
353 | |||
354 | hcd = usb_create_hcd(&c67x00_hc_driver, sie_dev(sie), "c67x00_sie"); | ||
355 | if (!hcd) { | ||
356 | retval = -ENOMEM; | ||
357 | goto err0; | ||
358 | } | ||
359 | c67x00 = hcd_to_c67x00_hcd(hcd); | ||
360 | |||
361 | spin_lock_init(&c67x00->lock); | ||
362 | c67x00->sie = sie; | ||
363 | |||
364 | INIT_LIST_HEAD(&c67x00->list[PIPE_ISOCHRONOUS]); | ||
365 | INIT_LIST_HEAD(&c67x00->list[PIPE_INTERRUPT]); | ||
366 | INIT_LIST_HEAD(&c67x00->list[PIPE_CONTROL]); | ||
367 | INIT_LIST_HEAD(&c67x00->list[PIPE_BULK]); | ||
368 | c67x00->urb_count = 0; | ||
369 | INIT_LIST_HEAD(&c67x00->td_list); | ||
370 | c67x00->td_base_addr = CY_HCD_BUF_ADDR + SIE_TD_OFFSET(sie->sie_num); | ||
371 | c67x00->buf_base_addr = CY_HCD_BUF_ADDR + SIE_BUF_OFFSET(sie->sie_num); | ||
372 | c67x00->max_frame_bw = MAX_FRAME_BW_STD; | ||
373 | |||
374 | c67x00_ll_husb_init_host_port(sie); | ||
375 | |||
376 | init_completion(&c67x00->endpoint_disable); | ||
377 | retval = c67x00_sched_start_scheduler(c67x00); | ||
378 | if (retval) | ||
379 | goto err1; | ||
380 | |||
381 | retval = usb_add_hcd(hcd, 0, 0); | ||
382 | if (retval) { | ||
383 | dev_dbg(sie_dev(sie), "%s: usb_add_hcd returned %d\n", | ||
384 | __func__, retval); | ||
385 | goto err2; | ||
386 | } | ||
387 | |||
388 | spin_lock_irqsave(&sie->lock, flags); | ||
389 | sie->private_data = c67x00; | ||
390 | sie->irq = c67x00_hcd_irq; | ||
391 | spin_unlock_irqrestore(&sie->lock, flags); | ||
392 | |||
393 | return retval; | ||
394 | |||
395 | err2: | ||
396 | c67x00_sched_stop_scheduler(c67x00); | ||
397 | err1: | ||
398 | usb_put_hcd(hcd); | ||
399 | err0: | ||
400 | return retval; | ||
401 | } | ||
402 | |||
403 | /* may be called with controller, bus, and devices active */ | ||
404 | void c67x00_hcd_remove(struct c67x00_sie *sie) | ||
405 | { | ||
406 | struct c67x00_hcd *c67x00 = sie->private_data; | ||
407 | struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); | ||
408 | |||
409 | c67x00_sched_stop_scheduler(c67x00); | ||
410 | usb_remove_hcd(hcd); | ||
411 | usb_put_hcd(hcd); | ||
412 | } | ||
diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h new file mode 100644 index 000000000000..e8c6d94b2514 --- /dev/null +++ b/drivers/usb/c67x00/c67x00-hcd.h | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * c67x00-hcd.h: Cypress C67X00 USB HCD | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_C67X00_HCD_H | ||
25 | #define _USB_C67X00_HCD_H | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include "../core/hcd.h" | ||
32 | #include "c67x00.h" | ||
33 | |||
34 | /* | ||
35 | * The following parameters depend on the CPU speed, bus speed, ... | ||
36 | * These can be tuned for specific use cases, e.g. if isochronous transfers | ||
37 | * are very important, bandwith can be sacrificed to guarantee that the | ||
38 | * 1ms deadline will be met. | ||
39 | * If bulk transfers are important, the MAX_FRAME_BW can be increased, | ||
40 | * but some (or many) isochronous deadlines might not be met. | ||
41 | * | ||
42 | * The values are specified in bittime. | ||
43 | */ | ||
44 | |||
45 | /* | ||
46 | * The current implementation switches between _STD (default) and _ISO (when | ||
47 | * isochronous transfers are scheduled), in order to optimize the throughput | ||
48 | * in normal cicrumstances, but also provide good isochronous behaviour. | ||
49 | * | ||
50 | * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms | ||
51 | * frames; there are 12000 bit times per frame. | ||
52 | */ | ||
53 | |||
54 | #define TOTAL_FRAME_BW 12000 | ||
55 | #define DEFAULT_EOT 2250 | ||
56 | |||
57 | #define MAX_FRAME_BW_STD (TOTAL_FRAME_BW - DEFAULT_EOT) | ||
58 | #define MAX_FRAME_BW_ISO 2400 | ||
59 | |||
60 | /* | ||
61 | * Periodic transfers may only use 90% of the full frame, but as | ||
62 | * we currently don't even use 90% of the full frame, we may | ||
63 | * use the full usable time for periodic transfers. | ||
64 | */ | ||
65 | #define MAX_PERIODIC_BW(full_bw) full_bw | ||
66 | |||
67 | /* -------------------------------------------------------------------------- */ | ||
68 | |||
69 | struct c67x00_hcd { | ||
70 | spinlock_t lock; | ||
71 | struct c67x00_sie *sie; | ||
72 | unsigned int low_speed_ports; /* bitmask of low speed ports */ | ||
73 | unsigned int urb_count; | ||
74 | unsigned int urb_iso_count; | ||
75 | |||
76 | struct list_head list[4]; /* iso, int, ctrl, bulk */ | ||
77 | #if PIPE_BULK != 3 | ||
78 | #error "Sanity check failed, this code presumes PIPE_... to range from 0 to 3" | ||
79 | #endif | ||
80 | |||
81 | /* USB bandwidth allocated to td_list */ | ||
82 | int bandwidth_allocated; | ||
83 | /* USB bandwidth allocated for isoc/int transfer */ | ||
84 | int periodic_bw_allocated; | ||
85 | struct list_head td_list; | ||
86 | int max_frame_bw; | ||
87 | |||
88 | u16 td_base_addr; | ||
89 | u16 buf_base_addr; | ||
90 | u16 next_td_addr; | ||
91 | u16 next_buf_addr; | ||
92 | |||
93 | struct tasklet_struct tasklet; | ||
94 | |||
95 | struct completion endpoint_disable; | ||
96 | |||
97 | u16 current_frame; | ||
98 | u16 last_frame; | ||
99 | }; | ||
100 | |||
101 | static inline struct c67x00_hcd *hcd_to_c67x00_hcd(struct usb_hcd *hcd) | ||
102 | { | ||
103 | return (struct c67x00_hcd *)(hcd->hcd_priv); | ||
104 | } | ||
105 | |||
106 | static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00) | ||
107 | { | ||
108 | return container_of((void *)c67x00, struct usb_hcd, hcd_priv); | ||
109 | } | ||
110 | |||
111 | /* --------------------------------------------------------------------- | ||
112 | * Functions used by c67x00-drv | ||
113 | */ | ||
114 | |||
115 | int c67x00_hcd_probe(struct c67x00_sie *sie); | ||
116 | void c67x00_hcd_remove(struct c67x00_sie *sie); | ||
117 | |||
118 | /* --------------------------------------------------------------------- | ||
119 | * Transfer Descriptor scheduling functions | ||
120 | */ | ||
121 | int c67x00_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); | ||
122 | int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | ||
123 | void c67x00_endpoint_disable(struct usb_hcd *hcd, | ||
124 | struct usb_host_endpoint *ep); | ||
125 | |||
126 | void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg); | ||
127 | void c67x00_sched_kick(struct c67x00_hcd *c67x00); | ||
128 | int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00); | ||
129 | void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00); | ||
130 | |||
131 | #define c67x00_hcd_dev(x) (c67x00_hcd_to_hcd(x)->self.controller) | ||
132 | |||
133 | #endif /* _USB_C67X00_HCD_H */ | ||
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c new file mode 100644 index 000000000000..a9636f43bca2 --- /dev/null +++ b/drivers/usb/c67x00/c67x00-ll-hpi.c | |||
@@ -0,0 +1,481 @@ | |||
1 | /* | ||
2 | * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #include <asm/byteorder.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/usb/c67x00.h> | ||
28 | #include "c67x00.h" | ||
29 | |||
30 | #define COMM_REGS 14 | ||
31 | |||
32 | struct c67x00_lcp_int_data { | ||
33 | u16 regs[COMM_REGS]; | ||
34 | }; | ||
35 | |||
36 | /* -------------------------------------------------------------------------- */ | ||
37 | /* Interface definitions */ | ||
38 | |||
39 | #define COMM_ACK 0x0FED | ||
40 | #define COMM_NAK 0xDEAD | ||
41 | |||
42 | #define COMM_RESET 0xFA50 | ||
43 | #define COMM_EXEC_INT 0xCE01 | ||
44 | #define COMM_INT_NUM 0x01C2 | ||
45 | |||
46 | /* Registers 0 to COMM_REGS-1 */ | ||
47 | #define COMM_R(x) (0x01C4 + 2 * (x)) | ||
48 | |||
49 | #define HUSB_SIE_pCurrentTDPtr(x) ((x) ? 0x01B2 : 0x01B0) | ||
50 | #define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6) | ||
51 | #define HUSB_pEOT 0x01B4 | ||
52 | |||
53 | /* Software interrupts */ | ||
54 | /* 114, 115: */ | ||
55 | #define HUSB_SIE_INIT_INT(x) ((x) ? 0x0073 : 0x0072) | ||
56 | #define HUSB_RESET_INT 0x0074 | ||
57 | |||
58 | #define SUSB_INIT_INT 0x0071 | ||
59 | #define SUSB_INIT_INT_LOC (SUSB_INIT_INT * 2) | ||
60 | |||
61 | /* ----------------------------------------------------------------------- | ||
62 | * HPI implementation | ||
63 | * | ||
64 | * The c67x00 chip also support control via SPI or HSS serial | ||
65 | * interfaces. However, this driver assumes that register access can | ||
66 | * be performed from IRQ context. While this is a safe assuption with | ||
67 | * the HPI interface, it is not true for the serial interfaces. | ||
68 | */ | ||
69 | |||
70 | /* HPI registers */ | ||
71 | #define HPI_DATA 0 | ||
72 | #define HPI_MAILBOX 1 | ||
73 | #define HPI_ADDR 2 | ||
74 | #define HPI_STATUS 3 | ||
75 | |||
76 | static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg) | ||
77 | { | ||
78 | return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep); | ||
79 | } | ||
80 | |||
81 | static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value) | ||
82 | { | ||
83 | __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep); | ||
84 | } | ||
85 | |||
86 | static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg) | ||
87 | { | ||
88 | hpi_write_reg(dev, HPI_ADDR, reg); | ||
89 | return hpi_read_reg(dev, HPI_DATA); | ||
90 | } | ||
91 | |||
92 | static u16 hpi_read_word(struct c67x00_device *dev, u16 reg) | ||
93 | { | ||
94 | u16 value; | ||
95 | unsigned long flags; | ||
96 | |||
97 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
98 | value = hpi_read_word_nolock(dev, reg); | ||
99 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
100 | |||
101 | return value; | ||
102 | } | ||
103 | |||
104 | static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value) | ||
105 | { | ||
106 | hpi_write_reg(dev, HPI_ADDR, reg); | ||
107 | hpi_write_reg(dev, HPI_DATA, value); | ||
108 | } | ||
109 | |||
110 | static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) | ||
111 | { | ||
112 | unsigned long flags; | ||
113 | |||
114 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
115 | hpi_write_word_nolock(dev, reg, value); | ||
116 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Only data is little endian, addr has cpu endianess | ||
121 | */ | ||
122 | static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, | ||
123 | __le16 *data, u16 count) | ||
124 | { | ||
125 | unsigned long flags; | ||
126 | int i; | ||
127 | |||
128 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
129 | |||
130 | hpi_write_reg(dev, HPI_ADDR, addr); | ||
131 | for (i = 0; i < count; i++) | ||
132 | hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++)); | ||
133 | |||
134 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Only data is little endian, addr has cpu endianess | ||
139 | */ | ||
140 | static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, | ||
141 | __le16 *data, u16 count) | ||
142 | { | ||
143 | unsigned long flags; | ||
144 | int i; | ||
145 | |||
146 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
147 | hpi_write_reg(dev, HPI_ADDR, addr); | ||
148 | for (i = 0; i < count; i++) | ||
149 | *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA)); | ||
150 | |||
151 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
152 | } | ||
153 | |||
154 | static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask) | ||
155 | { | ||
156 | u16 value; | ||
157 | unsigned long flags; | ||
158 | |||
159 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
160 | value = hpi_read_word_nolock(dev, reg); | ||
161 | hpi_write_word_nolock(dev, reg, value | mask); | ||
162 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
163 | } | ||
164 | |||
165 | static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask) | ||
166 | { | ||
167 | u16 value; | ||
168 | unsigned long flags; | ||
169 | |||
170 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
171 | value = hpi_read_word_nolock(dev, reg); | ||
172 | hpi_write_word_nolock(dev, reg, value & ~mask); | ||
173 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
174 | } | ||
175 | |||
176 | static u16 hpi_recv_mbox(struct c67x00_device *dev) | ||
177 | { | ||
178 | u16 value; | ||
179 | unsigned long flags; | ||
180 | |||
181 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
182 | value = hpi_read_reg(dev, HPI_MAILBOX); | ||
183 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
184 | |||
185 | return value; | ||
186 | } | ||
187 | |||
188 | static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value) | ||
189 | { | ||
190 | unsigned long flags; | ||
191 | |||
192 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
193 | hpi_write_reg(dev, HPI_MAILBOX, value); | ||
194 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
195 | |||
196 | return value; | ||
197 | } | ||
198 | |||
199 | u16 c67x00_ll_hpi_status(struct c67x00_device *dev) | ||
200 | { | ||
201 | u16 value; | ||
202 | unsigned long flags; | ||
203 | |||
204 | spin_lock_irqsave(&dev->hpi.lock, flags); | ||
205 | value = hpi_read_reg(dev, HPI_STATUS); | ||
206 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | ||
207 | |||
208 | return value; | ||
209 | } | ||
210 | |||
211 | void c67x00_ll_hpi_reg_init(struct c67x00_device *dev) | ||
212 | { | ||
213 | int i; | ||
214 | |||
215 | hpi_recv_mbox(dev); | ||
216 | c67x00_ll_hpi_status(dev); | ||
217 | hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0); | ||
218 | |||
219 | for (i = 0; i < C67X00_SIES; i++) { | ||
220 | hpi_write_word(dev, SIEMSG_REG(i), 0); | ||
221 | hpi_read_word(dev, SIEMSG_REG(i)); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie) | ||
226 | { | ||
227 | hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, | ||
228 | SOFEOP_TO_HPI_EN(sie->sie_num)); | ||
229 | } | ||
230 | |||
231 | void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie) | ||
232 | { | ||
233 | hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG, | ||
234 | SOFEOP_TO_HPI_EN(sie->sie_num)); | ||
235 | } | ||
236 | |||
237 | /* -------------------------------------------------------------------------- */ | ||
238 | /* Transactions */ | ||
239 | |||
240 | static inline u16 ll_recv_msg(struct c67x00_device *dev) | ||
241 | { | ||
242 | u16 res; | ||
243 | |||
244 | res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ); | ||
245 | WARN_ON(!res); | ||
246 | |||
247 | return (res == 0) ? -EIO : 0; | ||
248 | } | ||
249 | |||
250 | /* -------------------------------------------------------------------------- */ | ||
251 | /* General functions */ | ||
252 | |||
253 | u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num) | ||
254 | { | ||
255 | u16 val; | ||
256 | |||
257 | val = hpi_read_word(dev, SIEMSG_REG(sie_num)); | ||
258 | /* clear register to allow next message */ | ||
259 | hpi_write_word(dev, SIEMSG_REG(sie_num), 0); | ||
260 | |||
261 | return val; | ||
262 | } | ||
263 | |||
264 | u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie) | ||
265 | { | ||
266 | return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * c67x00_ll_usb_clear_status - clear the USB status bits | ||
271 | */ | ||
272 | void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits) | ||
273 | { | ||
274 | hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits); | ||
275 | } | ||
276 | |||
277 | u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie) | ||
278 | { | ||
279 | return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num)); | ||
280 | } | ||
281 | |||
282 | /* -------------------------------------------------------------------------- */ | ||
283 | |||
284 | static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr, | ||
285 | struct c67x00_lcp_int_data *data) | ||
286 | { | ||
287 | int i, rc; | ||
288 | |||
289 | mutex_lock(&dev->hpi.lcp.mutex); | ||
290 | hpi_write_word(dev, COMM_INT_NUM, nr); | ||
291 | for (i = 0; i < COMM_REGS; i++) | ||
292 | hpi_write_word(dev, COMM_R(i), data->regs[i]); | ||
293 | hpi_send_mbox(dev, COMM_EXEC_INT); | ||
294 | rc = ll_recv_msg(dev); | ||
295 | mutex_unlock(&dev->hpi.lcp.mutex); | ||
296 | |||
297 | return rc; | ||
298 | } | ||
299 | |||
300 | /* -------------------------------------------------------------------------- */ | ||
301 | /* Host specific functions */ | ||
302 | |||
303 | void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value) | ||
304 | { | ||
305 | mutex_lock(&dev->hpi.lcp.mutex); | ||
306 | hpi_write_word(dev, HUSB_pEOT, value); | ||
307 | mutex_unlock(&dev->hpi.lcp.mutex); | ||
308 | } | ||
309 | |||
310 | static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie) | ||
311 | { | ||
312 | struct c67x00_device *dev = sie->dev; | ||
313 | struct c67x00_lcp_int_data data; | ||
314 | int rc; | ||
315 | |||
316 | rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data); | ||
317 | BUG_ON(rc); /* No return path for error code; crash spectacularly */ | ||
318 | } | ||
319 | |||
320 | void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port) | ||
321 | { | ||
322 | struct c67x00_device *dev = sie->dev; | ||
323 | struct c67x00_lcp_int_data data; | ||
324 | int rc; | ||
325 | |||
326 | data.regs[0] = 50; /* Reset USB port for 50ms */ | ||
327 | data.regs[1] = port | (sie->sie_num << 1); | ||
328 | rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data); | ||
329 | BUG_ON(rc); /* No return path for error code; crash spectacularly */ | ||
330 | } | ||
331 | |||
332 | void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr) | ||
333 | { | ||
334 | hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr); | ||
335 | } | ||
336 | |||
337 | u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie) | ||
338 | { | ||
339 | return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num)); | ||
340 | } | ||
341 | |||
342 | u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie) | ||
343 | { | ||
344 | return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num)); | ||
345 | } | ||
346 | |||
347 | void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie) | ||
348 | { | ||
349 | /* Set port into host mode */ | ||
350 | hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE); | ||
351 | c67x00_ll_husb_sie_init(sie); | ||
352 | /* Clear interrupts */ | ||
353 | c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK); | ||
354 | /* Check */ | ||
355 | if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE)) | ||
356 | dev_warn(sie_dev(sie), | ||
357 | "SIE %d not set to host mode\n", sie->sie_num); | ||
358 | } | ||
359 | |||
360 | void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port) | ||
361 | { | ||
362 | /* Clear connect change */ | ||
363 | c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port)); | ||
364 | |||
365 | /* Enable interrupts */ | ||
366 | hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, | ||
367 | SOFEOP_TO_CPU_EN(sie->sie_num)); | ||
368 | hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num), | ||
369 | SOF_EOP_IRQ_EN | DONE_IRQ_EN); | ||
370 | |||
371 | /* Enable pull down transistors */ | ||
372 | hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port)); | ||
373 | } | ||
374 | |||
375 | /* -------------------------------------------------------------------------- */ | ||
376 | |||
377 | void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status) | ||
378 | { | ||
379 | if ((int_status & MBX_OUT_FLG) == 0) | ||
380 | return; | ||
381 | |||
382 | dev->hpi.lcp.last_msg = hpi_recv_mbox(dev); | ||
383 | complete(&dev->hpi.lcp.msg_received); | ||
384 | } | ||
385 | |||
386 | /* -------------------------------------------------------------------------- */ | ||
387 | |||
388 | int c67x00_ll_reset(struct c67x00_device *dev) | ||
389 | { | ||
390 | int rc; | ||
391 | |||
392 | mutex_lock(&dev->hpi.lcp.mutex); | ||
393 | hpi_send_mbox(dev, COMM_RESET); | ||
394 | rc = ll_recv_msg(dev); | ||
395 | mutex_unlock(&dev->hpi.lcp.mutex); | ||
396 | |||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | /* -------------------------------------------------------------------------- */ | ||
401 | |||
402 | /** | ||
403 | * c67x00_ll_write_mem_le16 - write into c67x00 memory | ||
404 | * Only data is little endian, addr has cpu endianess. | ||
405 | */ | ||
406 | void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, | ||
407 | void *data, int len) | ||
408 | { | ||
409 | u8 *buf = data; | ||
410 | |||
411 | /* Sanity check */ | ||
412 | if (addr + len > 0xffff) { | ||
413 | dev_err(&dev->pdev->dev, | ||
414 | "Trying to write beyond writable region!\n"); | ||
415 | return; | ||
416 | } | ||
417 | |||
418 | if (addr & 0x01) { | ||
419 | /* unaligned access */ | ||
420 | u16 tmp; | ||
421 | tmp = hpi_read_word(dev, addr - 1); | ||
422 | tmp = (tmp & 0x00ff) | (*buf++ << 8); | ||
423 | hpi_write_word(dev, addr - 1, tmp); | ||
424 | addr++; | ||
425 | len--; | ||
426 | } | ||
427 | |||
428 | hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2); | ||
429 | buf += len & ~0x01; | ||
430 | addr += len & ~0x01; | ||
431 | len &= 0x01; | ||
432 | |||
433 | if (len) { | ||
434 | u16 tmp; | ||
435 | tmp = hpi_read_word(dev, addr); | ||
436 | tmp = (tmp & 0xff00) | *buf; | ||
437 | hpi_write_word(dev, addr, tmp); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /** | ||
442 | * c67x00_ll_read_mem_le16 - read from c67x00 memory | ||
443 | * Only data is little endian, addr has cpu endianess. | ||
444 | */ | ||
445 | void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, | ||
446 | void *data, int len) | ||
447 | { | ||
448 | u8 *buf = data; | ||
449 | |||
450 | if (addr & 0x01) { | ||
451 | /* unaligned access */ | ||
452 | u16 tmp; | ||
453 | tmp = hpi_read_word(dev, addr - 1); | ||
454 | *buf++ = (tmp >> 8) & 0x00ff; | ||
455 | addr++; | ||
456 | len--; | ||
457 | } | ||
458 | |||
459 | hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2); | ||
460 | buf += len & ~0x01; | ||
461 | addr += len & ~0x01; | ||
462 | len &= 0x01; | ||
463 | |||
464 | if (len) { | ||
465 | u16 tmp; | ||
466 | tmp = hpi_read_word(dev, addr); | ||
467 | *buf = tmp & 0x00ff; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* -------------------------------------------------------------------------- */ | ||
472 | |||
473 | void c67x00_ll_init(struct c67x00_device *dev) | ||
474 | { | ||
475 | mutex_init(&dev->hpi.lcp.mutex); | ||
476 | init_completion(&dev->hpi.lcp.msg_received); | ||
477 | } | ||
478 | |||
479 | void c67x00_ll_release(struct c67x00_device *dev) | ||
480 | { | ||
481 | } | ||
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c new file mode 100644 index 000000000000..85dfe2965661 --- /dev/null +++ b/drivers/usb/c67x00/c67x00-sched.c | |||
@@ -0,0 +1,1170 @@ | |||
1 | /* | ||
2 | * c67x00-sched.c: Cypress C67X00 USB Host Controller Driver - TD scheduling | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kthread.h> | ||
25 | |||
26 | #include "c67x00.h" | ||
27 | #include "c67x00-hcd.h" | ||
28 | |||
29 | /* | ||
30 | * These are the stages for a control urb, they are kept | ||
31 | * in both urb->interval and td->privdata. | ||
32 | */ | ||
33 | #define SETUP_STAGE 0 | ||
34 | #define DATA_STAGE 1 | ||
35 | #define STATUS_STAGE 2 | ||
36 | |||
37 | /* -------------------------------------------------------------------------- */ | ||
38 | |||
39 | /** | ||
40 | * struct c67x00_ep_data: Host endpoint data structure | ||
41 | */ | ||
42 | struct c67x00_ep_data { | ||
43 | struct list_head queue; | ||
44 | struct list_head node; | ||
45 | struct usb_host_endpoint *hep; | ||
46 | struct usb_device *dev; | ||
47 | u16 next_frame; /* For int/isoc transactions */ | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * struct c67x00_td | ||
52 | * | ||
53 | * Hardware parts are little endiannes, SW in CPU endianess. | ||
54 | */ | ||
55 | struct c67x00_td { | ||
56 | /* HW specific part */ | ||
57 | __le16 ly_base_addr; /* Bytes 0-1 */ | ||
58 | __le16 port_length; /* Bytes 2-3 */ | ||
59 | u8 pid_ep; /* Byte 4 */ | ||
60 | u8 dev_addr; /* Byte 5 */ | ||
61 | u8 ctrl_reg; /* Byte 6 */ | ||
62 | u8 status; /* Byte 7 */ | ||
63 | u8 retry_cnt; /* Byte 8 */ | ||
64 | #define TT_OFFSET 2 | ||
65 | #define TT_CONTROL 0 | ||
66 | #define TT_ISOCHRONOUS 1 | ||
67 | #define TT_BULK 2 | ||
68 | #define TT_INTERRUPT 3 | ||
69 | u8 residue; /* Byte 9 */ | ||
70 | __le16 next_td_addr; /* Bytes 10-11 */ | ||
71 | /* SW part */ | ||
72 | struct list_head td_list; | ||
73 | u16 td_addr; | ||
74 | void *data; | ||
75 | struct urb *urb; | ||
76 | unsigned long privdata; | ||
77 | |||
78 | /* These are needed for handling the toggle bits: | ||
79 | * an urb can be dequeued while a td is in progress | ||
80 | * after checking the td, the toggle bit might need to | ||
81 | * be fixed */ | ||
82 | struct c67x00_ep_data *ep_data; | ||
83 | unsigned int pipe; | ||
84 | }; | ||
85 | |||
86 | struct c67x00_urb_priv { | ||
87 | struct list_head hep_node; | ||
88 | struct urb *urb; | ||
89 | int port; | ||
90 | int cnt; /* packet number for isoc */ | ||
91 | int status; | ||
92 | struct c67x00_ep_data *ep_data; | ||
93 | }; | ||
94 | |||
95 | #define td_udev(td) ((td)->ep_data->dev) | ||
96 | |||
97 | #define CY_TD_SIZE 12 | ||
98 | |||
99 | #define TD_PIDEP_OFFSET 0x04 | ||
100 | #define TD_PIDEPMASK_PID 0xF0 | ||
101 | #define TD_PIDEPMASK_EP 0x0F | ||
102 | #define TD_PORTLENMASK_DL 0x02FF | ||
103 | #define TD_PORTLENMASK_PN 0xC000 | ||
104 | |||
105 | #define TD_STATUS_OFFSET 0x07 | ||
106 | #define TD_STATUSMASK_ACK 0x01 | ||
107 | #define TD_STATUSMASK_ERR 0x02 | ||
108 | #define TD_STATUSMASK_TMOUT 0x04 | ||
109 | #define TD_STATUSMASK_SEQ 0x08 | ||
110 | #define TD_STATUSMASK_SETUP 0x10 | ||
111 | #define TD_STATUSMASK_OVF 0x20 | ||
112 | #define TD_STATUSMASK_NAK 0x40 | ||
113 | #define TD_STATUSMASK_STALL 0x80 | ||
114 | |||
115 | #define TD_ERROR_MASK (TD_STATUSMASK_ERR | TD_STATUSMASK_TMOUT | \ | ||
116 | TD_STATUSMASK_STALL) | ||
117 | |||
118 | #define TD_RETRYCNT_OFFSET 0x08 | ||
119 | #define TD_RETRYCNTMASK_ACT_FLG 0x10 | ||
120 | #define TD_RETRYCNTMASK_TX_TYPE 0x0C | ||
121 | #define TD_RETRYCNTMASK_RTY_CNT 0x03 | ||
122 | |||
123 | #define TD_RESIDUE_OVERFLOW 0x80 | ||
124 | |||
125 | #define TD_PID_IN 0x90 | ||
126 | |||
127 | /* Residue: signed 8bits, neg -> OVERFLOW, pos -> UNDERFLOW */ | ||
128 | #define td_residue(td) ((__s8)(td->residue)) | ||
129 | #define td_ly_base_addr(td) (__le16_to_cpu((td)->ly_base_addr)) | ||
130 | #define td_port_length(td) (__le16_to_cpu((td)->port_length)) | ||
131 | #define td_next_td_addr(td) (__le16_to_cpu((td)->next_td_addr)) | ||
132 | |||
133 | #define td_active(td) ((td)->retry_cnt & TD_RETRYCNTMASK_ACT_FLG) | ||
134 | #define td_length(td) (td_port_length(td) & TD_PORTLENMASK_DL) | ||
135 | |||
136 | #define td_sequence_ok(td) (!td->status || \ | ||
137 | (!(td->status & TD_STATUSMASK_SEQ) == \ | ||
138 | !(td->ctrl_reg & SEQ_SEL))) | ||
139 | |||
140 | #define td_acked(td) (!td->status || \ | ||
141 | (td->status & TD_STATUSMASK_ACK)) | ||
142 | #define td_actual_bytes(td) (td_length(td) - td_residue(td)) | ||
143 | |||
144 | /* -------------------------------------------------------------------------- */ | ||
145 | |||
146 | #ifdef DEBUG | ||
147 | |||
148 | /** | ||
149 | * dbg_td - Dump the contents of the TD | ||
150 | */ | ||
151 | static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) | ||
152 | { | ||
153 | struct device *dev = c67x00_hcd_dev(c67x00); | ||
154 | |||
155 | dev_dbg(dev, "### %s at 0x%04x\n", msg, td->td_addr); | ||
156 | dev_dbg(dev, "urb: 0x%p\n", td->urb); | ||
157 | dev_dbg(dev, "endpoint: %4d\n", usb_pipeendpoint(td->pipe)); | ||
158 | dev_dbg(dev, "pipeout: %4d\n", usb_pipeout(td->pipe)); | ||
159 | dev_dbg(dev, "ly_base_addr: 0x%04x\n", td_ly_base_addr(td)); | ||
160 | dev_dbg(dev, "port_length: 0x%04x\n", td_port_length(td)); | ||
161 | dev_dbg(dev, "pid_ep: 0x%02x\n", td->pid_ep); | ||
162 | dev_dbg(dev, "dev_addr: 0x%02x\n", td->dev_addr); | ||
163 | dev_dbg(dev, "ctrl_reg: 0x%02x\n", td->ctrl_reg); | ||
164 | dev_dbg(dev, "status: 0x%02x\n", td->status); | ||
165 | dev_dbg(dev, "retry_cnt: 0x%02x\n", td->retry_cnt); | ||
166 | dev_dbg(dev, "residue: 0x%02x\n", td->residue); | ||
167 | dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td)); | ||
168 | dev_dbg(dev, "data:"); | ||
169 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, | ||
170 | td->data, td_length(td), 1); | ||
171 | } | ||
172 | #else /* DEBUG */ | ||
173 | |||
174 | static inline void | ||
175 | dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { } | ||
176 | |||
177 | #endif /* DEBUG */ | ||
178 | |||
179 | /* -------------------------------------------------------------------------- */ | ||
180 | /* Helper functions */ | ||
181 | |||
182 | static inline u16 c67x00_get_current_frame_number(struct c67x00_hcd *c67x00) | ||
183 | { | ||
184 | return c67x00_ll_husb_get_frame(c67x00->sie) & HOST_FRAME_MASK; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * frame_add | ||
189 | * Software wraparound for framenumbers. | ||
190 | */ | ||
191 | static inline u16 frame_add(u16 a, u16 b) | ||
192 | { | ||
193 | return (a + b) & HOST_FRAME_MASK; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * frame_after - is frame a after frame b | ||
198 | */ | ||
199 | static inline int frame_after(u16 a, u16 b) | ||
200 | { | ||
201 | return ((HOST_FRAME_MASK + a - b) & HOST_FRAME_MASK) < | ||
202 | (HOST_FRAME_MASK / 2); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * frame_after_eq - is frame a after or equal to frame b | ||
207 | */ | ||
208 | static inline int frame_after_eq(u16 a, u16 b) | ||
209 | { | ||
210 | return ((HOST_FRAME_MASK + 1 + a - b) & HOST_FRAME_MASK) < | ||
211 | (HOST_FRAME_MASK / 2); | ||
212 | } | ||
213 | |||
214 | /* -------------------------------------------------------------------------- */ | ||
215 | |||
216 | /** | ||
217 | * c67x00_release_urb - remove link from all tds to this urb | ||
218 | * Disconnects the urb from it's tds, so that it can be given back. | ||
219 | * pre: urb->hcpriv != NULL | ||
220 | */ | ||
221 | static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb) | ||
222 | { | ||
223 | struct c67x00_td *td; | ||
224 | struct c67x00_urb_priv *urbp; | ||
225 | |||
226 | BUG_ON(!urb); | ||
227 | |||
228 | c67x00->urb_count--; | ||
229 | |||
230 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
231 | c67x00->urb_iso_count--; | ||
232 | if (c67x00->urb_iso_count == 0) | ||
233 | c67x00->max_frame_bw = MAX_FRAME_BW_STD; | ||
234 | } | ||
235 | |||
236 | /* TODO this might be not so efficient when we've got many urbs! | ||
237 | * Alternatives: | ||
238 | * * only clear when needed | ||
239 | * * keep a list of tds with each urbp | ||
240 | */ | ||
241 | list_for_each_entry(td, &c67x00->td_list, td_list) | ||
242 | if (urb == td->urb) | ||
243 | td->urb = NULL; | ||
244 | |||
245 | urbp = urb->hcpriv; | ||
246 | urb->hcpriv = NULL; | ||
247 | list_del(&urbp->hep_node); | ||
248 | kfree(urbp); | ||
249 | } | ||
250 | |||
251 | /* -------------------------------------------------------------------------- */ | ||
252 | |||
253 | static struct c67x00_ep_data * | ||
254 | c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb) | ||
255 | { | ||
256 | struct usb_host_endpoint *hep = urb->ep; | ||
257 | struct c67x00_ep_data *ep_data; | ||
258 | int type; | ||
259 | |||
260 | c67x00->current_frame = c67x00_get_current_frame_number(c67x00); | ||
261 | |||
262 | /* Check if endpoint already has a c67x00_ep_data struct allocated */ | ||
263 | if (hep->hcpriv) { | ||
264 | ep_data = hep->hcpriv; | ||
265 | if (frame_after(c67x00->current_frame, ep_data->next_frame)) | ||
266 | ep_data->next_frame = | ||
267 | frame_add(c67x00->current_frame, 1); | ||
268 | return hep->hcpriv; | ||
269 | } | ||
270 | |||
271 | /* Allocate and initialize a new c67x00 endpoint data structure */ | ||
272 | ep_data = kzalloc(sizeof(*ep_data), GFP_ATOMIC); | ||
273 | if (!ep_data) | ||
274 | return NULL; | ||
275 | |||
276 | INIT_LIST_HEAD(&ep_data->queue); | ||
277 | INIT_LIST_HEAD(&ep_data->node); | ||
278 | ep_data->hep = hep; | ||
279 | |||
280 | /* hold a reference to udev as long as this endpoint lives, | ||
281 | * this is needed to possibly fix the data toggle */ | ||
282 | ep_data->dev = usb_get_dev(urb->dev); | ||
283 | hep->hcpriv = ep_data; | ||
284 | |||
285 | /* For ISOC and INT endpoints, start ASAP: */ | ||
286 | ep_data->next_frame = frame_add(c67x00->current_frame, 1); | ||
287 | |||
288 | /* Add the endpoint data to one of the pipe lists; must be added | ||
289 | in order of endpoint address */ | ||
290 | type = usb_pipetype(urb->pipe); | ||
291 | if (list_empty(&ep_data->node)) { | ||
292 | list_add(&ep_data->node, &c67x00->list[type]); | ||
293 | } else { | ||
294 | struct c67x00_ep_data *prev; | ||
295 | |||
296 | list_for_each_entry(prev, &c67x00->list[type], node) { | ||
297 | if (prev->hep->desc.bEndpointAddress > | ||
298 | hep->desc.bEndpointAddress) { | ||
299 | list_add(&ep_data->node, prev->node.prev); | ||
300 | break; | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | return ep_data; | ||
306 | } | ||
307 | |||
308 | static int c67x00_ep_data_free(struct usb_host_endpoint *hep) | ||
309 | { | ||
310 | struct c67x00_ep_data *ep_data = hep->hcpriv; | ||
311 | |||
312 | if (!ep_data) | ||
313 | return 0; | ||
314 | |||
315 | if (!list_empty(&ep_data->queue)) | ||
316 | return -EBUSY; | ||
317 | |||
318 | usb_put_dev(ep_data->dev); | ||
319 | list_del(&ep_data->queue); | ||
320 | list_del(&ep_data->node); | ||
321 | |||
322 | kfree(ep_data); | ||
323 | hep->hcpriv = NULL; | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | ||
329 | { | ||
330 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
331 | unsigned long flags; | ||
332 | |||
333 | if (!list_empty(&ep->urb_list)) | ||
334 | dev_warn(c67x00_hcd_dev(c67x00), "error: urb list not empty\n"); | ||
335 | |||
336 | spin_lock_irqsave(&c67x00->lock, flags); | ||
337 | |||
338 | /* loop waiting for all transfers in the endpoint queue to complete */ | ||
339 | while (c67x00_ep_data_free(ep)) { | ||
340 | /* Drop the lock so we can sleep waiting for the hardware */ | ||
341 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
342 | |||
343 | /* it could happen that we reinitialize this completion, while | ||
344 | * somebody was waiting for that completion. The timeout and | ||
345 | * while loop handle such cases, but this might be improved */ | ||
346 | INIT_COMPLETION(c67x00->endpoint_disable); | ||
347 | c67x00_sched_kick(c67x00); | ||
348 | wait_for_completion_timeout(&c67x00->endpoint_disable, 1 * HZ); | ||
349 | |||
350 | spin_lock_irqsave(&c67x00->lock, flags); | ||
351 | } | ||
352 | |||
353 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
354 | } | ||
355 | |||
356 | /* -------------------------------------------------------------------------- */ | ||
357 | |||
358 | static inline int get_root_port(struct usb_device *dev) | ||
359 | { | ||
360 | while (dev->parent->parent) | ||
361 | dev = dev->parent; | ||
362 | return dev->portnum; | ||
363 | } | ||
364 | |||
365 | int c67x00_urb_enqueue(struct usb_hcd *hcd, | ||
366 | struct urb *urb, gfp_t mem_flags) | ||
367 | { | ||
368 | int ret; | ||
369 | unsigned long flags; | ||
370 | struct c67x00_urb_priv *urbp; | ||
371 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
372 | int port = get_root_port(urb->dev)-1; | ||
373 | |||
374 | spin_lock_irqsave(&c67x00->lock, flags); | ||
375 | |||
376 | /* Make sure host controller is running */ | ||
377 | if (!HC_IS_RUNNING(hcd->state)) { | ||
378 | ret = -ENODEV; | ||
379 | goto err_not_linked; | ||
380 | } | ||
381 | |||
382 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
383 | if (ret) | ||
384 | goto err_not_linked; | ||
385 | |||
386 | /* Allocate and initialize urb private data */ | ||
387 | urbp = kzalloc(sizeof(*urbp), mem_flags); | ||
388 | if (!urbp) { | ||
389 | ret = -ENOMEM; | ||
390 | goto err_urbp; | ||
391 | } | ||
392 | |||
393 | INIT_LIST_HEAD(&urbp->hep_node); | ||
394 | urbp->urb = urb; | ||
395 | urbp->port = port; | ||
396 | |||
397 | urbp->ep_data = c67x00_ep_data_alloc(c67x00, urb); | ||
398 | |||
399 | if (!urbp->ep_data) { | ||
400 | ret = -ENOMEM; | ||
401 | goto err_epdata; | ||
402 | } | ||
403 | |||
404 | /* TODO claim bandwidth with usb_claim_bandwidth? | ||
405 | * also release it somewhere! */ | ||
406 | |||
407 | urb->hcpriv = urbp; | ||
408 | |||
409 | urb->actual_length = 0; /* Nothing received/transmitted yet */ | ||
410 | |||
411 | switch (usb_pipetype(urb->pipe)) { | ||
412 | case PIPE_CONTROL: | ||
413 | urb->interval = SETUP_STAGE; | ||
414 | break; | ||
415 | case PIPE_INTERRUPT: | ||
416 | break; | ||
417 | case PIPE_BULK: | ||
418 | break; | ||
419 | case PIPE_ISOCHRONOUS: | ||
420 | if (c67x00->urb_iso_count == 0) | ||
421 | c67x00->max_frame_bw = MAX_FRAME_BW_ISO; | ||
422 | c67x00->urb_iso_count++; | ||
423 | /* Assume always URB_ISO_ASAP, FIXME */ | ||
424 | if (list_empty(&urbp->ep_data->queue)) | ||
425 | urb->start_frame = urbp->ep_data->next_frame; | ||
426 | else { | ||
427 | /* Go right after the last one */ | ||
428 | struct urb *last_urb; | ||
429 | |||
430 | last_urb = list_entry(urbp->ep_data->queue.prev, | ||
431 | struct c67x00_urb_priv, | ||
432 | hep_node)->urb; | ||
433 | urb->start_frame = | ||
434 | frame_add(last_urb->start_frame, | ||
435 | last_urb->number_of_packets * | ||
436 | last_urb->interval); | ||
437 | } | ||
438 | urbp->cnt = 0; | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | /* Add the URB to the endpoint queue */ | ||
443 | list_add_tail(&urbp->hep_node, &urbp->ep_data->queue); | ||
444 | |||
445 | /* If this is the only URB, kick start the controller */ | ||
446 | if (!c67x00->urb_count++) | ||
447 | c67x00_ll_hpi_enable_sofeop(c67x00->sie); | ||
448 | |||
449 | c67x00_sched_kick(c67x00); | ||
450 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
451 | |||
452 | return 0; | ||
453 | |||
454 | err_epdata: | ||
455 | kfree(urbp); | ||
456 | err_urbp: | ||
457 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
458 | err_not_linked: | ||
459 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
460 | |||
461 | return ret; | ||
462 | } | ||
463 | |||
464 | int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | ||
465 | { | ||
466 | struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); | ||
467 | unsigned long flags; | ||
468 | int rc; | ||
469 | |||
470 | spin_lock_irqsave(&c67x00->lock, flags); | ||
471 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
472 | if (rc) | ||
473 | goto done; | ||
474 | |||
475 | c67x00_release_urb(c67x00, urb); | ||
476 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
477 | |||
478 | spin_unlock(&c67x00->lock); | ||
479 | usb_hcd_giveback_urb(hcd, urb, status); | ||
480 | spin_lock(&c67x00->lock); | ||
481 | |||
482 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
483 | |||
484 | return 0; | ||
485 | |||
486 | done: | ||
487 | spin_unlock_irqrestore(&c67x00->lock, flags); | ||
488 | return rc; | ||
489 | } | ||
490 | |||
491 | /* -------------------------------------------------------------------------- */ | ||
492 | |||
493 | /* | ||
494 | * pre: c67x00 locked, urb unlocked | ||
495 | */ | ||
496 | static void | ||
497 | c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status) | ||
498 | { | ||
499 | struct c67x00_urb_priv *urbp; | ||
500 | |||
501 | if (!urb) | ||
502 | return; | ||
503 | |||
504 | urbp = urb->hcpriv; | ||
505 | urbp->status = status; | ||
506 | |||
507 | list_del_init(&urbp->hep_node); | ||
508 | |||
509 | c67x00_release_urb(c67x00, urb); | ||
510 | usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00), urb); | ||
511 | spin_unlock(&c67x00->lock); | ||
512 | usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb, urbp->status); | ||
513 | spin_lock(&c67x00->lock); | ||
514 | } | ||
515 | |||
516 | /* -------------------------------------------------------------------------- */ | ||
517 | |||
518 | static int c67x00_claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb, | ||
519 | int len, int periodic) | ||
520 | { | ||
521 | struct c67x00_urb_priv *urbp = urb->hcpriv; | ||
522 | int bit_time; | ||
523 | |||
524 | /* According to the C67x00 BIOS user manual, page 3-18,19, the | ||
525 | * following calculations provide the full speed bit times for | ||
526 | * a transaction. | ||
527 | * | ||
528 | * FS(in) = 112.5 + 9.36*BC + HOST_DELAY | ||
529 | * FS(in,iso) = 90.5 + 9.36*BC + HOST_DELAY | ||
530 | * FS(out) = 112.5 + 9.36*BC + HOST_DELAY | ||
531 | * FS(out,iso) = 78.4 + 9.36*BC + HOST_DELAY | ||
532 | * LS(in) = 802.4 + 75.78*BC + HOST_DELAY | ||
533 | * LS(out) = 802.6 + 74.67*BC + HOST_DELAY | ||
534 | * | ||
535 | * HOST_DELAY == 106 for the c67200 and c67300. | ||
536 | */ | ||
537 | |||
538 | /* make calculations in 1/100 bit times to maintain resolution */ | ||
539 | if (urbp->ep_data->dev->speed == USB_SPEED_LOW) { | ||
540 | /* Low speed pipe */ | ||
541 | if (usb_pipein(urb->pipe)) | ||
542 | bit_time = 80240 + 7578*len; | ||
543 | else | ||
544 | bit_time = 80260 + 7467*len; | ||
545 | } else { | ||
546 | /* FS pipes */ | ||
547 | if (usb_pipeisoc(urb->pipe)) | ||
548 | bit_time = usb_pipein(urb->pipe) ? 9050 : 7840; | ||
549 | else | ||
550 | bit_time = 11250; | ||
551 | bit_time += 936*len; | ||
552 | } | ||
553 | |||
554 | /* Scale back down to integer bit times. Use a host delay of 106. | ||
555 | * (this is the only place it is used) */ | ||
556 | bit_time = ((bit_time+50) / 100) + 106; | ||
557 | |||
558 | if (unlikely(bit_time + c67x00->bandwidth_allocated >= | ||
559 | c67x00->max_frame_bw)) | ||
560 | return -EMSGSIZE; | ||
561 | |||
562 | if (unlikely(c67x00->next_td_addr + CY_TD_SIZE >= | ||
563 | c67x00->td_base_addr + SIE_TD_SIZE)) | ||
564 | return -EMSGSIZE; | ||
565 | |||
566 | if (unlikely(c67x00->next_buf_addr + len >= | ||
567 | c67x00->buf_base_addr + SIE_TD_BUF_SIZE)) | ||
568 | return -EMSGSIZE; | ||
569 | |||
570 | if (periodic) { | ||
571 | if (unlikely(bit_time + c67x00->periodic_bw_allocated >= | ||
572 | MAX_PERIODIC_BW(c67x00->max_frame_bw))) | ||
573 | return -EMSGSIZE; | ||
574 | c67x00->periodic_bw_allocated += bit_time; | ||
575 | } | ||
576 | |||
577 | c67x00->bandwidth_allocated += bit_time; | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* -------------------------------------------------------------------------- */ | ||
582 | |||
583 | /** | ||
584 | * td_addr and buf_addr must be word aligned | ||
585 | */ | ||
586 | static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, | ||
587 | void *data, int len, int pid, int toggle, | ||
588 | unsigned long privdata) | ||
589 | { | ||
590 | struct c67x00_td *td; | ||
591 | struct c67x00_urb_priv *urbp = urb->hcpriv; | ||
592 | const __u8 active_flag = 1, retry_cnt = 1; | ||
593 | __u8 cmd = 0; | ||
594 | int tt = 0; | ||
595 | |||
596 | if (c67x00_claim_frame_bw(c67x00, urb, len, usb_pipeisoc(urb->pipe) | ||
597 | || usb_pipeint(urb->pipe))) | ||
598 | return -EMSGSIZE; /* Not really an error, but expected */ | ||
599 | |||
600 | td = kzalloc(sizeof(*td), GFP_ATOMIC); | ||
601 | if (!td) | ||
602 | return -ENOMEM; | ||
603 | |||
604 | td->pipe = urb->pipe; | ||
605 | td->ep_data = urbp->ep_data; | ||
606 | |||
607 | if ((td_udev(td)->speed == USB_SPEED_LOW) && | ||
608 | !(c67x00->low_speed_ports & (1 << urbp->port))) | ||
609 | cmd |= PREAMBLE_EN; | ||
610 | |||
611 | switch (usb_pipetype(td->pipe)) { | ||
612 | case PIPE_ISOCHRONOUS: | ||
613 | tt = TT_ISOCHRONOUS; | ||
614 | cmd |= ISO_EN; | ||
615 | break; | ||
616 | case PIPE_CONTROL: | ||
617 | tt = TT_CONTROL; | ||
618 | break; | ||
619 | case PIPE_BULK: | ||
620 | tt = TT_BULK; | ||
621 | break; | ||
622 | case PIPE_INTERRUPT: | ||
623 | tt = TT_INTERRUPT; | ||
624 | break; | ||
625 | } | ||
626 | |||
627 | if (toggle) | ||
628 | cmd |= SEQ_SEL; | ||
629 | |||
630 | cmd |= ARM_EN; | ||
631 | |||
632 | /* SW part */ | ||
633 | td->td_addr = c67x00->next_td_addr; | ||
634 | c67x00->next_td_addr = c67x00->next_td_addr + CY_TD_SIZE; | ||
635 | |||
636 | /* HW part */ | ||
637 | td->ly_base_addr = __cpu_to_le16(c67x00->next_buf_addr); | ||
638 | td->port_length = __cpu_to_le16((c67x00->sie->sie_num << 15) | | ||
639 | (urbp->port << 14) | (len & 0x3FF)); | ||
640 | td->pid_ep = ((pid & 0xF) << TD_PIDEP_OFFSET) | | ||
641 | (usb_pipeendpoint(td->pipe) & 0xF); | ||
642 | td->dev_addr = usb_pipedevice(td->pipe) & 0x7F; | ||
643 | td->ctrl_reg = cmd; | ||
644 | td->status = 0; | ||
645 | td->retry_cnt = (tt << TT_OFFSET) | (active_flag << 4) | retry_cnt; | ||
646 | td->residue = 0; | ||
647 | td->next_td_addr = __cpu_to_le16(c67x00->next_td_addr); | ||
648 | |||
649 | /* SW part */ | ||
650 | td->data = data; | ||
651 | td->urb = urb; | ||
652 | td->privdata = privdata; | ||
653 | |||
654 | c67x00->next_buf_addr += (len + 1) & ~0x01; /* properly align */ | ||
655 | |||
656 | list_add_tail(&td->td_list, &c67x00->td_list); | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static inline void c67x00_release_td(struct c67x00_td *td) | ||
661 | { | ||
662 | list_del_init(&td->td_list); | ||
663 | kfree(td); | ||
664 | } | ||
665 | |||
666 | /* -------------------------------------------------------------------------- */ | ||
667 | |||
668 | static int c67x00_add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb) | ||
669 | { | ||
670 | int remaining; | ||
671 | int toggle; | ||
672 | int pid; | ||
673 | int ret = 0; | ||
674 | int maxps; | ||
675 | int need_empty; | ||
676 | |||
677 | toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
678 | usb_pipeout(urb->pipe)); | ||
679 | remaining = urb->transfer_buffer_length - urb->actual_length; | ||
680 | |||
681 | maxps = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); | ||
682 | |||
683 | need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && | ||
684 | usb_pipeout(urb->pipe) && !(remaining % maxps); | ||
685 | |||
686 | while (remaining || need_empty) { | ||
687 | int len; | ||
688 | char *td_buf; | ||
689 | |||
690 | len = (remaining > maxps) ? maxps : remaining; | ||
691 | if (!len) | ||
692 | need_empty = 0; | ||
693 | |||
694 | pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; | ||
695 | td_buf = urb->transfer_buffer + urb->transfer_buffer_length - | ||
696 | remaining; | ||
697 | ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, toggle, | ||
698 | DATA_STAGE); | ||
699 | if (ret) | ||
700 | return ret; /* td wasn't created */ | ||
701 | |||
702 | toggle ^= 1; | ||
703 | remaining -= len; | ||
704 | if (usb_pipecontrol(urb->pipe)) | ||
705 | break; | ||
706 | } | ||
707 | |||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | /** | ||
712 | * return 0 in case more bandwidth is available, else errorcode | ||
713 | */ | ||
714 | static int c67x00_add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb) | ||
715 | { | ||
716 | int ret; | ||
717 | int pid; | ||
718 | |||
719 | switch (urb->interval) { | ||
720 | default: | ||
721 | case SETUP_STAGE: | ||
722 | ret = c67x00_create_td(c67x00, urb, urb->setup_packet, | ||
723 | 8, USB_PID_SETUP, 0, SETUP_STAGE); | ||
724 | if (ret) | ||
725 | return ret; | ||
726 | urb->interval = SETUP_STAGE; | ||
727 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
728 | usb_pipeout(urb->pipe), 1); | ||
729 | break; | ||
730 | case DATA_STAGE: | ||
731 | if (urb->transfer_buffer_length) { | ||
732 | ret = c67x00_add_data_urb(c67x00, urb); | ||
733 | if (ret) | ||
734 | return ret; | ||
735 | break; | ||
736 | } /* else fallthrough */ | ||
737 | case STATUS_STAGE: | ||
738 | pid = !usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; | ||
739 | ret = c67x00_create_td(c67x00, urb, NULL, 0, pid, 1, | ||
740 | STATUS_STAGE); | ||
741 | if (ret) | ||
742 | return ret; | ||
743 | break; | ||
744 | } | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | /* | ||
750 | * return 0 in case more bandwidth is available, else errorcode | ||
751 | */ | ||
752 | static int c67x00_add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb) | ||
753 | { | ||
754 | struct c67x00_urb_priv *urbp = urb->hcpriv; | ||
755 | |||
756 | if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { | ||
757 | urbp->ep_data->next_frame = | ||
758 | frame_add(urbp->ep_data->next_frame, urb->interval); | ||
759 | return c67x00_add_data_urb(c67x00, urb); | ||
760 | } | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb) | ||
765 | { | ||
766 | struct c67x00_urb_priv *urbp = urb->hcpriv; | ||
767 | |||
768 | if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { | ||
769 | char *td_buf; | ||
770 | int len, pid, ret; | ||
771 | |||
772 | BUG_ON(urbp->cnt >= urb->number_of_packets); | ||
773 | |||
774 | td_buf = urb->transfer_buffer + | ||
775 | urb->iso_frame_desc[urbp->cnt].offset; | ||
776 | len = urb->iso_frame_desc[urbp->cnt].length; | ||
777 | pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; | ||
778 | |||
779 | ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0, | ||
780 | urbp->cnt); | ||
781 | if (ret) { | ||
782 | printk(KERN_DEBUG "create failed: %d\n", ret); | ||
783 | urb->iso_frame_desc[urbp->cnt].actual_length = 0; | ||
784 | urb->iso_frame_desc[urbp->cnt].status = ret; | ||
785 | if (urbp->cnt + 1 == urb->number_of_packets) | ||
786 | c67x00_giveback_urb(c67x00, urb, 0); | ||
787 | } | ||
788 | |||
789 | urbp->ep_data->next_frame = | ||
790 | frame_add(urbp->ep_data->next_frame, urb->interval); | ||
791 | urbp->cnt++; | ||
792 | } | ||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | /* -------------------------------------------------------------------------- */ | ||
797 | |||
798 | static void c67x00_fill_from_list(struct c67x00_hcd *c67x00, int type, | ||
799 | int (*add)(struct c67x00_hcd *, struct urb *)) | ||
800 | { | ||
801 | struct c67x00_ep_data *ep_data; | ||
802 | struct urb *urb; | ||
803 | |||
804 | /* traverse every endpoint on the list */ | ||
805 | list_for_each_entry(ep_data, &c67x00->list[type], node) { | ||
806 | if (!list_empty(&ep_data->queue)) { | ||
807 | /* and add the first urb */ | ||
808 | /* isochronous transfer rely on this */ | ||
809 | urb = list_entry(ep_data->queue.next, | ||
810 | struct c67x00_urb_priv, | ||
811 | hep_node)->urb; | ||
812 | add(c67x00, urb); | ||
813 | } | ||
814 | } | ||
815 | } | ||
816 | |||
817 | static void c67x00_fill_frame(struct c67x00_hcd *c67x00) | ||
818 | { | ||
819 | struct c67x00_td *td, *ttd; | ||
820 | |||
821 | /* Check if we can proceed */ | ||
822 | if (!list_empty(&c67x00->td_list)) { | ||
823 | dev_warn(c67x00_hcd_dev(c67x00), | ||
824 | "TD list not empty! This should not happen!\n"); | ||
825 | list_for_each_entry_safe(td, ttd, &c67x00->td_list, td_list) { | ||
826 | dbg_td(c67x00, td, "Unprocessed td"); | ||
827 | c67x00_release_td(td); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | /* Reinitialize variables */ | ||
832 | c67x00->bandwidth_allocated = 0; | ||
833 | c67x00->periodic_bw_allocated = 0; | ||
834 | |||
835 | c67x00->next_td_addr = c67x00->td_base_addr; | ||
836 | c67x00->next_buf_addr = c67x00->buf_base_addr; | ||
837 | |||
838 | /* Fill the list */ | ||
839 | c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, c67x00_add_iso_urb); | ||
840 | c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, c67x00_add_int_urb); | ||
841 | c67x00_fill_from_list(c67x00, PIPE_CONTROL, c67x00_add_ctrl_urb); | ||
842 | c67x00_fill_from_list(c67x00, PIPE_BULK, c67x00_add_data_urb); | ||
843 | } | ||
844 | |||
845 | /* -------------------------------------------------------------------------- */ | ||
846 | |||
847 | /** | ||
848 | * Get TD from C67X00 | ||
849 | */ | ||
850 | static inline void | ||
851 | c67x00_parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) | ||
852 | { | ||
853 | c67x00_ll_read_mem_le16(c67x00->sie->dev, | ||
854 | td->td_addr, td, CY_TD_SIZE); | ||
855 | |||
856 | if (usb_pipein(td->pipe) && td_actual_bytes(td)) | ||
857 | c67x00_ll_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), | ||
858 | td->data, td_actual_bytes(td)); | ||
859 | } | ||
860 | |||
861 | static int c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td) | ||
862 | { | ||
863 | if (td->status & TD_STATUSMASK_ERR) { | ||
864 | dbg_td(c67x00, td, "ERROR_FLAG"); | ||
865 | return -EILSEQ; | ||
866 | } | ||
867 | if (td->status & TD_STATUSMASK_STALL) { | ||
868 | /* dbg_td(c67x00, td, "STALL"); */ | ||
869 | return -EPIPE; | ||
870 | } | ||
871 | if (td->status & TD_STATUSMASK_TMOUT) { | ||
872 | dbg_td(c67x00, td, "TIMEOUT"); | ||
873 | return -ETIMEDOUT; | ||
874 | } | ||
875 | |||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static inline int c67x00_end_of_data(struct c67x00_td *td) | ||
880 | { | ||
881 | int maxps, need_empty, remaining; | ||
882 | struct urb *urb = td->urb; | ||
883 | int act_bytes; | ||
884 | |||
885 | act_bytes = td_actual_bytes(td); | ||
886 | |||
887 | if (unlikely(!act_bytes)) | ||
888 | return 1; /* This was an empty packet */ | ||
889 | |||
890 | maxps = usb_maxpacket(td_udev(td), td->pipe, usb_pipeout(td->pipe)); | ||
891 | |||
892 | if (unlikely(act_bytes < maxps)) | ||
893 | return 1; /* Smaller then full packet */ | ||
894 | |||
895 | remaining = urb->transfer_buffer_length - urb->actual_length; | ||
896 | need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && | ||
897 | usb_pipeout(urb->pipe) && !(remaining % maxps); | ||
898 | |||
899 | if (unlikely(!remaining && !need_empty)) | ||
900 | return 1; | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | /* -------------------------------------------------------------------------- */ | ||
906 | |||
907 | /* Remove all td's from the list which come | ||
908 | * after last_td and are meant for the same pipe. | ||
909 | * This is used when a short packet has occured */ | ||
910 | static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00, | ||
911 | struct c67x00_td *last_td) | ||
912 | { | ||
913 | struct c67x00_td *td, *tmp; | ||
914 | td = last_td; | ||
915 | tmp = last_td; | ||
916 | while (td->td_list.next != &c67x00->td_list) { | ||
917 | td = list_entry(td->td_list.next, struct c67x00_td, td_list); | ||
918 | if (td->pipe == last_td->pipe) { | ||
919 | c67x00_release_td(td); | ||
920 | td = tmp; | ||
921 | } | ||
922 | tmp = td; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | /* -------------------------------------------------------------------------- */ | ||
927 | |||
928 | static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00, | ||
929 | struct c67x00_td *td) | ||
930 | { | ||
931 | struct urb *urb = td->urb; | ||
932 | |||
933 | if (!urb) | ||
934 | return; | ||
935 | |||
936 | urb->actual_length += td_actual_bytes(td); | ||
937 | |||
938 | switch (usb_pipetype(td->pipe)) { | ||
939 | /* isochronous tds are handled separately */ | ||
940 | case PIPE_CONTROL: | ||
941 | switch (td->privdata) { | ||
942 | case SETUP_STAGE: | ||
943 | urb->interval = | ||
944 | urb->transfer_buffer_length ? | ||
945 | DATA_STAGE : STATUS_STAGE; | ||
946 | /* Don't count setup_packet with normal data: */ | ||
947 | urb->actual_length = 0; | ||
948 | break; | ||
949 | |||
950 | case DATA_STAGE: | ||
951 | if (c67x00_end_of_data(td)) { | ||
952 | urb->interval = STATUS_STAGE; | ||
953 | c67x00_clear_pipe(c67x00, td); | ||
954 | } | ||
955 | break; | ||
956 | |||
957 | case STATUS_STAGE: | ||
958 | urb->interval = 0; | ||
959 | c67x00_giveback_urb(c67x00, urb, 0); | ||
960 | break; | ||
961 | } | ||
962 | break; | ||
963 | |||
964 | case PIPE_INTERRUPT: | ||
965 | case PIPE_BULK: | ||
966 | if (unlikely(c67x00_end_of_data(td))) { | ||
967 | c67x00_clear_pipe(c67x00, td); | ||
968 | c67x00_giveback_urb(c67x00, urb, 0); | ||
969 | } | ||
970 | break; | ||
971 | } | ||
972 | } | ||
973 | |||
974 | static void c67x00_handle_isoc(struct c67x00_hcd *c67x00, struct c67x00_td *td) | ||
975 | { | ||
976 | struct urb *urb = td->urb; | ||
977 | struct c67x00_urb_priv *urbp; | ||
978 | int cnt; | ||
979 | |||
980 | if (!urb) | ||
981 | return; | ||
982 | |||
983 | urbp = urb->hcpriv; | ||
984 | cnt = td->privdata; | ||
985 | |||
986 | if (td->status & TD_ERROR_MASK) | ||
987 | urb->error_count++; | ||
988 | |||
989 | urb->iso_frame_desc[cnt].actual_length = td_actual_bytes(td); | ||
990 | urb->iso_frame_desc[cnt].status = c67x00_td_to_error(c67x00, td); | ||
991 | if (cnt + 1 == urb->number_of_packets) /* Last packet */ | ||
992 | c67x00_giveback_urb(c67x00, urb, 0); | ||
993 | } | ||
994 | |||
995 | /* -------------------------------------------------------------------------- */ | ||
996 | |||
997 | /** | ||
998 | * c67x00_check_td_list - handle tds which have been processed by the c67x00 | ||
999 | * pre: current_td == 0 | ||
1000 | */ | ||
1001 | static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00) | ||
1002 | { | ||
1003 | struct c67x00_td *td, *tmp; | ||
1004 | struct urb *urb; | ||
1005 | int ack_ok; | ||
1006 | int clear_endpoint; | ||
1007 | |||
1008 | list_for_each_entry_safe(td, tmp, &c67x00->td_list, td_list) { | ||
1009 | /* get the TD */ | ||
1010 | c67x00_parse_td(c67x00, td); | ||
1011 | urb = td->urb; /* urb can be NULL! */ | ||
1012 | ack_ok = 0; | ||
1013 | clear_endpoint = 1; | ||
1014 | |||
1015 | /* Handle isochronous transfers separately */ | ||
1016 | if (usb_pipeisoc(td->pipe)) { | ||
1017 | clear_endpoint = 0; | ||
1018 | c67x00_handle_isoc(c67x00, td); | ||
1019 | goto cont; | ||
1020 | } | ||
1021 | |||
1022 | /* When an error occurs, all td's for that pipe go into an | ||
1023 | * inactive state. This state matches successful transfers so | ||
1024 | * we must make sure not to service them. */ | ||
1025 | if (td->status & TD_ERROR_MASK) { | ||
1026 | c67x00_giveback_urb(c67x00, urb, | ||
1027 | c67x00_td_to_error(c67x00, td)); | ||
1028 | goto cont; | ||
1029 | } | ||
1030 | |||
1031 | if ((td->status & TD_STATUSMASK_NAK) || !td_sequence_ok(td) || | ||
1032 | !td_acked(td)) | ||
1033 | goto cont; | ||
1034 | |||
1035 | /* Sequence ok and acked, don't need to fix toggle */ | ||
1036 | ack_ok = 1; | ||
1037 | |||
1038 | if (unlikely(td->status & TD_STATUSMASK_OVF)) { | ||
1039 | if (td_residue(td) & TD_RESIDUE_OVERFLOW) { | ||
1040 | /* Overflow */ | ||
1041 | c67x00_giveback_urb(c67x00, urb, -EOVERFLOW); | ||
1042 | goto cont; | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | clear_endpoint = 0; | ||
1047 | c67x00_handle_successful_td(c67x00, td); | ||
1048 | |||
1049 | cont: | ||
1050 | if (clear_endpoint) | ||
1051 | c67x00_clear_pipe(c67x00, td); | ||
1052 | if (ack_ok) | ||
1053 | usb_settoggle(td_udev(td), usb_pipeendpoint(td->pipe), | ||
1054 | usb_pipeout(td->pipe), | ||
1055 | !(td->ctrl_reg & SEQ_SEL)); | ||
1056 | /* next in list could have been removed, due to clear_pipe! */ | ||
1057 | tmp = list_entry(td->td_list.next, typeof(*td), td_list); | ||
1058 | c67x00_release_td(td); | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | /* -------------------------------------------------------------------------- */ | ||
1063 | |||
1064 | static inline int c67x00_all_tds_processed(struct c67x00_hcd *c67x00) | ||
1065 | { | ||
1066 | /* If all tds are processed, we can check the previous frame (if | ||
1067 | * there was any) and start our next frame. | ||
1068 | */ | ||
1069 | return !c67x00_ll_husb_get_current_td(c67x00->sie); | ||
1070 | } | ||
1071 | |||
1072 | /** | ||
1073 | * Send td to C67X00 | ||
1074 | */ | ||
1075 | static void c67x00_send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) | ||
1076 | { | ||
1077 | int len = td_length(td); | ||
1078 | |||
1079 | if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN)) | ||
1080 | c67x00_ll_write_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), | ||
1081 | td->data, len); | ||
1082 | |||
1083 | c67x00_ll_write_mem_le16(c67x00->sie->dev, | ||
1084 | td->td_addr, td, CY_TD_SIZE); | ||
1085 | } | ||
1086 | |||
1087 | static void c67x00_send_frame(struct c67x00_hcd *c67x00) | ||
1088 | { | ||
1089 | struct c67x00_td *td; | ||
1090 | |||
1091 | if (list_empty(&c67x00->td_list)) | ||
1092 | dev_warn(c67x00_hcd_dev(c67x00), | ||
1093 | "%s: td list should not be empty here!\n", | ||
1094 | __func__); | ||
1095 | |||
1096 | list_for_each_entry(td, &c67x00->td_list, td_list) { | ||
1097 | if (td->td_list.next == &c67x00->td_list) | ||
1098 | td->next_td_addr = 0; /* Last td in list */ | ||
1099 | |||
1100 | c67x00_send_td(c67x00, td); | ||
1101 | } | ||
1102 | |||
1103 | c67x00_ll_husb_set_current_td(c67x00->sie, c67x00->td_base_addr); | ||
1104 | } | ||
1105 | |||
1106 | /* -------------------------------------------------------------------------- */ | ||
1107 | |||
1108 | /** | ||
1109 | * c67x00_do_work - Schedulers state machine | ||
1110 | */ | ||
1111 | static void c67x00_do_work(struct c67x00_hcd *c67x00) | ||
1112 | { | ||
1113 | spin_lock(&c67x00->lock); | ||
1114 | /* Make sure all tds are processed */ | ||
1115 | if (!c67x00_all_tds_processed(c67x00)) | ||
1116 | goto out; | ||
1117 | |||
1118 | c67x00_check_td_list(c67x00); | ||
1119 | |||
1120 | /* no td's are being processed (current == 0) | ||
1121 | * and all have been "checked" */ | ||
1122 | complete(&c67x00->endpoint_disable); | ||
1123 | |||
1124 | if (!list_empty(&c67x00->td_list)) | ||
1125 | goto out; | ||
1126 | |||
1127 | c67x00->current_frame = c67x00_get_current_frame_number(c67x00); | ||
1128 | if (c67x00->current_frame == c67x00->last_frame) | ||
1129 | goto out; /* Don't send tds in same frame */ | ||
1130 | c67x00->last_frame = c67x00->current_frame; | ||
1131 | |||
1132 | /* If no urbs are scheduled, our work is done */ | ||
1133 | if (!c67x00->urb_count) { | ||
1134 | c67x00_ll_hpi_disable_sofeop(c67x00->sie); | ||
1135 | goto out; | ||
1136 | } | ||
1137 | |||
1138 | c67x00_fill_frame(c67x00); | ||
1139 | if (!list_empty(&c67x00->td_list)) | ||
1140 | /* TD's have been added to the frame */ | ||
1141 | c67x00_send_frame(c67x00); | ||
1142 | |||
1143 | out: | ||
1144 | spin_unlock(&c67x00->lock); | ||
1145 | } | ||
1146 | |||
1147 | /* -------------------------------------------------------------------------- */ | ||
1148 | |||
1149 | static void c67x00_sched_tasklet(unsigned long __c67x00) | ||
1150 | { | ||
1151 | struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00; | ||
1152 | c67x00_do_work(c67x00); | ||
1153 | } | ||
1154 | |||
1155 | void c67x00_sched_kick(struct c67x00_hcd *c67x00) | ||
1156 | { | ||
1157 | tasklet_hi_schedule(&c67x00->tasklet); | ||
1158 | } | ||
1159 | |||
1160 | int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00) | ||
1161 | { | ||
1162 | tasklet_init(&c67x00->tasklet, c67x00_sched_tasklet, | ||
1163 | (unsigned long)c67x00); | ||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00) | ||
1168 | { | ||
1169 | tasklet_kill(&c67x00->tasklet); | ||
1170 | } | ||
diff --git a/drivers/usb/c67x00/c67x00.h b/drivers/usb/c67x00/c67x00.h new file mode 100644 index 000000000000..a26e9ded0f32 --- /dev/null +++ b/drivers/usb/c67x00/c67x00.h | |||
@@ -0,0 +1,294 @@ | |||
1 | /* | ||
2 | * c67x00.h: Cypress C67X00 USB register and field definitions | ||
3 | * | ||
4 | * Copyright (C) 2006-2008 Barco N.V. | ||
5 | * Derived from the Cypress cy7c67200/300 ezusb linux driver and | ||
6 | * based on multiple host controller drivers inside the linux kernel. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
21 | * MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_C67X00_H | ||
25 | #define _USB_C67X00_H | ||
26 | |||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/completion.h> | ||
30 | #include <linux/mutex.h> | ||
31 | |||
32 | /* --------------------------------------------------------------------- | ||
33 | * Cypress C67x00 register definitions | ||
34 | */ | ||
35 | |||
36 | /* Hardware Revision Register */ | ||
37 | #define HW_REV_REG 0xC004 | ||
38 | |||
39 | /* General USB registers */ | ||
40 | /* ===================== */ | ||
41 | |||
42 | /* USB Control Register */ | ||
43 | #define USB_CTL_REG(x) ((x) ? 0xC0AA : 0xC08A) | ||
44 | |||
45 | #define LOW_SPEED_PORT(x) ((x) ? 0x0800 : 0x0400) | ||
46 | #define HOST_MODE 0x0200 | ||
47 | #define PORT_RES_EN(x) ((x) ? 0x0100 : 0x0080) | ||
48 | #define SOF_EOP_EN(x) ((x) ? 0x0002 : 0x0001) | ||
49 | |||
50 | /* USB status register - Notice it has different content in hcd/udc mode */ | ||
51 | #define USB_STAT_REG(x) ((x) ? 0xC0B0 : 0xC090) | ||
52 | |||
53 | #define EP0_IRQ_FLG 0x0001 | ||
54 | #define EP1_IRQ_FLG 0x0002 | ||
55 | #define EP2_IRQ_FLG 0x0004 | ||
56 | #define EP3_IRQ_FLG 0x0008 | ||
57 | #define EP4_IRQ_FLG 0x0010 | ||
58 | #define EP5_IRQ_FLG 0x0020 | ||
59 | #define EP6_IRQ_FLG 0x0040 | ||
60 | #define EP7_IRQ_FLG 0x0080 | ||
61 | #define RESET_IRQ_FLG 0x0100 | ||
62 | #define SOF_EOP_IRQ_FLG 0x0200 | ||
63 | #define ID_IRQ_FLG 0x4000 | ||
64 | #define VBUS_IRQ_FLG 0x8000 | ||
65 | |||
66 | /* USB Host only registers */ | ||
67 | /* ======================= */ | ||
68 | |||
69 | /* Host n Control Register */ | ||
70 | #define HOST_CTL_REG(x) ((x) ? 0xC0A0 : 0xC080) | ||
71 | |||
72 | #define PREAMBLE_EN 0x0080 /* Preamble enable */ | ||
73 | #define SEQ_SEL 0x0040 /* Data Toggle Sequence Bit Select */ | ||
74 | #define ISO_EN 0x0010 /* Isochronous enable */ | ||
75 | #define ARM_EN 0x0001 /* Arm operation */ | ||
76 | |||
77 | /* Host n Interrupt Enable Register */ | ||
78 | #define HOST_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) | ||
79 | |||
80 | #define SOF_EOP_IRQ_EN 0x0200 /* SOF/EOP Interrupt Enable */ | ||
81 | #define SOF_EOP_TMOUT_IRQ_EN 0x0800 /* SOF/EOP Timeout Interrupt Enable */ | ||
82 | #define ID_IRQ_EN 0x4000 /* ID interrupt enable */ | ||
83 | #define VBUS_IRQ_EN 0x8000 /* VBUS interrupt enable */ | ||
84 | #define DONE_IRQ_EN 0x0001 /* Done Interrupt Enable */ | ||
85 | |||
86 | /* USB status register */ | ||
87 | #define HOST_STAT_MASK 0x02FD | ||
88 | #define PORT_CONNECT_CHANGE(x) ((x) ? 0x0020 : 0x0010) | ||
89 | #define PORT_SE0_STATUS(x) ((x) ? 0x0008 : 0x0004) | ||
90 | |||
91 | /* Host Frame Register */ | ||
92 | #define HOST_FRAME_REG(x) ((x) ? 0xC0B6 : 0xC096) | ||
93 | |||
94 | #define HOST_FRAME_MASK 0x07FF | ||
95 | |||
96 | /* USB Peripheral only registers */ | ||
97 | /* ============================= */ | ||
98 | |||
99 | /* Device n Port Sel reg */ | ||
100 | #define DEVICE_N_PORT_SEL(x) ((x) ? 0xC0A4 : 0xC084) | ||
101 | |||
102 | /* Device n Interrupt Enable Register */ | ||
103 | #define DEVICE_N_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) | ||
104 | |||
105 | #define DEVICE_N_ENDPOINT_N_CTL_REG(dev, ep) ((dev) \ | ||
106 | ? (0x0280 + (ep << 4)) \ | ||
107 | : (0x0200 + (ep << 4))) | ||
108 | #define DEVICE_N_ENDPOINT_N_STAT_REG(dev, ep) ((dev) \ | ||
109 | ? (0x0286 + (ep << 4)) \ | ||
110 | : (0x0206 + (ep << 4))) | ||
111 | |||
112 | #define DEVICE_N_ADDRESS(dev) ((dev) ? (0xC0AE) : (0xC08E)) | ||
113 | |||
114 | /* HPI registers */ | ||
115 | /* ============= */ | ||
116 | |||
117 | /* HPI Status register */ | ||
118 | #define SOFEOP_FLG(x) (1 << ((x) ? 12 : 10)) | ||
119 | #define SIEMSG_FLG(x) (1 << (4 + (x))) | ||
120 | #define RESET_FLG(x) ((x) ? 0x0200 : 0x0002) | ||
121 | #define DONE_FLG(x) (1 << (2 + (x))) | ||
122 | #define RESUME_FLG(x) (1 << (6 + (x))) | ||
123 | #define MBX_OUT_FLG 0x0001 /* Message out available */ | ||
124 | #define MBX_IN_FLG 0x0100 | ||
125 | #define ID_FLG 0x4000 | ||
126 | #define VBUS_FLG 0x8000 | ||
127 | |||
128 | /* Interrupt routing register */ | ||
129 | #define HPI_IRQ_ROUTING_REG 0x0142 | ||
130 | |||
131 | #define HPI_SWAP_ENABLE(x) ((x) ? 0x0100 : 0x0001) | ||
132 | #define RESET_TO_HPI_ENABLE(x) ((x) ? 0x0200 : 0x0002) | ||
133 | #define DONE_TO_HPI_ENABLE(x) ((x) ? 0x0008 : 0x0004) | ||
134 | #define RESUME_TO_HPI_ENABLE(x) ((x) ? 0x0080 : 0x0040) | ||
135 | #define SOFEOP_TO_HPI_EN(x) ((x) ? 0x2000 : 0x0800) | ||
136 | #define SOFEOP_TO_CPU_EN(x) ((x) ? 0x1000 : 0x0400) | ||
137 | #define ID_TO_HPI_ENABLE 0x4000 | ||
138 | #define VBUS_TO_HPI_ENABLE 0x8000 | ||
139 | |||
140 | /* SIE msg registers */ | ||
141 | #define SIEMSG_REG(x) ((x) ? 0x0148 : 0x0144) | ||
142 | |||
143 | #define HUSB_TDListDone 0x1000 | ||
144 | |||
145 | #define SUSB_EP0_MSG 0x0001 | ||
146 | #define SUSB_EP1_MSG 0x0002 | ||
147 | #define SUSB_EP2_MSG 0x0004 | ||
148 | #define SUSB_EP3_MSG 0x0008 | ||
149 | #define SUSB_EP4_MSG 0x0010 | ||
150 | #define SUSB_EP5_MSG 0x0020 | ||
151 | #define SUSB_EP6_MSG 0x0040 | ||
152 | #define SUSB_EP7_MSG 0x0080 | ||
153 | #define SUSB_RST_MSG 0x0100 | ||
154 | #define SUSB_SOF_MSG 0x0200 | ||
155 | #define SUSB_CFG_MSG 0x0400 | ||
156 | #define SUSB_SUS_MSG 0x0800 | ||
157 | #define SUSB_ID_MSG 0x4000 | ||
158 | #define SUSB_VBUS_MSG 0x8000 | ||
159 | |||
160 | /* BIOS interrupt routines */ | ||
161 | |||
162 | #define SUSBx_RECEIVE_INT(x) ((x) ? 97 : 81) | ||
163 | #define SUSBx_SEND_INT(x) ((x) ? 96 : 80) | ||
164 | |||
165 | #define SUSBx_DEV_DESC_VEC(x) ((x) ? 0x00D4 : 0x00B4) | ||
166 | #define SUSBx_CONF_DESC_VEC(x) ((x) ? 0x00D6 : 0x00B6) | ||
167 | #define SUSBx_STRING_DESC_VEC(x) ((x) ? 0x00D8 : 0x00B8) | ||
168 | |||
169 | #define CY_HCD_BUF_ADDR 0x500 /* Base address for host */ | ||
170 | #define SIE_TD_SIZE 0x200 /* size of the td list */ | ||
171 | #define SIE_TD_BUF_SIZE 0x400 /* size of the data buffer */ | ||
172 | |||
173 | #define SIE_TD_OFFSET(host) ((host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0) | ||
174 | #define SIE_BUF_OFFSET(host) (SIE_TD_OFFSET(host) + SIE_TD_SIZE) | ||
175 | |||
176 | /* Base address of HCD + 2 x TD_SIZE + 2 x TD_BUF_SIZE */ | ||
177 | #define CY_UDC_REQ_HEADER_BASE 0x1100 | ||
178 | /* 8- byte request headers for IN/OUT transfers */ | ||
179 | #define CY_UDC_REQ_HEADER_SIZE 8 | ||
180 | |||
181 | #define CY_UDC_REQ_HEADER_ADDR(ep_num) (CY_UDC_REQ_HEADER_BASE + \ | ||
182 | ((ep_num) * CY_UDC_REQ_HEADER_SIZE)) | ||
183 | #define CY_UDC_DESC_BASE_ADDRESS (CY_UDC_REQ_HEADER_ADDR(8)) | ||
184 | |||
185 | #define CY_UDC_BIOS_REPLACE_BASE 0x1800 | ||
186 | #define CY_UDC_REQ_BUFFER_BASE 0x2000 | ||
187 | #define CY_UDC_REQ_BUFFER_SIZE 0x0400 | ||
188 | #define CY_UDC_REQ_BUFFER_ADDR(ep_num) (CY_UDC_REQ_BUFFER_BASE + \ | ||
189 | ((ep_num) * CY_UDC_REQ_BUFFER_SIZE)) | ||
190 | |||
191 | /* --------------------------------------------------------------------- | ||
192 | * Driver data structures | ||
193 | */ | ||
194 | |||
195 | struct c67x00_device; | ||
196 | |||
197 | /** | ||
198 | * struct c67x00_sie - Common data associated with a SIE | ||
199 | * @lock: lock to protect this struct and the associated chip registers | ||
200 | * @private_data: subdriver dependent data | ||
201 | * @irq: subdriver dependent irq handler, set NULL when not used | ||
202 | * @dev: link to common driver structure | ||
203 | * @sie_num: SIE number on chip, starting from 0 | ||
204 | * @mode: SIE mode (host/peripheral/otg/not used) | ||
205 | */ | ||
206 | struct c67x00_sie { | ||
207 | /* Entries to be used by the subdrivers */ | ||
208 | spinlock_t lock; /* protect this structure */ | ||
209 | void *private_data; | ||
210 | void (*irq) (struct c67x00_sie *sie, u16 int_status, u16 msg); | ||
211 | |||
212 | /* Read only: */ | ||
213 | struct c67x00_device *dev; | ||
214 | int sie_num; | ||
215 | int mode; | ||
216 | }; | ||
217 | |||
218 | #define sie_dev(s) (&(s)->dev->pdev->dev) | ||
219 | |||
220 | /** | ||
221 | * struct c67x00_lcp | ||
222 | */ | ||
223 | struct c67x00_lcp { | ||
224 | /* Internal use only */ | ||
225 | struct mutex mutex; | ||
226 | struct completion msg_received; | ||
227 | u16 last_msg; | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * struct c67x00_hpi | ||
232 | */ | ||
233 | struct c67x00_hpi { | ||
234 | void __iomem *base; | ||
235 | int regstep; | ||
236 | spinlock_t lock; | ||
237 | struct c67x00_lcp lcp; | ||
238 | }; | ||
239 | |||
240 | #define C67X00_SIES 2 | ||
241 | #define C67X00_PORTS 2 | ||
242 | |||
243 | /** | ||
244 | * struct c67x00_device - Common data associated with a c67x00 instance | ||
245 | * @hpi: hpi addresses | ||
246 | * @sie: array of sie's on this chip | ||
247 | * @pdev: platform device of instance | ||
248 | * @pdata: configuration provided by the platform | ||
249 | */ | ||
250 | struct c67x00_device { | ||
251 | struct c67x00_hpi hpi; | ||
252 | struct c67x00_sie sie[C67X00_SIES]; | ||
253 | struct platform_device *pdev; | ||
254 | struct c67x00_platform_data *pdata; | ||
255 | }; | ||
256 | |||
257 | /* --------------------------------------------------------------------- | ||
258 | * Low level interface functions | ||
259 | */ | ||
260 | |||
261 | /* Host Port Interface (HPI) functions */ | ||
262 | u16 c67x00_ll_hpi_status(struct c67x00_device *dev); | ||
263 | void c67x00_ll_hpi_reg_init(struct c67x00_device *dev); | ||
264 | void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie); | ||
265 | void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie); | ||
266 | |||
267 | /* General functions */ | ||
268 | u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num); | ||
269 | u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie); | ||
270 | void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits); | ||
271 | u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie); | ||
272 | void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, | ||
273 | void *data, int len); | ||
274 | void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, | ||
275 | void *data, int len); | ||
276 | |||
277 | /* Host specific functions */ | ||
278 | void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value); | ||
279 | void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port); | ||
280 | void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr); | ||
281 | u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie); | ||
282 | u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie); | ||
283 | void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie); | ||
284 | void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port); | ||
285 | |||
286 | /* Called by c67x00_irq to handle lcp interrupts */ | ||
287 | void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status); | ||
288 | |||
289 | /* Setup and teardown */ | ||
290 | void c67x00_ll_init(struct c67x00_device *dev); | ||
291 | void c67x00_ll_release(struct c67x00_device *dev); | ||
292 | int c67x00_ll_reset(struct c67x00_device *dev); | ||
293 | |||
294 | #endif /* _USB_C67X00_H */ | ||
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 3a9102d2591b..66f17ed88cb5 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig | |||
@@ -29,3 +29,14 @@ config USB_PRINTER | |||
29 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
30 | module will be called usblp. | 30 | module will be called usblp. |
31 | 31 | ||
32 | config USB_WDM | ||
33 | tristate "USB Wireless Device Management support" | ||
34 | depends on USB | ||
35 | ---help--- | ||
36 | This driver supports the WMC Device Management functionality | ||
37 | of cell phones compliant to the CDC WMC specification. You can use | ||
38 | AT commands over this device. | ||
39 | |||
40 | To compile this driver as a module, choose M here: the | ||
41 | module will be called cdc-wdm. | ||
42 | |||
diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index cc391e6c2af8..535d59a30600 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile | |||
@@ -5,3 +5,4 @@ | |||
5 | 5 | ||
6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o | 6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o |
7 | obj-$(CONFIG_USB_PRINTER) += usblp.o | 7 | obj-$(CONFIG_USB_PRINTER) += usblp.o |
8 | obj-$(CONFIG_USB_WDM) += cdc-wdm.o | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index cefe7f2c6f75..c3201affa0b6 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1125,9 +1125,6 @@ static void stop_data_traffic(struct acm *acm) | |||
1125 | for (i = 0; i < acm->rx_buflimit; i++) | 1125 | for (i = 0; i < acm->rx_buflimit; i++) |
1126 | usb_kill_urb(acm->ru[i].urb); | 1126 | usb_kill_urb(acm->ru[i].urb); |
1127 | 1127 | ||
1128 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
1129 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
1130 | |||
1131 | tasklet_enable(&acm->urb_task); | 1128 | tasklet_enable(&acm->urb_task); |
1132 | 1129 | ||
1133 | cancel_work_sync(&acm->work); | 1130 | cancel_work_sync(&acm->work); |
@@ -1248,6 +1245,9 @@ static struct usb_device_id acm_ids[] = { | |||
1248 | { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ | 1245 | { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ |
1249 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1246 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1250 | }, | 1247 | }, |
1248 | { USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */ | ||
1249 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
1250 | }, | ||
1251 | 1251 | ||
1252 | /* control interfaces with various AT-command sets */ | 1252 | /* control interfaces with various AT-command sets */ |
1253 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1253 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c new file mode 100644 index 000000000000..731db051070a --- /dev/null +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -0,0 +1,740 @@ | |||
1 | /* | ||
2 | * cdc-wdm.c | ||
3 | * | ||
4 | * This driver supports USB CDC WCM Device Management. | ||
5 | * | ||
6 | * Copyright (c) 2007-2008 Oliver Neukum | ||
7 | * | ||
8 | * Some code taken from cdc-acm.c | ||
9 | * | ||
10 | * Released under the GPLv2. | ||
11 | * | ||
12 | * Many thanks to Carl Nordbeck | ||
13 | */ | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/uaccess.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/poll.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/usb/cdc.h> | ||
25 | #include <asm/byteorder.h> | ||
26 | #include <asm/unaligned.h> | ||
27 | |||
28 | /* | ||
29 | * Version Information | ||
30 | */ | ||
31 | #define DRIVER_VERSION "v0.02" | ||
32 | #define DRIVER_AUTHOR "Oliver Neukum" | ||
33 | |||
34 | static struct usb_device_id wdm_ids[] = { | ||
35 | { | ||
36 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | ||
37 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
38 | .bInterfaceClass = USB_CLASS_COMM, | ||
39 | .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM | ||
40 | }, | ||
41 | { } | ||
42 | }; | ||
43 | |||
44 | #define WDM_MINOR_BASE 176 | ||
45 | |||
46 | |||
47 | #define WDM_IN_USE 1 | ||
48 | #define WDM_DISCONNECTING 2 | ||
49 | #define WDM_RESULT 3 | ||
50 | #define WDM_READ 4 | ||
51 | #define WDM_INT_STALL 5 | ||
52 | #define WDM_POLL_RUNNING 6 | ||
53 | |||
54 | |||
55 | #define WDM_MAX 16 | ||
56 | |||
57 | |||
58 | static DEFINE_MUTEX(wdm_mutex); | ||
59 | |||
60 | /* --- method tables --- */ | ||
61 | |||
62 | struct wdm_device { | ||
63 | u8 *inbuf; /* buffer for response */ | ||
64 | u8 *outbuf; /* buffer for command */ | ||
65 | u8 *sbuf; /* buffer for status */ | ||
66 | u8 *ubuf; /* buffer for copy to user space */ | ||
67 | |||
68 | struct urb *command; | ||
69 | struct urb *response; | ||
70 | struct urb *validity; | ||
71 | struct usb_interface *intf; | ||
72 | struct usb_ctrlrequest *orq; | ||
73 | struct usb_ctrlrequest *irq; | ||
74 | spinlock_t iuspin; | ||
75 | |||
76 | unsigned long flags; | ||
77 | u16 bufsize; | ||
78 | u16 wMaxCommand; | ||
79 | u16 wMaxPacketSize; | ||
80 | u16 bMaxPacketSize0; | ||
81 | __le16 inum; | ||
82 | int reslength; | ||
83 | int length; | ||
84 | int read; | ||
85 | int count; | ||
86 | dma_addr_t shandle; | ||
87 | dma_addr_t ihandle; | ||
88 | struct mutex wlock; | ||
89 | struct mutex rlock; | ||
90 | wait_queue_head_t wait; | ||
91 | struct work_struct rxwork; | ||
92 | int werr; | ||
93 | int rerr; | ||
94 | }; | ||
95 | |||
96 | static struct usb_driver wdm_driver; | ||
97 | |||
98 | /* --- callbacks --- */ | ||
99 | static void wdm_out_callback(struct urb *urb) | ||
100 | { | ||
101 | struct wdm_device *desc; | ||
102 | desc = urb->context; | ||
103 | spin_lock(&desc->iuspin); | ||
104 | desc->werr = urb->status; | ||
105 | spin_unlock(&desc->iuspin); | ||
106 | clear_bit(WDM_IN_USE, &desc->flags); | ||
107 | kfree(desc->outbuf); | ||
108 | wake_up(&desc->wait); | ||
109 | } | ||
110 | |||
111 | static void wdm_in_callback(struct urb *urb) | ||
112 | { | ||
113 | struct wdm_device *desc = urb->context; | ||
114 | int status = urb->status; | ||
115 | |||
116 | spin_lock(&desc->iuspin); | ||
117 | |||
118 | if (status) { | ||
119 | switch (status) { | ||
120 | case -ENOENT: | ||
121 | dev_dbg(&desc->intf->dev, | ||
122 | "nonzero urb status received: -ENOENT"); | ||
123 | break; | ||
124 | case -ECONNRESET: | ||
125 | dev_dbg(&desc->intf->dev, | ||
126 | "nonzero urb status received: -ECONNRESET"); | ||
127 | break; | ||
128 | case -ESHUTDOWN: | ||
129 | dev_dbg(&desc->intf->dev, | ||
130 | "nonzero urb status received: -ESHUTDOWN"); | ||
131 | break; | ||
132 | case -EPIPE: | ||
133 | err("nonzero urb status received: -EPIPE"); | ||
134 | break; | ||
135 | default: | ||
136 | err("Unexpected error %d", status); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | desc->rerr = status; | ||
142 | desc->reslength = urb->actual_length; | ||
143 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | ||
144 | desc->length += desc->reslength; | ||
145 | wake_up(&desc->wait); | ||
146 | |||
147 | set_bit(WDM_READ, &desc->flags); | ||
148 | spin_unlock(&desc->iuspin); | ||
149 | } | ||
150 | |||
151 | static void wdm_int_callback(struct urb *urb) | ||
152 | { | ||
153 | int rv = 0; | ||
154 | int status = urb->status; | ||
155 | struct wdm_device *desc; | ||
156 | struct usb_ctrlrequest *req; | ||
157 | struct usb_cdc_notification *dr; | ||
158 | |||
159 | desc = urb->context; | ||
160 | req = desc->irq; | ||
161 | dr = (struct usb_cdc_notification *)desc->sbuf; | ||
162 | |||
163 | if (status) { | ||
164 | switch (status) { | ||
165 | case -ESHUTDOWN: | ||
166 | case -ENOENT: | ||
167 | case -ECONNRESET: | ||
168 | return; /* unplug */ | ||
169 | case -EPIPE: | ||
170 | set_bit(WDM_INT_STALL, &desc->flags); | ||
171 | err("Stall on int endpoint"); | ||
172 | goto sw; /* halt is cleared in work */ | ||
173 | default: | ||
174 | err("nonzero urb status received: %d", status); | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | if (urb->actual_length < sizeof(struct usb_cdc_notification)) { | ||
180 | err("wdm_int_callback - %d bytes", urb->actual_length); | ||
181 | goto exit; | ||
182 | } | ||
183 | |||
184 | switch (dr->bNotificationType) { | ||
185 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: | ||
186 | dev_dbg(&desc->intf->dev, | ||
187 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", | ||
188 | dr->wIndex, dr->wLength); | ||
189 | break; | ||
190 | |||
191 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | ||
192 | |||
193 | dev_dbg(&desc->intf->dev, | ||
194 | "NOTIFY_NETWORK_CONNECTION %s network", | ||
195 | dr->wValue ? "connected to" : "disconnected from"); | ||
196 | goto exit; | ||
197 | default: | ||
198 | clear_bit(WDM_POLL_RUNNING, &desc->flags); | ||
199 | err("unknown notification %d received: index %d len %d", | ||
200 | dr->bNotificationType, dr->wIndex, dr->wLength); | ||
201 | goto exit; | ||
202 | } | ||
203 | |||
204 | req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); | ||
205 | req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; | ||
206 | req->wValue = 0; | ||
207 | req->wIndex = desc->inum; | ||
208 | req->wLength = cpu_to_le16(desc->bMaxPacketSize0); | ||
209 | |||
210 | usb_fill_control_urb( | ||
211 | desc->response, | ||
212 | interface_to_usbdev(desc->intf), | ||
213 | /* using common endpoint 0 */ | ||
214 | usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), | ||
215 | (unsigned char *)req, | ||
216 | desc->inbuf, | ||
217 | desc->bMaxPacketSize0, | ||
218 | wdm_in_callback, | ||
219 | desc | ||
220 | ); | ||
221 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
222 | spin_lock(&desc->iuspin); | ||
223 | clear_bit(WDM_READ, &desc->flags); | ||
224 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
225 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | ||
226 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | ||
227 | __func__, rv); | ||
228 | } | ||
229 | spin_unlock(&desc->iuspin); | ||
230 | if (rv < 0) { | ||
231 | if (rv == -EPERM) | ||
232 | return; | ||
233 | if (rv == -ENOMEM) { | ||
234 | sw: | ||
235 | rv = schedule_work(&desc->rxwork); | ||
236 | if (rv) | ||
237 | err("Cannot schedule work"); | ||
238 | } | ||
239 | } | ||
240 | exit: | ||
241 | rv = usb_submit_urb(urb, GFP_ATOMIC); | ||
242 | if (rv) | ||
243 | err("%s - usb_submit_urb failed with result %d", | ||
244 | __func__, rv); | ||
245 | |||
246 | } | ||
247 | |||
248 | static void kill_urbs(struct wdm_device *desc) | ||
249 | { | ||
250 | usb_kill_urb(desc->command); | ||
251 | usb_kill_urb(desc->validity); | ||
252 | usb_kill_urb(desc->response); | ||
253 | } | ||
254 | |||
255 | static void free_urbs(struct wdm_device *desc) | ||
256 | { | ||
257 | usb_free_urb(desc->validity); | ||
258 | usb_free_urb(desc->response); | ||
259 | usb_free_urb(desc->command); | ||
260 | } | ||
261 | |||
262 | static void cleanup(struct wdm_device *desc) | ||
263 | { | ||
264 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
265 | desc->wMaxPacketSize, | ||
266 | desc->sbuf, | ||
267 | desc->validity->transfer_dma); | ||
268 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
269 | desc->wMaxPacketSize, | ||
270 | desc->inbuf, | ||
271 | desc->response->transfer_dma); | ||
272 | kfree(desc->orq); | ||
273 | kfree(desc->irq); | ||
274 | kfree(desc->ubuf); | ||
275 | free_urbs(desc); | ||
276 | kfree(desc); | ||
277 | } | ||
278 | |||
279 | static ssize_t wdm_write | ||
280 | (struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
281 | { | ||
282 | u8 *buf; | ||
283 | int rv = -EMSGSIZE, r, we; | ||
284 | struct wdm_device *desc = file->private_data; | ||
285 | struct usb_ctrlrequest *req; | ||
286 | |||
287 | if (count > desc->wMaxCommand) | ||
288 | count = desc->wMaxCommand; | ||
289 | |||
290 | spin_lock_irq(&desc->iuspin); | ||
291 | we = desc->werr; | ||
292 | desc->werr = 0; | ||
293 | spin_unlock_irq(&desc->iuspin); | ||
294 | if (we < 0) | ||
295 | return -EIO; | ||
296 | |||
297 | r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ | ||
298 | rv = -ERESTARTSYS; | ||
299 | if (r) | ||
300 | goto outnl; | ||
301 | |||
302 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | ||
303 | &desc->flags)); | ||
304 | if (r < 0) | ||
305 | goto out; | ||
306 | |||
307 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
308 | rv = -ENODEV; | ||
309 | goto out; | ||
310 | } | ||
311 | |||
312 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); | ||
313 | if (!buf) { | ||
314 | rv = -ENOMEM; | ||
315 | goto out; | ||
316 | } | ||
317 | |||
318 | r = copy_from_user(buf, buffer, count); | ||
319 | if (r > 0) { | ||
320 | kfree(buf); | ||
321 | rv = -EFAULT; | ||
322 | goto out; | ||
323 | } | ||
324 | |||
325 | req = desc->orq; | ||
326 | usb_fill_control_urb( | ||
327 | desc->command, | ||
328 | interface_to_usbdev(desc->intf), | ||
329 | /* using common endpoint 0 */ | ||
330 | usb_sndctrlpipe(interface_to_usbdev(desc->intf), 0), | ||
331 | (unsigned char *)req, | ||
332 | buf, | ||
333 | count, | ||
334 | wdm_out_callback, | ||
335 | desc | ||
336 | ); | ||
337 | |||
338 | req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | | ||
339 | USB_RECIP_INTERFACE); | ||
340 | req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; | ||
341 | req->wValue = 0; | ||
342 | req->wIndex = desc->inum; | ||
343 | req->wLength = cpu_to_le16(count); | ||
344 | set_bit(WDM_IN_USE, &desc->flags); | ||
345 | |||
346 | rv = usb_submit_urb(desc->command, GFP_KERNEL); | ||
347 | if (rv < 0) { | ||
348 | kfree(buf); | ||
349 | clear_bit(WDM_IN_USE, &desc->flags); | ||
350 | } else { | ||
351 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", | ||
352 | req->wIndex); | ||
353 | } | ||
354 | out: | ||
355 | mutex_unlock(&desc->wlock); | ||
356 | outnl: | ||
357 | return rv < 0 ? rv : count; | ||
358 | } | ||
359 | |||
360 | static ssize_t wdm_read | ||
361 | (struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
362 | { | ||
363 | int rv, cntr; | ||
364 | int i = 0; | ||
365 | struct wdm_device *desc = file->private_data; | ||
366 | |||
367 | |||
368 | rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ | ||
369 | if (rv < 0) | ||
370 | return -ERESTARTSYS; | ||
371 | |||
372 | if (desc->length == 0) { | ||
373 | desc->read = 0; | ||
374 | retry: | ||
375 | i++; | ||
376 | rv = wait_event_interruptible(desc->wait, | ||
377 | test_bit(WDM_READ, &desc->flags)); | ||
378 | |||
379 | if (rv < 0) { | ||
380 | rv = -ERESTARTSYS; | ||
381 | goto err; | ||
382 | } | ||
383 | |||
384 | spin_lock_irq(&desc->iuspin); | ||
385 | |||
386 | if (desc->rerr) { /* read completed, error happened */ | ||
387 | int t = desc->rerr; | ||
388 | desc->rerr = 0; | ||
389 | spin_unlock_irq(&desc->iuspin); | ||
390 | err("reading had resulted in %d", t); | ||
391 | rv = -EIO; | ||
392 | goto err; | ||
393 | } | ||
394 | /* | ||
395 | * recheck whether we've lost the race | ||
396 | * against the completion handler | ||
397 | */ | ||
398 | if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */ | ||
399 | spin_unlock_irq(&desc->iuspin); | ||
400 | goto retry; | ||
401 | } | ||
402 | if (!desc->reslength) { /* zero length read */ | ||
403 | spin_unlock_irq(&desc->iuspin); | ||
404 | goto retry; | ||
405 | } | ||
406 | clear_bit(WDM_READ, &desc->flags); | ||
407 | spin_unlock_irq(&desc->iuspin); | ||
408 | } | ||
409 | |||
410 | cntr = count > desc->length ? desc->length : count; | ||
411 | rv = copy_to_user(buffer, desc->ubuf, cntr); | ||
412 | if (rv > 0) { | ||
413 | rv = -EFAULT; | ||
414 | goto err; | ||
415 | } | ||
416 | |||
417 | for (i = 0; i < desc->length - cntr; i++) | ||
418 | desc->ubuf[i] = desc->ubuf[i + cntr]; | ||
419 | |||
420 | desc->length -= cntr; | ||
421 | rv = cntr; | ||
422 | |||
423 | err: | ||
424 | mutex_unlock(&desc->rlock); | ||
425 | if (rv < 0) | ||
426 | err("wdm_read: exit error"); | ||
427 | return rv; | ||
428 | } | ||
429 | |||
430 | static int wdm_flush(struct file *file, fl_owner_t id) | ||
431 | { | ||
432 | struct wdm_device *desc = file->private_data; | ||
433 | |||
434 | wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); | ||
435 | if (desc->werr < 0) | ||
436 | err("Error in flush path: %d", desc->werr); | ||
437 | |||
438 | return desc->werr; | ||
439 | } | ||
440 | |||
441 | static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait) | ||
442 | { | ||
443 | struct wdm_device *desc = file->private_data; | ||
444 | unsigned long flags; | ||
445 | unsigned int mask = 0; | ||
446 | |||
447 | spin_lock_irqsave(&desc->iuspin, flags); | ||
448 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
449 | mask = POLLERR; | ||
450 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
451 | goto desc_out; | ||
452 | } | ||
453 | if (test_bit(WDM_READ, &desc->flags)) | ||
454 | mask = POLLIN | POLLRDNORM; | ||
455 | if (desc->rerr || desc->werr) | ||
456 | mask |= POLLERR; | ||
457 | if (!test_bit(WDM_IN_USE, &desc->flags)) | ||
458 | mask |= POLLOUT | POLLWRNORM; | ||
459 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
460 | |||
461 | poll_wait(file, &desc->wait, wait); | ||
462 | |||
463 | desc_out: | ||
464 | return mask; | ||
465 | } | ||
466 | |||
467 | static int wdm_open(struct inode *inode, struct file *file) | ||
468 | { | ||
469 | int minor = iminor(inode); | ||
470 | int rv = -ENODEV; | ||
471 | struct usb_interface *intf; | ||
472 | struct wdm_device *desc; | ||
473 | |||
474 | mutex_lock(&wdm_mutex); | ||
475 | intf = usb_find_interface(&wdm_driver, minor); | ||
476 | if (!intf) | ||
477 | goto out; | ||
478 | |||
479 | desc = usb_get_intfdata(intf); | ||
480 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) | ||
481 | goto out; | ||
482 | |||
483 | desc->count++; | ||
484 | file->private_data = desc; | ||
485 | |||
486 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); | ||
487 | |||
488 | if (rv < 0) { | ||
489 | desc->count--; | ||
490 | err("Error submitting int urb - %d", rv); | ||
491 | goto out; | ||
492 | } | ||
493 | rv = 0; | ||
494 | |||
495 | out: | ||
496 | mutex_unlock(&wdm_mutex); | ||
497 | return rv; | ||
498 | } | ||
499 | |||
500 | static int wdm_release(struct inode *inode, struct file *file) | ||
501 | { | ||
502 | struct wdm_device *desc = file->private_data; | ||
503 | |||
504 | mutex_lock(&wdm_mutex); | ||
505 | desc->count--; | ||
506 | if (!desc->count) { | ||
507 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | ||
508 | kill_urbs(desc); | ||
509 | } | ||
510 | mutex_unlock(&wdm_mutex); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static const struct file_operations wdm_fops = { | ||
515 | .owner = THIS_MODULE, | ||
516 | .read = wdm_read, | ||
517 | .write = wdm_write, | ||
518 | .open = wdm_open, | ||
519 | .flush = wdm_flush, | ||
520 | .release = wdm_release, | ||
521 | .poll = wdm_poll | ||
522 | }; | ||
523 | |||
524 | static struct usb_class_driver wdm_class = { | ||
525 | .name = "cdc-wdm%d", | ||
526 | .fops = &wdm_fops, | ||
527 | .minor_base = WDM_MINOR_BASE, | ||
528 | }; | ||
529 | |||
530 | /* --- error handling --- */ | ||
531 | static void wdm_rxwork(struct work_struct *work) | ||
532 | { | ||
533 | struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); | ||
534 | unsigned long flags; | ||
535 | int rv; | ||
536 | |||
537 | spin_lock_irqsave(&desc->iuspin, flags); | ||
538 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
539 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
540 | } else { | ||
541 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
542 | rv = usb_submit_urb(desc->response, GFP_KERNEL); | ||
543 | if (rv < 0 && rv != -EPERM) { | ||
544 | spin_lock_irqsave(&desc->iuspin, flags); | ||
545 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) | ||
546 | schedule_work(&desc->rxwork); | ||
547 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | /* --- hotplug --- */ | ||
553 | |||
554 | static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
555 | { | ||
556 | int rv = -EINVAL; | ||
557 | struct usb_device *udev = interface_to_usbdev(intf); | ||
558 | struct wdm_device *desc; | ||
559 | struct usb_host_interface *iface; | ||
560 | struct usb_endpoint_descriptor *ep; | ||
561 | struct usb_cdc_dmm_desc *dmhd; | ||
562 | u8 *buffer = intf->altsetting->extra; | ||
563 | int buflen = intf->altsetting->extralen; | ||
564 | u16 maxcom = 0; | ||
565 | |||
566 | if (!buffer) | ||
567 | goto out; | ||
568 | |||
569 | while (buflen > 0) { | ||
570 | if (buffer [1] != USB_DT_CS_INTERFACE) { | ||
571 | err("skipping garbage"); | ||
572 | goto next_desc; | ||
573 | } | ||
574 | |||
575 | switch (buffer [2]) { | ||
576 | case USB_CDC_HEADER_TYPE: | ||
577 | break; | ||
578 | case USB_CDC_DMM_TYPE: | ||
579 | dmhd = (struct usb_cdc_dmm_desc *)buffer; | ||
580 | maxcom = le16_to_cpu(dmhd->wMaxCommand); | ||
581 | dev_dbg(&intf->dev, | ||
582 | "Finding maximum buffer length: %d", maxcom); | ||
583 | break; | ||
584 | default: | ||
585 | err("Ignoring extra header, type %d, length %d", | ||
586 | buffer[2], buffer[0]); | ||
587 | break; | ||
588 | } | ||
589 | next_desc: | ||
590 | buflen -= buffer[0]; | ||
591 | buffer += buffer[0]; | ||
592 | } | ||
593 | |||
594 | rv = -ENOMEM; | ||
595 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); | ||
596 | if (!desc) | ||
597 | goto out; | ||
598 | mutex_init(&desc->wlock); | ||
599 | mutex_init(&desc->rlock); | ||
600 | spin_lock_init(&desc->iuspin); | ||
601 | init_waitqueue_head(&desc->wait); | ||
602 | desc->wMaxCommand = maxcom; | ||
603 | desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); | ||
604 | desc->intf = intf; | ||
605 | INIT_WORK(&desc->rxwork, wdm_rxwork); | ||
606 | |||
607 | iface = &intf->altsetting[0]; | ||
608 | ep = &iface->endpoint[0].desc; | ||
609 | if (!usb_endpoint_is_int_in(ep)) { | ||
610 | rv = -EINVAL; | ||
611 | goto err; | ||
612 | } | ||
613 | |||
614 | desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); | ||
615 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; | ||
616 | |||
617 | desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | ||
618 | if (!desc->orq) | ||
619 | goto err; | ||
620 | desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | ||
621 | if (!desc->irq) | ||
622 | goto err; | ||
623 | |||
624 | desc->validity = usb_alloc_urb(0, GFP_KERNEL); | ||
625 | if (!desc->validity) | ||
626 | goto err; | ||
627 | |||
628 | desc->response = usb_alloc_urb(0, GFP_KERNEL); | ||
629 | if (!desc->response) | ||
630 | goto err; | ||
631 | |||
632 | desc->command = usb_alloc_urb(0, GFP_KERNEL); | ||
633 | if (!desc->command) | ||
634 | goto err; | ||
635 | |||
636 | desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); | ||
637 | if (!desc->ubuf) | ||
638 | goto err; | ||
639 | |||
640 | desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf), | ||
641 | desc->wMaxPacketSize, | ||
642 | GFP_KERNEL, | ||
643 | &desc->validity->transfer_dma); | ||
644 | if (!desc->sbuf) | ||
645 | goto err; | ||
646 | |||
647 | desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf), | ||
648 | desc->bMaxPacketSize0, | ||
649 | GFP_KERNEL, | ||
650 | &desc->response->transfer_dma); | ||
651 | if (!desc->inbuf) | ||
652 | goto err2; | ||
653 | |||
654 | usb_fill_int_urb( | ||
655 | desc->validity, | ||
656 | interface_to_usbdev(intf), | ||
657 | usb_rcvintpipe(interface_to_usbdev(intf), ep->bEndpointAddress), | ||
658 | desc->sbuf, | ||
659 | desc->wMaxPacketSize, | ||
660 | wdm_int_callback, | ||
661 | desc, | ||
662 | ep->bInterval | ||
663 | ); | ||
664 | desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
665 | |||
666 | usb_set_intfdata(intf, desc); | ||
667 | rv = usb_register_dev(intf, &wdm_class); | ||
668 | dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", | ||
669 | intf->minor - WDM_MINOR_BASE); | ||
670 | if (rv < 0) | ||
671 | goto err; | ||
672 | out: | ||
673 | return rv; | ||
674 | err2: | ||
675 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
676 | desc->wMaxPacketSize, | ||
677 | desc->sbuf, | ||
678 | desc->validity->transfer_dma); | ||
679 | err: | ||
680 | free_urbs(desc); | ||
681 | kfree(desc->ubuf); | ||
682 | kfree(desc->orq); | ||
683 | kfree(desc->irq); | ||
684 | kfree(desc); | ||
685 | return rv; | ||
686 | } | ||
687 | |||
688 | static void wdm_disconnect(struct usb_interface *intf) | ||
689 | { | ||
690 | struct wdm_device *desc; | ||
691 | unsigned long flags; | ||
692 | |||
693 | usb_deregister_dev(intf, &wdm_class); | ||
694 | mutex_lock(&wdm_mutex); | ||
695 | desc = usb_get_intfdata(intf); | ||
696 | |||
697 | /* the spinlock makes sure no new urbs are generated in the callbacks */ | ||
698 | spin_lock_irqsave(&desc->iuspin, flags); | ||
699 | set_bit(WDM_DISCONNECTING, &desc->flags); | ||
700 | set_bit(WDM_READ, &desc->flags); | ||
701 | clear_bit(WDM_IN_USE, &desc->flags); | ||
702 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
703 | cancel_work_sync(&desc->rxwork); | ||
704 | kill_urbs(desc); | ||
705 | wake_up_all(&desc->wait); | ||
706 | if (!desc->count) | ||
707 | cleanup(desc); | ||
708 | mutex_unlock(&wdm_mutex); | ||
709 | } | ||
710 | |||
711 | static struct usb_driver wdm_driver = { | ||
712 | .name = "cdc_wdm", | ||
713 | .probe = wdm_probe, | ||
714 | .disconnect = wdm_disconnect, | ||
715 | .id_table = wdm_ids, | ||
716 | }; | ||
717 | |||
718 | /* --- low level module stuff --- */ | ||
719 | |||
720 | static int __init wdm_init(void) | ||
721 | { | ||
722 | int rv; | ||
723 | |||
724 | rv = usb_register(&wdm_driver); | ||
725 | |||
726 | return rv; | ||
727 | } | ||
728 | |||
729 | static void __exit wdm_exit(void) | ||
730 | { | ||
731 | usb_deregister(&wdm_driver); | ||
732 | } | ||
733 | |||
734 | module_init(wdm_init); | ||
735 | module_exit(wdm_exit); | ||
736 | |||
737 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
738 | MODULE_DESCRIPTION("USB Abstract Control Model driver for " | ||
739 | "USB WCM Device Management"); | ||
740 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 99e5a68a3f12..fae55a31e26d 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -156,6 +156,10 @@ static struct attribute *ep_dev_attrs[] = { | |||
156 | static struct attribute_group ep_dev_attr_grp = { | 156 | static struct attribute_group ep_dev_attr_grp = { |
157 | .attrs = ep_dev_attrs, | 157 | .attrs = ep_dev_attrs, |
158 | }; | 158 | }; |
159 | static struct attribute_group *ep_dev_groups[] = { | ||
160 | &ep_dev_attr_grp, | ||
161 | NULL | ||
162 | }; | ||
159 | 163 | ||
160 | static int usb_endpoint_major_init(void) | 164 | static int usb_endpoint_major_init(void) |
161 | { | 165 | { |
@@ -298,6 +302,7 @@ int usb_create_ep_files(struct device *parent, | |||
298 | 302 | ||
299 | ep_dev->desc = &endpoint->desc; | 303 | ep_dev->desc = &endpoint->desc; |
300 | ep_dev->udev = udev; | 304 | ep_dev->udev = udev; |
305 | ep_dev->dev.groups = ep_dev_groups; | ||
301 | ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor); | 306 | ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor); |
302 | ep_dev->dev.class = ep_class->class; | 307 | ep_dev->dev.class = ep_class->class; |
303 | ep_dev->dev.parent = parent; | 308 | ep_dev->dev.parent = parent; |
@@ -309,9 +314,6 @@ int usb_create_ep_files(struct device *parent, | |||
309 | retval = device_register(&ep_dev->dev); | 314 | retval = device_register(&ep_dev->dev); |
310 | if (retval) | 315 | if (retval) |
311 | goto error_chrdev; | 316 | goto error_chrdev; |
312 | retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | ||
313 | if (retval) | ||
314 | goto error_group; | ||
315 | 317 | ||
316 | /* create the symlink to the old-style "ep_XX" directory */ | 318 | /* create the symlink to the old-style "ep_XX" directory */ |
317 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | 319 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); |
@@ -322,8 +324,6 @@ int usb_create_ep_files(struct device *parent, | |||
322 | return retval; | 324 | return retval; |
323 | 325 | ||
324 | error_link: | 326 | error_link: |
325 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | ||
326 | error_group: | ||
327 | device_unregister(&ep_dev->dev); | 327 | device_unregister(&ep_dev->dev); |
328 | destroy_endpoint_class(); | 328 | destroy_endpoint_class(); |
329 | return retval; | 329 | return retval; |
@@ -348,7 +348,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | |||
348 | 348 | ||
349 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | 349 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); |
350 | sysfs_remove_link(&ep_dev->dev.parent->kobj, name); | 350 | sysfs_remove_link(&ep_dev->dev.parent->kobj, name); |
351 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | ||
352 | device_unregister(&ep_dev->dev); | 351 | device_unregister(&ep_dev->dev); |
353 | endpoint->ep_dev = NULL; | 352 | endpoint->ep_dev = NULL; |
354 | destroy_endpoint_class(); | 353 | destroy_endpoint_class(); |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index c1cb94e9f242..7e912f21fd36 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -155,9 +155,6 @@ static int generic_probe(struct usb_device *udev) | |||
155 | { | 155 | { |
156 | int err, c; | 156 | int err, c; |
157 | 157 | ||
158 | /* put device-specific files into sysfs */ | ||
159 | usb_create_sysfs_dev_files(udev); | ||
160 | |||
161 | /* Choose and set the configuration. This registers the interfaces | 158 | /* Choose and set the configuration. This registers the interfaces |
162 | * with the driver core and lets interface drivers bind to them. | 159 | * with the driver core and lets interface drivers bind to them. |
163 | */ | 160 | */ |
@@ -189,8 +186,6 @@ static void generic_disconnect(struct usb_device *udev) | |||
189 | * unconfigure the device */ | 186 | * unconfigure the device */ |
190 | if (udev->actconfig) | 187 | if (udev->actconfig) |
191 | usb_set_configuration(udev, -1); | 188 | usb_set_configuration(udev, -1); |
192 | |||
193 | usb_remove_sysfs_dev_files(udev); | ||
194 | } | 189 | } |
195 | 190 | ||
196 | #ifdef CONFIG_PM | 191 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bf10e9c4195e..42a436478b78 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -818,12 +818,12 @@ static int usb_register_bus(struct usb_bus *bus) | |||
818 | set_bit (busnum, busmap.busmap); | 818 | set_bit (busnum, busmap.busmap); |
819 | bus->busnum = busnum; | 819 | bus->busnum = busnum; |
820 | 820 | ||
821 | bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), | 821 | bus->dev = device_create_drvdata(usb_host_class, bus->controller, |
822 | "usb_host%d", busnum); | 822 | MKDEV(0, 0), bus, |
823 | "usb_host%d", busnum); | ||
823 | result = PTR_ERR(bus->dev); | 824 | result = PTR_ERR(bus->dev); |
824 | if (IS_ERR(bus->dev)) | 825 | if (IS_ERR(bus->dev)) |
825 | goto error_create_class_dev; | 826 | goto error_create_class_dev; |
826 | dev_set_drvdata(bus->dev, bus); | ||
827 | 827 | ||
828 | /* Add it to the local list of buses */ | 828 | /* Add it to the local list of buses */ |
829 | list_add (&bus->bus_list, &usb_bus_list); | 829 | list_add (&bus->bus_list, &usb_bus_list); |
@@ -924,6 +924,15 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
924 | return retval; | 924 | return retval; |
925 | } | 925 | } |
926 | 926 | ||
927 | void usb_enable_root_hub_irq (struct usb_bus *bus) | ||
928 | { | ||
929 | struct usb_hcd *hcd; | ||
930 | |||
931 | hcd = container_of (bus, struct usb_hcd, self); | ||
932 | if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT) | ||
933 | hcd->driver->hub_irq_enable (hcd); | ||
934 | } | ||
935 | |||
927 | 936 | ||
928 | /*-------------------------------------------------------------------------*/ | 937 | /*-------------------------------------------------------------------------*/ |
929 | 938 | ||
@@ -1684,19 +1693,30 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); | |||
1684 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) | 1693 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) |
1685 | { | 1694 | { |
1686 | struct usb_hcd *hcd = __hcd; | 1695 | struct usb_hcd *hcd = __hcd; |
1687 | int start = hcd->state; | 1696 | unsigned long flags; |
1697 | irqreturn_t rc; | ||
1688 | 1698 | ||
1689 | if (unlikely(start == HC_STATE_HALT || | 1699 | /* IRQF_DISABLED doesn't work correctly with shared IRQs |
1690 | !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) | 1700 | * when the first handler doesn't use it. So let's just |
1691 | return IRQ_NONE; | 1701 | * assume it's never used. |
1692 | if (hcd->driver->irq (hcd) == IRQ_NONE) | 1702 | */ |
1693 | return IRQ_NONE; | 1703 | local_irq_save(flags); |
1694 | 1704 | ||
1695 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 1705 | if (unlikely(hcd->state == HC_STATE_HALT || |
1706 | !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
1707 | rc = IRQ_NONE; | ||
1708 | } else if (hcd->driver->irq(hcd) == IRQ_NONE) { | ||
1709 | rc = IRQ_NONE; | ||
1710 | } else { | ||
1711 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
1712 | |||
1713 | if (unlikely(hcd->state == HC_STATE_HALT)) | ||
1714 | usb_hc_died(hcd); | ||
1715 | rc = IRQ_HANDLED; | ||
1716 | } | ||
1696 | 1717 | ||
1697 | if (unlikely(hcd->state == HC_STATE_HALT)) | 1718 | local_irq_restore(flags); |
1698 | usb_hc_died (hcd); | 1719 | return rc; |
1699 | return IRQ_HANDLED; | ||
1700 | } | 1720 | } |
1701 | 1721 | ||
1702 | /*-------------------------------------------------------------------------*/ | 1722 | /*-------------------------------------------------------------------------*/ |
@@ -1860,6 +1880,13 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1860 | 1880 | ||
1861 | /* enable irqs just before we start the controller */ | 1881 | /* enable irqs just before we start the controller */ |
1862 | if (hcd->driver->irq) { | 1882 | if (hcd->driver->irq) { |
1883 | |||
1884 | /* IRQF_DISABLED doesn't work as advertised when used together | ||
1885 | * with IRQF_SHARED. As usb_hcd_irq() will always disable | ||
1886 | * interrupts we can remove it here. | ||
1887 | */ | ||
1888 | irqflags &= ~IRQF_DISABLED; | ||
1889 | |||
1863 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | 1890 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
1864 | hcd->driver->description, hcd->self.busnum); | 1891 | hcd->driver->description, hcd->self.busnum); |
1865 | if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, | 1892 | if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1e4b81e9eb50..b9de1569b39e 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -210,9 +210,13 @@ struct hc_driver { | |||
210 | int (*bus_suspend)(struct usb_hcd *); | 210 | int (*bus_suspend)(struct usb_hcd *); |
211 | int (*bus_resume)(struct usb_hcd *); | 211 | int (*bus_resume)(struct usb_hcd *); |
212 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); | 212 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); |
213 | void (*hub_irq_enable)(struct usb_hcd *); | ||
214 | /* Needed only if port-change IRQs are level-triggered */ | ||
213 | 215 | ||
214 | /* force handover of high-speed port to full-speed companion */ | 216 | /* force handover of high-speed port to full-speed companion */ |
215 | void (*relinquish_port)(struct usb_hcd *, int); | 217 | void (*relinquish_port)(struct usb_hcd *, int); |
218 | /* has a port been handed over to a companion? */ | ||
219 | int (*port_handed_over)(struct usb_hcd *, int); | ||
216 | }; | 220 | }; |
217 | 221 | ||
218 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 222 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eb57fcc701d7..4cfe32a16c37 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub) | |||
644 | 644 | ||
645 | #ifdef CONFIG_PM | 645 | #ifdef CONFIG_PM |
646 | 646 | ||
647 | /* Try to identify which devices need USB-PERSIST handling */ | ||
648 | static int persistent_device(struct usb_device *udev) | ||
649 | { | ||
650 | int i; | ||
651 | int retval; | ||
652 | struct usb_host_config *actconfig; | ||
653 | |||
654 | /* Explicitly not marked persistent? */ | ||
655 | if (!udev->persist_enabled) | ||
656 | return 0; | ||
657 | |||
658 | /* No active config? */ | ||
659 | actconfig = udev->actconfig; | ||
660 | if (!actconfig) | ||
661 | return 0; | ||
662 | |||
663 | /* FIXME! We should check whether it's open here or not! */ | ||
664 | |||
665 | /* | ||
666 | * Check that all the interface drivers have a | ||
667 | * 'reset_resume' entrypoint | ||
668 | */ | ||
669 | retval = 0; | ||
670 | for (i = 0; i < actconfig->desc.bNumInterfaces; i++) { | ||
671 | struct usb_interface *intf; | ||
672 | struct usb_driver *driver; | ||
673 | |||
674 | intf = actconfig->interface[i]; | ||
675 | if (!intf->dev.driver) | ||
676 | continue; | ||
677 | driver = to_usb_driver(intf->dev.driver); | ||
678 | if (!driver->reset_resume) | ||
679 | return 0; | ||
680 | /* | ||
681 | * We have at least one driver, and that one | ||
682 | * has a reset_resume method. | ||
683 | */ | ||
684 | retval = 1; | ||
685 | } | ||
686 | return retval; | ||
687 | } | ||
688 | |||
647 | static void hub_restart(struct usb_hub *hub, int type) | 689 | static void hub_restart(struct usb_hub *hub, int type) |
648 | { | 690 | { |
649 | struct usb_device *hdev = hub->hdev; | 691 | struct usb_device *hdev = hub->hdev; |
@@ -671,26 +713,19 @@ static void hub_restart(struct usb_hub *hub, int type) | |||
671 | } | 713 | } |
672 | 714 | ||
673 | /* Was the power session lost while we were suspended? */ | 715 | /* Was the power session lost while we were suspended? */ |
674 | switch (type) { | 716 | status = hub_port_status(hub, port1, &portstatus, &portchange); |
675 | case HUB_RESET_RESUME: | ||
676 | portstatus = 0; | ||
677 | portchange = USB_PORT_STAT_C_CONNECTION; | ||
678 | break; | ||
679 | 717 | ||
680 | case HUB_RESET: | 718 | /* If the device is gone, khubd will handle it later */ |
681 | case HUB_RESUME: | 719 | if (status == 0 && !(portstatus & USB_PORT_STAT_CONNECTION)) |
682 | status = hub_port_status(hub, port1, | 720 | continue; |
683 | &portstatus, &portchange); | ||
684 | break; | ||
685 | } | ||
686 | 721 | ||
687 | /* For "USB_PERSIST"-enabled children we must | 722 | /* For "USB_PERSIST"-enabled children we must |
688 | * mark the child device for reset-resume and | 723 | * mark the child device for reset-resume and |
689 | * turn off the various status changes to prevent | 724 | * turn off the various status changes to prevent |
690 | * khubd from disconnecting it later. | 725 | * khubd from disconnecting it later. |
691 | */ | 726 | */ |
692 | if (udev->persist_enabled && status == 0 && | 727 | if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) && |
693 | !(portstatus & USB_PORT_STAT_ENABLE)) { | 728 | persistent_device(udev)) { |
694 | if (portchange & USB_PORT_STAT_C_ENABLE) | 729 | if (portchange & USB_PORT_STAT_C_ENABLE) |
695 | clear_port_feature(hub->hdev, port1, | 730 | clear_port_feature(hub->hdev, port1, |
696 | USB_PORT_FEAT_C_ENABLE); | 731 | USB_PORT_FEAT_C_ENABLE); |
@@ -1326,6 +1361,12 @@ void usb_disconnect(struct usb_device **pdev) | |||
1326 | 1361 | ||
1327 | usb_unlock_device(udev); | 1362 | usb_unlock_device(udev); |
1328 | 1363 | ||
1364 | /* Remove the device-specific files from sysfs. This must be | ||
1365 | * done with udev unlocked, because some of the attribute | ||
1366 | * routines try to acquire the device lock. | ||
1367 | */ | ||
1368 | usb_remove_sysfs_dev_files(udev); | ||
1369 | |||
1329 | /* Unregister the device. The device driver is responsible | 1370 | /* Unregister the device. The device driver is responsible |
1330 | * for removing the device files from usbfs and sysfs and for | 1371 | * for removing the device files from usbfs and sysfs and for |
1331 | * de-configuring the device. | 1372 | * de-configuring the device. |
@@ -1541,6 +1582,9 @@ int usb_new_device(struct usb_device *udev) | |||
1541 | goto fail; | 1582 | goto fail; |
1542 | } | 1583 | } |
1543 | 1584 | ||
1585 | /* put device-specific files into sysfs */ | ||
1586 | usb_create_sysfs_dev_files(udev); | ||
1587 | |||
1544 | /* Tell the world! */ | 1588 | /* Tell the world! */ |
1545 | announce_device(udev); | 1589 | announce_device(udev); |
1546 | return err; | 1590 | return err; |
@@ -2029,6 +2073,8 @@ int usb_port_resume(struct usb_device *udev) | |||
2029 | } | 2073 | } |
2030 | 2074 | ||
2031 | clear_bit(port1, hub->busy_bits); | 2075 | clear_bit(port1, hub->busy_bits); |
2076 | if (!hub->hdev->parent && !hub->busy_bits[0]) | ||
2077 | usb_enable_root_hub_irq(hub->hdev->bus); | ||
2032 | 2078 | ||
2033 | if (status == 0) | 2079 | if (status == 0) |
2034 | status = finish_port_resume(udev); | 2080 | status = finish_port_resume(udev); |
@@ -2744,7 +2790,11 @@ loop: | |||
2744 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 2790 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
2745 | break; | 2791 | break; |
2746 | } | 2792 | } |
2747 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); | 2793 | if (hub->hdev->parent || |
2794 | !hcd->driver->port_handed_over || | ||
2795 | !(hcd->driver->port_handed_over)(hcd, port1)) | ||
2796 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", | ||
2797 | port1); | ||
2748 | 2798 | ||
2749 | done: | 2799 | done: |
2750 | hub_port_disable(hub, port1, 1); | 2800 | hub_port_disable(hub, port1, 1); |
@@ -2954,6 +3004,11 @@ static void hub_events(void) | |||
2954 | 3004 | ||
2955 | hub->activating = 0; | 3005 | hub->activating = 0; |
2956 | 3006 | ||
3007 | /* If this is a root hub, tell the HCD it's okay to | ||
3008 | * re-enable port-change interrupts now. */ | ||
3009 | if (!hdev->parent && !hub->busy_bits[0]) | ||
3010 | usb_enable_root_hub_irq(hdev->bus); | ||
3011 | |||
2957 | loop_autopm: | 3012 | loop_autopm: |
2958 | /* Allow autosuspend if we're not going to run again */ | 3013 | /* Allow autosuspend if we're not going to run again */ |
2959 | if (list_empty(&hub->event_list)) | 3014 | if (list_empty(&hub->event_list)) |
@@ -3179,6 +3234,8 @@ int usb_reset_device(struct usb_device *udev) | |||
3179 | break; | 3234 | break; |
3180 | } | 3235 | } |
3181 | clear_bit(port1, parent_hub->busy_bits); | 3236 | clear_bit(port1, parent_hub->busy_bits); |
3237 | if (!parent_hdev->parent && !parent_hub->busy_bits[0]) | ||
3238 | usb_enable_root_hub_irq(parent_hdev->bus); | ||
3182 | 3239 | ||
3183 | if (ret < 0) | 3240 | if (ret < 0) |
3184 | goto re_enumerate; | 3241 | goto re_enumerate; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index e819e5359d57..fe47d145255a 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -394,7 +394,9 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
394 | if (!io->urbs) | 394 | if (!io->urbs) |
395 | goto nomem; | 395 | goto nomem; |
396 | 396 | ||
397 | urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; | 397 | urb_flags = URB_NO_INTERRUPT; |
398 | if (dma) | ||
399 | urb_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
398 | if (usb_pipein(pipe)) | 400 | if (usb_pipein(pipe)) |
399 | urb_flags |= URB_SHORT_NOT_OK; | 401 | urb_flags |= URB_SHORT_NOT_OK; |
400 | 402 | ||
@@ -1605,6 +1607,7 @@ free_interfaces: | |||
1605 | intf->dev.driver = NULL; | 1607 | intf->dev.driver = NULL; |
1606 | intf->dev.bus = &usb_bus_type; | 1608 | intf->dev.bus = &usb_bus_type; |
1607 | intf->dev.type = &usb_if_device_type; | 1609 | intf->dev.type = &usb_if_device_type; |
1610 | intf->dev.groups = usb_interface_groups; | ||
1608 | intf->dev.dma_mask = dev->dev.dma_mask; | 1611 | intf->dev.dma_mask = dev->dev.dma_mask; |
1609 | device_initialize(&intf->dev); | 1612 | device_initialize(&intf->dev); |
1610 | mark_quiesced(intf); | 1613 | mark_quiesced(intf); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 2e2019390290..c070b34b669d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -47,6 +47,13 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
47 | /* Edirol SD-20 */ | 47 | /* Edirol SD-20 */ |
48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, | 48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, |
49 | 49 | ||
50 | /* appletouch */ | ||
51 | { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
52 | |||
53 | /* Avision AV600U */ | ||
54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | ||
55 | USB_QUIRK_STRING_FETCH_255 }, | ||
56 | |||
50 | /* M-Systems Flash Disk Pioneers */ | 57 | /* M-Systems Flash Disk Pioneers */ |
51 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 58 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
52 | 59 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 5b20a60de8ba..5e1f5d55bf04 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -538,6 +538,46 @@ static struct attribute_group dev_attr_grp = { | |||
538 | .attrs = dev_attrs, | 538 | .attrs = dev_attrs, |
539 | }; | 539 | }; |
540 | 540 | ||
541 | /* When modifying this list, be sure to modify dev_string_attrs_are_visible() | ||
542 | * accordingly. | ||
543 | */ | ||
544 | static struct attribute *dev_string_attrs[] = { | ||
545 | &dev_attr_manufacturer.attr, | ||
546 | &dev_attr_product.attr, | ||
547 | &dev_attr_serial.attr, | ||
548 | NULL | ||
549 | }; | ||
550 | |||
551 | static mode_t dev_string_attrs_are_visible(struct kobject *kobj, | ||
552 | struct attribute *a, int n) | ||
553 | { | ||
554 | struct usb_device *udev = to_usb_device( | ||
555 | container_of(kobj, struct device, kobj)); | ||
556 | |||
557 | if (a == &dev_attr_manufacturer.attr) { | ||
558 | if (udev->manufacturer == NULL) | ||
559 | return 0; | ||
560 | } else if (a == &dev_attr_product.attr) { | ||
561 | if (udev->product == NULL) | ||
562 | return 0; | ||
563 | } else if (a == &dev_attr_serial.attr) { | ||
564 | if (udev->serial == NULL) | ||
565 | return 0; | ||
566 | } | ||
567 | return a->mode; | ||
568 | } | ||
569 | |||
570 | static struct attribute_group dev_string_attr_grp = { | ||
571 | .attrs = dev_string_attrs, | ||
572 | .is_visible = dev_string_attrs_are_visible, | ||
573 | }; | ||
574 | |||
575 | struct attribute_group *usb_device_groups[] = { | ||
576 | &dev_attr_grp, | ||
577 | &dev_string_attr_grp, | ||
578 | NULL | ||
579 | }; | ||
580 | |||
541 | /* Binary descriptors */ | 581 | /* Binary descriptors */ |
542 | 582 | ||
543 | static ssize_t | 583 | static ssize_t |
@@ -548,35 +588,33 @@ read_descriptors(struct kobject *kobj, struct bin_attribute *attr, | |||
548 | container_of(kobj, struct device, kobj)); | 588 | container_of(kobj, struct device, kobj)); |
549 | size_t nleft = count; | 589 | size_t nleft = count; |
550 | size_t srclen, n; | 590 | size_t srclen, n; |
591 | int cfgno; | ||
592 | void *src; | ||
551 | 593 | ||
552 | usb_lock_device(udev); | 594 | /* The binary attribute begins with the device descriptor. |
553 | 595 | * Following that are the raw descriptor entries for all the | |
554 | /* The binary attribute begins with the device descriptor */ | 596 | * configurations (config plus subsidiary descriptors). |
555 | srclen = sizeof(struct usb_device_descriptor); | ||
556 | if (off < srclen) { | ||
557 | n = min_t(size_t, nleft, srclen - off); | ||
558 | memcpy(buf, off + (char *) &udev->descriptor, n); | ||
559 | nleft -= n; | ||
560 | buf += n; | ||
561 | off = 0; | ||
562 | } else { | ||
563 | off -= srclen; | ||
564 | } | ||
565 | |||
566 | /* Then follows the raw descriptor entry for the current | ||
567 | * configuration (config plus subsidiary descriptors). | ||
568 | */ | 597 | */ |
569 | if (udev->actconfig) { | 598 | for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations && |
570 | int cfgno = udev->actconfig - udev->config; | 599 | nleft > 0; ++cfgno) { |
571 | 600 | if (cfgno < 0) { | |
572 | srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); | 601 | src = &udev->descriptor; |
602 | srclen = sizeof(struct usb_device_descriptor); | ||
603 | } else { | ||
604 | src = udev->rawdescriptors[cfgno]; | ||
605 | srclen = __le16_to_cpu(udev->config[cfgno].desc. | ||
606 | wTotalLength); | ||
607 | } | ||
573 | if (off < srclen) { | 608 | if (off < srclen) { |
574 | n = min_t(size_t, nleft, srclen - off); | 609 | n = min(nleft, srclen - (size_t) off); |
575 | memcpy(buf, off + udev->rawdescriptors[cfgno], n); | 610 | memcpy(buf, src + off, n); |
576 | nleft -= n; | 611 | nleft -= n; |
612 | buf += n; | ||
613 | off = 0; | ||
614 | } else { | ||
615 | off -= srclen; | ||
577 | } | 616 | } |
578 | } | 617 | } |
579 | usb_unlock_device(udev); | ||
580 | return count - nleft; | 618 | return count - nleft; |
581 | } | 619 | } |
582 | 620 | ||
@@ -591,10 +629,9 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
591 | struct device *dev = &udev->dev; | 629 | struct device *dev = &udev->dev; |
592 | int retval; | 630 | int retval; |
593 | 631 | ||
594 | retval = sysfs_create_group(&dev->kobj, &dev_attr_grp); | 632 | /* Unforunately these attributes cannot be created before |
595 | if (retval) | 633 | * the uevent is broadcast. |
596 | return retval; | 634 | */ |
597 | |||
598 | retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); | 635 | retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); |
599 | if (retval) | 636 | if (retval) |
600 | goto error; | 637 | goto error; |
@@ -607,21 +644,6 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
607 | if (retval) | 644 | if (retval) |
608 | goto error; | 645 | goto error; |
609 | 646 | ||
610 | if (udev->manufacturer) { | ||
611 | retval = device_create_file(dev, &dev_attr_manufacturer); | ||
612 | if (retval) | ||
613 | goto error; | ||
614 | } | ||
615 | if (udev->product) { | ||
616 | retval = device_create_file(dev, &dev_attr_product); | ||
617 | if (retval) | ||
618 | goto error; | ||
619 | } | ||
620 | if (udev->serial) { | ||
621 | retval = device_create_file(dev, &dev_attr_serial); | ||
622 | if (retval) | ||
623 | goto error; | ||
624 | } | ||
625 | retval = usb_create_ep_files(dev, &udev->ep0, udev); | 647 | retval = usb_create_ep_files(dev, &udev->ep0, udev); |
626 | if (retval) | 648 | if (retval) |
627 | goto error; | 649 | goto error; |
@@ -636,13 +658,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) | |||
636 | struct device *dev = &udev->dev; | 658 | struct device *dev = &udev->dev; |
637 | 659 | ||
638 | usb_remove_ep_files(&udev->ep0); | 660 | usb_remove_ep_files(&udev->ep0); |
639 | device_remove_file(dev, &dev_attr_manufacturer); | ||
640 | device_remove_file(dev, &dev_attr_product); | ||
641 | device_remove_file(dev, &dev_attr_serial); | ||
642 | remove_power_attributes(dev); | 661 | remove_power_attributes(dev); |
643 | remove_persist_attributes(dev); | 662 | remove_persist_attributes(dev); |
644 | device_remove_bin_file(dev, &dev_bin_attr_descriptors); | 663 | device_remove_bin_file(dev, &dev_bin_attr_descriptors); |
645 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); | ||
646 | } | 664 | } |
647 | 665 | ||
648 | /* Interface Accociation Descriptor fields */ | 666 | /* Interface Accociation Descriptor fields */ |
@@ -688,17 +706,15 @@ static ssize_t show_interface_string(struct device *dev, | |||
688 | struct device_attribute *attr, char *buf) | 706 | struct device_attribute *attr, char *buf) |
689 | { | 707 | { |
690 | struct usb_interface *intf; | 708 | struct usb_interface *intf; |
691 | struct usb_device *udev; | 709 | char *string; |
692 | int len; | ||
693 | 710 | ||
694 | intf = to_usb_interface(dev); | 711 | intf = to_usb_interface(dev); |
695 | udev = interface_to_usbdev(intf); | 712 | string = intf->cur_altsetting->string; |
696 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); | 713 | barrier(); /* The altsetting might change! */ |
697 | if (len < 0) | 714 | |
715 | if (!string) | ||
698 | return 0; | 716 | return 0; |
699 | buf[len] = '\n'; | 717 | return sprintf(buf, "%s\n", string); |
700 | buf[len+1] = 0; | ||
701 | return len+1; | ||
702 | } | 718 | } |
703 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); | 719 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); |
704 | 720 | ||
@@ -727,18 +743,6 @@ static ssize_t show_modalias(struct device *dev, | |||
727 | } | 743 | } |
728 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 744 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); |
729 | 745 | ||
730 | static struct attribute *intf_assoc_attrs[] = { | ||
731 | &dev_attr_iad_bFirstInterface.attr, | ||
732 | &dev_attr_iad_bInterfaceCount.attr, | ||
733 | &dev_attr_iad_bFunctionClass.attr, | ||
734 | &dev_attr_iad_bFunctionSubClass.attr, | ||
735 | &dev_attr_iad_bFunctionProtocol.attr, | ||
736 | NULL, | ||
737 | }; | ||
738 | static struct attribute_group intf_assoc_attr_grp = { | ||
739 | .attrs = intf_assoc_attrs, | ||
740 | }; | ||
741 | |||
742 | static struct attribute *intf_attrs[] = { | 746 | static struct attribute *intf_attrs[] = { |
743 | &dev_attr_bInterfaceNumber.attr, | 747 | &dev_attr_bInterfaceNumber.attr, |
744 | &dev_attr_bAlternateSetting.attr, | 748 | &dev_attr_bAlternateSetting.attr, |
@@ -753,6 +757,37 @@ static struct attribute_group intf_attr_grp = { | |||
753 | .attrs = intf_attrs, | 757 | .attrs = intf_attrs, |
754 | }; | 758 | }; |
755 | 759 | ||
760 | static struct attribute *intf_assoc_attrs[] = { | ||
761 | &dev_attr_iad_bFirstInterface.attr, | ||
762 | &dev_attr_iad_bInterfaceCount.attr, | ||
763 | &dev_attr_iad_bFunctionClass.attr, | ||
764 | &dev_attr_iad_bFunctionSubClass.attr, | ||
765 | &dev_attr_iad_bFunctionProtocol.attr, | ||
766 | NULL, | ||
767 | }; | ||
768 | |||
769 | static mode_t intf_assoc_attrs_are_visible(struct kobject *kobj, | ||
770 | struct attribute *a, int n) | ||
771 | { | ||
772 | struct usb_interface *intf = to_usb_interface( | ||
773 | container_of(kobj, struct device, kobj)); | ||
774 | |||
775 | if (intf->intf_assoc == NULL) | ||
776 | return 0; | ||
777 | return a->mode; | ||
778 | } | ||
779 | |||
780 | static struct attribute_group intf_assoc_attr_grp = { | ||
781 | .attrs = intf_assoc_attrs, | ||
782 | .is_visible = intf_assoc_attrs_are_visible, | ||
783 | }; | ||
784 | |||
785 | struct attribute_group *usb_interface_groups[] = { | ||
786 | &intf_attr_grp, | ||
787 | &intf_assoc_attr_grp, | ||
788 | NULL | ||
789 | }; | ||
790 | |||
756 | static inline void usb_create_intf_ep_files(struct usb_interface *intf, | 791 | static inline void usb_create_intf_ep_files(struct usb_interface *intf, |
757 | struct usb_device *udev) | 792 | struct usb_device *udev) |
758 | { | 793 | { |
@@ -777,23 +812,21 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf) | |||
777 | 812 | ||
778 | int usb_create_sysfs_intf_files(struct usb_interface *intf) | 813 | int usb_create_sysfs_intf_files(struct usb_interface *intf) |
779 | { | 814 | { |
780 | struct device *dev = &intf->dev; | ||
781 | struct usb_device *udev = interface_to_usbdev(intf); | 815 | struct usb_device *udev = interface_to_usbdev(intf); |
782 | struct usb_host_interface *alt = intf->cur_altsetting; | 816 | struct usb_host_interface *alt = intf->cur_altsetting; |
783 | int retval; | 817 | int retval; |
784 | 818 | ||
785 | if (intf->sysfs_files_created) | 819 | if (intf->sysfs_files_created) |
786 | return 0; | 820 | return 0; |
787 | retval = sysfs_create_group(&dev->kobj, &intf_attr_grp); | ||
788 | if (retval) | ||
789 | return retval; | ||
790 | 821 | ||
822 | /* The interface string may be present in some altsettings | ||
823 | * and missing in others. Hence its attribute cannot be created | ||
824 | * before the uevent is broadcast. | ||
825 | */ | ||
791 | if (alt->string == NULL) | 826 | if (alt->string == NULL) |
792 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | 827 | alt->string = usb_cache_string(udev, alt->desc.iInterface); |
793 | if (alt->string) | 828 | if (alt->string) |
794 | retval = device_create_file(dev, &dev_attr_interface); | 829 | retval = device_create_file(&intf->dev, &dev_attr_interface); |
795 | if (intf->intf_assoc) | ||
796 | retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp); | ||
797 | usb_create_intf_ep_files(intf, udev); | 830 | usb_create_intf_ep_files(intf, udev); |
798 | intf->sysfs_files_created = 1; | 831 | intf->sysfs_files_created = 1; |
799 | return 0; | 832 | return 0; |
@@ -807,7 +840,5 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf) | |||
807 | return; | 840 | return; |
808 | usb_remove_intf_ep_files(intf); | 841 | usb_remove_intf_ep_files(intf); |
809 | device_remove_file(dev, &dev_attr_interface); | 842 | device_remove_file(dev, &dev_attr_interface); |
810 | sysfs_remove_group(&dev->kobj, &intf_attr_grp); | ||
811 | sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp); | ||
812 | intf->sysfs_files_created = 0; | 843 | intf->sysfs_files_created = 0; |
813 | } | 844 | } |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 1f0db51190cc..325774375837 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -291,6 +291,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
291 | device_initialize(&dev->dev); | 291 | device_initialize(&dev->dev); |
292 | dev->dev.bus = &usb_bus_type; | 292 | dev->dev.bus = &usb_bus_type; |
293 | dev->dev.type = &usb_device_type; | 293 | dev->dev.type = &usb_device_type; |
294 | dev->dev.groups = usb_device_groups; | ||
294 | dev->dev.dma_mask = bus->controller->dma_mask; | 295 | dev->dev.dma_mask = bus->controller->dma_mask; |
295 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 296 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
296 | dev->state = USB_STATE_ATTACHED; | 297 | dev->state = USB_STATE_ATTACHED; |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1bf8ccb9c58d..1a8bc21c335e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -130,6 +130,10 @@ static inline int is_active(const struct usb_interface *f) | |||
130 | /* for labeling diagnostics */ | 130 | /* for labeling diagnostics */ |
131 | extern const char *usbcore_name; | 131 | extern const char *usbcore_name; |
132 | 132 | ||
133 | /* sysfs stuff */ | ||
134 | extern struct attribute_group *usb_device_groups[]; | ||
135 | extern struct attribute_group *usb_interface_groups[]; | ||
136 | |||
133 | /* usbfs stuff */ | 137 | /* usbfs stuff */ |
134 | extern struct mutex usbfs_mutex; | 138 | extern struct mutex usbfs_mutex; |
135 | extern struct usb_driver usbfs_driver; | 139 | extern struct usb_driver usbfs_driver; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f7b54651dd42..6e784d2db423 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -231,6 +231,26 @@ config SUPERH_BUILT_IN_M66592 | |||
231 | However, this problem is improved if change a value of | 231 | However, this problem is improved if change a value of |
232 | NET_IP_ALIGN to 4. | 232 | NET_IP_ALIGN to 4. |
233 | 233 | ||
234 | config USB_GADGET_PXA27X | ||
235 | boolean "PXA 27x" | ||
236 | depends on ARCH_PXA && PXA27x | ||
237 | help | ||
238 | Intel's PXA 27x series XScale ARM v5TE processors include | ||
239 | an integrated full speed USB 1.1 device controller. | ||
240 | |||
241 | It has up to 23 endpoints, as well as endpoint zero (for | ||
242 | control transfers). | ||
243 | |||
244 | Say "y" to link the driver statically, or "m" to build a | ||
245 | dynamically linked module called "pxa27x_udc" and force all | ||
246 | gadget drivers to also be dynamically linked. | ||
247 | |||
248 | config USB_PXA27X | ||
249 | tristate | ||
250 | depends on USB_GADGET_PXA27X | ||
251 | default USB_GADGET | ||
252 | select USB_GADGET_SELECTED | ||
253 | |||
234 | config USB_GADGET_GOKU | 254 | config USB_GADGET_GOKU |
235 | boolean "Toshiba TC86C001 'Goku-S'" | 255 | boolean "Toshiba TC86C001 'Goku-S'" |
236 | depends on PCI | 256 | depends on PCI |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index c3aab80b6c76..12357255d740 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | |||
9 | obj-$(CONFIG_USB_NET2280) += net2280.o | 9 | obj-$(CONFIG_USB_NET2280) += net2280.o |
10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | 10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o |
11 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o | 11 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o |
12 | obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o | ||
12 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | 13 | obj-$(CONFIG_USB_GOKU) += goku_udc.o |
13 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | 14 | obj-$(CONFIG_USB_OMAP) += omap_udc.o |
14 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o | 15 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index ce337cb5d137..f261d2a9a5f0 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -3251,7 +3251,7 @@ static int udc_pci_probe( | |||
3251 | /* pci setup */ | 3251 | /* pci setup */ |
3252 | if (pci_enable_device(pdev) < 0) { | 3252 | if (pci_enable_device(pdev) < 0) { |
3253 | kfree(dev); | 3253 | kfree(dev); |
3254 | dev = 0; | 3254 | dev = NULL; |
3255 | retval = -ENODEV; | 3255 | retval = -ENODEV; |
3256 | goto finished; | 3256 | goto finished; |
3257 | } | 3257 | } |
@@ -3264,7 +3264,7 @@ static int udc_pci_probe( | |||
3264 | if (!request_mem_region(resource, len, name)) { | 3264 | if (!request_mem_region(resource, len, name)) { |
3265 | dev_dbg(&pdev->dev, "pci device used already\n"); | 3265 | dev_dbg(&pdev->dev, "pci device used already\n"); |
3266 | kfree(dev); | 3266 | kfree(dev); |
3267 | dev = 0; | 3267 | dev = NULL; |
3268 | retval = -EBUSY; | 3268 | retval = -EBUSY; |
3269 | goto finished; | 3269 | goto finished; |
3270 | } | 3270 | } |
@@ -3274,7 +3274,7 @@ static int udc_pci_probe( | |||
3274 | if (dev->virt_addr == NULL) { | 3274 | if (dev->virt_addr == NULL) { |
3275 | dev_dbg(&pdev->dev, "start address cannot be mapped\n"); | 3275 | dev_dbg(&pdev->dev, "start address cannot be mapped\n"); |
3276 | kfree(dev); | 3276 | kfree(dev); |
3277 | dev = 0; | 3277 | dev = NULL; |
3278 | retval = -EFAULT; | 3278 | retval = -EFAULT; |
3279 | goto finished; | 3279 | goto finished; |
3280 | } | 3280 | } |
@@ -3282,7 +3282,7 @@ static int udc_pci_probe( | |||
3282 | if (!pdev->irq) { | 3282 | if (!pdev->irq) { |
3283 | dev_err(&dev->pdev->dev, "irq not set\n"); | 3283 | dev_err(&dev->pdev->dev, "irq not set\n"); |
3284 | kfree(dev); | 3284 | kfree(dev); |
3285 | dev = 0; | 3285 | dev = NULL; |
3286 | retval = -ENODEV; | 3286 | retval = -ENODEV; |
3287 | goto finished; | 3287 | goto finished; |
3288 | } | 3288 | } |
@@ -3290,7 +3290,7 @@ static int udc_pci_probe( | |||
3290 | if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { | 3290 | if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { |
3291 | dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); | 3291 | dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); |
3292 | kfree(dev); | 3292 | kfree(dev); |
3293 | dev = 0; | 3293 | dev = NULL; |
3294 | retval = -EBUSY; | 3294 | retval = -EBUSY; |
3295 | goto finished; | 3295 | goto finished; |
3296 | } | 3296 | } |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e756023362c2..07e5a0b5dcda 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -649,7 +649,13 @@ static int usba_ep_disable(struct usb_ep *_ep) | |||
649 | 649 | ||
650 | if (!ep->desc) { | 650 | if (!ep->desc) { |
651 | spin_unlock_irqrestore(&udc->lock, flags); | 651 | spin_unlock_irqrestore(&udc->lock, flags); |
652 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); | 652 | /* REVISIT because this driver disables endpoints in |
653 | * reset_all_endpoints() before calling disconnect(), | ||
654 | * most gadget drivers would trigger this non-error ... | ||
655 | */ | ||
656 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) | ||
657 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", | ||
658 | ep->ep.name); | ||
653 | return -EINVAL; | 659 | return -EINVAL; |
654 | } | 660 | } |
655 | ep->desc = NULL; | 661 | ep->desc = NULL; |
@@ -1032,8 +1038,6 @@ static struct usba_udc the_udc = { | |||
1032 | .release = nop_release, | 1038 | .release = nop_release, |
1033 | }, | 1039 | }, |
1034 | }, | 1040 | }, |
1035 | |||
1036 | .lock = SPIN_LOCK_UNLOCKED, | ||
1037 | }; | 1041 | }; |
1038 | 1042 | ||
1039 | /* | 1043 | /* |
@@ -1052,6 +1056,12 @@ static void reset_all_endpoints(struct usba_udc *udc) | |||
1052 | request_complete(ep, req, -ECONNRESET); | 1056 | request_complete(ep, req, -ECONNRESET); |
1053 | } | 1057 | } |
1054 | 1058 | ||
1059 | /* NOTE: normally, the next call to the gadget driver is in | ||
1060 | * charge of disabling endpoints... usually disconnect(). | ||
1061 | * The exception would be entering a high speed test mode. | ||
1062 | * | ||
1063 | * FIXME remove this code ... and retest thoroughly. | ||
1064 | */ | ||
1055 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | 1065 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { |
1056 | if (ep->desc) { | 1066 | if (ep->desc) { |
1057 | spin_unlock(&udc->lock); | 1067 | spin_unlock(&udc->lock); |
@@ -1219,7 +1229,7 @@ static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | |||
1219 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | 1229 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, |
1220 | struct usb_ctrlrequest *crq) | 1230 | struct usb_ctrlrequest *crq) |
1221 | { | 1231 | { |
1222 | int retval = 0;; | 1232 | int retval = 0; |
1223 | 1233 | ||
1224 | switch (crq->bRequest) { | 1234 | switch (crq->bRequest) { |
1225 | case USB_REQ_GET_STATUS: { | 1235 | case USB_REQ_GET_STATUS: { |
@@ -1693,6 +1703,14 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1693 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | 1703 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); |
1694 | reset_all_endpoints(udc); | 1704 | reset_all_endpoints(udc); |
1695 | 1705 | ||
1706 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
1707 | && udc->driver->disconnect) { | ||
1708 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1709 | spin_unlock(&udc->lock); | ||
1710 | udc->driver->disconnect(&udc->gadget); | ||
1711 | spin_lock(&udc->lock); | ||
1712 | } | ||
1713 | |||
1696 | if (status & USBA_HIGH_SPEED) { | 1714 | if (status & USBA_HIGH_SPEED) { |
1697 | DBG(DBG_BUS, "High-speed bus reset detected\n"); | 1715 | DBG(DBG_BUS, "High-speed bus reset detected\n"); |
1698 | udc->gadget.speed = USB_SPEED_HIGH; | 1716 | udc->gadget.speed = USB_SPEED_HIGH; |
@@ -1716,9 +1734,13 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1716 | | USBA_DET_SUSPEND | 1734 | | USBA_DET_SUSPEND |
1717 | | USBA_END_OF_RESUME)); | 1735 | | USBA_END_OF_RESUME)); |
1718 | 1736 | ||
1737 | /* | ||
1738 | * Unclear why we hit this irregularly, e.g. in usbtest, | ||
1739 | * but it's clearly harmless... | ||
1740 | */ | ||
1719 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) | 1741 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) |
1720 | dev_warn(&udc->pdev->dev, | 1742 | dev_dbg(&udc->pdev->dev, |
1721 | "WARNING: EP0 configuration is invalid!\n"); | 1743 | "ODD: EP0 configuration is invalid!\n"); |
1722 | } | 1744 | } |
1723 | 1745 | ||
1724 | spin_unlock(&udc->lock); | 1746 | spin_unlock(&udc->lock); |
@@ -1751,9 +1773,11 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
1751 | reset_all_endpoints(udc); | 1773 | reset_all_endpoints(udc); |
1752 | toggle_bias(0); | 1774 | toggle_bias(0); |
1753 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1775 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1754 | spin_unlock(&udc->lock); | 1776 | if (udc->driver->disconnect) { |
1755 | udc->driver->disconnect(&udc->gadget); | 1777 | spin_unlock(&udc->lock); |
1756 | spin_lock(&udc->lock); | 1778 | udc->driver->disconnect(&udc->gadget); |
1779 | spin_lock(&udc->lock); | ||
1780 | } | ||
1757 | } | 1781 | } |
1758 | udc->vbus_prev = vbus; | 1782 | udc->vbus_prev = vbus; |
1759 | } | 1783 | } |
@@ -1825,7 +1849,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1825 | 1849 | ||
1826 | if (!udc->pdev) | 1850 | if (!udc->pdev) |
1827 | return -ENODEV; | 1851 | return -ENODEV; |
1828 | if (driver != udc->driver) | 1852 | if (driver != udc->driver || !driver->unbind) |
1829 | return -EINVAL; | 1853 | return -EINVAL; |
1830 | 1854 | ||
1831 | if (udc->vbus_pin != -1) | 1855 | if (udc->vbus_pin != -1) |
@@ -1840,6 +1864,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1840 | toggle_bias(0); | 1864 | toggle_bias(0); |
1841 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1865 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1842 | 1866 | ||
1867 | if (udc->driver->disconnect) | ||
1868 | udc->driver->disconnect(&udc->gadget); | ||
1869 | |||
1843 | driver->unbind(&udc->gadget); | 1870 | driver->unbind(&udc->gadget); |
1844 | udc->gadget.dev.driver = NULL; | 1871 | udc->gadget.dev.driver = NULL; |
1845 | udc->driver = NULL; | 1872 | udc->driver = NULL; |
@@ -1879,6 +1906,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
1879 | goto err_get_hclk; | 1906 | goto err_get_hclk; |
1880 | } | 1907 | } |
1881 | 1908 | ||
1909 | spin_lock_init(&udc->lock); | ||
1882 | udc->pdev = pdev; | 1910 | udc->pdev = pdev; |
1883 | udc->pclk = pclk; | 1911 | udc->pclk = pclk; |
1884 | udc->hclk = hclk; | 1912 | udc->hclk = hclk; |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index bb93bdd76593..8d61ea67a817 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -235,10 +235,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
235 | #define DEV_CONFIG_CDC | 235 | #define DEV_CONFIG_CDC |
236 | #endif | 236 | #endif |
237 | 237 | ||
238 | #ifdef CONFIG_USB_GADGET_PXA27X | ||
239 | #define DEV_CONFIG_CDC | ||
240 | #endif | ||
241 | |||
242 | #ifdef CONFIG_USB_GADGET_S3C2410 | 238 | #ifdef CONFIG_USB_GADGET_S3C2410 |
243 | #define DEV_CONFIG_CDC | 239 | #define DEV_CONFIG_CDC |
244 | #endif | 240 | #endif |
@@ -270,6 +266,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
270 | #define DEV_CONFIG_SUBSET | 266 | #define DEV_CONFIG_SUBSET |
271 | #endif | 267 | #endif |
272 | 268 | ||
269 | #ifdef CONFIG_USB_GADGET_PXA27X | ||
270 | #define DEV_CONFIG_SUBSET | ||
271 | #endif | ||
272 | |||
273 | #ifdef CONFIG_USB_GADGET_SUPERH | 273 | #ifdef CONFIG_USB_GADGET_SUPERH |
274 | #define DEV_CONFIG_SUBSET | 274 | #define DEV_CONFIG_SUBSET |
275 | #endif | 275 | #endif |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index bf3f946fd455..47bb9f09a1aa 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -2307,6 +2307,29 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg) | |||
2307 | return rc; | 2307 | return rc; |
2308 | } | 2308 | } |
2309 | 2309 | ||
2310 | static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) | ||
2311 | { | ||
2312 | int rc; | ||
2313 | |||
2314 | DBG(fsg, "bulk-in set wedge\n"); | ||
2315 | rc = usb_ep_set_wedge(fsg->bulk_in); | ||
2316 | if (rc == -EAGAIN) | ||
2317 | VDBG(fsg, "delayed bulk-in endpoint wedge\n"); | ||
2318 | while (rc != 0) { | ||
2319 | if (rc != -EAGAIN) { | ||
2320 | WARN(fsg, "usb_ep_set_wedge -> %d\n", rc); | ||
2321 | rc = 0; | ||
2322 | break; | ||
2323 | } | ||
2324 | |||
2325 | /* Wait for a short time and then try again */ | ||
2326 | if (msleep_interruptible(100) != 0) | ||
2327 | return -EINTR; | ||
2328 | rc = usb_ep_set_wedge(fsg->bulk_in); | ||
2329 | } | ||
2330 | return rc; | ||
2331 | } | ||
2332 | |||
2310 | static int pad_with_zeros(struct fsg_dev *fsg) | 2333 | static int pad_with_zeros(struct fsg_dev *fsg) |
2311 | { | 2334 | { |
2312 | struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; | 2335 | struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; |
@@ -2957,7 +2980,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2957 | * We aren't required to halt the OUT endpoint; instead | 2980 | * We aren't required to halt the OUT endpoint; instead |
2958 | * we can simply accept and discard any data received | 2981 | * we can simply accept and discard any data received |
2959 | * until the next reset. */ | 2982 | * until the next reset. */ |
2960 | halt_bulk_in_endpoint(fsg); | 2983 | wedge_bulk_in_endpoint(fsg); |
2961 | set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | 2984 | set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); |
2962 | return -EINVAL; | 2985 | return -EINVAL; |
2963 | } | 2986 | } |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 651b82701394..18687543d7fa 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -1627,7 +1627,9 @@ static int reset_queues(struct fsl_udc *udc) | |||
1627 | udc_reset_ep_queue(udc, pipe); | 1627 | udc_reset_ep_queue(udc, pipe); |
1628 | 1628 | ||
1629 | /* report disconnect; the driver is already quiesced */ | 1629 | /* report disconnect; the driver is already quiesced */ |
1630 | spin_unlock(&udc->lock); | ||
1630 | udc->driver->disconnect(&udc->gadget); | 1631 | udc->driver->disconnect(&udc->gadget); |
1632 | spin_lock(&udc->lock); | ||
1631 | 1633 | ||
1632 | return 0; | 1634 | return 0; |
1633 | } | 1635 | } |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c new file mode 100644 index 000000000000..e02bfd4df3a6 --- /dev/null +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -0,0 +1,2404 @@ | |||
1 | /* | ||
2 | * Handles the Intel 27x USB Device Controller (UDC) | ||
3 | * | ||
4 | * Inspired by original driver by Frank Becker, David Brownell, and others. | ||
5 | * Copyright (C) 2008 Robert Jarzmik | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/version.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/clk.h> | ||
33 | #include <linux/irq.h> | ||
34 | |||
35 | #include <asm/byteorder.h> | ||
36 | #include <asm/hardware.h> | ||
37 | |||
38 | #include <linux/usb.h> | ||
39 | #include <linux/usb/ch9.h> | ||
40 | #include <linux/usb/gadget.h> | ||
41 | |||
42 | #include <asm/arch/udc.h> | ||
43 | |||
44 | #include "pxa27x_udc.h" | ||
45 | |||
46 | /* | ||
47 | * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x | ||
48 | * series processors. | ||
49 | * | ||
50 | * Such controller drivers work with a gadget driver. The gadget driver | ||
51 | * returns descriptors, implements configuration and data protocols used | ||
52 | * by the host to interact with this device, and allocates endpoints to | ||
53 | * the different protocol interfaces. The controller driver virtualizes | ||
54 | * usb hardware so that the gadget drivers will be more portable. | ||
55 | * | ||
56 | * This UDC hardware wants to implement a bit too much USB protocol. The | ||
57 | * biggest issues are: that the endpoints have to be set up before the | ||
58 | * controller can be enabled (minor, and not uncommon); and each endpoint | ||
59 | * can only have one configuration, interface and alternative interface | ||
60 | * number (major, and very unusual). Once set up, these cannot be changed | ||
61 | * without a controller reset. | ||
62 | * | ||
63 | * The workaround is to setup all combinations necessary for the gadgets which | ||
64 | * will work with this driver. This is done in pxa_udc structure, statically. | ||
65 | * See pxa_udc, udc_usb_ep versus pxa_ep, and matching function find_pxa_ep. | ||
66 | * (You could modify this if needed. Some drivers have a "fifo_mode" module | ||
67 | * parameter to facilitate such changes.) | ||
68 | * | ||
69 | * The combinations have been tested with these gadgets : | ||
70 | * - zero gadget | ||
71 | * - file storage gadget | ||
72 | * - ether gadget | ||
73 | * | ||
74 | * The driver doesn't use DMA, only IO access and IRQ callbacks. No use is | ||
75 | * made of UDC's double buffering either. USB "On-The-Go" is not implemented. | ||
76 | * | ||
77 | * All the requests are handled the same way : | ||
78 | * - the drivers tries to handle the request directly to the IO | ||
79 | * - if the IO fifo is not big enough, the remaining is send/received in | ||
80 | * interrupt handling. | ||
81 | */ | ||
82 | |||
83 | #define DRIVER_VERSION "2008-04-18" | ||
84 | #define DRIVER_DESC "PXA 27x USB Device Controller driver" | ||
85 | |||
86 | static const char driver_name[] = "pxa27x_udc"; | ||
87 | static struct pxa_udc *the_controller; | ||
88 | |||
89 | static void handle_ep(struct pxa_ep *ep); | ||
90 | |||
91 | /* | ||
92 | * Debug filesystem | ||
93 | */ | ||
94 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
95 | |||
96 | #include <linux/debugfs.h> | ||
97 | #include <linux/uaccess.h> | ||
98 | #include <linux/seq_file.h> | ||
99 | |||
100 | static int state_dbg_show(struct seq_file *s, void *p) | ||
101 | { | ||
102 | struct pxa_udc *udc = s->private; | ||
103 | int pos = 0, ret; | ||
104 | u32 tmp; | ||
105 | |||
106 | ret = -ENODEV; | ||
107 | if (!udc->driver) | ||
108 | goto out; | ||
109 | |||
110 | /* basic device status */ | ||
111 | pos += seq_printf(s, DRIVER_DESC "\n" | ||
112 | "%s version: %s\nGadget driver: %s\n", | ||
113 | driver_name, DRIVER_VERSION, | ||
114 | udc->driver ? udc->driver->driver.name : "(none)"); | ||
115 | |||
116 | tmp = udc_readl(udc, UDCCR); | ||
117 | pos += seq_printf(s, | ||
118 | "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), " | ||
119 | "con=%d,inter=%d,altinter=%d\n", tmp, | ||
120 | (tmp & UDCCR_OEN) ? " oen":"", | ||
121 | (tmp & UDCCR_AALTHNP) ? " aalthnp":"", | ||
122 | (tmp & UDCCR_AHNP) ? " rem" : "", | ||
123 | (tmp & UDCCR_BHNP) ? " rstir" : "", | ||
124 | (tmp & UDCCR_DWRE) ? " dwre" : "", | ||
125 | (tmp & UDCCR_SMAC) ? " smac" : "", | ||
126 | (tmp & UDCCR_EMCE) ? " emce" : "", | ||
127 | (tmp & UDCCR_UDR) ? " udr" : "", | ||
128 | (tmp & UDCCR_UDA) ? " uda" : "", | ||
129 | (tmp & UDCCR_UDE) ? " ude" : "", | ||
130 | (tmp & UDCCR_ACN) >> UDCCR_ACN_S, | ||
131 | (tmp & UDCCR_AIN) >> UDCCR_AIN_S, | ||
132 | (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S); | ||
133 | /* registers for device and ep0 */ | ||
134 | pos += seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n", | ||
135 | udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1)); | ||
136 | pos += seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n", | ||
137 | udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1)); | ||
138 | pos += seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR)); | ||
139 | pos += seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, " | ||
140 | "reconfig=%lu\n", | ||
141 | udc->stats.irqs_reset, udc->stats.irqs_suspend, | ||
142 | udc->stats.irqs_resume, udc->stats.irqs_reconfig); | ||
143 | |||
144 | ret = 0; | ||
145 | out: | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | static int queues_dbg_show(struct seq_file *s, void *p) | ||
150 | { | ||
151 | struct pxa_udc *udc = s->private; | ||
152 | struct pxa_ep *ep; | ||
153 | struct pxa27x_request *req; | ||
154 | int pos = 0, i, maxpkt, ret; | ||
155 | |||
156 | ret = -ENODEV; | ||
157 | if (!udc->driver) | ||
158 | goto out; | ||
159 | |||
160 | /* dump endpoint queues */ | ||
161 | for (i = 0; i < NR_PXA_ENDPOINTS; i++) { | ||
162 | ep = &udc->pxa_ep[i]; | ||
163 | maxpkt = ep->fifo_size; | ||
164 | pos += seq_printf(s, "%-12s max_pkt=%d %s\n", | ||
165 | EPNAME(ep), maxpkt, "pio"); | ||
166 | |||
167 | if (list_empty(&ep->queue)) { | ||
168 | pos += seq_printf(s, "\t(nothing queued)\n"); | ||
169 | continue; | ||
170 | } | ||
171 | |||
172 | list_for_each_entry(req, &ep->queue, queue) { | ||
173 | pos += seq_printf(s, "\treq %p len %d/%d buf %p\n", | ||
174 | &req->req, req->req.actual, | ||
175 | req->req.length, req->req.buf); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | ret = 0; | ||
180 | out: | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int eps_dbg_show(struct seq_file *s, void *p) | ||
185 | { | ||
186 | struct pxa_udc *udc = s->private; | ||
187 | struct pxa_ep *ep; | ||
188 | int pos = 0, i, ret; | ||
189 | u32 tmp; | ||
190 | |||
191 | ret = -ENODEV; | ||
192 | if (!udc->driver) | ||
193 | goto out; | ||
194 | |||
195 | ep = &udc->pxa_ep[0]; | ||
196 | tmp = udc_ep_readl(ep, UDCCSR); | ||
197 | pos += seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", tmp, | ||
198 | (tmp & UDCCSR0_SA) ? " sa" : "", | ||
199 | (tmp & UDCCSR0_RNE) ? " rne" : "", | ||
200 | (tmp & UDCCSR0_FST) ? " fst" : "", | ||
201 | (tmp & UDCCSR0_SST) ? " sst" : "", | ||
202 | (tmp & UDCCSR0_DME) ? " dme" : "", | ||
203 | (tmp & UDCCSR0_IPR) ? " ipr" : "", | ||
204 | (tmp & UDCCSR0_OPC) ? " opc" : ""); | ||
205 | for (i = 0; i < NR_PXA_ENDPOINTS; i++) { | ||
206 | ep = &udc->pxa_ep[i]; | ||
207 | tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR); | ||
208 | pos += seq_printf(s, "%-12s: " | ||
209 | "IN %lu(%lu reqs), OUT %lu(%lu reqs), " | ||
210 | "irqs=%lu, udccr=0x%08x, udccsr=0x%03x, " | ||
211 | "udcbcr=%d\n", | ||
212 | EPNAME(ep), | ||
213 | ep->stats.in_bytes, ep->stats.in_ops, | ||
214 | ep->stats.out_bytes, ep->stats.out_ops, | ||
215 | ep->stats.irqs, | ||
216 | tmp, udc_ep_readl(ep, UDCCSR), | ||
217 | udc_ep_readl(ep, UDCBCR)); | ||
218 | } | ||
219 | |||
220 | ret = 0; | ||
221 | out: | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static int eps_dbg_open(struct inode *inode, struct file *file) | ||
226 | { | ||
227 | return single_open(file, eps_dbg_show, inode->i_private); | ||
228 | } | ||
229 | |||
230 | static int queues_dbg_open(struct inode *inode, struct file *file) | ||
231 | { | ||
232 | return single_open(file, queues_dbg_show, inode->i_private); | ||
233 | } | ||
234 | |||
235 | static int state_dbg_open(struct inode *inode, struct file *file) | ||
236 | { | ||
237 | return single_open(file, state_dbg_show, inode->i_private); | ||
238 | } | ||
239 | |||
240 | static const struct file_operations state_dbg_fops = { | ||
241 | .owner = THIS_MODULE, | ||
242 | .open = state_dbg_open, | ||
243 | .llseek = seq_lseek, | ||
244 | .read = seq_read, | ||
245 | .release = single_release, | ||
246 | }; | ||
247 | |||
248 | static const struct file_operations queues_dbg_fops = { | ||
249 | .owner = THIS_MODULE, | ||
250 | .open = queues_dbg_open, | ||
251 | .llseek = seq_lseek, | ||
252 | .read = seq_read, | ||
253 | .release = single_release, | ||
254 | }; | ||
255 | |||
256 | static const struct file_operations eps_dbg_fops = { | ||
257 | .owner = THIS_MODULE, | ||
258 | .open = eps_dbg_open, | ||
259 | .llseek = seq_lseek, | ||
260 | .read = seq_read, | ||
261 | .release = single_release, | ||
262 | }; | ||
263 | |||
264 | static void pxa_init_debugfs(struct pxa_udc *udc) | ||
265 | { | ||
266 | struct dentry *root, *state, *queues, *eps; | ||
267 | |||
268 | root = debugfs_create_dir(udc->gadget.name, NULL); | ||
269 | if (IS_ERR(root) || !root) | ||
270 | goto err_root; | ||
271 | |||
272 | state = debugfs_create_file("udcstate", 0400, root, udc, | ||
273 | &state_dbg_fops); | ||
274 | if (!state) | ||
275 | goto err_state; | ||
276 | queues = debugfs_create_file("queues", 0400, root, udc, | ||
277 | &queues_dbg_fops); | ||
278 | if (!queues) | ||
279 | goto err_queues; | ||
280 | eps = debugfs_create_file("epstate", 0400, root, udc, | ||
281 | &eps_dbg_fops); | ||
282 | if (!queues) | ||
283 | goto err_eps; | ||
284 | |||
285 | udc->debugfs_root = root; | ||
286 | udc->debugfs_state = state; | ||
287 | udc->debugfs_queues = queues; | ||
288 | udc->debugfs_eps = eps; | ||
289 | return; | ||
290 | err_eps: | ||
291 | debugfs_remove(eps); | ||
292 | err_queues: | ||
293 | debugfs_remove(queues); | ||
294 | err_state: | ||
295 | debugfs_remove(root); | ||
296 | err_root: | ||
297 | dev_err(udc->dev, "debugfs is not available\n"); | ||
298 | } | ||
299 | |||
300 | static void pxa_cleanup_debugfs(struct pxa_udc *udc) | ||
301 | { | ||
302 | debugfs_remove(udc->debugfs_eps); | ||
303 | debugfs_remove(udc->debugfs_queues); | ||
304 | debugfs_remove(udc->debugfs_state); | ||
305 | debugfs_remove(udc->debugfs_root); | ||
306 | udc->debugfs_eps = NULL; | ||
307 | udc->debugfs_queues = NULL; | ||
308 | udc->debugfs_state = NULL; | ||
309 | udc->debugfs_root = NULL; | ||
310 | } | ||
311 | |||
312 | #else | ||
313 | static inline void pxa_init_debugfs(struct pxa_udc *udc) | ||
314 | { | ||
315 | } | ||
316 | |||
317 | static inline void pxa_cleanup_debugfs(struct pxa_udc *udc) | ||
318 | { | ||
319 | } | ||
320 | #endif | ||
321 | |||
322 | /** | ||
323 | * is_match_usb_pxa - check if usb_ep and pxa_ep match | ||
324 | * @udc_usb_ep: usb endpoint | ||
325 | * @ep: pxa endpoint | ||
326 | * @config: configuration required in pxa_ep | ||
327 | * @interface: interface required in pxa_ep | ||
328 | * @altsetting: altsetting required in pxa_ep | ||
329 | * | ||
330 | * Returns 1 if all criteria match between pxa and usb endpoint, 0 otherwise | ||
331 | */ | ||
332 | static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep, | ||
333 | int config, int interface, int altsetting) | ||
334 | { | ||
335 | if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr) | ||
336 | return 0; | ||
337 | if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in) | ||
338 | return 0; | ||
339 | if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type) | ||
340 | return 0; | ||
341 | if ((ep->config != config) || (ep->interface != interface) | ||
342 | || (ep->alternate != altsetting)) | ||
343 | return 0; | ||
344 | return 1; | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * find_pxa_ep - find pxa_ep structure matching udc_usb_ep | ||
349 | * @udc: pxa udc | ||
350 | * @udc_usb_ep: udc_usb_ep structure | ||
351 | * | ||
352 | * Match udc_usb_ep and all pxa_ep available, to see if one matches. | ||
353 | * This is necessary because of the strong pxa hardware restriction requiring | ||
354 | * that once pxa endpoints are initialized, their configuration is freezed, and | ||
355 | * no change can be made to their address, direction, or in which configuration, | ||
356 | * interface or altsetting they are active ... which differs from more usual | ||
357 | * models which have endpoints be roughly just addressable fifos, and leave | ||
358 | * configuration events up to gadget drivers (like all control messages). | ||
359 | * | ||
360 | * Note that there is still a blurred point here : | ||
361 | * - we rely on UDCCR register "active interface" and "active altsetting". | ||
362 | * This is a nonsense in regard of USB spec, where multiple interfaces are | ||
363 | * active at the same time. | ||
364 | * - if we knew for sure that the pxa can handle multiple interface at the | ||
365 | * same time, assuming Intel's Developer Guide is wrong, this function | ||
366 | * should be reviewed, and a cache of couples (iface, altsetting) should | ||
367 | * be kept in the pxa_udc structure. In this case this function would match | ||
368 | * against the cache of couples instead of the "last altsetting" set up. | ||
369 | * | ||
370 | * Returns the matched pxa_ep structure or NULL if none found | ||
371 | */ | ||
372 | static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc, | ||
373 | struct udc_usb_ep *udc_usb_ep) | ||
374 | { | ||
375 | int i; | ||
376 | struct pxa_ep *ep; | ||
377 | int cfg = udc->config; | ||
378 | int iface = udc->last_interface; | ||
379 | int alt = udc->last_alternate; | ||
380 | |||
381 | if (udc_usb_ep == &udc->udc_usb_ep[0]) | ||
382 | return &udc->pxa_ep[0]; | ||
383 | |||
384 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) { | ||
385 | ep = &udc->pxa_ep[i]; | ||
386 | if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt)) | ||
387 | return ep; | ||
388 | } | ||
389 | return NULL; | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * update_pxa_ep_matches - update pxa_ep cached values in all udc_usb_ep | ||
394 | * @udc: pxa udc | ||
395 | * | ||
396 | * Context: in_interrupt() | ||
397 | * | ||
398 | * Updates all pxa_ep fields in udc_usb_ep structures, if this field was | ||
399 | * previously set up (and is not NULL). The update is necessary is a | ||
400 | * configuration change or altsetting change was issued by the USB host. | ||
401 | */ | ||
402 | static void update_pxa_ep_matches(struct pxa_udc *udc) | ||
403 | { | ||
404 | int i; | ||
405 | struct udc_usb_ep *udc_usb_ep; | ||
406 | |||
407 | for (i = 1; i < NR_USB_ENDPOINTS; i++) { | ||
408 | udc_usb_ep = &udc->udc_usb_ep[i]; | ||
409 | if (udc_usb_ep->pxa_ep) | ||
410 | udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | /** | ||
415 | * pio_irq_enable - Enables irq generation for one endpoint | ||
416 | * @ep: udc endpoint | ||
417 | */ | ||
418 | static void pio_irq_enable(struct pxa_ep *ep) | ||
419 | { | ||
420 | struct pxa_udc *udc = ep->dev; | ||
421 | int index = EPIDX(ep); | ||
422 | u32 udcicr0 = udc_readl(udc, UDCICR0); | ||
423 | u32 udcicr1 = udc_readl(udc, UDCICR1); | ||
424 | |||
425 | if (index < 16) | ||
426 | udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2))); | ||
427 | else | ||
428 | udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2))); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * pio_irq_disable - Disables irq generation for one endpoint | ||
433 | * @ep: udc endpoint | ||
434 | * @index: endpoint number | ||
435 | */ | ||
436 | static void pio_irq_disable(struct pxa_ep *ep) | ||
437 | { | ||
438 | struct pxa_udc *udc = ep->dev; | ||
439 | int index = EPIDX(ep); | ||
440 | u32 udcicr0 = udc_readl(udc, UDCICR0); | ||
441 | u32 udcicr1 = udc_readl(udc, UDCICR1); | ||
442 | |||
443 | if (index < 16) | ||
444 | udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2))); | ||
445 | else | ||
446 | udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2))); | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * udc_set_mask_UDCCR - set bits in UDCCR | ||
451 | * @udc: udc device | ||
452 | * @mask: bits to set in UDCCR | ||
453 | * | ||
454 | * Sets bits in UDCCR, leaving DME and FST bits as they were. | ||
455 | */ | ||
456 | static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask) | ||
457 | { | ||
458 | u32 udccr = udc_readl(udc, UDCCR); | ||
459 | udc_writel(udc, UDCCR, | ||
460 | (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS)); | ||
461 | } | ||
462 | |||
463 | /** | ||
464 | * udc_clear_mask_UDCCR - clears bits in UDCCR | ||
465 | * @udc: udc device | ||
466 | * @mask: bit to clear in UDCCR | ||
467 | * | ||
468 | * Clears bits in UDCCR, leaving DME and FST bits as they were. | ||
469 | */ | ||
470 | static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask) | ||
471 | { | ||
472 | u32 udccr = udc_readl(udc, UDCCR); | ||
473 | udc_writel(udc, UDCCR, | ||
474 | (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS)); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * ep_count_bytes_remain - get how many bytes in udc endpoint | ||
479 | * @ep: udc endpoint | ||
480 | * | ||
481 | * Returns number of bytes in OUT fifos. Broken for IN fifos (-EOPNOTSUPP) | ||
482 | */ | ||
483 | static int ep_count_bytes_remain(struct pxa_ep *ep) | ||
484 | { | ||
485 | if (ep->dir_in) | ||
486 | return -EOPNOTSUPP; | ||
487 | return udc_ep_readl(ep, UDCBCR) & 0x3ff; | ||
488 | } | ||
489 | |||
490 | /** | ||
491 | * ep_is_empty - checks if ep has byte ready for reading | ||
492 | * @ep: udc endpoint | ||
493 | * | ||
494 | * If endpoint is the control endpoint, checks if there are bytes in the | ||
495 | * control endpoint fifo. If endpoint is a data endpoint, checks if bytes | ||
496 | * are ready for reading on OUT endpoint. | ||
497 | * | ||
498 | * Returns 0 if ep not empty, 1 if ep empty, -EOPNOTSUPP if IN endpoint | ||
499 | */ | ||
500 | static int ep_is_empty(struct pxa_ep *ep) | ||
501 | { | ||
502 | int ret; | ||
503 | |||
504 | if (!is_ep0(ep) && ep->dir_in) | ||
505 | return -EOPNOTSUPP; | ||
506 | if (is_ep0(ep)) | ||
507 | ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE); | ||
508 | else | ||
509 | ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE); | ||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | /** | ||
514 | * ep_is_full - checks if ep has place to write bytes | ||
515 | * @ep: udc endpoint | ||
516 | * | ||
517 | * If endpoint is not the control endpoint and is an IN endpoint, checks if | ||
518 | * there is place to write bytes into the endpoint. | ||
519 | * | ||
520 | * Returns 0 if ep not full, 1 if ep full, -EOPNOTSUPP if OUT endpoint | ||
521 | */ | ||
522 | static int ep_is_full(struct pxa_ep *ep) | ||
523 | { | ||
524 | if (is_ep0(ep)) | ||
525 | return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR); | ||
526 | if (!ep->dir_in) | ||
527 | return -EOPNOTSUPP; | ||
528 | return (!(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF)); | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * epout_has_pkt - checks if OUT endpoint fifo has a packet available | ||
533 | * @ep: pxa endpoint | ||
534 | * | ||
535 | * Returns 1 if a complete packet is available, 0 if not, -EOPNOTSUPP for IN ep. | ||
536 | */ | ||
537 | static int epout_has_pkt(struct pxa_ep *ep) | ||
538 | { | ||
539 | if (!is_ep0(ep) && ep->dir_in) | ||
540 | return -EOPNOTSUPP; | ||
541 | if (is_ep0(ep)) | ||
542 | return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC); | ||
543 | return (udc_ep_readl(ep, UDCCSR) & UDCCSR_PC); | ||
544 | } | ||
545 | |||
546 | /** | ||
547 | * set_ep0state - Set ep0 automata state | ||
548 | * @dev: udc device | ||
549 | * @state: state | ||
550 | */ | ||
551 | static void set_ep0state(struct pxa_udc *udc, int state) | ||
552 | { | ||
553 | struct pxa_ep *ep = &udc->pxa_ep[0]; | ||
554 | char *old_stname = EP0_STNAME(udc); | ||
555 | |||
556 | udc->ep0state = state; | ||
557 | ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname, | ||
558 | EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR), | ||
559 | udc_ep_readl(ep, UDCBCR)); | ||
560 | } | ||
561 | |||
562 | /** | ||
563 | * ep0_idle - Put control endpoint into idle state | ||
564 | * @dev: udc device | ||
565 | */ | ||
566 | static void ep0_idle(struct pxa_udc *dev) | ||
567 | { | ||
568 | set_ep0state(dev, WAIT_FOR_SETUP); | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * inc_ep_stats_reqs - Update ep stats counts | ||
573 | * @ep: physical endpoint | ||
574 | * @req: usb request | ||
575 | * @is_in: ep direction (USB_DIR_IN or 0) | ||
576 | * | ||
577 | */ | ||
578 | static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in) | ||
579 | { | ||
580 | if (is_in) | ||
581 | ep->stats.in_ops++; | ||
582 | else | ||
583 | ep->stats.out_ops++; | ||
584 | } | ||
585 | |||
586 | /** | ||
587 | * inc_ep_stats_bytes - Update ep stats counts | ||
588 | * @ep: physical endpoint | ||
589 | * @count: bytes transfered on endpoint | ||
590 | * @req: usb request | ||
591 | * @is_in: ep direction (USB_DIR_IN or 0) | ||
592 | */ | ||
593 | static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) | ||
594 | { | ||
595 | if (is_in) | ||
596 | ep->stats.in_bytes += count; | ||
597 | else | ||
598 | ep->stats.out_bytes += count; | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * pxa_ep_setup - Sets up an usb physical endpoint | ||
603 | * @ep: pxa27x physical endpoint | ||
604 | * | ||
605 | * Find the physical pxa27x ep, and setup its UDCCR | ||
606 | */ | ||
607 | static __init void pxa_ep_setup(struct pxa_ep *ep) | ||
608 | { | ||
609 | u32 new_udccr; | ||
610 | |||
611 | new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN) | ||
612 | | ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN) | ||
613 | | ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN) | ||
614 | | ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN) | ||
615 | | ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET) | ||
616 | | ((ep->dir_in) ? UDCCONR_ED : 0) | ||
617 | | ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS) | ||
618 | | UDCCONR_EE; | ||
619 | |||
620 | udc_ep_writel(ep, UDCCR, new_udccr); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * pxa_eps_setup - Sets up all usb physical endpoints | ||
625 | * @dev: udc device | ||
626 | * | ||
627 | * Setup all pxa physical endpoints, except ep0 | ||
628 | */ | ||
629 | static __init void pxa_eps_setup(struct pxa_udc *dev) | ||
630 | { | ||
631 | unsigned int i; | ||
632 | |||
633 | dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev); | ||
634 | |||
635 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) | ||
636 | pxa_ep_setup(&dev->pxa_ep[i]); | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * pxa_ep_alloc_request - Allocate usb request | ||
641 | * @_ep: usb endpoint | ||
642 | * @gfp_flags: | ||
643 | * | ||
644 | * For the pxa27x, these can just wrap kmalloc/kfree. gadget drivers | ||
645 | * must still pass correctly initialized endpoints, since other controller | ||
646 | * drivers may care about how it's currently set up (dma issues etc). | ||
647 | */ | ||
648 | static struct usb_request * | ||
649 | pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
650 | { | ||
651 | struct pxa27x_request *req; | ||
652 | |||
653 | req = kzalloc(sizeof *req, gfp_flags); | ||
654 | if (!req || !_ep) | ||
655 | return NULL; | ||
656 | |||
657 | INIT_LIST_HEAD(&req->queue); | ||
658 | req->in_use = 0; | ||
659 | req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
660 | |||
661 | return &req->req; | ||
662 | } | ||
663 | |||
664 | /** | ||
665 | * pxa_ep_free_request - Free usb request | ||
666 | * @_ep: usb endpoint | ||
667 | * @_req: usb request | ||
668 | * | ||
669 | * Wrapper around kfree to free _req | ||
670 | */ | ||
671 | static void pxa_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
672 | { | ||
673 | struct pxa27x_request *req; | ||
674 | |||
675 | req = container_of(_req, struct pxa27x_request, req); | ||
676 | WARN_ON(!list_empty(&req->queue)); | ||
677 | kfree(req); | ||
678 | } | ||
679 | |||
680 | /** | ||
681 | * ep_add_request - add a request to the endpoint's queue | ||
682 | * @ep: usb endpoint | ||
683 | * @req: usb request | ||
684 | * | ||
685 | * Context: ep->lock held | ||
686 | * | ||
687 | * Queues the request in the endpoint's queue, and enables the interrupts | ||
688 | * on the endpoint. | ||
689 | */ | ||
690 | static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req) | ||
691 | { | ||
692 | if (unlikely(!req)) | ||
693 | return; | ||
694 | ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, | ||
695 | req->req.length, udc_ep_readl(ep, UDCCSR)); | ||
696 | |||
697 | req->in_use = 1; | ||
698 | list_add_tail(&req->queue, &ep->queue); | ||
699 | pio_irq_enable(ep); | ||
700 | } | ||
701 | |||
702 | /** | ||
703 | * ep_del_request - removes a request from the endpoint's queue | ||
704 | * @ep: usb endpoint | ||
705 | * @req: usb request | ||
706 | * | ||
707 | * Context: ep->lock held | ||
708 | * | ||
709 | * Unqueue the request from the endpoint's queue. If there are no more requests | ||
710 | * on the endpoint, and if it's not the control endpoint, interrupts are | ||
711 | * disabled on the endpoint. | ||
712 | */ | ||
713 | static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req) | ||
714 | { | ||
715 | if (unlikely(!req)) | ||
716 | return; | ||
717 | ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, | ||
718 | req->req.length, udc_ep_readl(ep, UDCCSR)); | ||
719 | |||
720 | list_del_init(&req->queue); | ||
721 | req->in_use = 0; | ||
722 | if (!is_ep0(ep) && list_empty(&ep->queue)) | ||
723 | pio_irq_disable(ep); | ||
724 | } | ||
725 | |||
726 | /** | ||
727 | * req_done - Complete an usb request | ||
728 | * @ep: pxa physical endpoint | ||
729 | * @req: pxa request | ||
730 | * @status: usb request status sent to gadget API | ||
731 | * | ||
732 | * Context: ep->lock held | ||
733 | * | ||
734 | * Retire a pxa27x usb request. Endpoint must be locked. | ||
735 | */ | ||
736 | static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | ||
737 | { | ||
738 | ep_del_request(ep, req); | ||
739 | if (likely(req->req.status == -EINPROGRESS)) | ||
740 | req->req.status = status; | ||
741 | else | ||
742 | status = req->req.status; | ||
743 | |||
744 | if (status && status != -ESHUTDOWN) | ||
745 | ep_dbg(ep, "complete req %p stat %d len %u/%u\n", | ||
746 | &req->req, status, | ||
747 | req->req.actual, req->req.length); | ||
748 | |||
749 | req->req.complete(&req->udc_usb_ep->usb_ep, &req->req); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * ep_end_out_req - Ends control endpoint in request | ||
754 | * @ep: physical endpoint | ||
755 | * @req: pxa request | ||
756 | * | ||
757 | * Context: ep->lock held | ||
758 | * | ||
759 | * Ends endpoint in request (completes usb request). | ||
760 | */ | ||
761 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | ||
762 | { | ||
763 | inc_ep_stats_reqs(ep, !USB_DIR_IN); | ||
764 | req_done(ep, req, 0); | ||
765 | } | ||
766 | |||
767 | /** | ||
768 | * ep0_end_out_req - Ends control endpoint in request (ends data stage) | ||
769 | * @ep: physical endpoint | ||
770 | * @req: pxa request | ||
771 | * | ||
772 | * Context: ep->lock held | ||
773 | * | ||
774 | * Ends control endpoint in request (completes usb request), and puts | ||
775 | * control endpoint into idle state | ||
776 | */ | ||
777 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | ||
778 | { | ||
779 | set_ep0state(ep->dev, OUT_STATUS_STAGE); | ||
780 | ep_end_out_req(ep, req); | ||
781 | ep0_idle(ep->dev); | ||
782 | } | ||
783 | |||
784 | /** | ||
785 | * ep_end_in_req - Ends endpoint out request | ||
786 | * @ep: physical endpoint | ||
787 | * @req: pxa request | ||
788 | * | ||
789 | * Context: ep->lock held | ||
790 | * | ||
791 | * Ends endpoint out request (completes usb request). | ||
792 | */ | ||
793 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | ||
794 | { | ||
795 | inc_ep_stats_reqs(ep, USB_DIR_IN); | ||
796 | req_done(ep, req, 0); | ||
797 | } | ||
798 | |||
799 | /** | ||
800 | * ep0_end_in_req - Ends control endpoint out request (ends data stage) | ||
801 | * @ep: physical endpoint | ||
802 | * @req: pxa request | ||
803 | * | ||
804 | * Context: ep->lock held | ||
805 | * | ||
806 | * Ends control endpoint out request (completes usb request), and puts | ||
807 | * control endpoint into status state | ||
808 | */ | ||
809 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | ||
810 | { | ||
811 | struct pxa_udc *udc = ep->dev; | ||
812 | |||
813 | set_ep0state(udc, IN_STATUS_STAGE); | ||
814 | ep_end_in_req(ep, req); | ||
815 | } | ||
816 | |||
817 | /** | ||
818 | * nuke - Dequeue all requests | ||
819 | * @ep: pxa endpoint | ||
820 | * @status: usb request status | ||
821 | * | ||
822 | * Context: ep->lock held | ||
823 | * | ||
824 | * Dequeues all requests on an endpoint. As a side effect, interrupts will be | ||
825 | * disabled on that endpoint (because no more requests). | ||
826 | */ | ||
827 | static void nuke(struct pxa_ep *ep, int status) | ||
828 | { | ||
829 | struct pxa27x_request *req; | ||
830 | |||
831 | while (!list_empty(&ep->queue)) { | ||
832 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
833 | req_done(ep, req, status); | ||
834 | } | ||
835 | } | ||
836 | |||
837 | /** | ||
838 | * read_packet - transfer 1 packet from an OUT endpoint into request | ||
839 | * @ep: pxa physical endpoint | ||
840 | * @req: usb request | ||
841 | * | ||
842 | * Takes bytes from OUT endpoint and transfers them info the usb request. | ||
843 | * If there is less space in request than bytes received in OUT endpoint, | ||
844 | * bytes are left in the OUT endpoint. | ||
845 | * | ||
846 | * Returns how many bytes were actually transfered | ||
847 | */ | ||
848 | static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req) | ||
849 | { | ||
850 | u32 *buf; | ||
851 | int bytes_ep, bufferspace, count, i; | ||
852 | |||
853 | bytes_ep = ep_count_bytes_remain(ep); | ||
854 | bufferspace = req->req.length - req->req.actual; | ||
855 | |||
856 | buf = (u32 *)(req->req.buf + req->req.actual); | ||
857 | prefetchw(buf); | ||
858 | |||
859 | if (likely(!ep_is_empty(ep))) | ||
860 | count = min(bytes_ep, bufferspace); | ||
861 | else /* zlp */ | ||
862 | count = 0; | ||
863 | |||
864 | for (i = count; i > 0; i -= 4) | ||
865 | *buf++ = udc_ep_readl(ep, UDCDR); | ||
866 | req->req.actual += count; | ||
867 | |||
868 | udc_ep_writel(ep, UDCCSR, UDCCSR_PC); | ||
869 | |||
870 | return count; | ||
871 | } | ||
872 | |||
873 | /** | ||
874 | * write_packet - transfer 1 packet from request into an IN endpoint | ||
875 | * @ep: pxa physical endpoint | ||
876 | * @req: usb request | ||
877 | * @max: max bytes that fit into endpoint | ||
878 | * | ||
879 | * Takes bytes from usb request, and transfers them into the physical | ||
880 | * endpoint. If there are no bytes to transfer, doesn't write anything | ||
881 | * to physical endpoint. | ||
882 | * | ||
883 | * Returns how many bytes were actually transfered. | ||
884 | */ | ||
885 | static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req, | ||
886 | unsigned int max) | ||
887 | { | ||
888 | int length, count, remain, i; | ||
889 | u32 *buf; | ||
890 | u8 *buf_8; | ||
891 | |||
892 | buf = (u32 *)(req->req.buf + req->req.actual); | ||
893 | prefetch(buf); | ||
894 | |||
895 | length = min(req->req.length - req->req.actual, max); | ||
896 | req->req.actual += length; | ||
897 | |||
898 | remain = length & 0x3; | ||
899 | count = length & ~(0x3); | ||
900 | for (i = count; i > 0 ; i -= 4) | ||
901 | udc_ep_writel(ep, UDCDR, *buf++); | ||
902 | |||
903 | buf_8 = (u8 *)buf; | ||
904 | for (i = remain; i > 0; i--) | ||
905 | udc_ep_writeb(ep, UDCDR, *buf_8++); | ||
906 | |||
907 | ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain, | ||
908 | udc_ep_readl(ep, UDCCSR)); | ||
909 | |||
910 | return length; | ||
911 | } | ||
912 | |||
913 | /** | ||
914 | * read_fifo - Transfer packets from OUT endpoint into usb request | ||
915 | * @ep: pxa physical endpoint | ||
916 | * @req: usb request | ||
917 | * | ||
918 | * Context: callable when in_interrupt() | ||
919 | * | ||
920 | * Unload as many packets as possible from the fifo we use for usb OUT | ||
921 | * transfers and put them into the request. Caller should have made sure | ||
922 | * there's at least one packet ready. | ||
923 | * Doesn't complete the request, that's the caller's job | ||
924 | * | ||
925 | * Returns 1 if the request completed, 0 otherwise | ||
926 | */ | ||
927 | static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req) | ||
928 | { | ||
929 | int count, is_short, completed = 0; | ||
930 | |||
931 | while (epout_has_pkt(ep)) { | ||
932 | count = read_packet(ep, req); | ||
933 | inc_ep_stats_bytes(ep, count, !USB_DIR_IN); | ||
934 | |||
935 | is_short = (count < ep->fifo_size); | ||
936 | ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", | ||
937 | udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", | ||
938 | &req->req, req->req.actual, req->req.length); | ||
939 | |||
940 | /* completion */ | ||
941 | if (is_short || req->req.actual == req->req.length) { | ||
942 | completed = 1; | ||
943 | break; | ||
944 | } | ||
945 | /* finished that packet. the next one may be waiting... */ | ||
946 | } | ||
947 | return completed; | ||
948 | } | ||
949 | |||
950 | /** | ||
951 | * write_fifo - transfer packets from usb request into an IN endpoint | ||
952 | * @ep: pxa physical endpoint | ||
953 | * @req: pxa usb request | ||
954 | * | ||
955 | * Write to an IN endpoint fifo, as many packets as possible. | ||
956 | * irqs will use this to write the rest later. | ||
957 | * caller guarantees at least one packet buffer is ready (or a zlp). | ||
958 | * Doesn't complete the request, that's the caller's job | ||
959 | * | ||
960 | * Returns 1 if request fully transfered, 0 if partial transfer | ||
961 | */ | ||
962 | static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req) | ||
963 | { | ||
964 | unsigned max; | ||
965 | int count, is_short, is_last = 0, completed = 0, totcount = 0; | ||
966 | u32 udccsr; | ||
967 | |||
968 | max = ep->fifo_size; | ||
969 | do { | ||
970 | is_short = 0; | ||
971 | |||
972 | udccsr = udc_ep_readl(ep, UDCCSR); | ||
973 | if (udccsr & UDCCSR_PC) { | ||
974 | ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n", | ||
975 | udccsr); | ||
976 | udc_ep_writel(ep, UDCCSR, UDCCSR_PC); | ||
977 | } | ||
978 | if (udccsr & UDCCSR_TRN) { | ||
979 | ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n", | ||
980 | udccsr); | ||
981 | udc_ep_writel(ep, UDCCSR, UDCCSR_TRN); | ||
982 | } | ||
983 | |||
984 | count = write_packet(ep, req, max); | ||
985 | inc_ep_stats_bytes(ep, count, USB_DIR_IN); | ||
986 | totcount += count; | ||
987 | |||
988 | /* last packet is usually short (or a zlp) */ | ||
989 | if (unlikely(count < max)) { | ||
990 | is_last = 1; | ||
991 | is_short = 1; | ||
992 | } else { | ||
993 | if (likely(req->req.length > req->req.actual) | ||
994 | || req->req.zero) | ||
995 | is_last = 0; | ||
996 | else | ||
997 | is_last = 1; | ||
998 | /* interrupt/iso maxpacket may not fill the fifo */ | ||
999 | is_short = unlikely(max < ep->fifo_size); | ||
1000 | } | ||
1001 | |||
1002 | if (is_short) | ||
1003 | udc_ep_writel(ep, UDCCSR, UDCCSR_SP); | ||
1004 | |||
1005 | /* requests complete when all IN data is in the FIFO */ | ||
1006 | if (is_last) { | ||
1007 | completed = 1; | ||
1008 | break; | ||
1009 | } | ||
1010 | } while (!ep_is_full(ep)); | ||
1011 | |||
1012 | ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n", | ||
1013 | totcount, is_last ? "/L" : "", is_short ? "/S" : "", | ||
1014 | req->req.length - req->req.actual, &req->req); | ||
1015 | |||
1016 | return completed; | ||
1017 | } | ||
1018 | |||
1019 | /** | ||
1020 | * read_ep0_fifo - Transfer packets from control endpoint into usb request | ||
1021 | * @ep: control endpoint | ||
1022 | * @req: pxa usb request | ||
1023 | * | ||
1024 | * Special ep0 version of the above read_fifo. Reads as many bytes from control | ||
1025 | * endpoint as can be read, and stores them into usb request (limited by request | ||
1026 | * maximum length). | ||
1027 | * | ||
1028 | * Returns 0 if usb request only partially filled, 1 if fully filled | ||
1029 | */ | ||
1030 | static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) | ||
1031 | { | ||
1032 | int count, is_short, completed = 0; | ||
1033 | |||
1034 | while (epout_has_pkt(ep)) { | ||
1035 | count = read_packet(ep, req); | ||
1036 | udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); | ||
1037 | inc_ep_stats_bytes(ep, count, !USB_DIR_IN); | ||
1038 | |||
1039 | is_short = (count < ep->fifo_size); | ||
1040 | ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", | ||
1041 | udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", | ||
1042 | &req->req, req->req.actual, req->req.length); | ||
1043 | |||
1044 | if (is_short || req->req.actual >= req->req.length) { | ||
1045 | completed = 1; | ||
1046 | break; | ||
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | return completed; | ||
1051 | } | ||
1052 | |||
1053 | /** | ||
1054 | * write_ep0_fifo - Send a request to control endpoint (ep0 in) | ||
1055 | * @ep: control endpoint | ||
1056 | * @req: request | ||
1057 | * | ||
1058 | * Context: callable when in_interrupt() | ||
1059 | * | ||
1060 | * Sends a request (or a part of the request) to the control endpoint (ep0 in). | ||
1061 | * If the request doesn't fit, the remaining part will be sent from irq. | ||
1062 | * The request is considered fully written only if either : | ||
1063 | * - last write transfered all remaining bytes, but fifo was not fully filled | ||
1064 | * - last write was a 0 length write | ||
1065 | * | ||
1066 | * Returns 1 if request fully written, 0 if request only partially sent | ||
1067 | */ | ||
1068 | static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) | ||
1069 | { | ||
1070 | unsigned count; | ||
1071 | int is_last, is_short; | ||
1072 | |||
1073 | count = write_packet(ep, req, EP0_FIFO_SIZE); | ||
1074 | inc_ep_stats_bytes(ep, count, USB_DIR_IN); | ||
1075 | |||
1076 | is_short = (count < EP0_FIFO_SIZE); | ||
1077 | is_last = ((count == 0) || (count < EP0_FIFO_SIZE)); | ||
1078 | |||
1079 | /* Sends either a short packet or a 0 length packet */ | ||
1080 | if (unlikely(is_short)) | ||
1081 | udc_ep_writel(ep, UDCCSR, UDCCSR0_IPR); | ||
1082 | |||
1083 | ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n", | ||
1084 | count, is_short ? "/S" : "", is_last ? "/L" : "", | ||
1085 | req->req.length - req->req.actual, | ||
1086 | &req->req, udc_ep_readl(ep, UDCCSR)); | ||
1087 | |||
1088 | return is_last; | ||
1089 | } | ||
1090 | |||
1091 | /** | ||
1092 | * pxa_ep_queue - Queue a request into an IN endpoint | ||
1093 | * @_ep: usb endpoint | ||
1094 | * @_req: usb request | ||
1095 | * @gfp_flags: flags | ||
1096 | * | ||
1097 | * Context: normally called when !in_interrupt, but callable when in_interrupt() | ||
1098 | * in the special case of ep0 setup : | ||
1099 | * (irq->handle_ep0_ctrl_req->gadget_setup->pxa_ep_queue) | ||
1100 | * | ||
1101 | * Returns 0 if succedeed, error otherwise | ||
1102 | */ | ||
1103 | static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1104 | gfp_t gfp_flags) | ||
1105 | { | ||
1106 | struct udc_usb_ep *udc_usb_ep; | ||
1107 | struct pxa_ep *ep; | ||
1108 | struct pxa27x_request *req; | ||
1109 | struct pxa_udc *dev; | ||
1110 | unsigned long flags; | ||
1111 | int rc = 0; | ||
1112 | int is_first_req; | ||
1113 | unsigned length; | ||
1114 | |||
1115 | req = container_of(_req, struct pxa27x_request, req); | ||
1116 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1117 | |||
1118 | if (unlikely(!_req || !_req->complete || !_req->buf)) | ||
1119 | return -EINVAL; | ||
1120 | |||
1121 | if (unlikely(!_ep)) | ||
1122 | return -EINVAL; | ||
1123 | |||
1124 | dev = udc_usb_ep->dev; | ||
1125 | ep = udc_usb_ep->pxa_ep; | ||
1126 | if (unlikely(!ep)) | ||
1127 | return -EINVAL; | ||
1128 | |||
1129 | dev = ep->dev; | ||
1130 | if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { | ||
1131 | ep_dbg(ep, "bogus device state\n"); | ||
1132 | return -ESHUTDOWN; | ||
1133 | } | ||
1134 | |||
1135 | /* iso is always one packet per request, that's the only way | ||
1136 | * we can report per-packet status. that also helps with dma. | ||
1137 | */ | ||
1138 | if (unlikely(EPXFERTYPE_is_ISO(ep) | ||
1139 | && req->req.length > ep->fifo_size)) | ||
1140 | return -EMSGSIZE; | ||
1141 | |||
1142 | spin_lock_irqsave(&ep->lock, flags); | ||
1143 | |||
1144 | is_first_req = list_empty(&ep->queue); | ||
1145 | ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n", | ||
1146 | _req, is_first_req ? "yes" : "no", | ||
1147 | _req->length, _req->buf); | ||
1148 | |||
1149 | if (!ep->enabled) { | ||
1150 | _req->status = -ESHUTDOWN; | ||
1151 | rc = -ESHUTDOWN; | ||
1152 | goto out; | ||
1153 | } | ||
1154 | |||
1155 | if (req->in_use) { | ||
1156 | ep_err(ep, "refusing to queue req %p (already queued)\n", req); | ||
1157 | goto out; | ||
1158 | } | ||
1159 | |||
1160 | length = _req->length; | ||
1161 | _req->status = -EINPROGRESS; | ||
1162 | _req->actual = 0; | ||
1163 | |||
1164 | ep_add_request(ep, req); | ||
1165 | |||
1166 | if (is_ep0(ep)) { | ||
1167 | switch (dev->ep0state) { | ||
1168 | case WAIT_ACK_SET_CONF_INTERF: | ||
1169 | if (length == 0) { | ||
1170 | ep_end_in_req(ep, req); | ||
1171 | } else { | ||
1172 | ep_err(ep, "got a request of %d bytes while" | ||
1173 | "in state WATI_ACK_SET_CONF_INTERF\n", | ||
1174 | length); | ||
1175 | ep_del_request(ep, req); | ||
1176 | rc = -EL2HLT; | ||
1177 | } | ||
1178 | ep0_idle(ep->dev); | ||
1179 | break; | ||
1180 | case IN_DATA_STAGE: | ||
1181 | if (!ep_is_full(ep)) | ||
1182 | if (write_ep0_fifo(ep, req)) | ||
1183 | ep0_end_in_req(ep, req); | ||
1184 | break; | ||
1185 | case OUT_DATA_STAGE: | ||
1186 | if ((length == 0) || !epout_has_pkt(ep)) | ||
1187 | if (read_ep0_fifo(ep, req)) | ||
1188 | ep0_end_out_req(ep, req); | ||
1189 | break; | ||
1190 | default: | ||
1191 | ep_err(ep, "odd state %s to send me a request\n", | ||
1192 | EP0_STNAME(ep->dev)); | ||
1193 | ep_del_request(ep, req); | ||
1194 | rc = -EL2HLT; | ||
1195 | break; | ||
1196 | } | ||
1197 | } else { | ||
1198 | handle_ep(ep); | ||
1199 | } | ||
1200 | |||
1201 | out: | ||
1202 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1203 | return rc; | ||
1204 | } | ||
1205 | |||
1206 | /** | ||
1207 | * pxa_ep_dequeue - Dequeue one request | ||
1208 | * @_ep: usb endpoint | ||
1209 | * @_req: usb request | ||
1210 | * | ||
1211 | * Return 0 if no error, -EINVAL or -ECONNRESET otherwise | ||
1212 | */ | ||
1213 | static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
1214 | { | ||
1215 | struct pxa_ep *ep; | ||
1216 | struct udc_usb_ep *udc_usb_ep; | ||
1217 | struct pxa27x_request *req; | ||
1218 | unsigned long flags; | ||
1219 | int rc; | ||
1220 | |||
1221 | if (!_ep) | ||
1222 | return -EINVAL; | ||
1223 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1224 | ep = udc_usb_ep->pxa_ep; | ||
1225 | if (!ep || is_ep0(ep)) | ||
1226 | return -EINVAL; | ||
1227 | |||
1228 | spin_lock_irqsave(&ep->lock, flags); | ||
1229 | |||
1230 | /* make sure it's actually queued on this endpoint */ | ||
1231 | list_for_each_entry(req, &ep->queue, queue) { | ||
1232 | if (&req->req == _req) | ||
1233 | break; | ||
1234 | } | ||
1235 | |||
1236 | rc = -EINVAL; | ||
1237 | if (&req->req != _req) | ||
1238 | goto out; | ||
1239 | |||
1240 | rc = 0; | ||
1241 | req_done(ep, req, -ECONNRESET); | ||
1242 | out: | ||
1243 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1244 | return rc; | ||
1245 | } | ||
1246 | |||
1247 | /** | ||
1248 | * pxa_ep_set_halt - Halts operations on one endpoint | ||
1249 | * @_ep: usb endpoint | ||
1250 | * @value: | ||
1251 | * | ||
1252 | * Returns 0 if no error, -EINVAL, -EROFS, -EAGAIN otherwise | ||
1253 | */ | ||
1254 | static int pxa_ep_set_halt(struct usb_ep *_ep, int value) | ||
1255 | { | ||
1256 | struct pxa_ep *ep; | ||
1257 | struct udc_usb_ep *udc_usb_ep; | ||
1258 | unsigned long flags; | ||
1259 | int rc; | ||
1260 | |||
1261 | |||
1262 | if (!_ep) | ||
1263 | return -EINVAL; | ||
1264 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1265 | ep = udc_usb_ep->pxa_ep; | ||
1266 | if (!ep || is_ep0(ep)) | ||
1267 | return -EINVAL; | ||
1268 | |||
1269 | if (value == 0) { | ||
1270 | /* | ||
1271 | * This path (reset toggle+halt) is needed to implement | ||
1272 | * SET_INTERFACE on normal hardware. but it can't be | ||
1273 | * done from software on the PXA UDC, and the hardware | ||
1274 | * forgets to do it as part of SET_INTERFACE automagic. | ||
1275 | */ | ||
1276 | ep_dbg(ep, "only host can clear halt\n"); | ||
1277 | return -EROFS; | ||
1278 | } | ||
1279 | |||
1280 | spin_lock_irqsave(&ep->lock, flags); | ||
1281 | |||
1282 | rc = -EAGAIN; | ||
1283 | if (ep->dir_in && (ep_is_full(ep) || !list_empty(&ep->queue))) | ||
1284 | goto out; | ||
1285 | |||
1286 | /* FST, FEF bits are the same for control and non control endpoints */ | ||
1287 | rc = 0; | ||
1288 | udc_ep_writel(ep, UDCCSR, UDCCSR_FST | UDCCSR_FEF); | ||
1289 | if (is_ep0(ep)) | ||
1290 | set_ep0state(ep->dev, STALL); | ||
1291 | |||
1292 | out: | ||
1293 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1294 | return rc; | ||
1295 | } | ||
1296 | |||
1297 | /** | ||
1298 | * pxa_ep_fifo_status - Get how many bytes in physical endpoint | ||
1299 | * @_ep: usb endpoint | ||
1300 | * | ||
1301 | * Returns number of bytes in OUT fifos. Broken for IN fifos. | ||
1302 | */ | ||
1303 | static int pxa_ep_fifo_status(struct usb_ep *_ep) | ||
1304 | { | ||
1305 | struct pxa_ep *ep; | ||
1306 | struct udc_usb_ep *udc_usb_ep; | ||
1307 | |||
1308 | if (!_ep) | ||
1309 | return -ENODEV; | ||
1310 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1311 | ep = udc_usb_ep->pxa_ep; | ||
1312 | if (!ep || is_ep0(ep)) | ||
1313 | return -ENODEV; | ||
1314 | |||
1315 | if (ep->dir_in) | ||
1316 | return -EOPNOTSUPP; | ||
1317 | if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep)) | ||
1318 | return 0; | ||
1319 | else | ||
1320 | return ep_count_bytes_remain(ep) + 1; | ||
1321 | } | ||
1322 | |||
1323 | /** | ||
1324 | * pxa_ep_fifo_flush - Flushes one endpoint | ||
1325 | * @_ep: usb endpoint | ||
1326 | * | ||
1327 | * Discards all data in one endpoint(IN or OUT), except control endpoint. | ||
1328 | */ | ||
1329 | static void pxa_ep_fifo_flush(struct usb_ep *_ep) | ||
1330 | { | ||
1331 | struct pxa_ep *ep; | ||
1332 | struct udc_usb_ep *udc_usb_ep; | ||
1333 | unsigned long flags; | ||
1334 | |||
1335 | if (!_ep) | ||
1336 | return; | ||
1337 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1338 | ep = udc_usb_ep->pxa_ep; | ||
1339 | if (!ep || is_ep0(ep)) | ||
1340 | return; | ||
1341 | |||
1342 | spin_lock_irqsave(&ep->lock, flags); | ||
1343 | |||
1344 | if (unlikely(!list_empty(&ep->queue))) | ||
1345 | ep_dbg(ep, "called while queue list not empty\n"); | ||
1346 | ep_dbg(ep, "called\n"); | ||
1347 | |||
1348 | /* for OUT, just read and discard the FIFO contents. */ | ||
1349 | if (!ep->dir_in) { | ||
1350 | while (!ep_is_empty(ep)) | ||
1351 | udc_ep_readl(ep, UDCDR); | ||
1352 | } else { | ||
1353 | /* most IN status is the same, but ISO can't stall */ | ||
1354 | udc_ep_writel(ep, UDCCSR, | ||
1355 | UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN | ||
1356 | | (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST)); | ||
1357 | } | ||
1358 | |||
1359 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1360 | |||
1361 | return; | ||
1362 | } | ||
1363 | |||
1364 | /** | ||
1365 | * pxa_ep_enable - Enables usb endpoint | ||
1366 | * @_ep: usb endpoint | ||
1367 | * @desc: usb endpoint descriptor | ||
1368 | * | ||
1369 | * Nothing much to do here, as ep configuration is done once and for all | ||
1370 | * before udc is enabled. After udc enable, no physical endpoint configuration | ||
1371 | * can be changed. | ||
1372 | * Function makes sanity checks and flushes the endpoint. | ||
1373 | */ | ||
1374 | static int pxa_ep_enable(struct usb_ep *_ep, | ||
1375 | const struct usb_endpoint_descriptor *desc) | ||
1376 | { | ||
1377 | struct pxa_ep *ep; | ||
1378 | struct udc_usb_ep *udc_usb_ep; | ||
1379 | struct pxa_udc *udc; | ||
1380 | |||
1381 | if (!_ep || !desc) | ||
1382 | return -EINVAL; | ||
1383 | |||
1384 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1385 | if (udc_usb_ep->pxa_ep) { | ||
1386 | ep = udc_usb_ep->pxa_ep; | ||
1387 | ep_warn(ep, "usb_ep %s already enabled, doing nothing\n", | ||
1388 | _ep->name); | ||
1389 | } else { | ||
1390 | ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep); | ||
1391 | } | ||
1392 | |||
1393 | if (!ep || is_ep0(ep)) { | ||
1394 | dev_err(udc_usb_ep->dev->dev, | ||
1395 | "unable to match pxa_ep for ep %s\n", | ||
1396 | _ep->name); | ||
1397 | return -EINVAL; | ||
1398 | } | ||
1399 | |||
1400 | if ((desc->bDescriptorType != USB_DT_ENDPOINT) | ||
1401 | || (ep->type != usb_endpoint_type(desc))) { | ||
1402 | ep_err(ep, "type mismatch\n"); | ||
1403 | return -EINVAL; | ||
1404 | } | ||
1405 | |||
1406 | if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) { | ||
1407 | ep_err(ep, "bad maxpacket\n"); | ||
1408 | return -ERANGE; | ||
1409 | } | ||
1410 | |||
1411 | udc_usb_ep->pxa_ep = ep; | ||
1412 | udc = ep->dev; | ||
1413 | |||
1414 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { | ||
1415 | ep_err(ep, "bogus device state\n"); | ||
1416 | return -ESHUTDOWN; | ||
1417 | } | ||
1418 | |||
1419 | ep->enabled = 1; | ||
1420 | |||
1421 | /* flush fifo (mostly for OUT buffers) */ | ||
1422 | pxa_ep_fifo_flush(_ep); | ||
1423 | |||
1424 | ep_dbg(ep, "enabled\n"); | ||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | /** | ||
1429 | * pxa_ep_disable - Disable usb endpoint | ||
1430 | * @_ep: usb endpoint | ||
1431 | * | ||
1432 | * Same as for pxa_ep_enable, no physical endpoint configuration can be | ||
1433 | * changed. | ||
1434 | * Function flushes the endpoint and related requests. | ||
1435 | */ | ||
1436 | static int pxa_ep_disable(struct usb_ep *_ep) | ||
1437 | { | ||
1438 | struct pxa_ep *ep; | ||
1439 | struct udc_usb_ep *udc_usb_ep; | ||
1440 | unsigned long flags; | ||
1441 | |||
1442 | if (!_ep) | ||
1443 | return -EINVAL; | ||
1444 | |||
1445 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | ||
1446 | ep = udc_usb_ep->pxa_ep; | ||
1447 | if (!ep || is_ep0(ep) || !list_empty(&ep->queue)) | ||
1448 | return -EINVAL; | ||
1449 | |||
1450 | spin_lock_irqsave(&ep->lock, flags); | ||
1451 | ep->enabled = 0; | ||
1452 | nuke(ep, -ESHUTDOWN); | ||
1453 | spin_unlock_irqrestore(&ep->lock, flags); | ||
1454 | |||
1455 | pxa_ep_fifo_flush(_ep); | ||
1456 | udc_usb_ep->pxa_ep = NULL; | ||
1457 | |||
1458 | ep_dbg(ep, "disabled\n"); | ||
1459 | return 0; | ||
1460 | } | ||
1461 | |||
1462 | static struct usb_ep_ops pxa_ep_ops = { | ||
1463 | .enable = pxa_ep_enable, | ||
1464 | .disable = pxa_ep_disable, | ||
1465 | |||
1466 | .alloc_request = pxa_ep_alloc_request, | ||
1467 | .free_request = pxa_ep_free_request, | ||
1468 | |||
1469 | .queue = pxa_ep_queue, | ||
1470 | .dequeue = pxa_ep_dequeue, | ||
1471 | |||
1472 | .set_halt = pxa_ep_set_halt, | ||
1473 | .fifo_status = pxa_ep_fifo_status, | ||
1474 | .fifo_flush = pxa_ep_fifo_flush, | ||
1475 | }; | ||
1476 | |||
1477 | |||
1478 | /** | ||
1479 | * pxa_udc_get_frame - Returns usb frame number | ||
1480 | * @_gadget: usb gadget | ||
1481 | */ | ||
1482 | static int pxa_udc_get_frame(struct usb_gadget *_gadget) | ||
1483 | { | ||
1484 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1485 | |||
1486 | return (udc_readl(udc, UDCFNR) & 0x7ff); | ||
1487 | } | ||
1488 | |||
1489 | /** | ||
1490 | * pxa_udc_wakeup - Force udc device out of suspend | ||
1491 | * @_gadget: usb gadget | ||
1492 | * | ||
1493 | * Returns 0 if succesfull, error code otherwise | ||
1494 | */ | ||
1495 | static int pxa_udc_wakeup(struct usb_gadget *_gadget) | ||
1496 | { | ||
1497 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1498 | |||
1499 | /* host may not have enabled remote wakeup */ | ||
1500 | if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0) | ||
1501 | return -EHOSTUNREACH; | ||
1502 | udc_set_mask_UDCCR(udc, UDCCR_UDR); | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static const struct usb_gadget_ops pxa_udc_ops = { | ||
1507 | .get_frame = pxa_udc_get_frame, | ||
1508 | .wakeup = pxa_udc_wakeup, | ||
1509 | /* current versions must always be self-powered */ | ||
1510 | }; | ||
1511 | |||
1512 | /** | ||
1513 | * udc_disable - disable udc device controller | ||
1514 | * @udc: udc device | ||
1515 | * | ||
1516 | * Disables the udc device : disables clocks, udc interrupts, control endpoint | ||
1517 | * interrupts. | ||
1518 | */ | ||
1519 | static void udc_disable(struct pxa_udc *udc) | ||
1520 | { | ||
1521 | udc_writel(udc, UDCICR0, 0); | ||
1522 | udc_writel(udc, UDCICR1, 0); | ||
1523 | |||
1524 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | ||
1525 | clk_disable(udc->clk); | ||
1526 | |||
1527 | ep0_idle(udc); | ||
1528 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1529 | if (udc->mach->udc_command) | ||
1530 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
1531 | } | ||
1532 | |||
1533 | /** | ||
1534 | * udc_init_data - Initialize udc device data structures | ||
1535 | * @dev: udc device | ||
1536 | * | ||
1537 | * Initializes gadget endpoint list, endpoints locks. No action is taken | ||
1538 | * on the hardware. | ||
1539 | */ | ||
1540 | static __init void udc_init_data(struct pxa_udc *dev) | ||
1541 | { | ||
1542 | int i; | ||
1543 | struct pxa_ep *ep; | ||
1544 | |||
1545 | /* device/ep0 records init */ | ||
1546 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
1547 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
1548 | dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0]; | ||
1549 | ep0_idle(dev); | ||
1550 | |||
1551 | /* PXA endpoints init */ | ||
1552 | for (i = 0; i < NR_PXA_ENDPOINTS; i++) { | ||
1553 | ep = &dev->pxa_ep[i]; | ||
1554 | |||
1555 | ep->enabled = is_ep0(ep); | ||
1556 | INIT_LIST_HEAD(&ep->queue); | ||
1557 | spin_lock_init(&ep->lock); | ||
1558 | } | ||
1559 | |||
1560 | /* USB endpoints init */ | ||
1561 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | ||
1562 | if (i != 0) | ||
1563 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, | ||
1564 | &dev->gadget.ep_list); | ||
1565 | } | ||
1566 | |||
1567 | /** | ||
1568 | * udc_enable - Enables the udc device | ||
1569 | * @dev: udc device | ||
1570 | * | ||
1571 | * Enables the udc device : enables clocks, udc interrupts, control endpoint | ||
1572 | * interrupts, sets usb as UDC client and setups endpoints. | ||
1573 | */ | ||
1574 | static void udc_enable(struct pxa_udc *udc) | ||
1575 | { | ||
1576 | udc_writel(udc, UDCICR0, 0); | ||
1577 | udc_writel(udc, UDCICR1, 0); | ||
1578 | udc_writel(udc, UP2OCR, UP2OCR_HXOE); | ||
1579 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | ||
1580 | |||
1581 | clk_enable(udc->clk); | ||
1582 | |||
1583 | ep0_idle(udc); | ||
1584 | udc->gadget.speed = USB_SPEED_FULL; | ||
1585 | memset(&udc->stats, 0, sizeof(udc->stats)); | ||
1586 | |||
1587 | udc_set_mask_UDCCR(udc, UDCCR_UDE); | ||
1588 | udelay(2); | ||
1589 | if (udc_readl(udc, UDCCR) & UDCCR_EMCE) | ||
1590 | dev_err(udc->dev, "Configuration errors, udc disabled\n"); | ||
1591 | |||
1592 | /* | ||
1593 | * Caller must be able to sleep in order to cope with startup transients | ||
1594 | */ | ||
1595 | msleep(100); | ||
1596 | |||
1597 | /* enable suspend/resume and reset irqs */ | ||
1598 | udc_writel(udc, UDCICR1, | ||
1599 | UDCICR1_IECC | UDCICR1_IERU | ||
1600 | | UDCICR1_IESU | UDCICR1_IERS); | ||
1601 | |||
1602 | /* enable ep0 irqs */ | ||
1603 | pio_irq_enable(&udc->pxa_ep[0]); | ||
1604 | |||
1605 | dev_info(udc->dev, "UDC connecting\n"); | ||
1606 | if (udc->mach->udc_command) | ||
1607 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
1608 | } | ||
1609 | |||
1610 | /** | ||
1611 | * usb_gadget_register_driver - Register gadget driver | ||
1612 | * @driver: gadget driver | ||
1613 | * | ||
1614 | * When a driver is successfully registered, it will receive control requests | ||
1615 | * including set_configuration(), which enables non-control requests. Then | ||
1616 | * usb traffic follows until a disconnect is reported. Then a host may connect | ||
1617 | * again, or the driver might get unbound. | ||
1618 | * | ||
1619 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise | ||
1620 | */ | ||
1621 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1622 | { | ||
1623 | struct pxa_udc *udc = the_controller; | ||
1624 | int retval; | ||
1625 | |||
1626 | if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind | ||
1627 | || !driver->disconnect || !driver->setup) | ||
1628 | return -EINVAL; | ||
1629 | if (!udc) | ||
1630 | return -ENODEV; | ||
1631 | if (udc->driver) | ||
1632 | return -EBUSY; | ||
1633 | |||
1634 | /* first hook up the driver ... */ | ||
1635 | udc->driver = driver; | ||
1636 | udc->gadget.dev.driver = &driver->driver; | ||
1637 | |||
1638 | retval = device_add(&udc->gadget.dev); | ||
1639 | if (retval) { | ||
1640 | dev_err(udc->dev, "device_add error %d\n", retval); | ||
1641 | goto add_fail; | ||
1642 | } | ||
1643 | retval = driver->bind(&udc->gadget); | ||
1644 | if (retval) { | ||
1645 | dev_err(udc->dev, "bind to driver %s --> error %d\n", | ||
1646 | driver->driver.name, retval); | ||
1647 | goto bind_fail; | ||
1648 | } | ||
1649 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", | ||
1650 | driver->driver.name); | ||
1651 | |||
1652 | udc_enable(udc); | ||
1653 | return 0; | ||
1654 | |||
1655 | bind_fail: | ||
1656 | device_del(&udc->gadget.dev); | ||
1657 | add_fail: | ||
1658 | udc->driver = NULL; | ||
1659 | udc->gadget.dev.driver = NULL; | ||
1660 | return retval; | ||
1661 | } | ||
1662 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1663 | |||
1664 | |||
1665 | /** | ||
1666 | * stop_activity - Stops udc endpoints | ||
1667 | * @udc: udc device | ||
1668 | * @driver: gadget driver | ||
1669 | * | ||
1670 | * Disables all udc endpoints (even control endpoint), report disconnect to | ||
1671 | * the gadget user. | ||
1672 | */ | ||
1673 | static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) | ||
1674 | { | ||
1675 | int i; | ||
1676 | |||
1677 | /* don't disconnect drivers more than once */ | ||
1678 | if (udc->gadget.speed == USB_SPEED_UNKNOWN) | ||
1679 | driver = NULL; | ||
1680 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1681 | |||
1682 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | ||
1683 | pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); | ||
1684 | |||
1685 | if (driver) | ||
1686 | driver->disconnect(&udc->gadget); | ||
1687 | } | ||
1688 | |||
1689 | /** | ||
1690 | * usb_gadget_unregister_driver - Unregister the gadget driver | ||
1691 | * @driver: gadget driver | ||
1692 | * | ||
1693 | * Returns 0 if no error, -ENODEV, -EINVAL otherwise | ||
1694 | */ | ||
1695 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1696 | { | ||
1697 | struct pxa_udc *udc = the_controller; | ||
1698 | |||
1699 | if (!udc) | ||
1700 | return -ENODEV; | ||
1701 | if (!driver || driver != udc->driver || !driver->unbind) | ||
1702 | return -EINVAL; | ||
1703 | |||
1704 | stop_activity(udc, driver); | ||
1705 | udc_disable(udc); | ||
1706 | |||
1707 | driver->unbind(&udc->gadget); | ||
1708 | udc->driver = NULL; | ||
1709 | |||
1710 | device_del(&udc->gadget.dev); | ||
1711 | |||
1712 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", | ||
1713 | driver->driver.name); | ||
1714 | return 0; | ||
1715 | } | ||
1716 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1717 | |||
1718 | /** | ||
1719 | * handle_ep0_ctrl_req - handle control endpoint control request | ||
1720 | * @udc: udc device | ||
1721 | * @req: control request | ||
1722 | */ | ||
1723 | static void handle_ep0_ctrl_req(struct pxa_udc *udc, | ||
1724 | struct pxa27x_request *req) | ||
1725 | { | ||
1726 | struct pxa_ep *ep = &udc->pxa_ep[0]; | ||
1727 | union { | ||
1728 | struct usb_ctrlrequest r; | ||
1729 | u32 word[2]; | ||
1730 | } u; | ||
1731 | int i; | ||
1732 | int have_extrabytes = 0; | ||
1733 | |||
1734 | nuke(ep, -EPROTO); | ||
1735 | |||
1736 | /* read SETUP packet */ | ||
1737 | for (i = 0; i < 2; i++) { | ||
1738 | if (unlikely(ep_is_empty(ep))) | ||
1739 | goto stall; | ||
1740 | u.word[i] = udc_ep_readl(ep, UDCDR); | ||
1741 | } | ||
1742 | |||
1743 | have_extrabytes = !ep_is_empty(ep); | ||
1744 | while (!ep_is_empty(ep)) { | ||
1745 | i = udc_ep_readl(ep, UDCDR); | ||
1746 | ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i); | ||
1747 | } | ||
1748 | |||
1749 | ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n", | ||
1750 | u.r.bRequestType, u.r.bRequest, | ||
1751 | le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex), | ||
1752 | le16_to_cpu(u.r.wLength)); | ||
1753 | if (unlikely(have_extrabytes)) | ||
1754 | goto stall; | ||
1755 | |||
1756 | if (u.r.bRequestType & USB_DIR_IN) | ||
1757 | set_ep0state(udc, IN_DATA_STAGE); | ||
1758 | else | ||
1759 | set_ep0state(udc, OUT_DATA_STAGE); | ||
1760 | |||
1761 | /* Tell UDC to enter Data Stage */ | ||
1762 | udc_ep_writel(ep, UDCCSR, UDCCSR0_SA | UDCCSR0_OPC); | ||
1763 | |||
1764 | i = udc->driver->setup(&udc->gadget, &u.r); | ||
1765 | if (i < 0) | ||
1766 | goto stall; | ||
1767 | out: | ||
1768 | return; | ||
1769 | stall: | ||
1770 | ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n", | ||
1771 | udc_ep_readl(ep, UDCCSR), i); | ||
1772 | udc_ep_writel(ep, UDCCSR, UDCCSR0_FST | UDCCSR0_FTF); | ||
1773 | set_ep0state(udc, STALL); | ||
1774 | goto out; | ||
1775 | } | ||
1776 | |||
1777 | /** | ||
1778 | * handle_ep0 - Handle control endpoint data transfers | ||
1779 | * @udc: udc device | ||
1780 | * @fifo_irq: 1 if triggered by fifo service type irq | ||
1781 | * @opc_irq: 1 if triggered by output packet complete type irq | ||
1782 | * | ||
1783 | * Context : when in_interrupt() or with ep->lock held | ||
1784 | * | ||
1785 | * Tries to transfer all pending request data into the endpoint and/or | ||
1786 | * transfer all pending data in the endpoint into usb requests. | ||
1787 | * Handles states of ep0 automata. | ||
1788 | * | ||
1789 | * PXA27x hardware handles several standard usb control requests without | ||
1790 | * driver notification. The requests fully handled by hardware are : | ||
1791 | * SET_ADDRESS, SET_FEATURE, CLEAR_FEATURE, GET_CONFIGURATION, GET_INTERFACE, | ||
1792 | * GET_STATUS | ||
1793 | * The requests handled by hardware, but with irq notification are : | ||
1794 | * SYNCH_FRAME, SET_CONFIGURATION, SET_INTERFACE | ||
1795 | * The remaining standard requests really handled by handle_ep0 are : | ||
1796 | * GET_DESCRIPTOR, SET_DESCRIPTOR, specific requests. | ||
1797 | * Requests standardized outside of USB 2.0 chapter 9 are handled more | ||
1798 | * uniformly, by gadget drivers. | ||
1799 | * | ||
1800 | * The control endpoint state machine is _not_ USB spec compliant, it's even | ||
1801 | * hardly compliant with Intel PXA270 developers guide. | ||
1802 | * The key points which inferred this state machine are : | ||
1803 | * - on every setup token, bit UDCCSR0_SA is raised and held until cleared by | ||
1804 | * software. | ||
1805 | * - on every OUT packet received, UDCCSR0_OPC is raised and held until | ||
1806 | * cleared by software. | ||
1807 | * - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it | ||
1808 | * before reading ep0. | ||
1809 | * - irq can be called on a "packet complete" event (opc_irq=1), while | ||
1810 | * UDCCSR0_OPC is not yet raised (delta can be as big as 100ms | ||
1811 | * from experimentation). | ||
1812 | * - as UDCCSR0_SA can be activated while in irq handling, and clearing | ||
1813 | * UDCCSR0_OPC would flush the setup data, we almost never clear UDCCSR0_OPC | ||
1814 | * => we never actually read the "status stage" packet of an IN data stage | ||
1815 | * => this is not documented in Intel documentation | ||
1816 | * - hardware as no idea of STATUS STAGE, it only handle SETUP STAGE and DATA | ||
1817 | * STAGE. The driver add STATUS STAGE to send last zero length packet in | ||
1818 | * OUT_STATUS_STAGE. | ||
1819 | * - special attention was needed for IN_STATUS_STAGE. If a packet complete | ||
1820 | * event is detected, we terminate the status stage without ackowledging the | ||
1821 | * packet (not to risk to loose a potential SETUP packet) | ||
1822 | */ | ||
1823 | static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | ||
1824 | { | ||
1825 | u32 udccsr0; | ||
1826 | struct pxa_ep *ep = &udc->pxa_ep[0]; | ||
1827 | struct pxa27x_request *req = NULL; | ||
1828 | int completed = 0; | ||
1829 | |||
1830 | udccsr0 = udc_ep_readl(ep, UDCCSR); | ||
1831 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", | ||
1832 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), | ||
1833 | (fifo_irq << 1 | opc_irq)); | ||
1834 | |||
1835 | if (!list_empty(&ep->queue)) | ||
1836 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
1837 | |||
1838 | if (udccsr0 & UDCCSR0_SST) { | ||
1839 | ep_dbg(ep, "clearing stall status\n"); | ||
1840 | nuke(ep, -EPIPE); | ||
1841 | udc_ep_writel(ep, UDCCSR, UDCCSR0_SST); | ||
1842 | ep0_idle(udc); | ||
1843 | } | ||
1844 | |||
1845 | if (udccsr0 & UDCCSR0_SA) { | ||
1846 | nuke(ep, 0); | ||
1847 | set_ep0state(udc, SETUP_STAGE); | ||
1848 | } | ||
1849 | |||
1850 | switch (udc->ep0state) { | ||
1851 | case WAIT_FOR_SETUP: | ||
1852 | /* | ||
1853 | * Hardware bug : beware, we cannot clear OPC, since we would | ||
1854 | * miss a potential OPC irq for a setup packet. | ||
1855 | * So, we only do ... nothing, and hope for a next irq with | ||
1856 | * UDCCSR0_SA set. | ||
1857 | */ | ||
1858 | break; | ||
1859 | case SETUP_STAGE: | ||
1860 | udccsr0 &= UDCCSR0_CTRL_REQ_MASK; | ||
1861 | if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK)) | ||
1862 | handle_ep0_ctrl_req(udc, req); | ||
1863 | break; | ||
1864 | case IN_DATA_STAGE: /* GET_DESCRIPTOR */ | ||
1865 | if (epout_has_pkt(ep)) | ||
1866 | udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); | ||
1867 | if (req && !ep_is_full(ep)) | ||
1868 | completed = write_ep0_fifo(ep, req); | ||
1869 | if (completed) | ||
1870 | ep0_end_in_req(ep, req); | ||
1871 | break; | ||
1872 | case OUT_DATA_STAGE: /* SET_DESCRIPTOR */ | ||
1873 | if (epout_has_pkt(ep) && req) | ||
1874 | completed = read_ep0_fifo(ep, req); | ||
1875 | if (completed) | ||
1876 | ep0_end_out_req(ep, req); | ||
1877 | break; | ||
1878 | case STALL: | ||
1879 | udc_ep_writel(ep, UDCCSR, UDCCSR0_FST); | ||
1880 | break; | ||
1881 | case IN_STATUS_STAGE: | ||
1882 | /* | ||
1883 | * Hardware bug : beware, we cannot clear OPC, since we would | ||
1884 | * miss a potential PC irq for a setup packet. | ||
1885 | * So, we only put the ep0 into WAIT_FOR_SETUP state. | ||
1886 | */ | ||
1887 | if (opc_irq) | ||
1888 | ep0_idle(udc); | ||
1889 | break; | ||
1890 | case OUT_STATUS_STAGE: | ||
1891 | case WAIT_ACK_SET_CONF_INTERF: | ||
1892 | ep_warn(ep, "should never get in %s state here!!!\n", | ||
1893 | EP0_STNAME(ep->dev)); | ||
1894 | ep0_idle(udc); | ||
1895 | break; | ||
1896 | } | ||
1897 | } | ||
1898 | |||
1899 | /** | ||
1900 | * handle_ep - Handle endpoint data tranfers | ||
1901 | * @ep: pxa physical endpoint | ||
1902 | * | ||
1903 | * Tries to transfer all pending request data into the endpoint and/or | ||
1904 | * transfer all pending data in the endpoint into usb requests. | ||
1905 | * | ||
1906 | * Is always called when in_interrupt() or with ep->lock held. | ||
1907 | */ | ||
1908 | static void handle_ep(struct pxa_ep *ep) | ||
1909 | { | ||
1910 | struct pxa27x_request *req; | ||
1911 | int completed; | ||
1912 | u32 udccsr; | ||
1913 | int is_in = ep->dir_in; | ||
1914 | int loop = 0; | ||
1915 | |||
1916 | do { | ||
1917 | completed = 0; | ||
1918 | udccsr = udc_ep_readl(ep, UDCCSR); | ||
1919 | if (likely(!list_empty(&ep->queue))) | ||
1920 | req = list_entry(ep->queue.next, | ||
1921 | struct pxa27x_request, queue); | ||
1922 | else | ||
1923 | req = NULL; | ||
1924 | |||
1925 | ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n", | ||
1926 | req, udccsr, loop++); | ||
1927 | |||
1928 | if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN))) | ||
1929 | udc_ep_writel(ep, UDCCSR, | ||
1930 | udccsr & (UDCCSR_SST | UDCCSR_TRN)); | ||
1931 | if (!req) | ||
1932 | break; | ||
1933 | |||
1934 | if (unlikely(is_in)) { | ||
1935 | if (likely(!ep_is_full(ep))) | ||
1936 | completed = write_fifo(ep, req); | ||
1937 | if (completed) | ||
1938 | ep_end_in_req(ep, req); | ||
1939 | } else { | ||
1940 | if (likely(epout_has_pkt(ep))) | ||
1941 | completed = read_fifo(ep, req); | ||
1942 | if (completed) | ||
1943 | ep_end_out_req(ep, req); | ||
1944 | } | ||
1945 | } while (completed); | ||
1946 | } | ||
1947 | |||
1948 | /** | ||
1949 | * pxa27x_change_configuration - Handle SET_CONF usb request notification | ||
1950 | * @udc: udc device | ||
1951 | * @config: usb configuration | ||
1952 | * | ||
1953 | * Post the request to upper level. | ||
1954 | * Don't use any pxa specific harware configuration capabilities | ||
1955 | */ | ||
1956 | static void pxa27x_change_configuration(struct pxa_udc *udc, int config) | ||
1957 | { | ||
1958 | struct usb_ctrlrequest req ; | ||
1959 | |||
1960 | dev_dbg(udc->dev, "config=%d\n", config); | ||
1961 | |||
1962 | udc->config = config; | ||
1963 | udc->last_interface = 0; | ||
1964 | udc->last_alternate = 0; | ||
1965 | |||
1966 | req.bRequestType = 0; | ||
1967 | req.bRequest = USB_REQ_SET_CONFIGURATION; | ||
1968 | req.wValue = config; | ||
1969 | req.wIndex = 0; | ||
1970 | req.wLength = 0; | ||
1971 | |||
1972 | set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); | ||
1973 | udc->driver->setup(&udc->gadget, &req); | ||
1974 | } | ||
1975 | |||
1976 | /** | ||
1977 | * pxa27x_change_interface - Handle SET_INTERF usb request notification | ||
1978 | * @udc: udc device | ||
1979 | * @iface: interface number | ||
1980 | * @alt: alternate setting number | ||
1981 | * | ||
1982 | * Post the request to upper level. | ||
1983 | * Don't use any pxa specific harware configuration capabilities | ||
1984 | */ | ||
1985 | static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt) | ||
1986 | { | ||
1987 | struct usb_ctrlrequest req; | ||
1988 | |||
1989 | dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt); | ||
1990 | |||
1991 | udc->last_interface = iface; | ||
1992 | udc->last_alternate = alt; | ||
1993 | |||
1994 | req.bRequestType = USB_RECIP_INTERFACE; | ||
1995 | req.bRequest = USB_REQ_SET_INTERFACE; | ||
1996 | req.wValue = alt; | ||
1997 | req.wIndex = iface; | ||
1998 | req.wLength = 0; | ||
1999 | |||
2000 | set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); | ||
2001 | udc->driver->setup(&udc->gadget, &req); | ||
2002 | } | ||
2003 | |||
2004 | /* | ||
2005 | * irq_handle_data - Handle data transfer | ||
2006 | * @irq: irq IRQ number | ||
2007 | * @udc: dev pxa_udc device structure | ||
2008 | * | ||
2009 | * Called from irq handler, transferts data to or from endpoint to queue | ||
2010 | */ | ||
2011 | static void irq_handle_data(int irq, struct pxa_udc *udc) | ||
2012 | { | ||
2013 | int i; | ||
2014 | struct pxa_ep *ep; | ||
2015 | u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK; | ||
2016 | u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK; | ||
2017 | |||
2018 | if (udcisr0 & UDCISR_INT_MASK) { | ||
2019 | udc->pxa_ep[0].stats.irqs++; | ||
2020 | udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK)); | ||
2021 | handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR), | ||
2022 | !!(udcisr0 & UDCICR_PKTCOMPL)); | ||
2023 | } | ||
2024 | |||
2025 | udcisr0 >>= 2; | ||
2026 | for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) { | ||
2027 | if (!(udcisr0 & UDCISR_INT_MASK)) | ||
2028 | continue; | ||
2029 | |||
2030 | udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK)); | ||
2031 | ep = &udc->pxa_ep[i]; | ||
2032 | ep->stats.irqs++; | ||
2033 | handle_ep(ep); | ||
2034 | } | ||
2035 | |||
2036 | for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) { | ||
2037 | udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK)); | ||
2038 | if (!(udcisr1 & UDCISR_INT_MASK)) | ||
2039 | continue; | ||
2040 | |||
2041 | ep = &udc->pxa_ep[i]; | ||
2042 | ep->stats.irqs++; | ||
2043 | handle_ep(ep); | ||
2044 | } | ||
2045 | |||
2046 | } | ||
2047 | |||
2048 | /** | ||
2049 | * irq_udc_suspend - Handle IRQ "UDC Suspend" | ||
2050 | * @udc: udc device | ||
2051 | */ | ||
2052 | static void irq_udc_suspend(struct pxa_udc *udc) | ||
2053 | { | ||
2054 | udc_writel(udc, UDCISR1, UDCISR1_IRSU); | ||
2055 | udc->stats.irqs_suspend++; | ||
2056 | |||
2057 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
2058 | && udc->driver && udc->driver->suspend) | ||
2059 | udc->driver->suspend(&udc->gadget); | ||
2060 | ep0_idle(udc); | ||
2061 | } | ||
2062 | |||
2063 | /** | ||
2064 | * irq_udc_resume - Handle IRQ "UDC Resume" | ||
2065 | * @udc: udc device | ||
2066 | */ | ||
2067 | static void irq_udc_resume(struct pxa_udc *udc) | ||
2068 | { | ||
2069 | udc_writel(udc, UDCISR1, UDCISR1_IRRU); | ||
2070 | udc->stats.irqs_resume++; | ||
2071 | |||
2072 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
2073 | && udc->driver && udc->driver->resume) | ||
2074 | udc->driver->resume(&udc->gadget); | ||
2075 | } | ||
2076 | |||
2077 | /** | ||
2078 | * irq_udc_reconfig - Handle IRQ "UDC Change Configuration" | ||
2079 | * @udc: udc device | ||
2080 | */ | ||
2081 | static void irq_udc_reconfig(struct pxa_udc *udc) | ||
2082 | { | ||
2083 | unsigned config, interface, alternate, config_change; | ||
2084 | u32 udccr = udc_readl(udc, UDCCR); | ||
2085 | |||
2086 | udc_writel(udc, UDCISR1, UDCISR1_IRCC); | ||
2087 | udc->stats.irqs_reconfig++; | ||
2088 | |||
2089 | config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S; | ||
2090 | config_change = (config != udc->config); | ||
2091 | pxa27x_change_configuration(udc, config); | ||
2092 | |||
2093 | interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S; | ||
2094 | alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S; | ||
2095 | pxa27x_change_interface(udc, interface, alternate); | ||
2096 | |||
2097 | if (config_change) | ||
2098 | update_pxa_ep_matches(udc); | ||
2099 | udc_set_mask_UDCCR(udc, UDCCR_SMAC); | ||
2100 | } | ||
2101 | |||
2102 | /** | ||
2103 | * irq_udc_reset - Handle IRQ "UDC Reset" | ||
2104 | * @udc: udc device | ||
2105 | */ | ||
2106 | static void irq_udc_reset(struct pxa_udc *udc) | ||
2107 | { | ||
2108 | u32 udccr = udc_readl(udc, UDCCR); | ||
2109 | struct pxa_ep *ep = &udc->pxa_ep[0]; | ||
2110 | |||
2111 | dev_info(udc->dev, "USB reset\n"); | ||
2112 | udc_writel(udc, UDCISR1, UDCISR1_IRRS); | ||
2113 | udc->stats.irqs_reset++; | ||
2114 | |||
2115 | if ((udccr & UDCCR_UDA) == 0) { | ||
2116 | dev_dbg(udc->dev, "USB reset start\n"); | ||
2117 | stop_activity(udc, udc->driver); | ||
2118 | } | ||
2119 | udc->gadget.speed = USB_SPEED_FULL; | ||
2120 | memset(&udc->stats, 0, sizeof udc->stats); | ||
2121 | |||
2122 | nuke(ep, -EPROTO); | ||
2123 | udc_ep_writel(ep, UDCCSR, UDCCSR0_FTF | UDCCSR0_OPC); | ||
2124 | ep0_idle(udc); | ||
2125 | } | ||
2126 | |||
2127 | /** | ||
2128 | * pxa_udc_irq - Main irq handler | ||
2129 | * @irq: irq number | ||
2130 | * @_dev: udc device | ||
2131 | * | ||
2132 | * Handles all udc interrupts | ||
2133 | */ | ||
2134 | static irqreturn_t pxa_udc_irq(int irq, void *_dev) | ||
2135 | { | ||
2136 | struct pxa_udc *udc = _dev; | ||
2137 | u32 udcisr0 = udc_readl(udc, UDCISR0); | ||
2138 | u32 udcisr1 = udc_readl(udc, UDCISR1); | ||
2139 | u32 udccr = udc_readl(udc, UDCCR); | ||
2140 | u32 udcisr1_spec; | ||
2141 | |||
2142 | dev_vdbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, " | ||
2143 | "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr); | ||
2144 | |||
2145 | udcisr1_spec = udcisr1 & 0xf8000000; | ||
2146 | if (unlikely(udcisr1_spec & UDCISR1_IRSU)) | ||
2147 | irq_udc_suspend(udc); | ||
2148 | if (unlikely(udcisr1_spec & UDCISR1_IRRU)) | ||
2149 | irq_udc_resume(udc); | ||
2150 | if (unlikely(udcisr1_spec & UDCISR1_IRCC)) | ||
2151 | irq_udc_reconfig(udc); | ||
2152 | if (unlikely(udcisr1_spec & UDCISR1_IRRS)) | ||
2153 | irq_udc_reset(udc); | ||
2154 | |||
2155 | if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK)) | ||
2156 | irq_handle_data(irq, udc); | ||
2157 | |||
2158 | return IRQ_HANDLED; | ||
2159 | } | ||
2160 | |||
2161 | static struct pxa_udc memory = { | ||
2162 | .gadget = { | ||
2163 | .ops = &pxa_udc_ops, | ||
2164 | .ep0 = &memory.udc_usb_ep[0].usb_ep, | ||
2165 | .name = driver_name, | ||
2166 | .dev = { | ||
2167 | .bus_id = "gadget", | ||
2168 | }, | ||
2169 | }, | ||
2170 | |||
2171 | .udc_usb_ep = { | ||
2172 | USB_EP_CTRL, | ||
2173 | USB_EP_OUT_BULK(1), | ||
2174 | USB_EP_IN_BULK(2), | ||
2175 | USB_EP_IN_ISO(3), | ||
2176 | USB_EP_OUT_ISO(4), | ||
2177 | USB_EP_IN_INT(5), | ||
2178 | }, | ||
2179 | |||
2180 | .pxa_ep = { | ||
2181 | PXA_EP_CTRL, | ||
2182 | /* Endpoints for gadget zero */ | ||
2183 | PXA_EP_OUT_BULK(1, 1, 3, 0, 0), | ||
2184 | PXA_EP_IN_BULK(2, 2, 3, 0, 0), | ||
2185 | /* Endpoints for ether gadget, file storage gadget */ | ||
2186 | PXA_EP_OUT_BULK(3, 1, 1, 0, 0), | ||
2187 | PXA_EP_IN_BULK(4, 2, 1, 0, 0), | ||
2188 | PXA_EP_IN_ISO(5, 3, 1, 0, 0), | ||
2189 | PXA_EP_OUT_ISO(6, 4, 1, 0, 0), | ||
2190 | PXA_EP_IN_INT(7, 5, 1, 0, 0), | ||
2191 | /* Endpoints for RNDIS, serial */ | ||
2192 | PXA_EP_OUT_BULK(8, 1, 2, 0, 0), | ||
2193 | PXA_EP_IN_BULK(9, 2, 2, 0, 0), | ||
2194 | PXA_EP_IN_INT(10, 5, 2, 0, 0), | ||
2195 | /* | ||
2196 | * All the following endpoints are only for completion. They | ||
2197 | * won't never work, as multiple interfaces are really broken on | ||
2198 | * the pxa. | ||
2199 | */ | ||
2200 | PXA_EP_OUT_BULK(11, 1, 2, 1, 0), | ||
2201 | PXA_EP_IN_BULK(12, 2, 2, 1, 0), | ||
2202 | /* Endpoint for CDC Ether */ | ||
2203 | PXA_EP_OUT_BULK(13, 1, 1, 1, 1), | ||
2204 | PXA_EP_IN_BULK(14, 2, 1, 1, 1), | ||
2205 | } | ||
2206 | }; | ||
2207 | |||
2208 | /** | ||
2209 | * pxa_udc_probe - probes the udc device | ||
2210 | * @_dev: platform device | ||
2211 | * | ||
2212 | * Perform basic init : allocates udc clock, creates sysfs files, requests | ||
2213 | * irq. | ||
2214 | */ | ||
2215 | static int __init pxa_udc_probe(struct platform_device *pdev) | ||
2216 | { | ||
2217 | struct resource *regs; | ||
2218 | struct pxa_udc *udc = &memory; | ||
2219 | int retval; | ||
2220 | |||
2221 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2222 | if (!regs) | ||
2223 | return -ENXIO; | ||
2224 | udc->irq = platform_get_irq(pdev, 0); | ||
2225 | if (udc->irq < 0) | ||
2226 | return udc->irq; | ||
2227 | |||
2228 | udc->dev = &pdev->dev; | ||
2229 | udc->mach = pdev->dev.platform_data; | ||
2230 | |||
2231 | udc->clk = clk_get(&pdev->dev, "UDCCLK"); | ||
2232 | if (IS_ERR(udc->clk)) { | ||
2233 | retval = PTR_ERR(udc->clk); | ||
2234 | goto err_clk; | ||
2235 | } | ||
2236 | |||
2237 | retval = -ENOMEM; | ||
2238 | udc->regs = ioremap(regs->start, regs->end - regs->start + 1); | ||
2239 | if (!udc->regs) { | ||
2240 | dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); | ||
2241 | goto err_map; | ||
2242 | } | ||
2243 | |||
2244 | device_initialize(&udc->gadget.dev); | ||
2245 | udc->gadget.dev.parent = &pdev->dev; | ||
2246 | udc->gadget.dev.dma_mask = NULL; | ||
2247 | |||
2248 | the_controller = udc; | ||
2249 | platform_set_drvdata(pdev, udc); | ||
2250 | udc_init_data(udc); | ||
2251 | pxa_eps_setup(udc); | ||
2252 | |||
2253 | /* irq setup after old hardware state is cleaned up */ | ||
2254 | retval = request_irq(udc->irq, pxa_udc_irq, | ||
2255 | IRQF_SHARED, driver_name, udc); | ||
2256 | if (retval != 0) { | ||
2257 | dev_err(udc->dev, "%s: can't get irq %i, err %d\n", | ||
2258 | driver_name, IRQ_USB, retval); | ||
2259 | goto err_irq; | ||
2260 | } | ||
2261 | |||
2262 | pxa_init_debugfs(udc); | ||
2263 | return 0; | ||
2264 | err_irq: | ||
2265 | iounmap(udc->regs); | ||
2266 | err_map: | ||
2267 | clk_put(udc->clk); | ||
2268 | udc->clk = NULL; | ||
2269 | err_clk: | ||
2270 | return retval; | ||
2271 | } | ||
2272 | |||
2273 | /** | ||
2274 | * pxa_udc_remove - removes the udc device driver | ||
2275 | * @_dev: platform device | ||
2276 | */ | ||
2277 | static int __exit pxa_udc_remove(struct platform_device *_dev) | ||
2278 | { | ||
2279 | struct pxa_udc *udc = platform_get_drvdata(_dev); | ||
2280 | |||
2281 | usb_gadget_unregister_driver(udc->driver); | ||
2282 | free_irq(udc->irq, udc); | ||
2283 | pxa_cleanup_debugfs(udc); | ||
2284 | |||
2285 | platform_set_drvdata(_dev, NULL); | ||
2286 | the_controller = NULL; | ||
2287 | clk_put(udc->clk); | ||
2288 | |||
2289 | return 0; | ||
2290 | } | ||
2291 | |||
2292 | static void pxa_udc_shutdown(struct platform_device *_dev) | ||
2293 | { | ||
2294 | struct pxa_udc *udc = platform_get_drvdata(_dev); | ||
2295 | |||
2296 | if (udc_readl(udc, UDCCR) & UDCCR_UDE) | ||
2297 | udc_disable(udc); | ||
2298 | } | ||
2299 | |||
2300 | #ifdef CONFIG_PM | ||
2301 | /** | ||
2302 | * pxa_udc_suspend - Suspend udc device | ||
2303 | * @_dev: platform device | ||
2304 | * @state: suspend state | ||
2305 | * | ||
2306 | * Suspends udc : saves configuration registers (UDCCR*), then disables the udc | ||
2307 | * device. | ||
2308 | */ | ||
2309 | static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | ||
2310 | { | ||
2311 | int i; | ||
2312 | struct pxa_udc *udc = platform_get_drvdata(_dev); | ||
2313 | struct pxa_ep *ep; | ||
2314 | |||
2315 | ep = &udc->pxa_ep[0]; | ||
2316 | udc->udccsr0 = udc_ep_readl(ep, UDCCSR); | ||
2317 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) { | ||
2318 | ep = &udc->pxa_ep[i]; | ||
2319 | ep->udccsr_value = udc_ep_readl(ep, UDCCSR); | ||
2320 | ep->udccr_value = udc_ep_readl(ep, UDCCR); | ||
2321 | ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", | ||
2322 | ep->udccsr_value, ep->udccr_value); | ||
2323 | } | ||
2324 | |||
2325 | udc_disable(udc); | ||
2326 | |||
2327 | return 0; | ||
2328 | } | ||
2329 | |||
2330 | /** | ||
2331 | * pxa_udc_resume - Resume udc device | ||
2332 | * @_dev: platform device | ||
2333 | * | ||
2334 | * Resumes udc : restores configuration registers (UDCCR*), then enables the udc | ||
2335 | * device. | ||
2336 | */ | ||
2337 | static int pxa_udc_resume(struct platform_device *_dev) | ||
2338 | { | ||
2339 | int i; | ||
2340 | struct pxa_udc *udc = platform_get_drvdata(_dev); | ||
2341 | struct pxa_ep *ep; | ||
2342 | |||
2343 | ep = &udc->pxa_ep[0]; | ||
2344 | udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); | ||
2345 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) { | ||
2346 | ep = &udc->pxa_ep[i]; | ||
2347 | udc_ep_writel(ep, UDCCSR, ep->udccsr_value); | ||
2348 | udc_ep_writel(ep, UDCCR, ep->udccr_value); | ||
2349 | ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", | ||
2350 | ep->udccsr_value, ep->udccr_value); | ||
2351 | } | ||
2352 | |||
2353 | udc_enable(udc); | ||
2354 | /* | ||
2355 | * We do not handle OTG yet. | ||
2356 | * | ||
2357 | * OTGPH bit is set when sleep mode is entered. | ||
2358 | * it indicates that OTG pad is retaining its state. | ||
2359 | * Upon exit from sleep mode and before clearing OTGPH, | ||
2360 | * Software must configure the USB OTG pad, UDC, and UHC | ||
2361 | * to the state they were in before entering sleep mode. | ||
2362 | */ | ||
2363 | PSSR |= PSSR_OTGPH; | ||
2364 | |||
2365 | return 0; | ||
2366 | } | ||
2367 | #endif | ||
2368 | |||
2369 | /* work with hotplug and coldplug */ | ||
2370 | MODULE_ALIAS("platform:pxa2xx-udc"); | ||
2371 | |||
2372 | static struct platform_driver udc_driver = { | ||
2373 | .driver = { | ||
2374 | .name = "pxa2xx-udc", | ||
2375 | .owner = THIS_MODULE, | ||
2376 | }, | ||
2377 | .remove = __exit_p(pxa_udc_remove), | ||
2378 | .shutdown = pxa_udc_shutdown, | ||
2379 | #ifdef CONFIG_PM | ||
2380 | .suspend = pxa_udc_suspend, | ||
2381 | .resume = pxa_udc_resume | ||
2382 | #endif | ||
2383 | }; | ||
2384 | |||
2385 | static int __init udc_init(void) | ||
2386 | { | ||
2387 | if (!cpu_is_pxa27x()) | ||
2388 | return -ENODEV; | ||
2389 | |||
2390 | printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); | ||
2391 | return platform_driver_probe(&udc_driver, pxa_udc_probe); | ||
2392 | } | ||
2393 | module_init(udc_init); | ||
2394 | |||
2395 | |||
2396 | static void __exit udc_exit(void) | ||
2397 | { | ||
2398 | platform_driver_unregister(&udc_driver); | ||
2399 | } | ||
2400 | module_exit(udc_exit); | ||
2401 | |||
2402 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
2403 | MODULE_AUTHOR("Robert Jarzmik"); | ||
2404 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h new file mode 100644 index 000000000000..97453db924ff --- /dev/null +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
@@ -0,0 +1,495 @@ | |||
1 | /* | ||
2 | * linux/drivers/usb/gadget/pxa27x_udc.h | ||
3 | * Intel PXA27x on-chip full speed USB device controller | ||
4 | * | ||
5 | * Inspired by original driver by Frank Becker, David Brownell, and others. | ||
6 | * Copyright (C) 2008 Robert Jarzmik | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_USB_GADGET_PXA27X_H | ||
24 | #define __LINUX_USB_GADGET_PXA27X_H | ||
25 | |||
26 | #include <linux/types.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/io.h> | ||
29 | |||
30 | /* | ||
31 | * Register definitions | ||
32 | */ | ||
33 | /* Offsets */ | ||
34 | #define UDCCR 0x0000 /* UDC Control Register */ | ||
35 | #define UDCICR0 0x0004 /* UDC Interrupt Control Register0 */ | ||
36 | #define UDCICR1 0x0008 /* UDC Interrupt Control Register1 */ | ||
37 | #define UDCISR0 0x000C /* UDC Interrupt Status Register 0 */ | ||
38 | #define UDCISR1 0x0010 /* UDC Interrupt Status Register 1 */ | ||
39 | #define UDCFNR 0x0014 /* UDC Frame Number Register */ | ||
40 | #define UDCOTGICR 0x0018 /* UDC On-The-Go interrupt control */ | ||
41 | #define UP2OCR 0x0020 /* USB Port 2 Output Control register */ | ||
42 | #define UP3OCR 0x0024 /* USB Port 3 Output Control register */ | ||
43 | #define UDCCSRn(x) (0x0100 + ((x)<<2)) /* UDC Control/Status register */ | ||
44 | #define UDCBCRn(x) (0x0200 + ((x)<<2)) /* UDC Byte Count Register */ | ||
45 | #define UDCDRn(x) (0x0300 + ((x)<<2)) /* UDC Data Register */ | ||
46 | #define UDCCRn(x) (0x0400 + ((x)<<2)) /* UDC Control Register */ | ||
47 | |||
48 | #define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ | ||
49 | #define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation | ||
50 | Protocol Port Support */ | ||
51 | #define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol | ||
52 | Support */ | ||
53 | #define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol | ||
54 | Enable */ | ||
55 | #define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ | ||
56 | #define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ | ||
57 | #define UDCCR_ACN_S 11 | ||
58 | #define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ | ||
59 | #define UDCCR_AIN_S 8 | ||
60 | #define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface | ||
61 | Setting Number */ | ||
62 | #define UDCCR_AAISN_S 5 | ||
63 | #define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active | ||
64 | Configuration */ | ||
65 | #define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration | ||
66 | Error */ | ||
67 | #define UDCCR_UDR (1 << 2) /* UDC Resume */ | ||
68 | #define UDCCR_UDA (1 << 1) /* UDC Active */ | ||
69 | #define UDCCR_UDE (1 << 0) /* UDC Enable */ | ||
70 | |||
71 | #define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) | ||
72 | #define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ | ||
73 | #define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ | ||
74 | #define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ | ||
75 | #define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ | ||
76 | #define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ | ||
77 | #define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ | ||
78 | #define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ | ||
79 | #define UDCICR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) | ||
80 | |||
81 | #define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) | ||
82 | #define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ | ||
83 | #define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ | ||
84 | #define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ | ||
85 | #define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ | ||
86 | #define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ | ||
87 | #define UDCISR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) | ||
88 | |||
89 | #define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ | ||
90 | #define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt | ||
91 | Rising Edge Interrupt Enable */ | ||
92 | #define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt | ||
93 | Falling Edge Interrupt Enable */ | ||
94 | #define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge | ||
95 | Interrupt Enable */ | ||
96 | #define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge | ||
97 | Interrupt Enable */ | ||
98 | #define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge | ||
99 | Interrupt Enable */ | ||
100 | #define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge | ||
101 | Interrupt Enable */ | ||
102 | #define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge | ||
103 | Interrupt Enable */ | ||
104 | #define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge | ||
105 | Interrupt Enable */ | ||
106 | #define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising | ||
107 | Edge Interrupt Enable */ | ||
108 | #define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling | ||
109 | Edge Interrupt Enable */ | ||
110 | #define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge | ||
111 | Interrupt Enable */ | ||
112 | #define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge | ||
113 | Interrupt Enable */ | ||
114 | |||
115 | /* Host Port 2 field bits */ | ||
116 | #define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ | ||
117 | #define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ | ||
118 | /* Transceiver enablers */ | ||
119 | #define UP2OCR_DPPDE (1 << 2) /* D+ Pull Down Enable */ | ||
120 | #define UP2OCR_DMPDE (1 << 3) /* D- Pull Down Enable */ | ||
121 | #define UP2OCR_DPPUE (1 << 4) /* D+ Pull Up Enable */ | ||
122 | #define UP2OCR_DMPUE (1 << 5) /* D- Pull Up Enable */ | ||
123 | #define UP2OCR_DPPUBE (1 << 6) /* D+ Pull Up Bypass Enable */ | ||
124 | #define UP2OCR_DMPUBE (1 << 7) /* D- Pull Up Bypass Enable */ | ||
125 | #define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ | ||
126 | #define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ | ||
127 | #define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ | ||
128 | #define UP2OCR_HXS (1 << 16) /* Transceiver Output Select */ | ||
129 | #define UP2OCR_HXOE (1 << 17) /* Transceiver Output Enable */ | ||
130 | #define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ | ||
131 | |||
132 | #define UDCCSR0_SA (1 << 7) /* Setup Active */ | ||
133 | #define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ | ||
134 | #define UDCCSR0_FST (1 << 5) /* Force Stall */ | ||
135 | #define UDCCSR0_SST (1 << 4) /* Sent Stall */ | ||
136 | #define UDCCSR0_DME (1 << 3) /* DMA Enable */ | ||
137 | #define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ | ||
138 | #define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ | ||
139 | #define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ | ||
140 | |||
141 | #define UDCCSR_DPE (1 << 9) /* Data Packet Error */ | ||
142 | #define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ | ||
143 | #define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ | ||
144 | #define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ | ||
145 | #define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ | ||
146 | #define UDCCSR_FST (1 << 5) /* Force STALL */ | ||
147 | #define UDCCSR_SST (1 << 4) /* Sent STALL */ | ||
148 | #define UDCCSR_DME (1 << 3) /* DMA Enable */ | ||
149 | #define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ | ||
150 | #define UDCCSR_PC (1 << 1) /* Packet Complete */ | ||
151 | #define UDCCSR_FS (1 << 0) /* FIFO needs service */ | ||
152 | |||
153 | #define UDCCONR_CN (0x03 << 25) /* Configuration Number */ | ||
154 | #define UDCCONR_CN_S 25 | ||
155 | #define UDCCONR_IN (0x07 << 22) /* Interface Number */ | ||
156 | #define UDCCONR_IN_S 22 | ||
157 | #define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ | ||
158 | #define UDCCONR_AISN_S 19 | ||
159 | #define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ | ||
160 | #define UDCCONR_EN_S 15 | ||
161 | #define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ | ||
162 | #define UDCCONR_ET_S 13 | ||
163 | #define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ | ||
164 | #define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ | ||
165 | #define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ | ||
166 | #define UDCCONR_ET_NU (0x00 << 13) /* Not used */ | ||
167 | #define UDCCONR_ED (1 << 12) /* Endpoint Direction */ | ||
168 | #define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ | ||
169 | #define UDCCONR_MPS_S 2 | ||
170 | #define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ | ||
171 | #define UDCCONR_EE (1 << 0) /* Endpoint Enable */ | ||
172 | |||
173 | #define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_SMAC | UDCCR_UDR | UDCCR_UDE) | ||
174 | #define UDCCSR_WR_MASK (UDCCSR_DME | UDCCSR_FST) | ||
175 | #define UDC_FNR_MASK (0x7ff) | ||
176 | #define UDC_BCR_MASK (0x3ff) | ||
177 | |||
178 | /* | ||
179 | * UDCCR = UDC Endpoint Configuration Registers | ||
180 | * UDCCSR = UDC Control/Status Register for this EP | ||
181 | * UDCBCR = UDC Byte Count Remaining (contents of OUT fifo) | ||
182 | * UDCDR = UDC Endpoint Data Register (the fifo) | ||
183 | */ | ||
184 | #define ofs_UDCCR(ep) (UDCCRn(ep->idx)) | ||
185 | #define ofs_UDCCSR(ep) (UDCCSRn(ep->idx)) | ||
186 | #define ofs_UDCBCR(ep) (UDCBCRn(ep->idx)) | ||
187 | #define ofs_UDCDR(ep) (UDCDRn(ep->idx)) | ||
188 | |||
189 | /* Register access macros */ | ||
190 | #define udc_ep_readl(ep, reg) \ | ||
191 | __raw_readl((ep)->dev->regs + ofs_##reg(ep)) | ||
192 | #define udc_ep_writel(ep, reg, value) \ | ||
193 | __raw_writel((value), ep->dev->regs + ofs_##reg(ep)) | ||
194 | #define udc_ep_readb(ep, reg) \ | ||
195 | __raw_readb((ep)->dev->regs + ofs_##reg(ep)) | ||
196 | #define udc_ep_writeb(ep, reg, value) \ | ||
197 | __raw_writeb((value), ep->dev->regs + ofs_##reg(ep)) | ||
198 | #define udc_readl(dev, reg) \ | ||
199 | __raw_readl((dev)->regs + (reg)) | ||
200 | #define udc_writel(udc, reg, value) \ | ||
201 | __raw_writel((value), (udc)->regs + (reg)) | ||
202 | |||
203 | #define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME) | ||
204 | #define UDCCISR0_EP_MASK ~0 | ||
205 | #define UDCCISR1_EP_MASK 0xffff | ||
206 | #define UDCCSR0_CTRL_REQ_MASK (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE) | ||
207 | |||
208 | #define EPIDX(ep) (ep->idx) | ||
209 | #define EPADDR(ep) (ep->addr) | ||
210 | #define EPXFERTYPE(ep) (ep->type) | ||
211 | #define EPNAME(ep) (ep->name) | ||
212 | #define is_ep0(ep) (!ep->idx) | ||
213 | #define EPXFERTYPE_is_ISO(ep) (EPXFERTYPE(ep) == USB_ENDPOINT_XFER_ISOC) | ||
214 | |||
215 | /* | ||
216 | * Endpoint definitions | ||
217 | * | ||
218 | * Once enabled, pxa endpoint configuration is freezed, and cannot change | ||
219 | * unless a reset happens or the udc is disabled. | ||
220 | * Therefore, we must define all pxa potential endpoint definitions needed for | ||
221 | * all gadget and set them up before the udc is enabled. | ||
222 | * | ||
223 | * As the architecture chosen is fully static, meaning the pxa endpoint | ||
224 | * configurations are set up once and for all, we must provide a way to match | ||
225 | * one usb endpoint (usb_ep) to several pxa endpoints. The reason is that gadget | ||
226 | * layer autoconf doesn't choose the usb_ep endpoint on (config, interface, alt) | ||
227 | * criteria, while the pxa architecture requires that. | ||
228 | * | ||
229 | * The solution is to define several pxa endpoints matching one usb_ep. Ex: | ||
230 | * - "ep1-in" matches pxa endpoint EPA (which is an IN ep at addr 1, when | ||
231 | * the udc talks on (config=3, interface=0, alt=0) | ||
232 | * - "ep1-in" matches pxa endpoint EPB (which is an IN ep at addr 1, when | ||
233 | * the udc talks on (config=3, interface=0, alt=1) | ||
234 | * - "ep1-in" matches pxa endpoint EPC (which is an IN ep at addr 1, when | ||
235 | * the udc talks on (config=2, interface=0, alt=0) | ||
236 | * | ||
237 | * We'll define the pxa endpoint by its index (EPA => idx=1, EPB => idx=2, ...) | ||
238 | */ | ||
239 | |||
240 | /* | ||
241 | * Endpoint definition helpers | ||
242 | */ | ||
243 | #define USB_EP_DEF(addr, bname, dir, type, maxpkt) \ | ||
244 | { .usb_ep = { .name = bname, .ops = &pxa_ep_ops, .maxpacket = maxpkt, }, \ | ||
245 | .desc = { .bEndpointAddress = addr | (dir ? USB_DIR_IN : 0), \ | ||
246 | .bmAttributes = type, \ | ||
247 | .wMaxPacketSize = maxpkt, }, \ | ||
248 | .dev = &memory \ | ||
249 | } | ||
250 | #define USB_EP_BULK(addr, bname, dir) \ | ||
251 | USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE) | ||
252 | #define USB_EP_ISO(addr, bname, dir) \ | ||
253 | USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE) | ||
254 | #define USB_EP_INT(addr, bname, dir) \ | ||
255 | USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE) | ||
256 | #define USB_EP_IN_BULK(n) USB_EP_BULK(n, "ep" #n "in-bulk", 1) | ||
257 | #define USB_EP_OUT_BULK(n) USB_EP_BULK(n, "ep" #n "out-bulk", 0) | ||
258 | #define USB_EP_IN_ISO(n) USB_EP_ISO(n, "ep" #n "in-iso", 1) | ||
259 | #define USB_EP_OUT_ISO(n) USB_EP_ISO(n, "ep" #n "out-iso", 0) | ||
260 | #define USB_EP_IN_INT(n) USB_EP_INT(n, "ep" #n "in-int", 1) | ||
261 | #define USB_EP_CTRL USB_EP_DEF(0, "ep0", 0, 0, EP0_FIFO_SIZE) | ||
262 | |||
263 | #define PXA_EP_DEF(_idx, _addr, dir, _type, maxpkt, _config, iface, altset) \ | ||
264 | { \ | ||
265 | .dev = &memory, \ | ||
266 | .name = "ep" #_idx, \ | ||
267 | .idx = _idx, .enabled = 0, \ | ||
268 | .dir_in = dir, .addr = _addr, \ | ||
269 | .config = _config, .interface = iface, .alternate = altset, \ | ||
270 | .type = _type, .fifo_size = maxpkt, \ | ||
271 | } | ||
272 | #define PXA_EP_BULK(_idx, addr, dir, config, iface, alt) \ | ||
273 | PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE, \ | ||
274 | config, iface, alt) | ||
275 | #define PXA_EP_ISO(_idx, addr, dir, config, iface, alt) \ | ||
276 | PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE, \ | ||
277 | config, iface, alt) | ||
278 | #define PXA_EP_INT(_idx, addr, dir, config, iface, alt) \ | ||
279 | PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE, \ | ||
280 | config, iface, alt) | ||
281 | #define PXA_EP_IN_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 1, c, f, a) | ||
282 | #define PXA_EP_OUT_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 0, c, f, a) | ||
283 | #define PXA_EP_IN_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 1, c, f, a) | ||
284 | #define PXA_EP_OUT_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 0, c, f, a) | ||
285 | #define PXA_EP_IN_INT(i, adr, c, f, a) PXA_EP_INT(i, adr, 1, c, f, a) | ||
286 | #define PXA_EP_CTRL PXA_EP_DEF(0, 0, 0, 0, EP0_FIFO_SIZE, 0, 0, 0) | ||
287 | |||
288 | struct pxa27x_udc; | ||
289 | |||
290 | struct stats { | ||
291 | unsigned long in_ops; | ||
292 | unsigned long out_ops; | ||
293 | unsigned long in_bytes; | ||
294 | unsigned long out_bytes; | ||
295 | unsigned long irqs; | ||
296 | }; | ||
297 | |||
298 | /** | ||
299 | * struct udc_usb_ep - container of each usb_ep structure | ||
300 | * @usb_ep: usb endpoint | ||
301 | * @desc: usb descriptor, especially type and address | ||
302 | * @dev: udc managing this endpoint | ||
303 | * @pxa_ep: matching pxa_ep (cache of find_pxa_ep() call) | ||
304 | */ | ||
305 | struct udc_usb_ep { | ||
306 | struct usb_ep usb_ep; | ||
307 | struct usb_endpoint_descriptor desc; | ||
308 | struct pxa_udc *dev; | ||
309 | struct pxa_ep *pxa_ep; | ||
310 | }; | ||
311 | |||
312 | /** | ||
313 | * struct pxa_ep - pxa endpoint | ||
314 | * @dev: udc device | ||
315 | * @queue: requests queue | ||
316 | * @lock: lock to pxa_ep data (queues and stats) | ||
317 | * @enabled: true when endpoint enabled (not stopped by gadget layer) | ||
318 | * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) | ||
319 | * @name: endpoint name (for trace/debug purpose) | ||
320 | * @dir_in: 1 if IN endpoint, 0 if OUT endpoint | ||
321 | * @addr: usb endpoint number | ||
322 | * @config: configuration in which this endpoint is active | ||
323 | * @interface: interface in which this endpoint is active | ||
324 | * @alternate: altsetting in which this endpoitn is active | ||
325 | * @fifo_size: max packet size in the endpoint fifo | ||
326 | * @type: endpoint type (bulk, iso, int, ...) | ||
327 | * @udccsr_value: save register of UDCCSR0 for suspend/resume | ||
328 | * @udccr_value: save register of UDCCR for suspend/resume | ||
329 | * @stats: endpoint statistics | ||
330 | * | ||
331 | * The *PROBLEM* is that pxa's endpoint configuration scheme is both misdesigned | ||
332 | * (cares about config/interface/altsetting, thus placing needless limits on | ||
333 | * device capability) and full of implementation bugs forcing it to be set up | ||
334 | * for use more or less like a pxa255. | ||
335 | * | ||
336 | * As we define the pxa_ep statically, we must guess all needed pxa_ep for all | ||
337 | * gadget which may work with this udc driver. | ||
338 | */ | ||
339 | struct pxa_ep { | ||
340 | struct pxa_udc *dev; | ||
341 | |||
342 | struct list_head queue; | ||
343 | spinlock_t lock; /* Protects this structure */ | ||
344 | /* (queues, stats) */ | ||
345 | unsigned enabled:1; | ||
346 | |||
347 | unsigned idx:5; | ||
348 | char *name; | ||
349 | |||
350 | /* | ||
351 | * Specific pxa endpoint data, needed for hardware initialization | ||
352 | */ | ||
353 | unsigned dir_in:1; | ||
354 | unsigned addr:3; | ||
355 | unsigned config:2; | ||
356 | unsigned interface:3; | ||
357 | unsigned alternate:3; | ||
358 | unsigned fifo_size; | ||
359 | unsigned type; | ||
360 | |||
361 | #ifdef CONFIG_PM | ||
362 | u32 udccsr_value; | ||
363 | u32 udccr_value; | ||
364 | #endif | ||
365 | struct stats stats; | ||
366 | }; | ||
367 | |||
368 | /** | ||
369 | * struct pxa27x_request - container of each usb_request structure | ||
370 | * @req: usb request | ||
371 | * @udc_usb_ep: usb endpoint the request was submitted on | ||
372 | * @in_use: sanity check if request already queued on an pxa_ep | ||
373 | * @queue: linked list of requests, linked on pxa_ep->queue | ||
374 | */ | ||
375 | struct pxa27x_request { | ||
376 | struct usb_request req; | ||
377 | struct udc_usb_ep *udc_usb_ep; | ||
378 | unsigned in_use:1; | ||
379 | struct list_head queue; | ||
380 | }; | ||
381 | |||
382 | enum ep0_state { | ||
383 | WAIT_FOR_SETUP, | ||
384 | SETUP_STAGE, | ||
385 | IN_DATA_STAGE, | ||
386 | OUT_DATA_STAGE, | ||
387 | IN_STATUS_STAGE, | ||
388 | OUT_STATUS_STAGE, | ||
389 | STALL, | ||
390 | WAIT_ACK_SET_CONF_INTERF | ||
391 | }; | ||
392 | |||
393 | static char *ep0_state_name[] = { | ||
394 | "WAIT_FOR_SETUP", "SETUP_STAGE", "IN_DATA_STAGE", "OUT_DATA_STAGE", | ||
395 | "IN_STATUS_STAGE", "OUT_STATUS_STAGE", "STALL", | ||
396 | "WAIT_ACK_SET_CONF_INTERF" | ||
397 | }; | ||
398 | #define EP0_STNAME(udc) ep0_state_name[(udc)->ep0state] | ||
399 | |||
400 | #define EP0_FIFO_SIZE 16U | ||
401 | #define BULK_FIFO_SIZE 64U | ||
402 | #define ISO_FIFO_SIZE 256U | ||
403 | #define INT_FIFO_SIZE 16U | ||
404 | |||
405 | struct udc_stats { | ||
406 | unsigned long irqs_reset; | ||
407 | unsigned long irqs_suspend; | ||
408 | unsigned long irqs_resume; | ||
409 | unsigned long irqs_reconfig; | ||
410 | }; | ||
411 | |||
412 | #define NR_USB_ENDPOINTS (1 + 5) /* ep0 + ep1in-bulk + .. + ep3in-iso */ | ||
413 | #define NR_PXA_ENDPOINTS (1 + 14) /* ep0 + epA + epB + .. + epX */ | ||
414 | |||
415 | /** | ||
416 | * struct pxa_udc - udc structure | ||
417 | * @regs: mapped IO space | ||
418 | * @irq: udc irq | ||
419 | * @clk: udc clock | ||
420 | * @usb_gadget: udc gadget structure | ||
421 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) | ||
422 | * @dev: device | ||
423 | * @mach: machine info, used to activate specific GPIO | ||
424 | * @ep0state: control endpoint state machine state | ||
425 | * @stats: statistics on udc usage | ||
426 | * @udc_usb_ep: array of usb endpoints offered by the gadget | ||
427 | * @pxa_ep: array of pxa available endpoints | ||
428 | * @config: UDC active configuration | ||
429 | * @last_interface: UDC interface of the last SET_INTERFACE host request | ||
430 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request | ||
431 | * @udccsr0: save of udccsr0 in case of suspend | ||
432 | * @debugfs_root: root entry of debug filesystem | ||
433 | * @debugfs_state: debugfs entry for "udcstate" | ||
434 | * @debugfs_queues: debugfs entry for "queues" | ||
435 | * @debugfs_eps: debugfs entry for "epstate" | ||
436 | */ | ||
437 | struct pxa_udc { | ||
438 | void __iomem *regs; | ||
439 | int irq; | ||
440 | struct clk *clk; | ||
441 | |||
442 | struct usb_gadget gadget; | ||
443 | struct usb_gadget_driver *driver; | ||
444 | struct device *dev; | ||
445 | struct pxa2xx_udc_mach_info *mach; | ||
446 | |||
447 | enum ep0_state ep0state; | ||
448 | struct udc_stats stats; | ||
449 | |||
450 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; | ||
451 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; | ||
452 | |||
453 | unsigned config:2; | ||
454 | unsigned last_interface:3; | ||
455 | unsigned last_alternate:3; | ||
456 | |||
457 | #ifdef CONFIG_PM | ||
458 | unsigned udccsr0; | ||
459 | #endif | ||
460 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
461 | struct dentry *debugfs_root; | ||
462 | struct dentry *debugfs_state; | ||
463 | struct dentry *debugfs_queues; | ||
464 | struct dentry *debugfs_eps; | ||
465 | #endif | ||
466 | }; | ||
467 | |||
468 | static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) | ||
469 | { | ||
470 | return container_of(gadget, struct pxa_udc, gadget); | ||
471 | } | ||
472 | |||
473 | /* | ||
474 | * Debugging/message support | ||
475 | */ | ||
476 | #define ep_dbg(ep, fmt, arg...) \ | ||
477 | dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) | ||
478 | #define ep_vdbg(ep, fmt, arg...) \ | ||
479 | dev_vdbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) | ||
480 | #define ep_err(ep, fmt, arg...) \ | ||
481 | dev_err(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) | ||
482 | #define ep_info(ep, fmt, arg...) \ | ||
483 | dev_info(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) | ||
484 | #define ep_warn(ep, fmt, arg...) \ | ||
485 | dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg) | ||
486 | |||
487 | /* | ||
488 | * Cannot include pxa-regs.h, as register names are similar. | ||
489 | * So PSSR is redefined here. This should be removed once UDC registers will | ||
490 | * be gone from pxa-regs.h. | ||
491 | */ | ||
492 | #define PSSR __REG(0x40F00004) /* Power Manager Sleep Status */ | ||
493 | #define PSSR_OTGPH (1 << 6) /* OTG Peripheral Hold */ | ||
494 | |||
495 | #endif /* __LINUX_USB_GADGET_PXA27X_H */ | ||
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 8d158e5640e3..fa019fa73334 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * This software is distributed under the terms of the GNU General | 14 | * This software is distributed under the terms of the GNU General |
15 | * Public License ("GPL") as published by the Free Software Foundation, | 15 | * Public License ("GPL") as published by the Free Software Foundation, |
16 | * either version 2 of that License or (at your option) any later version. | 16 | * either version 2 of that License or (at your option) any later version. |
17 | * | ||
18 | */ | 17 | */ |
19 | 18 | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -33,7 +32,7 @@ | |||
33 | /* Defines */ | 32 | /* Defines */ |
34 | 33 | ||
35 | #define GS_VERSION_STR "v2.2" | 34 | #define GS_VERSION_STR "v2.2" |
36 | #define GS_VERSION_NUM 0x0202 | 35 | #define GS_VERSION_NUM 0x2200 |
37 | 36 | ||
38 | #define GS_LONG_NAME "Gadget Serial" | 37 | #define GS_LONG_NAME "Gadget Serial" |
39 | #define GS_SHORT_NAME "g_serial" | 38 | #define GS_SHORT_NAME "g_serial" |
@@ -41,7 +40,11 @@ | |||
41 | #define GS_MAJOR 127 | 40 | #define GS_MAJOR 127 |
42 | #define GS_MINOR_START 0 | 41 | #define GS_MINOR_START 0 |
43 | 42 | ||
44 | #define GS_NUM_PORTS 16 | 43 | /* REVISIT only one port is supported for now; |
44 | * see gs_{send,recv}_packet() ... no multiplexing, | ||
45 | * and no support for multiple ACM devices. | ||
46 | */ | ||
47 | #define GS_NUM_PORTS 1 | ||
45 | 48 | ||
46 | #define GS_NUM_CONFIGS 1 | 49 | #define GS_NUM_CONFIGS 1 |
47 | #define GS_NO_CONFIG_ID 0 | 50 | #define GS_NO_CONFIG_ID 0 |
@@ -65,6 +68,9 @@ | |||
65 | 68 | ||
66 | #define GS_DEFAULT_USE_ACM 0 | 69 | #define GS_DEFAULT_USE_ACM 0 |
67 | 70 | ||
71 | /* 9600-8-N-1 ... matches init_termios.c_cflag and defaults | ||
72 | * expected by "usbser.sys" on MS-Windows. | ||
73 | */ | ||
68 | #define GS_DEFAULT_DTE_RATE 9600 | 74 | #define GS_DEFAULT_DTE_RATE 9600 |
69 | #define GS_DEFAULT_DATA_BITS 8 | 75 | #define GS_DEFAULT_DATA_BITS 8 |
70 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY | 76 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY |
@@ -107,10 +113,6 @@ static int debug = 1; | |||
107 | #define GS_NOTIFY_MAXPACKET 8 | 113 | #define GS_NOTIFY_MAXPACKET 8 |
108 | 114 | ||
109 | 115 | ||
110 | /* Structures */ | ||
111 | |||
112 | struct gs_dev; | ||
113 | |||
114 | /* circular buffer */ | 116 | /* circular buffer */ |
115 | struct gs_buf { | 117 | struct gs_buf { |
116 | unsigned int buf_size; | 118 | unsigned int buf_size; |
@@ -119,12 +121,6 @@ struct gs_buf { | |||
119 | char *buf_put; | 121 | char *buf_put; |
120 | }; | 122 | }; |
121 | 123 | ||
122 | /* list of requests */ | ||
123 | struct gs_req_entry { | ||
124 | struct list_head re_entry; | ||
125 | struct usb_request *re_req; | ||
126 | }; | ||
127 | |||
128 | /* the port structure holds info for each port, one for each minor number */ | 124 | /* the port structure holds info for each port, one for each minor number */ |
129 | struct gs_port { | 125 | struct gs_port { |
130 | struct gs_dev *port_dev; /* pointer to device struct */ | 126 | struct gs_dev *port_dev; /* pointer to device struct */ |
@@ -135,7 +131,10 @@ struct gs_port { | |||
135 | int port_in_use; /* open/close in progress */ | 131 | int port_in_use; /* open/close in progress */ |
136 | wait_queue_head_t port_write_wait;/* waiting to write */ | 132 | wait_queue_head_t port_write_wait;/* waiting to write */ |
137 | struct gs_buf *port_write_buf; | 133 | struct gs_buf *port_write_buf; |
138 | struct usb_cdc_line_coding port_line_coding; | 134 | struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ |
135 | u16 port_handshake_bits; | ||
136 | #define RS232_RTS (1 << 1) | ||
137 | #define RS232_DTE (1 << 0) | ||
139 | }; | 138 | }; |
140 | 139 | ||
141 | /* the device structure holds info for the USB device */ | 140 | /* the device structure holds info for the USB device */ |
@@ -161,26 +160,7 @@ struct gs_dev { | |||
161 | 160 | ||
162 | /* Functions */ | 161 | /* Functions */ |
163 | 162 | ||
164 | /* module */ | 163 | /* tty driver internals */ |
165 | static int __init gs_module_init(void); | ||
166 | static void __exit gs_module_exit(void); | ||
167 | |||
168 | /* tty driver */ | ||
169 | static int gs_open(struct tty_struct *tty, struct file *file); | ||
170 | static void gs_close(struct tty_struct *tty, struct file *file); | ||
171 | static int gs_write(struct tty_struct *tty, | ||
172 | const unsigned char *buf, int count); | ||
173 | static int gs_put_char(struct tty_struct *tty, unsigned char ch); | ||
174 | static void gs_flush_chars(struct tty_struct *tty); | ||
175 | static int gs_write_room(struct tty_struct *tty); | ||
176 | static int gs_chars_in_buffer(struct tty_struct *tty); | ||
177 | static void gs_throttle(struct tty_struct * tty); | ||
178 | static void gs_unthrottle(struct tty_struct * tty); | ||
179 | static void gs_break(struct tty_struct *tty, int break_state); | ||
180 | static int gs_ioctl(struct tty_struct *tty, struct file *file, | ||
181 | unsigned int cmd, unsigned long arg); | ||
182 | static void gs_set_termios(struct tty_struct *tty, struct ktermios *old); | ||
183 | |||
184 | static int gs_send(struct gs_dev *dev); | 164 | static int gs_send(struct gs_dev *dev); |
185 | static int gs_send_packet(struct gs_dev *dev, char *packet, | 165 | static int gs_send_packet(struct gs_dev *dev, char *packet, |
186 | unsigned int size); | 166 | unsigned int size); |
@@ -189,17 +169,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, | |||
189 | static void gs_read_complete(struct usb_ep *ep, struct usb_request *req); | 169 | static void gs_read_complete(struct usb_ep *ep, struct usb_request *req); |
190 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req); | 170 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req); |
191 | 171 | ||
192 | /* gadget driver */ | 172 | /* gadget driver internals */ |
193 | static int gs_bind(struct usb_gadget *gadget); | ||
194 | static void gs_unbind(struct usb_gadget *gadget); | ||
195 | static int gs_setup(struct usb_gadget *gadget, | ||
196 | const struct usb_ctrlrequest *ctrl); | ||
197 | static int gs_setup_standard(struct usb_gadget *gadget, | ||
198 | const struct usb_ctrlrequest *ctrl); | ||
199 | static int gs_setup_class(struct usb_gadget *gadget, | ||
200 | const struct usb_ctrlrequest *ctrl); | ||
201 | static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); | ||
202 | static void gs_disconnect(struct usb_gadget *gadget); | ||
203 | static int gs_set_config(struct gs_dev *dev, unsigned config); | 173 | static int gs_set_config(struct gs_dev *dev, unsigned config); |
204 | static void gs_reset_config(struct gs_dev *dev); | 174 | static void gs_reset_config(struct gs_dev *dev); |
205 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, | 175 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
@@ -209,10 +179,6 @@ static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | |||
209 | gfp_t kmalloc_flags); | 179 | gfp_t kmalloc_flags); |
210 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req); | 180 | static void gs_free_req(struct usb_ep *ep, struct usb_request *req); |
211 | 181 | ||
212 | static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len, | ||
213 | gfp_t kmalloc_flags); | ||
214 | static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req); | ||
215 | |||
216 | static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags); | 182 | static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags); |
217 | static void gs_free_ports(struct gs_dev *dev); | 183 | static void gs_free_ports(struct gs_dev *dev); |
218 | 184 | ||
@@ -227,62 +193,15 @@ static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, | |||
227 | static unsigned int gs_buf_get(struct gs_buf *gb, char *buf, | 193 | static unsigned int gs_buf_get(struct gs_buf *gb, char *buf, |
228 | unsigned int count); | 194 | unsigned int count); |
229 | 195 | ||
230 | /* external functions */ | ||
231 | extern int net2280_set_fifo_mode(struct usb_gadget *gadget, int mode); | ||
232 | |||
233 | 196 | ||
234 | /* Globals */ | 197 | /* Globals */ |
235 | 198 | ||
236 | static struct gs_dev *gs_device; | 199 | static struct gs_dev *gs_device; |
237 | 200 | ||
238 | static const char *EP_IN_NAME; | ||
239 | static const char *EP_OUT_NAME; | ||
240 | static const char *EP_NOTIFY_NAME; | ||
241 | |||
242 | static struct mutex gs_open_close_lock[GS_NUM_PORTS]; | 201 | static struct mutex gs_open_close_lock[GS_NUM_PORTS]; |
243 | 202 | ||
244 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; | ||
245 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; | ||
246 | |||
247 | static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE; | ||
248 | |||
249 | static unsigned int use_acm = GS_DEFAULT_USE_ACM; | ||
250 | |||
251 | |||
252 | /* tty driver struct */ | ||
253 | static const struct tty_operations gs_tty_ops = { | ||
254 | .open = gs_open, | ||
255 | .close = gs_close, | ||
256 | .write = gs_write, | ||
257 | .put_char = gs_put_char, | ||
258 | .flush_chars = gs_flush_chars, | ||
259 | .write_room = gs_write_room, | ||
260 | .ioctl = gs_ioctl, | ||
261 | .set_termios = gs_set_termios, | ||
262 | .throttle = gs_throttle, | ||
263 | .unthrottle = gs_unthrottle, | ||
264 | .break_ctl = gs_break, | ||
265 | .chars_in_buffer = gs_chars_in_buffer, | ||
266 | }; | ||
267 | static struct tty_driver *gs_tty_driver; | ||
268 | |||
269 | /* gadget driver struct */ | ||
270 | static struct usb_gadget_driver gs_gadget_driver = { | ||
271 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
272 | .speed = USB_SPEED_HIGH, | ||
273 | #else | ||
274 | .speed = USB_SPEED_FULL, | ||
275 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
276 | .function = GS_LONG_NAME, | ||
277 | .bind = gs_bind, | ||
278 | .unbind = gs_unbind, | ||
279 | .setup = gs_setup, | ||
280 | .disconnect = gs_disconnect, | ||
281 | .driver = { | ||
282 | .name = GS_SHORT_NAME, | ||
283 | }, | ||
284 | }; | ||
285 | 203 | ||
204 | /*-------------------------------------------------------------------------*/ | ||
286 | 205 | ||
287 | /* USB descriptors */ | 206 | /* USB descriptors */ |
288 | 207 | ||
@@ -299,7 +218,6 @@ static char manufacturer[50]; | |||
299 | static struct usb_string gs_strings[] = { | 218 | static struct usb_string gs_strings[] = { |
300 | { GS_MANUFACTURER_STR_ID, manufacturer }, | 219 | { GS_MANUFACTURER_STR_ID, manufacturer }, |
301 | { GS_PRODUCT_STR_ID, GS_LONG_NAME }, | 220 | { GS_PRODUCT_STR_ID, GS_LONG_NAME }, |
302 | { GS_SERIAL_STR_ID, "0" }, | ||
303 | { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" }, | 221 | { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" }, |
304 | { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" }, | 222 | { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" }, |
305 | { GS_CONTROL_STR_ID, "Gadget Serial Control" }, | 223 | { GS_CONTROL_STR_ID, "Gadget Serial Control" }, |
@@ -322,7 +240,6 @@ static struct usb_device_descriptor gs_device_desc = { | |||
322 | .idProduct = __constant_cpu_to_le16(GS_PRODUCT_ID), | 240 | .idProduct = __constant_cpu_to_le16(GS_PRODUCT_ID), |
323 | .iManufacturer = GS_MANUFACTURER_STR_ID, | 241 | .iManufacturer = GS_MANUFACTURER_STR_ID, |
324 | .iProduct = GS_PRODUCT_STR_ID, | 242 | .iProduct = GS_PRODUCT_STR_ID, |
325 | .iSerialNumber = GS_SERIAL_STR_ID, | ||
326 | .bNumConfigurations = GS_NUM_CONFIGS, | 243 | .bNumConfigurations = GS_NUM_CONFIGS, |
327 | }; | 244 | }; |
328 | 245 | ||
@@ -359,7 +276,7 @@ static const struct usb_interface_descriptor gs_bulk_interface_desc = { | |||
359 | .bDescriptorType = USB_DT_INTERFACE, | 276 | .bDescriptorType = USB_DT_INTERFACE, |
360 | .bInterfaceNumber = GS_BULK_INTERFACE_ID, | 277 | .bInterfaceNumber = GS_BULK_INTERFACE_ID, |
361 | .bNumEndpoints = 2, | 278 | .bNumEndpoints = 2, |
362 | .bInterfaceClass = USB_CLASS_CDC_DATA, | 279 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
363 | .bInterfaceSubClass = 0, | 280 | .bInterfaceSubClass = 0, |
364 | .bInterfaceProtocol = 0, | 281 | .bInterfaceProtocol = 0, |
365 | .iInterface = GS_DATA_STR_ID, | 282 | .iInterface = GS_DATA_STR_ID, |
@@ -406,7 +323,7 @@ static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | |||
406 | .bLength = sizeof(gs_acm_descriptor), | 323 | .bLength = sizeof(gs_acm_descriptor), |
407 | .bDescriptorType = USB_DT_CS_INTERFACE, | 324 | .bDescriptorType = USB_DT_CS_INTERFACE, |
408 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | 325 | .bDescriptorSubType = USB_CDC_ACM_TYPE, |
409 | .bmCapabilities = 0, | 326 | .bmCapabilities = (1 << 1), |
410 | }; | 327 | }; |
411 | 328 | ||
412 | static const struct usb_cdc_union_desc gs_union_desc = { | 329 | static const struct usb_cdc_union_desc gs_union_desc = { |
@@ -516,6 +433,8 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | |||
516 | }; | 433 | }; |
517 | 434 | ||
518 | 435 | ||
436 | /*-------------------------------------------------------------------------*/ | ||
437 | |||
519 | /* Module */ | 438 | /* Module */ |
520 | MODULE_DESCRIPTION(GS_LONG_NAME); | 439 | MODULE_DESCRIPTION(GS_LONG_NAME); |
521 | MODULE_AUTHOR("Al Borchers"); | 440 | MODULE_AUTHOR("Al Borchers"); |
@@ -526,84 +445,23 @@ module_param(debug, int, S_IRUGO|S_IWUSR); | |||
526 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); | 445 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); |
527 | #endif | 446 | #endif |
528 | 447 | ||
448 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; | ||
529 | module_param(read_q_size, uint, S_IRUGO); | 449 | module_param(read_q_size, uint, S_IRUGO); |
530 | MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32"); | 450 | MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32"); |
531 | 451 | ||
452 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; | ||
532 | module_param(write_q_size, uint, S_IRUGO); | 453 | module_param(write_q_size, uint, S_IRUGO); |
533 | MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32"); | 454 | MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32"); |
534 | 455 | ||
456 | static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE; | ||
535 | module_param(write_buf_size, uint, S_IRUGO); | 457 | module_param(write_buf_size, uint, S_IRUGO); |
536 | MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192"); | 458 | MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192"); |
537 | 459 | ||
460 | static unsigned int use_acm = GS_DEFAULT_USE_ACM; | ||
538 | module_param(use_acm, uint, S_IRUGO); | 461 | module_param(use_acm, uint, S_IRUGO); |
539 | MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no"); | 462 | MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no"); |
540 | 463 | ||
541 | module_init(gs_module_init); | 464 | /*-------------------------------------------------------------------------*/ |
542 | module_exit(gs_module_exit); | ||
543 | |||
544 | /* | ||
545 | * gs_module_init | ||
546 | * | ||
547 | * Register as a USB gadget driver and a tty driver. | ||
548 | */ | ||
549 | static int __init gs_module_init(void) | ||
550 | { | ||
551 | int i; | ||
552 | int retval; | ||
553 | |||
554 | retval = usb_gadget_register_driver(&gs_gadget_driver); | ||
555 | if (retval) { | ||
556 | pr_err("gs_module_init: cannot register gadget driver, " | ||
557 | "ret=%d\n", retval); | ||
558 | return retval; | ||
559 | } | ||
560 | |||
561 | gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS); | ||
562 | if (!gs_tty_driver) | ||
563 | return -ENOMEM; | ||
564 | gs_tty_driver->owner = THIS_MODULE; | ||
565 | gs_tty_driver->driver_name = GS_SHORT_NAME; | ||
566 | gs_tty_driver->name = "ttygs"; | ||
567 | gs_tty_driver->major = GS_MAJOR; | ||
568 | gs_tty_driver->minor_start = GS_MINOR_START; | ||
569 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
570 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
571 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
572 | gs_tty_driver->init_termios = tty_std_termios; | ||
573 | gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
574 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | ||
575 | |||
576 | for (i=0; i < GS_NUM_PORTS; i++) | ||
577 | mutex_init(&gs_open_close_lock[i]); | ||
578 | |||
579 | retval = tty_register_driver(gs_tty_driver); | ||
580 | if (retval) { | ||
581 | usb_gadget_unregister_driver(&gs_gadget_driver); | ||
582 | put_tty_driver(gs_tty_driver); | ||
583 | pr_err("gs_module_init: cannot register tty driver, " | ||
584 | "ret=%d\n", retval); | ||
585 | return retval; | ||
586 | } | ||
587 | |||
588 | pr_info("gs_module_init: %s %s loaded\n", | ||
589 | GS_LONG_NAME, GS_VERSION_STR); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | /* | ||
594 | * gs_module_exit | ||
595 | * | ||
596 | * Unregister as a tty driver and a USB gadget driver. | ||
597 | */ | ||
598 | static void __exit gs_module_exit(void) | ||
599 | { | ||
600 | tty_unregister_driver(gs_tty_driver); | ||
601 | put_tty_driver(gs_tty_driver); | ||
602 | usb_gadget_unregister_driver(&gs_gadget_driver); | ||
603 | |||
604 | pr_info("gs_module_exit: %s %s unloaded\n", | ||
605 | GS_LONG_NAME, GS_VERSION_STR); | ||
606 | } | ||
607 | 465 | ||
608 | /* TTY Driver */ | 466 | /* TTY Driver */ |
609 | 467 | ||
@@ -748,15 +606,15 @@ exit_unlock_dev: | |||
748 | * gs_close | 606 | * gs_close |
749 | */ | 607 | */ |
750 | 608 | ||
751 | #define GS_WRITE_FINISHED_EVENT_SAFELY(p) \ | 609 | static int gs_write_finished_event_safely(struct gs_port *p) |
752 | ({ \ | 610 | { |
753 | int cond; \ | 611 | int cond; |
754 | \ | 612 | |
755 | spin_lock_irq(&(p)->port_lock); \ | 613 | spin_lock_irq(&(p)->port_lock); |
756 | cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \ | 614 | cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); |
757 | spin_unlock_irq(&(p)->port_lock); \ | 615 | spin_unlock_irq(&(p)->port_lock); |
758 | cond; \ | 616 | return cond; |
759 | }) | 617 | } |
760 | 618 | ||
761 | static void gs_close(struct tty_struct *tty, struct file *file) | 619 | static void gs_close(struct tty_struct *tty, struct file *file) |
762 | { | 620 | { |
@@ -802,7 +660,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
802 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 660 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
803 | spin_unlock_irq(&port->port_lock); | 661 | spin_unlock_irq(&port->port_lock); |
804 | wait_event_interruptible_timeout(port->port_write_wait, | 662 | wait_event_interruptible_timeout(port->port_write_wait, |
805 | GS_WRITE_FINISHED_EVENT_SAFELY(port), | 663 | gs_write_finished_event_safely(port), |
806 | GS_CLOSE_TIMEOUT * HZ); | 664 | GS_CLOSE_TIMEOUT * HZ); |
807 | spin_lock_irq(&port->port_lock); | 665 | spin_lock_irq(&port->port_lock); |
808 | } | 666 | } |
@@ -1060,6 +918,23 @@ static void gs_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1060 | { | 918 | { |
1061 | } | 919 | } |
1062 | 920 | ||
921 | static const struct tty_operations gs_tty_ops = { | ||
922 | .open = gs_open, | ||
923 | .close = gs_close, | ||
924 | .write = gs_write, | ||
925 | .put_char = gs_put_char, | ||
926 | .flush_chars = gs_flush_chars, | ||
927 | .write_room = gs_write_room, | ||
928 | .ioctl = gs_ioctl, | ||
929 | .set_termios = gs_set_termios, | ||
930 | .throttle = gs_throttle, | ||
931 | .unthrottle = gs_unthrottle, | ||
932 | .break_ctl = gs_break, | ||
933 | .chars_in_buffer = gs_chars_in_buffer, | ||
934 | }; | ||
935 | |||
936 | /*-------------------------------------------------------------------------*/ | ||
937 | |||
1063 | /* | 938 | /* |
1064 | * gs_send | 939 | * gs_send |
1065 | * | 940 | * |
@@ -1075,7 +950,6 @@ static int gs_send(struct gs_dev *dev) | |||
1075 | unsigned long flags; | 950 | unsigned long flags; |
1076 | struct usb_ep *ep; | 951 | struct usb_ep *ep; |
1077 | struct usb_request *req; | 952 | struct usb_request *req; |
1078 | struct gs_req_entry *req_entry; | ||
1079 | 953 | ||
1080 | if (dev == NULL) { | 954 | if (dev == NULL) { |
1081 | pr_err("gs_send: NULL device pointer\n"); | 955 | pr_err("gs_send: NULL device pointer\n"); |
@@ -1088,10 +962,8 @@ static int gs_send(struct gs_dev *dev) | |||
1088 | 962 | ||
1089 | while(!list_empty(&dev->dev_req_list)) { | 963 | while(!list_empty(&dev->dev_req_list)) { |
1090 | 964 | ||
1091 | req_entry = list_entry(dev->dev_req_list.next, | 965 | req = list_entry(dev->dev_req_list.next, |
1092 | struct gs_req_entry, re_entry); | 966 | struct usb_request, list); |
1093 | |||
1094 | req = req_entry->re_req; | ||
1095 | 967 | ||
1096 | len = gs_send_packet(dev, req->buf, ep->maxpacket); | 968 | len = gs_send_packet(dev, req->buf, ep->maxpacket); |
1097 | 969 | ||
@@ -1101,7 +973,7 @@ static int gs_send(struct gs_dev *dev) | |||
1101 | *((unsigned char *)req->buf), | 973 | *((unsigned char *)req->buf), |
1102 | *((unsigned char *)req->buf+1), | 974 | *((unsigned char *)req->buf+1), |
1103 | *((unsigned char *)req->buf+2)); | 975 | *((unsigned char *)req->buf+2)); |
1104 | list_del(&req_entry->re_entry); | 976 | list_del(&req->list); |
1105 | req->length = len; | 977 | req->length = len; |
1106 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 978 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
1107 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { | 979 | if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { |
@@ -1284,7 +1156,6 @@ requeue: | |||
1284 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) | 1156 | static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) |
1285 | { | 1157 | { |
1286 | struct gs_dev *dev = ep->driver_data; | 1158 | struct gs_dev *dev = ep->driver_data; |
1287 | struct gs_req_entry *gs_req = req->context; | ||
1288 | 1159 | ||
1289 | if (dev == NULL) { | 1160 | if (dev == NULL) { |
1290 | pr_err("gs_write_complete: NULL device pointer\n"); | 1161 | pr_err("gs_write_complete: NULL device pointer\n"); |
@@ -1295,13 +1166,8 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) | |||
1295 | case 0: | 1166 | case 0: |
1296 | /* normal completion */ | 1167 | /* normal completion */ |
1297 | requeue: | 1168 | requeue: |
1298 | if (gs_req == NULL) { | ||
1299 | pr_err("gs_write_complete: NULL request pointer\n"); | ||
1300 | return; | ||
1301 | } | ||
1302 | |||
1303 | spin_lock(&dev->dev_lock); | 1169 | spin_lock(&dev->dev_lock); |
1304 | list_add(&gs_req->re_entry, &dev->dev_req_list); | 1170 | list_add(&req->list, &dev->dev_req_list); |
1305 | spin_unlock(&dev->dev_lock); | 1171 | spin_unlock(&dev->dev_lock); |
1306 | 1172 | ||
1307 | gs_send(dev); | 1173 | gs_send(dev); |
@@ -1323,9 +1189,39 @@ requeue: | |||
1323 | } | 1189 | } |
1324 | } | 1190 | } |
1325 | 1191 | ||
1192 | /*-------------------------------------------------------------------------*/ | ||
1193 | |||
1326 | /* Gadget Driver */ | 1194 | /* Gadget Driver */ |
1327 | 1195 | ||
1328 | /* | 1196 | /* |
1197 | * gs_unbind | ||
1198 | * | ||
1199 | * Called on module unload. Frees the control request and device | ||
1200 | * structure. | ||
1201 | */ | ||
1202 | static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) | ||
1203 | { | ||
1204 | struct gs_dev *dev = get_gadget_data(gadget); | ||
1205 | |||
1206 | gs_device = NULL; | ||
1207 | |||
1208 | /* read/write requests already freed, only control request remains */ | ||
1209 | if (dev != NULL) { | ||
1210 | if (dev->dev_ctrl_req != NULL) { | ||
1211 | gs_free_req(gadget->ep0, dev->dev_ctrl_req); | ||
1212 | dev->dev_ctrl_req = NULL; | ||
1213 | } | ||
1214 | gs_reset_config(dev); | ||
1215 | gs_free_ports(dev); | ||
1216 | kfree(dev); | ||
1217 | set_gadget_data(gadget, NULL); | ||
1218 | } | ||
1219 | |||
1220 | pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, | ||
1221 | GS_VERSION_STR); | ||
1222 | } | ||
1223 | |||
1224 | /* | ||
1329 | * gs_bind | 1225 | * gs_bind |
1330 | * | 1226 | * |
1331 | * Called on module load. Allocates and initializes the device | 1227 | * Called on module load. Allocates and initializes the device |
@@ -1357,19 +1253,23 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1357 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); | 1253 | __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); |
1358 | } | 1254 | } |
1359 | 1255 | ||
1256 | dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); | ||
1257 | if (dev == NULL) | ||
1258 | return -ENOMEM; | ||
1259 | |||
1360 | usb_ep_autoconfig_reset(gadget); | 1260 | usb_ep_autoconfig_reset(gadget); |
1361 | 1261 | ||
1362 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); | 1262 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); |
1363 | if (!ep) | 1263 | if (!ep) |
1364 | goto autoconf_fail; | 1264 | goto autoconf_fail; |
1365 | EP_IN_NAME = ep->name; | 1265 | dev->dev_in_ep = ep; |
1366 | ep->driver_data = ep; /* claim the endpoint */ | 1266 | ep->driver_data = dev; /* claim the endpoint */ |
1367 | 1267 | ||
1368 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); | 1268 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); |
1369 | if (!ep) | 1269 | if (!ep) |
1370 | goto autoconf_fail; | 1270 | goto autoconf_fail; |
1371 | EP_OUT_NAME = ep->name; | 1271 | dev->dev_out_ep = ep; |
1372 | ep->driver_data = ep; /* claim the endpoint */ | 1272 | ep->driver_data = dev; /* claim the endpoint */ |
1373 | 1273 | ||
1374 | if (use_acm) { | 1274 | if (use_acm) { |
1375 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); | 1275 | ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); |
@@ -1379,8 +1279,8 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1379 | } | 1279 | } |
1380 | gs_device_desc.idProduct = __constant_cpu_to_le16( | 1280 | gs_device_desc.idProduct = __constant_cpu_to_le16( |
1381 | GS_CDC_PRODUCT_ID), | 1281 | GS_CDC_PRODUCT_ID), |
1382 | EP_NOTIFY_NAME = ep->name; | 1282 | dev->dev_notify_ep = ep; |
1383 | ep->driver_data = ep; /* claim the endpoint */ | 1283 | ep->driver_data = dev; /* claim the endpoint */ |
1384 | } | 1284 | } |
1385 | 1285 | ||
1386 | gs_device_desc.bDeviceClass = use_acm | 1286 | gs_device_desc.bDeviceClass = use_acm |
@@ -1410,9 +1310,7 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1410 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1310 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1411 | } | 1311 | } |
1412 | 1312 | ||
1413 | gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); | 1313 | gs_device = dev; |
1414 | if (dev == NULL) | ||
1415 | return -ENOMEM; | ||
1416 | 1314 | ||
1417 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 1315 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", |
1418 | init_utsname()->sysname, init_utsname()->release, | 1316 | init_utsname()->sysname, init_utsname()->release, |
@@ -1436,8 +1334,6 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1436 | gs_unbind(gadget); | 1334 | gs_unbind(gadget); |
1437 | return -ENOMEM; | 1335 | return -ENOMEM; |
1438 | } | 1336 | } |
1439 | dev->dev_ctrl_req->complete = gs_setup_complete; | ||
1440 | |||
1441 | gadget->ep0->driver_data = dev; | 1337 | gadget->ep0->driver_data = dev; |
1442 | 1338 | ||
1443 | pr_info("gs_bind: %s %s bound\n", | 1339 | pr_info("gs_bind: %s %s bound\n", |
@@ -1446,97 +1342,11 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1446 | return 0; | 1342 | return 0; |
1447 | 1343 | ||
1448 | autoconf_fail: | 1344 | autoconf_fail: |
1345 | kfree(dev); | ||
1449 | pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); | 1346 | pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); |
1450 | return -ENODEV; | 1347 | return -ENODEV; |
1451 | } | 1348 | } |
1452 | 1349 | ||
1453 | /* | ||
1454 | * gs_unbind | ||
1455 | * | ||
1456 | * Called on module unload. Frees the control request and device | ||
1457 | * structure. | ||
1458 | */ | ||
1459 | static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) | ||
1460 | { | ||
1461 | struct gs_dev *dev = get_gadget_data(gadget); | ||
1462 | |||
1463 | gs_device = NULL; | ||
1464 | |||
1465 | /* read/write requests already freed, only control request remains */ | ||
1466 | if (dev != NULL) { | ||
1467 | if (dev->dev_ctrl_req != NULL) { | ||
1468 | gs_free_req(gadget->ep0, dev->dev_ctrl_req); | ||
1469 | dev->dev_ctrl_req = NULL; | ||
1470 | } | ||
1471 | gs_free_ports(dev); | ||
1472 | if (dev->dev_notify_ep) | ||
1473 | usb_ep_disable(dev->dev_notify_ep); | ||
1474 | if (dev->dev_in_ep) | ||
1475 | usb_ep_disable(dev->dev_in_ep); | ||
1476 | if (dev->dev_out_ep) | ||
1477 | usb_ep_disable(dev->dev_out_ep); | ||
1478 | kfree(dev); | ||
1479 | set_gadget_data(gadget, NULL); | ||
1480 | } | ||
1481 | |||
1482 | pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, | ||
1483 | GS_VERSION_STR); | ||
1484 | } | ||
1485 | |||
1486 | /* | ||
1487 | * gs_setup | ||
1488 | * | ||
1489 | * Implements all the control endpoint functionality that's not | ||
1490 | * handled in hardware or the hardware driver. | ||
1491 | * | ||
1492 | * Returns the size of the data sent to the host, or a negative | ||
1493 | * error number. | ||
1494 | */ | ||
1495 | static int gs_setup(struct usb_gadget *gadget, | ||
1496 | const struct usb_ctrlrequest *ctrl) | ||
1497 | { | ||
1498 | int ret = -EOPNOTSUPP; | ||
1499 | struct gs_dev *dev = get_gadget_data(gadget); | ||
1500 | struct usb_request *req = dev->dev_ctrl_req; | ||
1501 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
1502 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
1503 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
1504 | |||
1505 | switch (ctrl->bRequestType & USB_TYPE_MASK) { | ||
1506 | case USB_TYPE_STANDARD: | ||
1507 | ret = gs_setup_standard(gadget,ctrl); | ||
1508 | break; | ||
1509 | |||
1510 | case USB_TYPE_CLASS: | ||
1511 | ret = gs_setup_class(gadget,ctrl); | ||
1512 | break; | ||
1513 | |||
1514 | default: | ||
1515 | pr_err("gs_setup: unknown request, type=%02x, request=%02x, " | ||
1516 | "value=%04x, index=%04x, length=%d\n", | ||
1517 | ctrl->bRequestType, ctrl->bRequest, | ||
1518 | wValue, wIndex, wLength); | ||
1519 | break; | ||
1520 | } | ||
1521 | |||
1522 | /* respond with data transfer before status phase? */ | ||
1523 | if (ret >= 0) { | ||
1524 | req->length = ret; | ||
1525 | req->zero = ret < wLength | ||
1526 | && (ret % gadget->ep0->maxpacket) == 0; | ||
1527 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
1528 | if (ret < 0) { | ||
1529 | pr_err("gs_setup: cannot queue response, ret=%d\n", | ||
1530 | ret); | ||
1531 | req->status = 0; | ||
1532 | gs_setup_complete(gadget->ep0, req); | ||
1533 | } | ||
1534 | } | ||
1535 | |||
1536 | /* device either stalls (ret < 0) or reports success */ | ||
1537 | return ret; | ||
1538 | } | ||
1539 | |||
1540 | static int gs_setup_standard(struct usb_gadget *gadget, | 1350 | static int gs_setup_standard(struct usb_gadget *gadget, |
1541 | const struct usb_ctrlrequest *ctrl) | 1351 | const struct usb_ctrlrequest *ctrl) |
1542 | { | 1352 | { |
@@ -1666,6 +1476,42 @@ set_interface_done: | |||
1666 | return ret; | 1476 | return ret; |
1667 | } | 1477 | } |
1668 | 1478 | ||
1479 | static void gs_setup_complete_set_line_coding(struct usb_ep *ep, | ||
1480 | struct usb_request *req) | ||
1481 | { | ||
1482 | struct gs_dev *dev = ep->driver_data; | ||
1483 | struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */ | ||
1484 | |||
1485 | switch (req->status) { | ||
1486 | case 0: | ||
1487 | /* normal completion */ | ||
1488 | if (req->actual != sizeof(port->port_line_coding)) | ||
1489 | usb_ep_set_halt(ep); | ||
1490 | else if (port) { | ||
1491 | struct usb_cdc_line_coding *value = req->buf; | ||
1492 | |||
1493 | /* REVISIT: we currently just remember this data. | ||
1494 | * If we change that, (a) validate it first, then | ||
1495 | * (b) update whatever hardware needs updating. | ||
1496 | */ | ||
1497 | spin_lock(&port->port_lock); | ||
1498 | port->port_line_coding = *value; | ||
1499 | spin_unlock(&port->port_lock); | ||
1500 | } | ||
1501 | break; | ||
1502 | |||
1503 | case -ESHUTDOWN: | ||
1504 | /* disconnect */ | ||
1505 | gs_free_req(ep, req); | ||
1506 | break; | ||
1507 | |||
1508 | default: | ||
1509 | /* unexpected */ | ||
1510 | break; | ||
1511 | } | ||
1512 | return; | ||
1513 | } | ||
1514 | |||
1669 | static int gs_setup_class(struct usb_gadget *gadget, | 1515 | static int gs_setup_class(struct usb_gadget *gadget, |
1670 | const struct usb_ctrlrequest *ctrl) | 1516 | const struct usb_ctrlrequest *ctrl) |
1671 | { | 1517 | { |
@@ -1679,18 +1525,14 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1679 | 1525 | ||
1680 | switch (ctrl->bRequest) { | 1526 | switch (ctrl->bRequest) { |
1681 | case USB_CDC_REQ_SET_LINE_CODING: | 1527 | case USB_CDC_REQ_SET_LINE_CODING: |
1682 | /* FIXME Submit req to read the data; have its completion | 1528 | if (wLength != sizeof(struct usb_cdc_line_coding)) |
1683 | * handler copy that data to port->port_line_coding (iff | 1529 | break; |
1684 | * it's valid) and maybe pass it on. Until then, fail. | 1530 | ret = wLength; |
1685 | */ | 1531 | req->complete = gs_setup_complete_set_line_coding; |
1686 | pr_warning("gs_setup: set_line_coding " | ||
1687 | "unuspported\n"); | ||
1688 | break; | 1532 | break; |
1689 | 1533 | ||
1690 | case USB_CDC_REQ_GET_LINE_CODING: | 1534 | case USB_CDC_REQ_GET_LINE_CODING: |
1691 | port = dev->dev_port[0]; /* ACM only has one port */ | 1535 | ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding)); |
1692 | ret = min(wLength, | ||
1693 | (u16)sizeof(struct usb_cdc_line_coding)); | ||
1694 | if (port) { | 1536 | if (port) { |
1695 | spin_lock(&port->port_lock); | 1537 | spin_lock(&port->port_lock); |
1696 | memcpy(req->buf, &port->port_line_coding, ret); | 1538 | memcpy(req->buf, &port->port_line_coding, ret); |
@@ -1699,15 +1541,27 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1699 | break; | 1541 | break; |
1700 | 1542 | ||
1701 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: | 1543 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: |
1702 | /* FIXME Submit req to read the data; have its completion | 1544 | if (wLength != 0) |
1703 | * handler use that to set the state (iff it's valid) and | 1545 | break; |
1704 | * maybe pass it on. Until then, fail. | 1546 | ret = 0; |
1705 | */ | 1547 | if (port) { |
1706 | pr_warning("gs_setup: set_control_line_state " | 1548 | /* REVISIT: we currently just remember this data. |
1707 | "unuspported\n"); | 1549 | * If we change that, update whatever hardware needs |
1550 | * updating. | ||
1551 | */ | ||
1552 | spin_lock(&port->port_lock); | ||
1553 | port->port_handshake_bits = wValue; | ||
1554 | spin_unlock(&port->port_lock); | ||
1555 | } | ||
1708 | break; | 1556 | break; |
1709 | 1557 | ||
1710 | default: | 1558 | default: |
1559 | /* NOTE: strictly speaking, we should accept AT-commands | ||
1560 | * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE. | ||
1561 | * But our call management descriptor says we don't handle | ||
1562 | * call management, so we should be able to get by without | ||
1563 | * handling those "required" commands (except by stalling). | ||
1564 | */ | ||
1711 | pr_err("gs_setup: unknown class request, " | 1565 | pr_err("gs_setup: unknown class request, " |
1712 | "type=%02x, request=%02x, value=%04x, " | 1566 | "type=%02x, request=%02x, value=%04x, " |
1713 | "index=%04x, length=%d\n", | 1567 | "index=%04x, length=%d\n", |
@@ -1732,6 +1586,62 @@ static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) | |||
1732 | } | 1586 | } |
1733 | 1587 | ||
1734 | /* | 1588 | /* |
1589 | * gs_setup | ||
1590 | * | ||
1591 | * Implements all the control endpoint functionality that's not | ||
1592 | * handled in hardware or the hardware driver. | ||
1593 | * | ||
1594 | * Returns the size of the data sent to the host, or a negative | ||
1595 | * error number. | ||
1596 | */ | ||
1597 | static int gs_setup(struct usb_gadget *gadget, | ||
1598 | const struct usb_ctrlrequest *ctrl) | ||
1599 | { | ||
1600 | int ret = -EOPNOTSUPP; | ||
1601 | struct gs_dev *dev = get_gadget_data(gadget); | ||
1602 | struct usb_request *req = dev->dev_ctrl_req; | ||
1603 | u16 wIndex = le16_to_cpu(ctrl->wIndex); | ||
1604 | u16 wValue = le16_to_cpu(ctrl->wValue); | ||
1605 | u16 wLength = le16_to_cpu(ctrl->wLength); | ||
1606 | |||
1607 | req->complete = gs_setup_complete; | ||
1608 | |||
1609 | switch (ctrl->bRequestType & USB_TYPE_MASK) { | ||
1610 | case USB_TYPE_STANDARD: | ||
1611 | ret = gs_setup_standard(gadget, ctrl); | ||
1612 | break; | ||
1613 | |||
1614 | case USB_TYPE_CLASS: | ||
1615 | ret = gs_setup_class(gadget, ctrl); | ||
1616 | break; | ||
1617 | |||
1618 | default: | ||
1619 | pr_err("gs_setup: unknown request, type=%02x, request=%02x, " | ||
1620 | "value=%04x, index=%04x, length=%d\n", | ||
1621 | ctrl->bRequestType, ctrl->bRequest, | ||
1622 | wValue, wIndex, wLength); | ||
1623 | break; | ||
1624 | } | ||
1625 | |||
1626 | /* respond with data transfer before status phase? */ | ||
1627 | if (ret >= 0) { | ||
1628 | req->length = ret; | ||
1629 | req->zero = ret < wLength | ||
1630 | && (ret % gadget->ep0->maxpacket) == 0; | ||
1631 | ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
1632 | if (ret < 0) { | ||
1633 | pr_err("gs_setup: cannot queue response, ret=%d\n", | ||
1634 | ret); | ||
1635 | req->status = 0; | ||
1636 | gs_setup_complete(gadget->ep0, req); | ||
1637 | } | ||
1638 | } | ||
1639 | |||
1640 | /* device either stalls (ret < 0) or reports success */ | ||
1641 | return ret; | ||
1642 | } | ||
1643 | |||
1644 | /* | ||
1735 | * gs_disconnect | 1645 | * gs_disconnect |
1736 | * | 1646 | * |
1737 | * Called when the device is disconnected. Frees the closed | 1647 | * Called when the device is disconnected. Frees the closed |
@@ -1760,6 +1670,23 @@ static void gs_disconnect(struct usb_gadget *gadget) | |||
1760 | pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); | 1670 | pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); |
1761 | } | 1671 | } |
1762 | 1672 | ||
1673 | static struct usb_gadget_driver gs_gadget_driver = { | ||
1674 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1675 | .speed = USB_SPEED_HIGH, | ||
1676 | #else | ||
1677 | .speed = USB_SPEED_FULL, | ||
1678 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1679 | .function = GS_LONG_NAME, | ||
1680 | .bind = gs_bind, | ||
1681 | .unbind = gs_unbind, | ||
1682 | .setup = gs_setup, | ||
1683 | .disconnect = gs_disconnect, | ||
1684 | .driver = { | ||
1685 | .name = GS_SHORT_NAME, | ||
1686 | .owner = THIS_MODULE, | ||
1687 | }, | ||
1688 | }; | ||
1689 | |||
1763 | /* | 1690 | /* |
1764 | * gs_set_config | 1691 | * gs_set_config |
1765 | * | 1692 | * |
@@ -1775,9 +1702,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1775 | int ret = 0; | 1702 | int ret = 0; |
1776 | struct usb_gadget *gadget = dev->dev_gadget; | 1703 | struct usb_gadget *gadget = dev->dev_gadget; |
1777 | struct usb_ep *ep; | 1704 | struct usb_ep *ep; |
1778 | struct usb_endpoint_descriptor *ep_desc; | 1705 | struct usb_endpoint_descriptor *out, *in, *notify; |
1779 | struct usb_request *req; | 1706 | struct usb_request *req; |
1780 | struct gs_req_entry *req_entry; | ||
1781 | 1707 | ||
1782 | if (dev == NULL) { | 1708 | if (dev == NULL) { |
1783 | pr_err("gs_set_config: NULL device pointer\n"); | 1709 | pr_err("gs_set_config: NULL device pointer\n"); |
@@ -1795,86 +1721,62 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1795 | case GS_BULK_CONFIG_ID: | 1721 | case GS_BULK_CONFIG_ID: |
1796 | if (use_acm) | 1722 | if (use_acm) |
1797 | return -EINVAL; | 1723 | return -EINVAL; |
1798 | /* device specific optimizations */ | ||
1799 | if (gadget_is_net2280(gadget)) | ||
1800 | net2280_set_fifo_mode(gadget, 1); | ||
1801 | break; | 1724 | break; |
1802 | case GS_ACM_CONFIG_ID: | 1725 | case GS_ACM_CONFIG_ID: |
1803 | if (!use_acm) | 1726 | if (!use_acm) |
1804 | return -EINVAL; | 1727 | return -EINVAL; |
1805 | /* device specific optimizations */ | ||
1806 | if (gadget_is_net2280(gadget)) | ||
1807 | net2280_set_fifo_mode(gadget, 1); | ||
1808 | break; | 1728 | break; |
1809 | default: | 1729 | default: |
1810 | return -EINVAL; | 1730 | return -EINVAL; |
1811 | } | 1731 | } |
1812 | 1732 | ||
1813 | dev->dev_config = config; | 1733 | in = choose_ep_desc(gadget, |
1814 | 1734 | &gs_highspeed_in_desc, | |
1815 | gadget_for_each_ep(ep, gadget) { | 1735 | &gs_fullspeed_in_desc); |
1816 | 1736 | out = choose_ep_desc(gadget, | |
1817 | if (EP_NOTIFY_NAME | 1737 | &gs_highspeed_out_desc, |
1818 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { | 1738 | &gs_fullspeed_out_desc); |
1819 | ep_desc = choose_ep_desc(gadget, | 1739 | notify = dev->dev_notify_ep |
1740 | ? choose_ep_desc(gadget, | ||
1820 | &gs_highspeed_notify_desc, | 1741 | &gs_highspeed_notify_desc, |
1821 | &gs_fullspeed_notify_desc); | 1742 | &gs_fullspeed_notify_desc) |
1822 | ret = usb_ep_enable(ep,ep_desc); | 1743 | : NULL; |
1823 | if (ret == 0) { | ||
1824 | ep->driver_data = dev; | ||
1825 | dev->dev_notify_ep = ep; | ||
1826 | dev->dev_notify_ep_desc = ep_desc; | ||
1827 | } else { | ||
1828 | pr_err("gs_set_config: cannot enable NOTIFY " | ||
1829 | "endpoint %s, ret=%d\n", | ||
1830 | ep->name, ret); | ||
1831 | goto exit_reset_config; | ||
1832 | } | ||
1833 | } | ||
1834 | 1744 | ||
1835 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { | 1745 | ret = usb_ep_enable(dev->dev_in_ep, in); |
1836 | ep_desc = choose_ep_desc(gadget, | 1746 | if (ret == 0) { |
1837 | &gs_highspeed_in_desc, | 1747 | dev->dev_in_ep_desc = in; |
1838 | &gs_fullspeed_in_desc); | 1748 | } else { |
1839 | ret = usb_ep_enable(ep,ep_desc); | 1749 | pr_debug("%s: cannot enable %s %s, ret=%d\n", |
1840 | if (ret == 0) { | 1750 | __func__, "IN", dev->dev_in_ep->name, ret); |
1841 | ep->driver_data = dev; | 1751 | return ret; |
1842 | dev->dev_in_ep = ep; | 1752 | } |
1843 | dev->dev_in_ep_desc = ep_desc; | ||
1844 | } else { | ||
1845 | pr_err("gs_set_config: cannot enable IN " | ||
1846 | "endpoint %s, ret=%d\n", | ||
1847 | ep->name, ret); | ||
1848 | goto exit_reset_config; | ||
1849 | } | ||
1850 | } | ||
1851 | |||
1852 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { | ||
1853 | ep_desc = choose_ep_desc(gadget, | ||
1854 | &gs_highspeed_out_desc, | ||
1855 | &gs_fullspeed_out_desc); | ||
1856 | ret = usb_ep_enable(ep,ep_desc); | ||
1857 | if (ret == 0) { | ||
1858 | ep->driver_data = dev; | ||
1859 | dev->dev_out_ep = ep; | ||
1860 | dev->dev_out_ep_desc = ep_desc; | ||
1861 | } else { | ||
1862 | pr_err("gs_set_config: cannot enable OUT " | ||
1863 | "endpoint %s, ret=%d\n", | ||
1864 | ep->name, ret); | ||
1865 | goto exit_reset_config; | ||
1866 | } | ||
1867 | } | ||
1868 | 1753 | ||
1754 | ret = usb_ep_enable(dev->dev_out_ep, out); | ||
1755 | if (ret == 0) { | ||
1756 | dev->dev_out_ep_desc = out; | ||
1757 | } else { | ||
1758 | pr_debug("%s: cannot enable %s %s, ret=%d\n", | ||
1759 | __func__, "OUT", dev->dev_out_ep->name, ret); | ||
1760 | fail0: | ||
1761 | usb_ep_disable(dev->dev_in_ep); | ||
1762 | return ret; | ||
1869 | } | 1763 | } |
1870 | 1764 | ||
1871 | if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL | 1765 | if (notify) { |
1872 | || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { | 1766 | ret = usb_ep_enable(dev->dev_notify_ep, notify); |
1873 | pr_err("gs_set_config: cannot find endpoints\n"); | 1767 | if (ret == 0) { |
1874 | ret = -ENODEV; | 1768 | dev->dev_notify_ep_desc = notify; |
1875 | goto exit_reset_config; | 1769 | } else { |
1770 | pr_debug("%s: cannot enable %s %s, ret=%d\n", | ||
1771 | __func__, "NOTIFY", | ||
1772 | dev->dev_notify_ep->name, ret); | ||
1773 | usb_ep_disable(dev->dev_out_ep); | ||
1774 | goto fail0; | ||
1775 | } | ||
1876 | } | 1776 | } |
1877 | 1777 | ||
1778 | dev->dev_config = config; | ||
1779 | |||
1878 | /* allocate and queue read requests */ | 1780 | /* allocate and queue read requests */ |
1879 | ep = dev->dev_out_ep; | 1781 | ep = dev->dev_out_ep; |
1880 | for (i=0; i<read_q_size && ret == 0; i++) { | 1782 | for (i=0; i<read_q_size && ret == 0; i++) { |
@@ -1895,9 +1797,10 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1895 | /* allocate write requests, and put on free list */ | 1797 | /* allocate write requests, and put on free list */ |
1896 | ep = dev->dev_in_ep; | 1798 | ep = dev->dev_in_ep; |
1897 | for (i=0; i<write_q_size; i++) { | 1799 | for (i=0; i<write_q_size; i++) { |
1898 | if ((req_entry=gs_alloc_req_entry(ep, ep->maxpacket, GFP_ATOMIC))) { | 1800 | req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC); |
1899 | req_entry->re_req->complete = gs_write_complete; | 1801 | if (req) { |
1900 | list_add(&req_entry->re_entry, &dev->dev_req_list); | 1802 | req->complete = gs_write_complete; |
1803 | list_add(&req->list, &dev->dev_req_list); | ||
1901 | } else { | 1804 | } else { |
1902 | pr_err("gs_set_config: cannot allocate " | 1805 | pr_err("gs_set_config: cannot allocate " |
1903 | "write requests\n"); | 1806 | "write requests\n"); |
@@ -1906,6 +1809,11 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1906 | } | 1809 | } |
1907 | } | 1810 | } |
1908 | 1811 | ||
1812 | /* REVISIT the ACM mode should be able to actually *issue* some | ||
1813 | * notifications, for at least serial state change events if | ||
1814 | * not also for network connection; say so in bmCapabilities. | ||
1815 | */ | ||
1816 | |||
1909 | pr_info("gs_set_config: %s configured, %s speed %s config\n", | 1817 | pr_info("gs_set_config: %s configured, %s speed %s config\n", |
1910 | GS_LONG_NAME, | 1818 | GS_LONG_NAME, |
1911 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", | 1819 | gadget->speed == USB_SPEED_HIGH ? "high" : "full", |
@@ -1930,7 +1838,7 @@ exit_reset_config: | |||
1930 | */ | 1838 | */ |
1931 | static void gs_reset_config(struct gs_dev *dev) | 1839 | static void gs_reset_config(struct gs_dev *dev) |
1932 | { | 1840 | { |
1933 | struct gs_req_entry *req_entry; | 1841 | struct usb_request *req; |
1934 | 1842 | ||
1935 | if (dev == NULL) { | 1843 | if (dev == NULL) { |
1936 | pr_err("gs_reset_config: NULL device pointer\n"); | 1844 | pr_err("gs_reset_config: NULL device pointer\n"); |
@@ -1944,26 +1852,18 @@ static void gs_reset_config(struct gs_dev *dev) | |||
1944 | 1852 | ||
1945 | /* free write requests on the free list */ | 1853 | /* free write requests on the free list */ |
1946 | while(!list_empty(&dev->dev_req_list)) { | 1854 | while(!list_empty(&dev->dev_req_list)) { |
1947 | req_entry = list_entry(dev->dev_req_list.next, | 1855 | req = list_entry(dev->dev_req_list.next, |
1948 | struct gs_req_entry, re_entry); | 1856 | struct usb_request, list); |
1949 | list_del(&req_entry->re_entry); | 1857 | list_del(&req->list); |
1950 | gs_free_req_entry(dev->dev_in_ep, req_entry); | 1858 | gs_free_req(dev->dev_in_ep, req); |
1951 | } | 1859 | } |
1952 | 1860 | ||
1953 | /* disable endpoints, forcing completion of pending i/o; */ | 1861 | /* disable endpoints, forcing completion of pending i/o; */ |
1954 | /* completion handlers free their requests in this case */ | 1862 | /* completion handlers free their requests in this case */ |
1955 | if (dev->dev_notify_ep) { | 1863 | if (dev->dev_notify_ep) |
1956 | usb_ep_disable(dev->dev_notify_ep); | 1864 | usb_ep_disable(dev->dev_notify_ep); |
1957 | dev->dev_notify_ep = NULL; | 1865 | usb_ep_disable(dev->dev_in_ep); |
1958 | } | 1866 | usb_ep_disable(dev->dev_out_ep); |
1959 | if (dev->dev_in_ep) { | ||
1960 | usb_ep_disable(dev->dev_in_ep); | ||
1961 | dev->dev_in_ep = NULL; | ||
1962 | } | ||
1963 | if (dev->dev_out_ep) { | ||
1964 | usb_ep_disable(dev->dev_out_ep); | ||
1965 | dev->dev_out_ep = NULL; | ||
1966 | } | ||
1967 | } | 1867 | } |
1968 | 1868 | ||
1969 | /* | 1869 | /* |
@@ -2057,46 +1957,6 @@ static void gs_free_req(struct usb_ep *ep, struct usb_request *req) | |||
2057 | } | 1957 | } |
2058 | 1958 | ||
2059 | /* | 1959 | /* |
2060 | * gs_alloc_req_entry | ||
2061 | * | ||
2062 | * Allocates a request and its buffer, using the given | ||
2063 | * endpoint, buffer len, and kmalloc flags. | ||
2064 | */ | ||
2065 | static struct gs_req_entry * | ||
2066 | gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) | ||
2067 | { | ||
2068 | struct gs_req_entry *req; | ||
2069 | |||
2070 | req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags); | ||
2071 | if (req == NULL) | ||
2072 | return NULL; | ||
2073 | |||
2074 | req->re_req = gs_alloc_req(ep, len, kmalloc_flags); | ||
2075 | if (req->re_req == NULL) { | ||
2076 | kfree(req); | ||
2077 | return NULL; | ||
2078 | } | ||
2079 | |||
2080 | req->re_req->context = req; | ||
2081 | |||
2082 | return req; | ||
2083 | } | ||
2084 | |||
2085 | /* | ||
2086 | * gs_free_req_entry | ||
2087 | * | ||
2088 | * Frees a request and its buffer. | ||
2089 | */ | ||
2090 | static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req) | ||
2091 | { | ||
2092 | if (ep != NULL && req != NULL) { | ||
2093 | if (req->re_req != NULL) | ||
2094 | gs_free_req(ep, req->re_req); | ||
2095 | kfree(req); | ||
2096 | } | ||
2097 | } | ||
2098 | |||
2099 | /* | ||
2100 | * gs_alloc_ports | 1960 | * gs_alloc_ports |
2101 | * | 1961 | * |
2102 | * Allocate all ports and set the gs_dev struct to point to them. | 1962 | * Allocate all ports and set the gs_dev struct to point to them. |
@@ -2177,6 +2037,8 @@ static void gs_free_ports(struct gs_dev *dev) | |||
2177 | } | 2037 | } |
2178 | } | 2038 | } |
2179 | 2039 | ||
2040 | /*-------------------------------------------------------------------------*/ | ||
2041 | |||
2180 | /* Circular Buffer */ | 2042 | /* Circular Buffer */ |
2181 | 2043 | ||
2182 | /* | 2044 | /* |
@@ -2337,3 +2199,77 @@ gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count) | |||
2337 | 2199 | ||
2338 | return count; | 2200 | return count; |
2339 | } | 2201 | } |
2202 | |||
2203 | /*-------------------------------------------------------------------------*/ | ||
2204 | |||
2205 | static struct tty_driver *gs_tty_driver; | ||
2206 | |||
2207 | /* | ||
2208 | * gs_module_init | ||
2209 | * | ||
2210 | * Register as a USB gadget driver and a tty driver. | ||
2211 | */ | ||
2212 | static int __init gs_module_init(void) | ||
2213 | { | ||
2214 | int i; | ||
2215 | int retval; | ||
2216 | |||
2217 | retval = usb_gadget_register_driver(&gs_gadget_driver); | ||
2218 | if (retval) { | ||
2219 | pr_err("gs_module_init: cannot register gadget driver, " | ||
2220 | "ret=%d\n", retval); | ||
2221 | return retval; | ||
2222 | } | ||
2223 | |||
2224 | gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS); | ||
2225 | if (!gs_tty_driver) | ||
2226 | return -ENOMEM; | ||
2227 | gs_tty_driver->owner = THIS_MODULE; | ||
2228 | gs_tty_driver->driver_name = GS_SHORT_NAME; | ||
2229 | gs_tty_driver->name = "ttygs"; | ||
2230 | gs_tty_driver->major = GS_MAJOR; | ||
2231 | gs_tty_driver->minor_start = GS_MINOR_START; | ||
2232 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
2233 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
2234 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
2235 | gs_tty_driver->init_termios = tty_std_termios; | ||
2236 | /* must match GS_DEFAULT_DTE_RATE and friends */ | ||
2237 | gs_tty_driver->init_termios.c_cflag = | ||
2238 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
2239 | gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE; | ||
2240 | gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE; | ||
2241 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | ||
2242 | |||
2243 | for (i = 0; i < GS_NUM_PORTS; i++) | ||
2244 | mutex_init(&gs_open_close_lock[i]); | ||
2245 | |||
2246 | retval = tty_register_driver(gs_tty_driver); | ||
2247 | if (retval) { | ||
2248 | usb_gadget_unregister_driver(&gs_gadget_driver); | ||
2249 | put_tty_driver(gs_tty_driver); | ||
2250 | pr_err("gs_module_init: cannot register tty driver, " | ||
2251 | "ret=%d\n", retval); | ||
2252 | return retval; | ||
2253 | } | ||
2254 | |||
2255 | pr_info("gs_module_init: %s %s loaded\n", | ||
2256 | GS_LONG_NAME, GS_VERSION_STR); | ||
2257 | return 0; | ||
2258 | } | ||
2259 | module_init(gs_module_init); | ||
2260 | |||
2261 | /* | ||
2262 | * gs_module_exit | ||
2263 | * | ||
2264 | * Unregister as a tty driver and a USB gadget driver. | ||
2265 | */ | ||
2266 | static void __exit gs_module_exit(void) | ||
2267 | { | ||
2268 | tty_unregister_driver(gs_tty_driver); | ||
2269 | put_tty_driver(gs_tty_driver); | ||
2270 | usb_gadget_unregister_driver(&gs_gadget_driver); | ||
2271 | |||
2272 | pr_info("gs_module_exit: %s %s unloaded\n", | ||
2273 | GS_LONG_NAME, GS_VERSION_STR); | ||
2274 | } | ||
2275 | module_exit(gs_module_exit); | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index d3d4f4048e6c..fce4924dbbe8 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -23,9 +23,7 @@ | |||
23 | /* | 23 | /* |
24 | * Gadget Zero only needs two bulk endpoints, and is an example of how you | 24 | * Gadget Zero only needs two bulk endpoints, and is an example of how you |
25 | * can write a hardware-agnostic gadget driver running inside a USB device. | 25 | * can write a hardware-agnostic gadget driver running inside a USB device. |
26 | * | 26 | * Some hardware details are visible, but don't affect most of the driver. |
27 | * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't | ||
28 | * affect most of the driver. | ||
29 | * | 27 | * |
30 | * Use it with the Linux host/master side "usbtest" driver to get a basic | 28 | * Use it with the Linux host/master side "usbtest" driver to get a basic |
31 | * functional test of your device-side usb stack, or with "usb-skeleton". | 29 | * functional test of your device-side usb stack, or with "usb-skeleton". |
@@ -37,6 +35,7 @@ | |||
37 | * buflen=N default N=4096, buffer size used | 35 | * buflen=N default N=4096, buffer size used |
38 | * qlen=N default N=32, how many buffers in the loopback queue | 36 | * qlen=N default N=32, how many buffers in the loopback queue |
39 | * loopdefault default false, list loopback config first | 37 | * loopdefault default false, list loopback config first |
38 | * autoresume=N default N=0, seconds before triggering remote wakeup | ||
40 | * | 39 | * |
41 | * Many drivers will only have one configuration, letting them be much | 40 | * Many drivers will only have one configuration, letting them be much |
42 | * simpler if they also don't support high speed operation (like this | 41 | * simpler if they also don't support high speed operation (like this |
@@ -62,13 +61,13 @@ | |||
62 | 61 | ||
63 | /*-------------------------------------------------------------------------*/ | 62 | /*-------------------------------------------------------------------------*/ |
64 | 63 | ||
65 | #define DRIVER_VERSION "Lughnasadh, 2007" | 64 | #define DRIVER_VERSION "Earth Day 2008" |
66 | 65 | ||
67 | static const char shortname [] = "zero"; | 66 | static const char shortname[] = "zero"; |
68 | static const char longname [] = "Gadget Zero"; | 67 | static const char longname[] = "Gadget Zero"; |
69 | 68 | ||
70 | static const char source_sink [] = "source and sink data"; | 69 | static const char source_sink[] = "source and sink data"; |
71 | static const char loopback [] = "loop input to output"; | 70 | static const char loopback[] = "loop input to output"; |
72 | 71 | ||
73 | /*-------------------------------------------------------------------------*/ | 72 | /*-------------------------------------------------------------------------*/ |
74 | 73 | ||
@@ -120,16 +119,16 @@ static unsigned buflen = 4096; | |||
120 | static unsigned qlen = 32; | 119 | static unsigned qlen = 32; |
121 | static unsigned pattern = 0; | 120 | static unsigned pattern = 0; |
122 | 121 | ||
123 | module_param (buflen, uint, S_IRUGO); | 122 | module_param(buflen, uint, S_IRUGO); |
124 | module_param (qlen, uint, S_IRUGO); | 123 | module_param(qlen, uint, S_IRUGO); |
125 | module_param (pattern, uint, S_IRUGO|S_IWUSR); | 124 | module_param(pattern, uint, S_IRUGO|S_IWUSR); |
126 | 125 | ||
127 | /* | 126 | /* |
128 | * if it's nonzero, autoresume says how many seconds to wait | 127 | * if it's nonzero, autoresume says how many seconds to wait |
129 | * before trying to wake up the host after suspend. | 128 | * before trying to wake up the host after suspend. |
130 | */ | 129 | */ |
131 | static unsigned autoresume = 0; | 130 | static unsigned autoresume = 0; |
132 | module_param (autoresume, uint, 0); | 131 | module_param(autoresume, uint, 0); |
133 | 132 | ||
134 | /* | 133 | /* |
135 | * Normally the "loopback" configuration is second (index 1) so | 134 | * Normally the "loopback" configuration is second (index 1) so |
@@ -138,8 +137,7 @@ module_param (autoresume, uint, 0); | |||
138 | * Or controllers (like superh) that only support one config. | 137 | * Or controllers (like superh) that only support one config. |
139 | */ | 138 | */ |
140 | static int loopdefault = 0; | 139 | static int loopdefault = 0; |
141 | 140 | module_param(loopdefault, bool, S_IRUGO|S_IWUSR); | |
142 | module_param (loopdefault, bool, S_IRUGO|S_IWUSR); | ||
143 | 141 | ||
144 | /*-------------------------------------------------------------------------*/ | 142 | /*-------------------------------------------------------------------------*/ |
145 | 143 | ||
@@ -176,24 +174,22 @@ module_param (loopdefault, bool, S_IRUGO|S_IWUSR); | |||
176 | #define CONFIG_SOURCE_SINK 3 | 174 | #define CONFIG_SOURCE_SINK 3 |
177 | #define CONFIG_LOOPBACK 2 | 175 | #define CONFIG_LOOPBACK 2 |
178 | 176 | ||
179 | static struct usb_device_descriptor | 177 | static struct usb_device_descriptor device_desc = { |
180 | device_desc = { | ||
181 | .bLength = sizeof device_desc, | 178 | .bLength = sizeof device_desc, |
182 | .bDescriptorType = USB_DT_DEVICE, | 179 | .bDescriptorType = USB_DT_DEVICE, |
183 | 180 | ||
184 | .bcdUSB = __constant_cpu_to_le16 (0x0200), | 181 | .bcdUSB = __constant_cpu_to_le16(0x0200), |
185 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, | 182 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, |
186 | 183 | ||
187 | .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), | 184 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), |
188 | .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), | 185 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), |
189 | .iManufacturer = STRING_MANUFACTURER, | 186 | .iManufacturer = STRING_MANUFACTURER, |
190 | .iProduct = STRING_PRODUCT, | 187 | .iProduct = STRING_PRODUCT, |
191 | .iSerialNumber = STRING_SERIAL, | 188 | .iSerialNumber = STRING_SERIAL, |
192 | .bNumConfigurations = 2, | 189 | .bNumConfigurations = 2, |
193 | }; | 190 | }; |
194 | 191 | ||
195 | static struct usb_config_descriptor | 192 | static struct usb_config_descriptor source_sink_config = { |
196 | source_sink_config = { | ||
197 | .bLength = sizeof source_sink_config, | 193 | .bLength = sizeof source_sink_config, |
198 | .bDescriptorType = USB_DT_CONFIG, | 194 | .bDescriptorType = USB_DT_CONFIG, |
199 | 195 | ||
@@ -205,8 +201,7 @@ source_sink_config = { | |||
205 | .bMaxPower = 1, /* self-powered */ | 201 | .bMaxPower = 1, /* self-powered */ |
206 | }; | 202 | }; |
207 | 203 | ||
208 | static struct usb_config_descriptor | 204 | static struct usb_config_descriptor loopback_config = { |
209 | loopback_config = { | ||
210 | .bLength = sizeof loopback_config, | 205 | .bLength = sizeof loopback_config, |
211 | .bDescriptorType = USB_DT_CONFIG, | 206 | .bDescriptorType = USB_DT_CONFIG, |
212 | 207 | ||
@@ -218,8 +213,7 @@ loopback_config = { | |||
218 | .bMaxPower = 1, /* self-powered */ | 213 | .bMaxPower = 1, /* self-powered */ |
219 | }; | 214 | }; |
220 | 215 | ||
221 | static struct usb_otg_descriptor | 216 | static struct usb_otg_descriptor otg_descriptor = { |
222 | otg_descriptor = { | ||
223 | .bLength = sizeof otg_descriptor, | 217 | .bLength = sizeof otg_descriptor, |
224 | .bDescriptorType = USB_DT_OTG, | 218 | .bDescriptorType = USB_DT_OTG, |
225 | 219 | ||
@@ -228,8 +222,7 @@ otg_descriptor = { | |||
228 | 222 | ||
229 | /* one interface in each configuration */ | 223 | /* one interface in each configuration */ |
230 | 224 | ||
231 | static const struct usb_interface_descriptor | 225 | static const struct usb_interface_descriptor source_sink_intf = { |
232 | source_sink_intf = { | ||
233 | .bLength = sizeof source_sink_intf, | 226 | .bLength = sizeof source_sink_intf, |
234 | .bDescriptorType = USB_DT_INTERFACE, | 227 | .bDescriptorType = USB_DT_INTERFACE, |
235 | 228 | ||
@@ -238,8 +231,7 @@ source_sink_intf = { | |||
238 | .iInterface = STRING_SOURCE_SINK, | 231 | .iInterface = STRING_SOURCE_SINK, |
239 | }; | 232 | }; |
240 | 233 | ||
241 | static const struct usb_interface_descriptor | 234 | static const struct usb_interface_descriptor loopback_intf = { |
242 | loopback_intf = { | ||
243 | .bLength = sizeof loopback_intf, | 235 | .bLength = sizeof loopback_intf, |
244 | .bDescriptorType = USB_DT_INTERFACE, | 236 | .bDescriptorType = USB_DT_INTERFACE, |
245 | 237 | ||
@@ -250,8 +242,7 @@ loopback_intf = { | |||
250 | 242 | ||
251 | /* two full speed bulk endpoints; their use is config-dependent */ | 243 | /* two full speed bulk endpoints; their use is config-dependent */ |
252 | 244 | ||
253 | static struct usb_endpoint_descriptor | 245 | static struct usb_endpoint_descriptor fs_source_desc = { |
254 | fs_source_desc = { | ||
255 | .bLength = USB_DT_ENDPOINT_SIZE, | 246 | .bLength = USB_DT_ENDPOINT_SIZE, |
256 | .bDescriptorType = USB_DT_ENDPOINT, | 247 | .bDescriptorType = USB_DT_ENDPOINT, |
257 | 248 | ||
@@ -259,8 +250,7 @@ fs_source_desc = { | |||
259 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
260 | }; | 251 | }; |
261 | 252 | ||
262 | static struct usb_endpoint_descriptor | 253 | static struct usb_endpoint_descriptor fs_sink_desc = { |
263 | fs_sink_desc = { | ||
264 | .bLength = USB_DT_ENDPOINT_SIZE, | 254 | .bLength = USB_DT_ENDPOINT_SIZE, |
265 | .bDescriptorType = USB_DT_ENDPOINT, | 255 | .bDescriptorType = USB_DT_ENDPOINT, |
266 | 256 | ||
@@ -268,7 +258,7 @@ fs_sink_desc = { | |||
268 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 258 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
269 | }; | 259 | }; |
270 | 260 | ||
271 | static const struct usb_descriptor_header *fs_source_sink_function [] = { | 261 | static const struct usb_descriptor_header *fs_source_sink_function[] = { |
272 | (struct usb_descriptor_header *) &otg_descriptor, | 262 | (struct usb_descriptor_header *) &otg_descriptor, |
273 | (struct usb_descriptor_header *) &source_sink_intf, | 263 | (struct usb_descriptor_header *) &source_sink_intf, |
274 | (struct usb_descriptor_header *) &fs_sink_desc, | 264 | (struct usb_descriptor_header *) &fs_sink_desc, |
@@ -276,7 +266,7 @@ static const struct usb_descriptor_header *fs_source_sink_function [] = { | |||
276 | NULL, | 266 | NULL, |
277 | }; | 267 | }; |
278 | 268 | ||
279 | static const struct usb_descriptor_header *fs_loopback_function [] = { | 269 | static const struct usb_descriptor_header *fs_loopback_function[] = { |
280 | (struct usb_descriptor_header *) &otg_descriptor, | 270 | (struct usb_descriptor_header *) &otg_descriptor, |
281 | (struct usb_descriptor_header *) &loopback_intf, | 271 | (struct usb_descriptor_header *) &loopback_intf, |
282 | (struct usb_descriptor_header *) &fs_sink_desc, | 272 | (struct usb_descriptor_header *) &fs_sink_desc, |
@@ -293,36 +283,33 @@ static const struct usb_descriptor_header *fs_loopback_function [] = { | |||
293 | * for the config descriptor. | 283 | * for the config descriptor. |
294 | */ | 284 | */ |
295 | 285 | ||
296 | static struct usb_endpoint_descriptor | 286 | static struct usb_endpoint_descriptor hs_source_desc = { |
297 | hs_source_desc = { | ||
298 | .bLength = USB_DT_ENDPOINT_SIZE, | 287 | .bLength = USB_DT_ENDPOINT_SIZE, |
299 | .bDescriptorType = USB_DT_ENDPOINT, | 288 | .bDescriptorType = USB_DT_ENDPOINT, |
300 | 289 | ||
301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 290 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
302 | .wMaxPacketSize = __constant_cpu_to_le16 (512), | 291 | .wMaxPacketSize = __constant_cpu_to_le16(512), |
303 | }; | 292 | }; |
304 | 293 | ||
305 | static struct usb_endpoint_descriptor | 294 | static struct usb_endpoint_descriptor hs_sink_desc = { |
306 | hs_sink_desc = { | ||
307 | .bLength = USB_DT_ENDPOINT_SIZE, | 295 | .bLength = USB_DT_ENDPOINT_SIZE, |
308 | .bDescriptorType = USB_DT_ENDPOINT, | 296 | .bDescriptorType = USB_DT_ENDPOINT, |
309 | 297 | ||
310 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 298 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
311 | .wMaxPacketSize = __constant_cpu_to_le16 (512), | 299 | .wMaxPacketSize = __constant_cpu_to_le16(512), |
312 | }; | 300 | }; |
313 | 301 | ||
314 | static struct usb_qualifier_descriptor | 302 | static struct usb_qualifier_descriptor dev_qualifier = { |
315 | dev_qualifier = { | ||
316 | .bLength = sizeof dev_qualifier, | 303 | .bLength = sizeof dev_qualifier, |
317 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 304 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
318 | 305 | ||
319 | .bcdUSB = __constant_cpu_to_le16 (0x0200), | 306 | .bcdUSB = __constant_cpu_to_le16(0x0200), |
320 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, | 307 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, |
321 | 308 | ||
322 | .bNumConfigurations = 2, | 309 | .bNumConfigurations = 2, |
323 | }; | 310 | }; |
324 | 311 | ||
325 | static const struct usb_descriptor_header *hs_source_sink_function [] = { | 312 | static const struct usb_descriptor_header *hs_source_sink_function[] = { |
326 | (struct usb_descriptor_header *) &otg_descriptor, | 313 | (struct usb_descriptor_header *) &otg_descriptor, |
327 | (struct usb_descriptor_header *) &source_sink_intf, | 314 | (struct usb_descriptor_header *) &source_sink_intf, |
328 | (struct usb_descriptor_header *) &hs_source_desc, | 315 | (struct usb_descriptor_header *) &hs_source_desc, |
@@ -330,7 +317,7 @@ static const struct usb_descriptor_header *hs_source_sink_function [] = { | |||
330 | NULL, | 317 | NULL, |
331 | }; | 318 | }; |
332 | 319 | ||
333 | static const struct usb_descriptor_header *hs_loopback_function [] = { | 320 | static const struct usb_descriptor_header *hs_loopback_function[] = { |
334 | (struct usb_descriptor_header *) &otg_descriptor, | 321 | (struct usb_descriptor_header *) &otg_descriptor, |
335 | (struct usb_descriptor_header *) &loopback_intf, | 322 | (struct usb_descriptor_header *) &loopback_intf, |
336 | (struct usb_descriptor_header *) &hs_source_desc, | 323 | (struct usb_descriptor_header *) &hs_source_desc, |
@@ -355,7 +342,7 @@ static char serial[] = "0123456789.0123456789.0123456789"; | |||
355 | 342 | ||
356 | 343 | ||
357 | /* static strings, in UTF-8 */ | 344 | /* static strings, in UTF-8 */ |
358 | static struct usb_string strings [] = { | 345 | static struct usb_string strings[] = { |
359 | { STRING_MANUFACTURER, manufacturer, }, | 346 | { STRING_MANUFACTURER, manufacturer, }, |
360 | { STRING_PRODUCT, longname, }, | 347 | { STRING_PRODUCT, longname, }, |
361 | { STRING_SERIAL, serial, }, | 348 | { STRING_SERIAL, serial, }, |
@@ -364,7 +351,7 @@ static struct usb_string strings [] = { | |||
364 | { } /* end of list */ | 351 | { } /* end of list */ |
365 | }; | 352 | }; |
366 | 353 | ||
367 | static struct usb_gadget_strings stringtab = { | 354 | static struct usb_gadget_strings stringtab = { |
368 | .language = 0x0409, /* en-us */ | 355 | .language = 0x0409, /* en-us */ |
369 | .strings = strings, | 356 | .strings = strings, |
370 | }; | 357 | }; |
@@ -387,8 +374,7 @@ static struct usb_gadget_strings stringtab = { | |||
387 | * high bandwidth modes at high speed. (Maybe work like Intel's test | 374 | * high bandwidth modes at high speed. (Maybe work like Intel's test |
388 | * device?) | 375 | * device?) |
389 | */ | 376 | */ |
390 | static int | 377 | static int config_buf(struct usb_gadget *gadget, |
391 | config_buf (struct usb_gadget *gadget, | ||
392 | u8 *buf, u8 type, unsigned index) | 378 | u8 *buf, u8 type, unsigned index) |
393 | { | 379 | { |
394 | int is_source_sink; | 380 | int is_source_sink; |
@@ -419,7 +405,7 @@ config_buf (struct usb_gadget *gadget, | |||
419 | if (!gadget_is_otg(gadget)) | 405 | if (!gadget_is_otg(gadget)) |
420 | function++; | 406 | function++; |
421 | 407 | ||
422 | len = usb_gadget_config_buf (is_source_sink | 408 | len = usb_gadget_config_buf(is_source_sink |
423 | ? &source_sink_config | 409 | ? &source_sink_config |
424 | : &loopback_config, | 410 | : &loopback_config, |
425 | buf, USB_BUFSIZ, function); | 411 | buf, USB_BUFSIZ, function); |
@@ -431,27 +417,26 @@ config_buf (struct usb_gadget *gadget, | |||
431 | 417 | ||
432 | /*-------------------------------------------------------------------------*/ | 418 | /*-------------------------------------------------------------------------*/ |
433 | 419 | ||
434 | static struct usb_request * | 420 | static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) |
435 | alloc_ep_req (struct usb_ep *ep, unsigned length) | ||
436 | { | 421 | { |
437 | struct usb_request *req; | 422 | struct usb_request *req; |
438 | 423 | ||
439 | req = usb_ep_alloc_request (ep, GFP_ATOMIC); | 424 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); |
440 | if (req) { | 425 | if (req) { |
441 | req->length = length; | 426 | req->length = length; |
442 | req->buf = kmalloc(length, GFP_ATOMIC); | 427 | req->buf = kmalloc(length, GFP_ATOMIC); |
443 | if (!req->buf) { | 428 | if (!req->buf) { |
444 | usb_ep_free_request (ep, req); | 429 | usb_ep_free_request(ep, req); |
445 | req = NULL; | 430 | req = NULL; |
446 | } | 431 | } |
447 | } | 432 | } |
448 | return req; | 433 | return req; |
449 | } | 434 | } |
450 | 435 | ||
451 | static void free_ep_req (struct usb_ep *ep, struct usb_request *req) | 436 | static void free_ep_req(struct usb_ep *ep, struct usb_request *req) |
452 | { | 437 | { |
453 | kfree(req->buf); | 438 | kfree(req->buf); |
454 | usb_ep_free_request (ep, req); | 439 | usb_ep_free_request(ep, req); |
455 | } | 440 | } |
456 | 441 | ||
457 | /*-------------------------------------------------------------------------*/ | 442 | /*-------------------------------------------------------------------------*/ |
@@ -472,7 +457,7 @@ static void free_ep_req (struct usb_ep *ep, struct usb_request *req) | |||
472 | /* optionally require specific source/sink data patterns */ | 457 | /* optionally require specific source/sink data patterns */ |
473 | 458 | ||
474 | static int | 459 | static int |
475 | check_read_data ( | 460 | check_read_data( |
476 | struct zero_dev *dev, | 461 | struct zero_dev *dev, |
477 | struct usb_ep *ep, | 462 | struct usb_ep *ep, |
478 | struct usb_request *req | 463 | struct usb_request *req |
@@ -498,8 +483,8 @@ check_read_data ( | |||
498 | continue; | 483 | continue; |
499 | break; | 484 | break; |
500 | } | 485 | } |
501 | ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf); | 486 | ERROR(dev, "bad OUT byte, buf[%d] = %d\n", i, *buf); |
502 | usb_ep_set_halt (ep); | 487 | usb_ep_set_halt(ep); |
503 | return -EINVAL; | 488 | return -EINVAL; |
504 | } | 489 | } |
505 | return 0; | 490 | return 0; |
@@ -512,7 +497,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) | |||
512 | 497 | ||
513 | switch (pattern) { | 498 | switch (pattern) { |
514 | case 0: | 499 | case 0: |
515 | memset (req->buf, 0, req->length); | 500 | memset(req->buf, 0, req->length); |
516 | break; | 501 | break; |
517 | case 1: | 502 | case 1: |
518 | for (i = 0; i < req->length; i++) | 503 | for (i = 0; i < req->length; i++) |
@@ -525,7 +510,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) | |||
525 | * irq delay between end of one request and start of the next. | 510 | * irq delay between end of one request and start of the next. |
526 | * that prevents using hardware dma queues. | 511 | * that prevents using hardware dma queues. |
527 | */ | 512 | */ |
528 | static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | 513 | static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) |
529 | { | 514 | { |
530 | struct zero_dev *dev = ep->driver_data; | 515 | struct zero_dev *dev = ep->driver_data; |
531 | int status = req->status; | 516 | int status = req->status; |
@@ -534,8 +519,8 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
534 | 519 | ||
535 | case 0: /* normal completion? */ | 520 | case 0: /* normal completion? */ |
536 | if (ep == dev->out_ep) { | 521 | if (ep == dev->out_ep) { |
537 | check_read_data (dev, ep, req); | 522 | check_read_data(dev, ep, req); |
538 | memset (req->buf, 0x55, req->length); | 523 | memset(req->buf, 0x55, req->length); |
539 | } else | 524 | } else |
540 | reinit_write_data(ep, req); | 525 | reinit_write_data(ep, req); |
541 | break; | 526 | break; |
@@ -544,11 +529,11 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
544 | case -ECONNABORTED: /* hardware forced ep reset */ | 529 | case -ECONNABORTED: /* hardware forced ep reset */ |
545 | case -ECONNRESET: /* request dequeued */ | 530 | case -ECONNRESET: /* request dequeued */ |
546 | case -ESHUTDOWN: /* disconnect from host */ | 531 | case -ESHUTDOWN: /* disconnect from host */ |
547 | VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, | 532 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, |
548 | req->actual, req->length); | 533 | req->actual, req->length); |
549 | if (ep == dev->out_ep) | 534 | if (ep == dev->out_ep) |
550 | check_read_data (dev, ep, req); | 535 | check_read_data(dev, ep, req); |
551 | free_ep_req (ep, req); | 536 | free_ep_req(ep, req); |
552 | return; | 537 | return; |
553 | 538 | ||
554 | case -EOVERFLOW: /* buffer overrun on read means that | 539 | case -EOVERFLOW: /* buffer overrun on read means that |
@@ -557,18 +542,18 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
557 | */ | 542 | */ |
558 | default: | 543 | default: |
559 | #if 1 | 544 | #if 1 |
560 | DBG (dev, "%s complete --> %d, %d/%d\n", ep->name, | 545 | DBG(dev, "%s complete --> %d, %d/%d\n", ep->name, |
561 | status, req->actual, req->length); | 546 | status, req->actual, req->length); |
562 | #endif | 547 | #endif |
563 | case -EREMOTEIO: /* short read */ | 548 | case -EREMOTEIO: /* short read */ |
564 | break; | 549 | break; |
565 | } | 550 | } |
566 | 551 | ||
567 | status = usb_ep_queue (ep, req, GFP_ATOMIC); | 552 | status = usb_ep_queue(ep, req, GFP_ATOMIC); |
568 | if (status) { | 553 | if (status) { |
569 | ERROR (dev, "kill %s: resubmit %d bytes --> %d\n", | 554 | ERROR(dev, "kill %s: resubmit %d bytes --> %d\n", |
570 | ep->name, req->length, status); | 555 | ep->name, req->length, status); |
571 | usb_ep_set_halt (ep); | 556 | usb_ep_set_halt(ep); |
572 | /* FIXME recover later ... somehow */ | 557 | /* FIXME recover later ... somehow */ |
573 | } | 558 | } |
574 | } | 559 | } |
@@ -578,24 +563,24 @@ static struct usb_request *source_sink_start_ep(struct usb_ep *ep) | |||
578 | struct usb_request *req; | 563 | struct usb_request *req; |
579 | int status; | 564 | int status; |
580 | 565 | ||
581 | req = alloc_ep_req (ep, buflen); | 566 | req = alloc_ep_req(ep, buflen); |
582 | if (!req) | 567 | if (!req) |
583 | return NULL; | 568 | return NULL; |
584 | 569 | ||
585 | memset (req->buf, 0, req->length); | 570 | memset(req->buf, 0, req->length); |
586 | req->complete = source_sink_complete; | 571 | req->complete = source_sink_complete; |
587 | 572 | ||
588 | if (strcmp (ep->name, EP_IN_NAME) == 0) | 573 | if (strcmp(ep->name, EP_IN_NAME) == 0) |
589 | reinit_write_data(ep, req); | 574 | reinit_write_data(ep, req); |
590 | else | 575 | else |
591 | memset (req->buf, 0x55, req->length); | 576 | memset(req->buf, 0x55, req->length); |
592 | 577 | ||
593 | status = usb_ep_queue(ep, req, GFP_ATOMIC); | 578 | status = usb_ep_queue(ep, req, GFP_ATOMIC); |
594 | if (status) { | 579 | if (status) { |
595 | struct zero_dev *dev = ep->driver_data; | 580 | struct zero_dev *dev = ep->driver_data; |
596 | 581 | ||
597 | ERROR (dev, "start %s --> %d\n", ep->name, status); | 582 | ERROR(dev, "start %s --> %d\n", ep->name, status); |
598 | free_ep_req (ep, req); | 583 | free_ep_req(ep, req); |
599 | req = NULL; | 584 | req = NULL; |
600 | } | 585 | } |
601 | 586 | ||
@@ -608,34 +593,34 @@ static int set_source_sink_config(struct zero_dev *dev) | |||
608 | struct usb_ep *ep; | 593 | struct usb_ep *ep; |
609 | struct usb_gadget *gadget = dev->gadget; | 594 | struct usb_gadget *gadget = dev->gadget; |
610 | 595 | ||
611 | gadget_for_each_ep (ep, gadget) { | 596 | gadget_for_each_ep(ep, gadget) { |
612 | const struct usb_endpoint_descriptor *d; | 597 | const struct usb_endpoint_descriptor *d; |
613 | 598 | ||
614 | /* one endpoint writes (sources) zeroes in (to the host) */ | 599 | /* one endpoint writes (sources) zeroes in (to the host) */ |
615 | if (strcmp (ep->name, EP_IN_NAME) == 0) { | 600 | if (strcmp(ep->name, EP_IN_NAME) == 0) { |
616 | d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); | 601 | d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); |
617 | result = usb_ep_enable (ep, d); | 602 | result = usb_ep_enable(ep, d); |
618 | if (result == 0) { | 603 | if (result == 0) { |
619 | ep->driver_data = dev; | 604 | ep->driver_data = dev; |
620 | if (source_sink_start_ep(ep) != NULL) { | 605 | if (source_sink_start_ep(ep) != NULL) { |
621 | dev->in_ep = ep; | 606 | dev->in_ep = ep; |
622 | continue; | 607 | continue; |
623 | } | 608 | } |
624 | usb_ep_disable (ep); | 609 | usb_ep_disable(ep); |
625 | result = -EIO; | 610 | result = -EIO; |
626 | } | 611 | } |
627 | 612 | ||
628 | /* one endpoint reads (sinks) anything out (from the host) */ | 613 | /* one endpoint reads (sinks) anything out (from the host) */ |
629 | } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { | 614 | } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { |
630 | d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); | 615 | d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); |
631 | result = usb_ep_enable (ep, d); | 616 | result = usb_ep_enable(ep, d); |
632 | if (result == 0) { | 617 | if (result == 0) { |
633 | ep->driver_data = dev; | 618 | ep->driver_data = dev; |
634 | if (source_sink_start_ep(ep) != NULL) { | 619 | if (source_sink_start_ep(ep) != NULL) { |
635 | dev->out_ep = ep; | 620 | dev->out_ep = ep; |
636 | continue; | 621 | continue; |
637 | } | 622 | } |
638 | usb_ep_disable (ep); | 623 | usb_ep_disable(ep); |
639 | result = -EIO; | 624 | result = -EIO; |
640 | } | 625 | } |
641 | 626 | ||
@@ -644,11 +629,11 @@ static int set_source_sink_config(struct zero_dev *dev) | |||
644 | continue; | 629 | continue; |
645 | 630 | ||
646 | /* stop on error */ | 631 | /* stop on error */ |
647 | ERROR (dev, "can't start %s, result %d\n", ep->name, result); | 632 | ERROR(dev, "can't start %s, result %d\n", ep->name, result); |
648 | break; | 633 | break; |
649 | } | 634 | } |
650 | if (result == 0) | 635 | if (result == 0) |
651 | DBG (dev, "buflen %d\n", buflen); | 636 | DBG(dev, "buflen %d\n", buflen); |
652 | 637 | ||
653 | /* caller is responsible for cleanup on error */ | 638 | /* caller is responsible for cleanup on error */ |
654 | return result; | 639 | return result; |
@@ -656,7 +641,7 @@ static int set_source_sink_config(struct zero_dev *dev) | |||
656 | 641 | ||
657 | /*-------------------------------------------------------------------------*/ | 642 | /*-------------------------------------------------------------------------*/ |
658 | 643 | ||
659 | static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | 644 | static void loopback_complete(struct usb_ep *ep, struct usb_request *req) |
660 | { | 645 | { |
661 | struct zero_dev *dev = ep->driver_data; | 646 | struct zero_dev *dev = ep->driver_data; |
662 | int status = req->status; | 647 | int status = req->status; |
@@ -668,19 +653,19 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
668 | /* loop this OUT packet back IN to the host */ | 653 | /* loop this OUT packet back IN to the host */ |
669 | req->zero = (req->actual < req->length); | 654 | req->zero = (req->actual < req->length); |
670 | req->length = req->actual; | 655 | req->length = req->actual; |
671 | status = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); | 656 | status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); |
672 | if (status == 0) | 657 | if (status == 0) |
673 | return; | 658 | return; |
674 | 659 | ||
675 | /* "should never get here" */ | 660 | /* "should never get here" */ |
676 | ERROR (dev, "can't loop %s to %s: %d\n", | 661 | ERROR(dev, "can't loop %s to %s: %d\n", |
677 | ep->name, dev->in_ep->name, | 662 | ep->name, dev->in_ep->name, |
678 | status); | 663 | status); |
679 | } | 664 | } |
680 | 665 | ||
681 | /* queue the buffer for some later OUT packet */ | 666 | /* queue the buffer for some later OUT packet */ |
682 | req->length = buflen; | 667 | req->length = buflen; |
683 | status = usb_ep_queue (dev->out_ep, req, GFP_ATOMIC); | 668 | status = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); |
684 | if (status == 0) | 669 | if (status == 0) |
685 | return; | 670 | return; |
686 | 671 | ||
@@ -688,7 +673,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
688 | /* FALLTHROUGH */ | 673 | /* FALLTHROUGH */ |
689 | 674 | ||
690 | default: | 675 | default: |
691 | ERROR (dev, "%s loop complete --> %d, %d/%d\n", ep->name, | 676 | ERROR(dev, "%s loop complete --> %d, %d/%d\n", ep->name, |
692 | status, req->actual, req->length); | 677 | status, req->actual, req->length); |
693 | /* FALLTHROUGH */ | 678 | /* FALLTHROUGH */ |
694 | 679 | ||
@@ -700,7 +685,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
700 | case -ECONNABORTED: /* hardware forced ep reset */ | 685 | case -ECONNABORTED: /* hardware forced ep reset */ |
701 | case -ECONNRESET: /* request dequeued */ | 686 | case -ECONNRESET: /* request dequeued */ |
702 | case -ESHUTDOWN: /* disconnect from host */ | 687 | case -ESHUTDOWN: /* disconnect from host */ |
703 | free_ep_req (ep, req); | 688 | free_ep_req(ep, req); |
704 | return; | 689 | return; |
705 | } | 690 | } |
706 | } | 691 | } |
@@ -711,13 +696,13 @@ static int set_loopback_config(struct zero_dev *dev) | |||
711 | struct usb_ep *ep; | 696 | struct usb_ep *ep; |
712 | struct usb_gadget *gadget = dev->gadget; | 697 | struct usb_gadget *gadget = dev->gadget; |
713 | 698 | ||
714 | gadget_for_each_ep (ep, gadget) { | 699 | gadget_for_each_ep(ep, gadget) { |
715 | const struct usb_endpoint_descriptor *d; | 700 | const struct usb_endpoint_descriptor *d; |
716 | 701 | ||
717 | /* one endpoint writes data back IN to the host */ | 702 | /* one endpoint writes data back IN to the host */ |
718 | if (strcmp (ep->name, EP_IN_NAME) == 0) { | 703 | if (strcmp(ep->name, EP_IN_NAME) == 0) { |
719 | d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); | 704 | d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); |
720 | result = usb_ep_enable (ep, d); | 705 | result = usb_ep_enable(ep, d); |
721 | if (result == 0) { | 706 | if (result == 0) { |
722 | ep->driver_data = dev; | 707 | ep->driver_data = dev; |
723 | dev->in_ep = ep; | 708 | dev->in_ep = ep; |
@@ -725,9 +710,9 @@ static int set_loopback_config(struct zero_dev *dev) | |||
725 | } | 710 | } |
726 | 711 | ||
727 | /* one endpoint just reads OUT packets */ | 712 | /* one endpoint just reads OUT packets */ |
728 | } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { | 713 | } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { |
729 | d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); | 714 | d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); |
730 | result = usb_ep_enable (ep, d); | 715 | result = usb_ep_enable(ep, d); |
731 | if (result == 0) { | 716 | if (result == 0) { |
732 | ep->driver_data = dev; | 717 | ep->driver_data = dev; |
733 | dev->out_ep = ep; | 718 | dev->out_ep = ep; |
@@ -739,7 +724,7 @@ static int set_loopback_config(struct zero_dev *dev) | |||
739 | continue; | 724 | continue; |
740 | 725 | ||
741 | /* stop on error */ | 726 | /* stop on error */ |
742 | ERROR (dev, "can't enable %s, result %d\n", ep->name, result); | 727 | ERROR(dev, "can't enable %s, result %d\n", ep->name, result); |
743 | break; | 728 | break; |
744 | } | 729 | } |
745 | 730 | ||
@@ -753,19 +738,19 @@ static int set_loopback_config(struct zero_dev *dev) | |||
753 | 738 | ||
754 | ep = dev->out_ep; | 739 | ep = dev->out_ep; |
755 | for (i = 0; i < qlen && result == 0; i++) { | 740 | for (i = 0; i < qlen && result == 0; i++) { |
756 | req = alloc_ep_req (ep, buflen); | 741 | req = alloc_ep_req(ep, buflen); |
757 | if (req) { | 742 | if (req) { |
758 | req->complete = loopback_complete; | 743 | req->complete = loopback_complete; |
759 | result = usb_ep_queue (ep, req, GFP_ATOMIC); | 744 | result = usb_ep_queue(ep, req, GFP_ATOMIC); |
760 | if (result) | 745 | if (result) |
761 | DBG (dev, "%s queue req --> %d\n", | 746 | DBG(dev, "%s queue req --> %d\n", |
762 | ep->name, result); | 747 | ep->name, result); |
763 | } else | 748 | } else |
764 | result = -ENOMEM; | 749 | result = -ENOMEM; |
765 | } | 750 | } |
766 | } | 751 | } |
767 | if (result == 0) | 752 | if (result == 0) |
768 | DBG (dev, "qlen %d, buflen %d\n", qlen, buflen); | 753 | DBG(dev, "qlen %d, buflen %d\n", qlen, buflen); |
769 | 754 | ||
770 | /* caller is responsible for cleanup on error */ | 755 | /* caller is responsible for cleanup on error */ |
771 | return result; | 756 | return result; |
@@ -773,26 +758,26 @@ static int set_loopback_config(struct zero_dev *dev) | |||
773 | 758 | ||
774 | /*-------------------------------------------------------------------------*/ | 759 | /*-------------------------------------------------------------------------*/ |
775 | 760 | ||
776 | static void zero_reset_config (struct zero_dev *dev) | 761 | static void zero_reset_config(struct zero_dev *dev) |
777 | { | 762 | { |
778 | if (dev->config == 0) | 763 | if (dev->config == 0) |
779 | return; | 764 | return; |
780 | 765 | ||
781 | DBG (dev, "reset config\n"); | 766 | DBG(dev, "reset config\n"); |
782 | 767 | ||
783 | /* just disable endpoints, forcing completion of pending i/o. | 768 | /* just disable endpoints, forcing completion of pending i/o. |
784 | * all our completion handlers free their requests in this case. | 769 | * all our completion handlers free their requests in this case. |
785 | */ | 770 | */ |
786 | if (dev->in_ep) { | 771 | if (dev->in_ep) { |
787 | usb_ep_disable (dev->in_ep); | 772 | usb_ep_disable(dev->in_ep); |
788 | dev->in_ep = NULL; | 773 | dev->in_ep = NULL; |
789 | } | 774 | } |
790 | if (dev->out_ep) { | 775 | if (dev->out_ep) { |
791 | usb_ep_disable (dev->out_ep); | 776 | usb_ep_disable(dev->out_ep); |
792 | dev->out_ep = NULL; | 777 | dev->out_ep = NULL; |
793 | } | 778 | } |
794 | dev->config = 0; | 779 | dev->config = 0; |
795 | del_timer (&dev->resume); | 780 | del_timer(&dev->resume); |
796 | } | 781 | } |
797 | 782 | ||
798 | /* change our operational config. this code must agree with the code | 783 | /* change our operational config. this code must agree with the code |
@@ -813,12 +798,12 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) | |||
813 | if (number == dev->config) | 798 | if (number == dev->config) |
814 | return 0; | 799 | return 0; |
815 | 800 | ||
816 | if (gadget_is_sa1100 (gadget) && dev->config) { | 801 | if (gadget_is_sa1100(gadget) && dev->config) { |
817 | /* tx fifo is full, but we can't clear it...*/ | 802 | /* tx fifo is full, but we can't clear it...*/ |
818 | ERROR(dev, "can't change configurations\n"); | 803 | ERROR(dev, "can't change configurations\n"); |
819 | return -ESPIPE; | 804 | return -ESPIPE; |
820 | } | 805 | } |
821 | zero_reset_config (dev); | 806 | zero_reset_config(dev); |
822 | 807 | ||
823 | switch (number) { | 808 | switch (number) { |
824 | case CONFIG_SOURCE_SINK: | 809 | case CONFIG_SOURCE_SINK: |
@@ -837,7 +822,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) | |||
837 | if (!result && (!dev->in_ep || !dev->out_ep)) | 822 | if (!result && (!dev->in_ep || !dev->out_ep)) |
838 | result = -ENODEV; | 823 | result = -ENODEV; |
839 | if (result) | 824 | if (result) |
840 | zero_reset_config (dev); | 825 | zero_reset_config(dev); |
841 | else { | 826 | else { |
842 | char *speed; | 827 | char *speed; |
843 | 828 | ||
@@ -849,7 +834,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) | |||
849 | } | 834 | } |
850 | 835 | ||
851 | dev->config = number; | 836 | dev->config = number; |
852 | INFO (dev, "%s speed config #%d: %s\n", speed, number, | 837 | INFO(dev, "%s speed config #%d: %s\n", speed, number, |
853 | (number == CONFIG_SOURCE_SINK) | 838 | (number == CONFIG_SOURCE_SINK) |
854 | ? source_sink : loopback); | 839 | ? source_sink : loopback); |
855 | } | 840 | } |
@@ -858,10 +843,10 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) | |||
858 | 843 | ||
859 | /*-------------------------------------------------------------------------*/ | 844 | /*-------------------------------------------------------------------------*/ |
860 | 845 | ||
861 | static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) | 846 | static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req) |
862 | { | 847 | { |
863 | if (req->status || req->actual != req->length) | 848 | if (req->status || req->actual != req->length) |
864 | DBG ((struct zero_dev *) ep->driver_data, | 849 | DBG((struct zero_dev *) ep->driver_data, |
865 | "setup complete --> %d, %d/%d\n", | 850 | "setup complete --> %d, %d/%d\n", |
866 | req->status, req->actual, req->length); | 851 | req->status, req->actual, req->length); |
867 | } | 852 | } |
@@ -874,9 +859,9 @@ static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) | |||
874 | * the work is in config-specific setup. | 859 | * the work is in config-specific setup. |
875 | */ | 860 | */ |
876 | static int | 861 | static int |
877 | zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | 862 | zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) |
878 | { | 863 | { |
879 | struct zero_dev *dev = get_gadget_data (gadget); | 864 | struct zero_dev *dev = get_gadget_data(gadget); |
880 | struct usb_request *req = dev->req; | 865 | struct usb_request *req = dev->req; |
881 | int value = -EOPNOTSUPP; | 866 | int value = -EOPNOTSUPP; |
882 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 867 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
@@ -895,14 +880,14 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
895 | switch (w_value >> 8) { | 880 | switch (w_value >> 8) { |
896 | 881 | ||
897 | case USB_DT_DEVICE: | 882 | case USB_DT_DEVICE: |
898 | value = min (w_length, (u16) sizeof device_desc); | 883 | value = min(w_length, (u16) sizeof device_desc); |
899 | memcpy (req->buf, &device_desc, value); | 884 | memcpy(req->buf, &device_desc, value); |
900 | break; | 885 | break; |
901 | case USB_DT_DEVICE_QUALIFIER: | 886 | case USB_DT_DEVICE_QUALIFIER: |
902 | if (!gadget_is_dualspeed(gadget)) | 887 | if (!gadget_is_dualspeed(gadget)) |
903 | break; | 888 | break; |
904 | value = min (w_length, (u16) sizeof dev_qualifier); | 889 | value = min(w_length, (u16) sizeof dev_qualifier); |
905 | memcpy (req->buf, &dev_qualifier, value); | 890 | memcpy(req->buf, &dev_qualifier, value); |
906 | break; | 891 | break; |
907 | 892 | ||
908 | case USB_DT_OTHER_SPEED_CONFIG: | 893 | case USB_DT_OTHER_SPEED_CONFIG: |
@@ -910,11 +895,11 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
910 | break; | 895 | break; |
911 | // FALLTHROUGH | 896 | // FALLTHROUGH |
912 | case USB_DT_CONFIG: | 897 | case USB_DT_CONFIG: |
913 | value = config_buf (gadget, req->buf, | 898 | value = config_buf(gadget, req->buf, |
914 | w_value >> 8, | 899 | w_value >> 8, |
915 | w_value & 0xff); | 900 | w_value & 0xff); |
916 | if (value >= 0) | 901 | if (value >= 0) |
917 | value = min (w_length, (u16) value); | 902 | value = min(w_length, (u16) value); |
918 | break; | 903 | break; |
919 | 904 | ||
920 | case USB_DT_STRING: | 905 | case USB_DT_STRING: |
@@ -923,10 +908,10 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
923 | * add string tables for other languages, using | 908 | * add string tables for other languages, using |
924 | * any UTF-8 characters | 909 | * any UTF-8 characters |
925 | */ | 910 | */ |
926 | value = usb_gadget_get_string (&stringtab, | 911 | value = usb_gadget_get_string(&stringtab, |
927 | w_value & 0xff, req->buf); | 912 | w_value & 0xff, req->buf); |
928 | if (value >= 0) | 913 | if (value >= 0) |
929 | value = min (w_length, (u16) value); | 914 | value = min(w_length, (u16) value); |
930 | break; | 915 | break; |
931 | } | 916 | } |
932 | break; | 917 | break; |
@@ -936,20 +921,20 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
936 | if (ctrl->bRequestType != 0) | 921 | if (ctrl->bRequestType != 0) |
937 | goto unknown; | 922 | goto unknown; |
938 | if (gadget->a_hnp_support) | 923 | if (gadget->a_hnp_support) |
939 | DBG (dev, "HNP available\n"); | 924 | DBG(dev, "HNP available\n"); |
940 | else if (gadget->a_alt_hnp_support) | 925 | else if (gadget->a_alt_hnp_support) |
941 | DBG (dev, "HNP needs a different root port\n"); | 926 | DBG(dev, "HNP needs a different root port\n"); |
942 | else | 927 | else |
943 | VDBG (dev, "HNP inactive\n"); | 928 | VDBG(dev, "HNP inactive\n"); |
944 | spin_lock (&dev->lock); | 929 | spin_lock(&dev->lock); |
945 | value = zero_set_config(dev, w_value); | 930 | value = zero_set_config(dev, w_value); |
946 | spin_unlock (&dev->lock); | 931 | spin_unlock(&dev->lock); |
947 | break; | 932 | break; |
948 | case USB_REQ_GET_CONFIGURATION: | 933 | case USB_REQ_GET_CONFIGURATION: |
949 | if (ctrl->bRequestType != USB_DIR_IN) | 934 | if (ctrl->bRequestType != USB_DIR_IN) |
950 | goto unknown; | 935 | goto unknown; |
951 | *(u8 *)req->buf = dev->config; | 936 | *(u8 *)req->buf = dev->config; |
952 | value = min (w_length, (u16) 1); | 937 | value = min(w_length, (u16) 1); |
953 | break; | 938 | break; |
954 | 939 | ||
955 | /* until we add altsetting support, or other interfaces, | 940 | /* until we add altsetting support, or other interfaces, |
@@ -959,7 +944,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
959 | case USB_REQ_SET_INTERFACE: | 944 | case USB_REQ_SET_INTERFACE: |
960 | if (ctrl->bRequestType != USB_RECIP_INTERFACE) | 945 | if (ctrl->bRequestType != USB_RECIP_INTERFACE) |
961 | goto unknown; | 946 | goto unknown; |
962 | spin_lock (&dev->lock); | 947 | spin_lock(&dev->lock); |
963 | if (dev->config && w_index == 0 && w_value == 0) { | 948 | if (dev->config && w_index == 0 && w_value == 0) { |
964 | u8 config = dev->config; | 949 | u8 config = dev->config; |
965 | 950 | ||
@@ -970,11 +955,11 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
970 | * if we had more than one interface we couldn't | 955 | * if we had more than one interface we couldn't |
971 | * use this "reset the config" shortcut. | 956 | * use this "reset the config" shortcut. |
972 | */ | 957 | */ |
973 | zero_reset_config (dev); | 958 | zero_reset_config(dev); |
974 | zero_set_config(dev, config); | 959 | zero_set_config(dev, config); |
975 | value = 0; | 960 | value = 0; |
976 | } | 961 | } |
977 | spin_unlock (&dev->lock); | 962 | spin_unlock(&dev->lock); |
978 | break; | 963 | break; |
979 | case USB_REQ_GET_INTERFACE: | 964 | case USB_REQ_GET_INTERFACE: |
980 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) | 965 | if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) |
@@ -986,7 +971,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
986 | break; | 971 | break; |
987 | } | 972 | } |
988 | *(u8 *)req->buf = 0; | 973 | *(u8 *)req->buf = 0; |
989 | value = min (w_length, (u16) 1); | 974 | value = min(w_length, (u16) 1); |
990 | break; | 975 | break; |
991 | 976 | ||
992 | /* | 977 | /* |
@@ -1018,7 +1003,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1018 | 1003 | ||
1019 | default: | 1004 | default: |
1020 | unknown: | 1005 | unknown: |
1021 | VDBG (dev, | 1006 | VDBG(dev, |
1022 | "unknown control req%02x.%02x v%04x i%04x l%d\n", | 1007 | "unknown control req%02x.%02x v%04x i%04x l%d\n", |
1023 | ctrl->bRequestType, ctrl->bRequest, | 1008 | ctrl->bRequestType, ctrl->bRequest, |
1024 | w_value, w_index, w_length); | 1009 | w_value, w_index, w_length); |
@@ -1028,11 +1013,11 @@ unknown: | |||
1028 | if (value >= 0) { | 1013 | if (value >= 0) { |
1029 | req->length = value; | 1014 | req->length = value; |
1030 | req->zero = value < w_length; | 1015 | req->zero = value < w_length; |
1031 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); | 1016 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); |
1032 | if (value < 0) { | 1017 | if (value < 0) { |
1033 | DBG (dev, "ep_queue --> %d\n", value); | 1018 | DBG(dev, "ep_queue --> %d\n", value); |
1034 | req->status = 0; | 1019 | req->status = 0; |
1035 | zero_setup_complete (gadget->ep0, req); | 1020 | zero_setup_complete(gadget->ep0, req); |
1036 | } | 1021 | } |
1037 | } | 1022 | } |
1038 | 1023 | ||
@@ -1040,28 +1025,26 @@ unknown: | |||
1040 | return value; | 1025 | return value; |
1041 | } | 1026 | } |
1042 | 1027 | ||
1043 | static void | 1028 | static void zero_disconnect(struct usb_gadget *gadget) |
1044 | zero_disconnect (struct usb_gadget *gadget) | ||
1045 | { | 1029 | { |
1046 | struct zero_dev *dev = get_gadget_data (gadget); | 1030 | struct zero_dev *dev = get_gadget_data(gadget); |
1047 | unsigned long flags; | 1031 | unsigned long flags; |
1048 | 1032 | ||
1049 | spin_lock_irqsave (&dev->lock, flags); | 1033 | spin_lock_irqsave(&dev->lock, flags); |
1050 | zero_reset_config (dev); | 1034 | zero_reset_config(dev); |
1051 | 1035 | ||
1052 | /* a more significant application might have some non-usb | 1036 | /* a more significant application might have some non-usb |
1053 | * activities to quiesce here, saving resources like power | 1037 | * activities to quiesce here, saving resources like power |
1054 | * or pushing the notification up a network stack. | 1038 | * or pushing the notification up a network stack. |
1055 | */ | 1039 | */ |
1056 | spin_unlock_irqrestore (&dev->lock, flags); | 1040 | spin_unlock_irqrestore(&dev->lock, flags); |
1057 | 1041 | ||
1058 | /* next we may get setup() calls to enumerate new connections; | 1042 | /* next we may get setup() calls to enumerate new connections; |
1059 | * or an unbind() during shutdown (including removing module). | 1043 | * or an unbind() during shutdown (including removing module). |
1060 | */ | 1044 | */ |
1061 | } | 1045 | } |
1062 | 1046 | ||
1063 | static void | 1047 | static void zero_autoresume(unsigned long _dev) |
1064 | zero_autoresume (unsigned long _dev) | ||
1065 | { | 1048 | { |
1066 | struct zero_dev *dev = (struct zero_dev *) _dev; | 1049 | struct zero_dev *dev = (struct zero_dev *) _dev; |
1067 | int status; | 1050 | int status; |
@@ -1070,32 +1053,30 @@ zero_autoresume (unsigned long _dev) | |||
1070 | * more significant than just a timer firing... | 1053 | * more significant than just a timer firing... |
1071 | */ | 1054 | */ |
1072 | if (dev->gadget->speed != USB_SPEED_UNKNOWN) { | 1055 | if (dev->gadget->speed != USB_SPEED_UNKNOWN) { |
1073 | status = usb_gadget_wakeup (dev->gadget); | 1056 | status = usb_gadget_wakeup(dev->gadget); |
1074 | DBG (dev, "wakeup --> %d\n", status); | 1057 | DBG(dev, "wakeup --> %d\n", status); |
1075 | } | 1058 | } |
1076 | } | 1059 | } |
1077 | 1060 | ||
1078 | /*-------------------------------------------------------------------------*/ | 1061 | /*-------------------------------------------------------------------------*/ |
1079 | 1062 | ||
1080 | static void /* __init_or_exit */ | 1063 | static void zero_unbind(struct usb_gadget *gadget) |
1081 | zero_unbind (struct usb_gadget *gadget) | ||
1082 | { | 1064 | { |
1083 | struct zero_dev *dev = get_gadget_data (gadget); | 1065 | struct zero_dev *dev = get_gadget_data(gadget); |
1084 | 1066 | ||
1085 | DBG (dev, "unbind\n"); | 1067 | DBG(dev, "unbind\n"); |
1086 | 1068 | ||
1087 | /* we've already been disconnected ... no i/o is active */ | 1069 | /* we've already been disconnected ... no i/o is active */ |
1088 | if (dev->req) { | 1070 | if (dev->req) { |
1089 | dev->req->length = USB_BUFSIZ; | 1071 | dev->req->length = USB_BUFSIZ; |
1090 | free_ep_req (gadget->ep0, dev->req); | 1072 | free_ep_req(gadget->ep0, dev->req); |
1091 | } | 1073 | } |
1092 | del_timer_sync (&dev->resume); | 1074 | del_timer_sync(&dev->resume); |
1093 | kfree (dev); | 1075 | kfree(dev); |
1094 | set_gadget_data (gadget, NULL); | 1076 | set_gadget_data(gadget, NULL); |
1095 | } | 1077 | } |
1096 | 1078 | ||
1097 | static int __init | 1079 | static int __init zero_bind(struct usb_gadget *gadget) |
1098 | zero_bind (struct usb_gadget *gadget) | ||
1099 | { | 1080 | { |
1100 | struct zero_dev *dev; | 1081 | struct zero_dev *dev; |
1101 | struct usb_ep *ep; | 1082 | struct usb_ep *ep; |
@@ -1111,8 +1092,8 @@ zero_bind (struct usb_gadget *gadget) | |||
1111 | * autoconfigure on any sane usb controller driver, | 1092 | * autoconfigure on any sane usb controller driver, |
1112 | * but there may also be important quirks to address. | 1093 | * but there may also be important quirks to address. |
1113 | */ | 1094 | */ |
1114 | usb_ep_autoconfig_reset (gadget); | 1095 | usb_ep_autoconfig_reset(gadget); |
1115 | ep = usb_ep_autoconfig (gadget, &fs_source_desc); | 1096 | ep = usb_ep_autoconfig(gadget, &fs_source_desc); |
1116 | if (!ep) { | 1097 | if (!ep) { |
1117 | autoconf_fail: | 1098 | autoconf_fail: |
1118 | pr_err("%s: can't autoconfigure on %s\n", | 1099 | pr_err("%s: can't autoconfigure on %s\n", |
@@ -1122,15 +1103,15 @@ autoconf_fail: | |||
1122 | EP_IN_NAME = ep->name; | 1103 | EP_IN_NAME = ep->name; |
1123 | ep->driver_data = ep; /* claim */ | 1104 | ep->driver_data = ep; /* claim */ |
1124 | 1105 | ||
1125 | ep = usb_ep_autoconfig (gadget, &fs_sink_desc); | 1106 | ep = usb_ep_autoconfig(gadget, &fs_sink_desc); |
1126 | if (!ep) | 1107 | if (!ep) |
1127 | goto autoconf_fail; | 1108 | goto autoconf_fail; |
1128 | EP_OUT_NAME = ep->name; | 1109 | EP_OUT_NAME = ep->name; |
1129 | ep->driver_data = ep; /* claim */ | 1110 | ep->driver_data = ep; /* claim */ |
1130 | 1111 | ||
1131 | gcnum = usb_gadget_controller_number (gadget); | 1112 | gcnum = usb_gadget_controller_number(gadget); |
1132 | if (gcnum >= 0) | 1113 | if (gcnum >= 0) |
1133 | device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum); | 1114 | device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); |
1134 | else { | 1115 | else { |
1135 | /* gadget zero is so simple (for now, no altsettings) that | 1116 | /* gadget zero is so simple (for now, no altsettings) that |
1136 | * it SHOULD NOT have problems with bulk-capable hardware. | 1117 | * it SHOULD NOT have problems with bulk-capable hardware. |
@@ -1141,7 +1122,7 @@ autoconf_fail: | |||
1141 | */ | 1122 | */ |
1142 | pr_warning("%s: controller '%s' not recognized\n", | 1123 | pr_warning("%s: controller '%s' not recognized\n", |
1143 | shortname, gadget->name); | 1124 | shortname, gadget->name); |
1144 | device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); | 1125 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); |
1145 | } | 1126 | } |
1146 | 1127 | ||
1147 | 1128 | ||
@@ -1149,12 +1130,16 @@ autoconf_fail: | |||
1149 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1130 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1150 | if (!dev) | 1131 | if (!dev) |
1151 | return -ENOMEM; | 1132 | return -ENOMEM; |
1152 | spin_lock_init (&dev->lock); | 1133 | spin_lock_init(&dev->lock); |
1153 | dev->gadget = gadget; | 1134 | dev->gadget = gadget; |
1154 | set_gadget_data (gadget, dev); | 1135 | set_gadget_data(gadget, dev); |
1136 | |||
1137 | init_timer(&dev->resume); | ||
1138 | dev->resume.function = zero_autoresume; | ||
1139 | dev->resume.data = (unsigned long) dev; | ||
1155 | 1140 | ||
1156 | /* preallocate control response and buffer */ | 1141 | /* preallocate control response and buffer */ |
1157 | dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); | 1142 | dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); |
1158 | if (!dev->req) | 1143 | if (!dev->req) |
1159 | goto enomem; | 1144 | goto enomem; |
1160 | dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); | 1145 | dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); |
@@ -1182,11 +1167,8 @@ autoconf_fail: | |||
1182 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1167 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1183 | } | 1168 | } |
1184 | 1169 | ||
1185 | usb_gadget_set_selfpowered (gadget); | 1170 | usb_gadget_set_selfpowered(gadget); |
1186 | 1171 | ||
1187 | init_timer (&dev->resume); | ||
1188 | dev->resume.function = zero_autoresume; | ||
1189 | dev->resume.data = (unsigned long) dev; | ||
1190 | if (autoresume) { | 1172 | if (autoresume) { |
1191 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1173 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1192 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1174 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
@@ -1194,45 +1176,43 @@ autoconf_fail: | |||
1194 | 1176 | ||
1195 | gadget->ep0->driver_data = dev; | 1177 | gadget->ep0->driver_data = dev; |
1196 | 1178 | ||
1197 | INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); | 1179 | INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); |
1198 | INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, | 1180 | INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, |
1199 | EP_OUT_NAME, EP_IN_NAME); | 1181 | EP_OUT_NAME, EP_IN_NAME); |
1200 | 1182 | ||
1201 | snprintf (manufacturer, sizeof manufacturer, "%s %s with %s", | 1183 | snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", |
1202 | init_utsname()->sysname, init_utsname()->release, | 1184 | init_utsname()->sysname, init_utsname()->release, |
1203 | gadget->name); | 1185 | gadget->name); |
1204 | 1186 | ||
1205 | return 0; | 1187 | return 0; |
1206 | 1188 | ||
1207 | enomem: | 1189 | enomem: |
1208 | zero_unbind (gadget); | 1190 | zero_unbind(gadget); |
1209 | return -ENOMEM; | 1191 | return -ENOMEM; |
1210 | } | 1192 | } |
1211 | 1193 | ||
1212 | /*-------------------------------------------------------------------------*/ | 1194 | /*-------------------------------------------------------------------------*/ |
1213 | 1195 | ||
1214 | static void | 1196 | static void zero_suspend(struct usb_gadget *gadget) |
1215 | zero_suspend (struct usb_gadget *gadget) | ||
1216 | { | 1197 | { |
1217 | struct zero_dev *dev = get_gadget_data (gadget); | 1198 | struct zero_dev *dev = get_gadget_data(gadget); |
1218 | 1199 | ||
1219 | if (gadget->speed == USB_SPEED_UNKNOWN) | 1200 | if (gadget->speed == USB_SPEED_UNKNOWN) |
1220 | return; | 1201 | return; |
1221 | 1202 | ||
1222 | if (autoresume) { | 1203 | if (autoresume) { |
1223 | mod_timer (&dev->resume, jiffies + (HZ * autoresume)); | 1204 | mod_timer(&dev->resume, jiffies + (HZ * autoresume)); |
1224 | DBG (dev, "suspend, wakeup in %d seconds\n", autoresume); | 1205 | DBG(dev, "suspend, wakeup in %d seconds\n", autoresume); |
1225 | } else | 1206 | } else |
1226 | DBG (dev, "suspend\n"); | 1207 | DBG(dev, "suspend\n"); |
1227 | } | 1208 | } |
1228 | 1209 | ||
1229 | static void | 1210 | static void zero_resume(struct usb_gadget *gadget) |
1230 | zero_resume (struct usb_gadget *gadget) | ||
1231 | { | 1211 | { |
1232 | struct zero_dev *dev = get_gadget_data (gadget); | 1212 | struct zero_dev *dev = get_gadget_data(gadget); |
1233 | 1213 | ||
1234 | DBG (dev, "resume\n"); | 1214 | DBG(dev, "resume\n"); |
1235 | del_timer (&dev->resume); | 1215 | del_timer(&dev->resume); |
1236 | } | 1216 | } |
1237 | 1217 | ||
1238 | 1218 | ||
@@ -1264,15 +1244,15 @@ MODULE_AUTHOR("David Brownell"); | |||
1264 | MODULE_LICENSE("GPL"); | 1244 | MODULE_LICENSE("GPL"); |
1265 | 1245 | ||
1266 | 1246 | ||
1267 | static int __init init (void) | 1247 | static int __init init(void) |
1268 | { | 1248 | { |
1269 | return usb_gadget_register_driver (&zero_driver); | 1249 | return usb_gadget_register_driver(&zero_driver); |
1270 | } | 1250 | } |
1271 | module_init (init); | 1251 | module_init(init); |
1272 | 1252 | ||
1273 | static void __exit cleanup (void) | 1253 | static void __exit cleanup(void) |
1274 | { | 1254 | { |
1275 | usb_gadget_unregister_driver (&zero_driver); | 1255 | usb_gadget_unregister_driver(&zero_driver); |
1276 | } | 1256 | } |
1277 | module_exit (cleanup); | 1257 | module_exit(cleanup); |
1278 | 1258 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0b87480dd713..228797e54f9c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -4,6 +4,19 @@ | |||
4 | comment "USB Host Controller Drivers" | 4 | comment "USB Host Controller Drivers" |
5 | depends on USB | 5 | depends on USB |
6 | 6 | ||
7 | config USB_C67X00_HCD | ||
8 | tristate "Cypress C67x00 HCD support" | ||
9 | depends on USB | ||
10 | help | ||
11 | The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role | ||
12 | host/peripheral/OTG USB controllers. | ||
13 | |||
14 | Enable this option to support this chip in host controller mode. | ||
15 | If unsure, say N. | ||
16 | |||
17 | To compile this driver as a module, choose M here: the | ||
18 | module will be called c67x00. | ||
19 | |||
7 | config USB_EHCI_HCD | 20 | config USB_EHCI_HCD |
8 | tristate "EHCI HCD (USB 2.0) support" | 21 | tristate "EHCI HCD (USB 2.0) support" |
9 | depends on USB && USB_ARCH_HAS_EHCI | 22 | depends on USB && USB_ARCH_HAS_EHCI |
@@ -95,6 +108,32 @@ config USB_ISP116X_HCD | |||
95 | To compile this driver as a module, choose M here: the | 108 | To compile this driver as a module, choose M here: the |
96 | module will be called isp116x-hcd. | 109 | module will be called isp116x-hcd. |
97 | 110 | ||
111 | config USB_ISP1760_HCD | ||
112 | tristate "ISP 1760 HCD support" | ||
113 | depends on USB && EXPERIMENTAL | ||
114 | ---help--- | ||
115 | The ISP1760 chip is a USB 2.0 host controller. | ||
116 | |||
117 | This driver does not support isochronous transfers or OTG. | ||
118 | |||
119 | To compile this driver as a module, choose M here: the | ||
120 | module will be called isp1760-hcd. | ||
121 | |||
122 | config USB_ISP1760_PCI | ||
123 | bool "Support for the PCI bus" | ||
124 | depends on USB_ISP1760_HCD && PCI | ||
125 | ---help--- | ||
126 | Enables support for the device present on the PCI bus. | ||
127 | This should only be required if you happen to have the eval kit from | ||
128 | NXP and you are going to test it. | ||
129 | |||
130 | config USB_ISP1760_OF | ||
131 | bool "Support for the OF platform bus" | ||
132 | depends on USB_ISP1760_HCD && PPC_OF | ||
133 | ---help--- | ||
134 | Enables support for the device present on the PowerPC | ||
135 | OpenFirmware platform bus. | ||
136 | |||
98 | config USB_OHCI_HCD | 137 | config USB_OHCI_HCD |
99 | tristate "OHCI HCD support" | 138 | tristate "OHCI HCD support" |
100 | depends on USB && USB_ARCH_HAS_OHCI | 139 | depends on USB && USB_ARCH_HAS_OHCI |
@@ -261,8 +300,8 @@ config USB_R8A66597_HCD | |||
261 | module will be called r8a66597-hcd. | 300 | module will be called r8a66597-hcd. |
262 | 301 | ||
263 | config SUPERH_ON_CHIP_R8A66597 | 302 | config SUPERH_ON_CHIP_R8A66597 |
264 | boolean "Enable SuperH on-chip USB like the R8A66597" | 303 | boolean "Enable SuperH on-chip R8A66597 USB" |
265 | depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 | 304 | depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723) |
266 | help | 305 | help |
267 | Renesas SuperH processor has USB like the R8A66597. | 306 | This driver enables support for the on-chip R8A66597 in the |
268 | This driver supported processor is SH7366. | 307 | SH7366 and SH7723 processors. |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index bb8e9d44f371..f1edda2dcfde 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -6,6 +6,8 @@ ifeq ($(CONFIG_USB_DEBUG),y) | |||
6 | EXTRA_CFLAGS += -DDEBUG | 6 | EXTRA_CFLAGS += -DDEBUG |
7 | endif | 7 | endif |
8 | 8 | ||
9 | isp1760-objs := isp1760-hcd.o isp1760-if.o | ||
10 | |||
9 | obj-$(CONFIG_PCI) += pci-quirks.o | 11 | obj-$(CONFIG_PCI) += pci-quirks.o |
10 | 12 | ||
11 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 13 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
@@ -16,4 +18,4 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | |||
16 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | 18 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o |
17 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | 19 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o |
18 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o | 20 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o |
19 | 21 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o | |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 8b5f991e949c..08a4335401a9 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -223,6 +223,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
223 | .bus_suspend = ehci_bus_suspend, | 223 | .bus_suspend = ehci_bus_suspend, |
224 | .bus_resume = ehci_bus_resume, | 224 | .bus_resume = ehci_bus_resume, |
225 | .relinquish_port = ehci_relinquish_port, | 225 | .relinquish_port = ehci_relinquish_port, |
226 | .port_handed_over = ehci_port_handed_over, | ||
226 | }; | 227 | }; |
227 | 228 | ||
228 | /*-------------------------------------------------------------------------*/ | 229 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 6d9bed6c1f48..7370d6187c64 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -269,7 +269,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
269 | if (retval) | 269 | if (retval) |
270 | return retval; | 270 | return retval; |
271 | 271 | ||
272 | ehci->is_tdi_rh_tt = 1; | 272 | hcd->has_tt = 1; |
273 | 273 | ||
274 | ehci->sbrn = 0x20; | 274 | ehci->sbrn = 0x20; |
275 | 275 | ||
@@ -295,10 +295,6 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
295 | */ | 295 | */ |
296 | .reset = ehci_fsl_setup, | 296 | .reset = ehci_fsl_setup, |
297 | .start = ehci_run, | 297 | .start = ehci_run, |
298 | #ifdef CONFIG_PM | ||
299 | .suspend = ehci_bus_suspend, | ||
300 | .resume = ehci_bus_resume, | ||
301 | #endif | ||
302 | .stop = ehci_stop, | 298 | .stop = ehci_stop, |
303 | .shutdown = ehci_shutdown, | 299 | .shutdown = ehci_shutdown, |
304 | 300 | ||
@@ -322,6 +318,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
322 | .bus_suspend = ehci_bus_suspend, | 318 | .bus_suspend = ehci_bus_suspend, |
323 | .bus_resume = ehci_bus_resume, | 319 | .bus_resume = ehci_bus_resume, |
324 | .relinquish_port = ehci_relinquish_port, | 320 | .relinquish_port = ehci_relinquish_port, |
321 | .port_handed_over = ehci_port_handed_over, | ||
325 | }; | 322 | }; |
326 | 323 | ||
327 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 324 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 382587c4457c..740835bb8575 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -609,7 +609,7 @@ static int ehci_hub_control ( | |||
609 | } | 609 | } |
610 | break; | 610 | break; |
611 | case USB_PORT_FEAT_C_SUSPEND: | 611 | case USB_PORT_FEAT_C_SUSPEND: |
612 | /* we auto-clear this feature */ | 612 | clear_bit(wIndex, &ehci->port_c_suspend); |
613 | break; | 613 | break; |
614 | case USB_PORT_FEAT_POWER: | 614 | case USB_PORT_FEAT_POWER: |
615 | if (HCS_PPC (ehci->hcs_params)) | 615 | if (HCS_PPC (ehci->hcs_params)) |
@@ -688,7 +688,7 @@ static int ehci_hub_control ( | |||
688 | /* resume completed? */ | 688 | /* resume completed? */ |
689 | else if (time_after_eq(jiffies, | 689 | else if (time_after_eq(jiffies, |
690 | ehci->reset_done[wIndex])) { | 690 | ehci->reset_done[wIndex])) { |
691 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | 691 | set_bit(wIndex, &ehci->port_c_suspend); |
692 | ehci->reset_done[wIndex] = 0; | 692 | ehci->reset_done[wIndex] = 0; |
693 | 693 | ||
694 | /* stop resume signaling */ | 694 | /* stop resume signaling */ |
@@ -765,6 +765,8 @@ static int ehci_hub_control ( | |||
765 | status |= 1 << USB_PORT_FEAT_RESET; | 765 | status |= 1 << USB_PORT_FEAT_RESET; |
766 | if (temp & PORT_POWER) | 766 | if (temp & PORT_POWER) |
767 | status |= 1 << USB_PORT_FEAT_POWER; | 767 | status |= 1 << USB_PORT_FEAT_POWER; |
768 | if (test_bit(wIndex, &ehci->port_c_suspend)) | ||
769 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
768 | 770 | ||
769 | #ifndef VERBOSE_DEBUG | 771 | #ifndef VERBOSE_DEBUG |
770 | if (status & ~0xffff) /* only if wPortChange is interesting */ | 772 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
@@ -875,3 +877,13 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) | |||
875 | set_owner(ehci, --portnum, PORT_OWNER); | 877 | set_owner(ehci, --portnum, PORT_OWNER); |
876 | } | 878 | } |
877 | 879 | ||
880 | static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) | ||
881 | { | ||
882 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
883 | u32 __iomem *reg; | ||
884 | |||
885 | if (ehci_is_TDI(ehci)) | ||
886 | return 0; | ||
887 | reg = &ehci->regs->port_status[portnum - 1]; | ||
888 | return ehci_readl(ehci, reg) & PORT_OWNER; | ||
889 | } | ||
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 601c8795a854..9d042f220097 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -26,7 +26,7 @@ static int ixp4xx_ehci_init(struct usb_hcd *hcd) | |||
26 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 26 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
28 | 28 | ||
29 | ehci->is_tdi_rh_tt = 1; | 29 | hcd->has_tt = 1; |
30 | ehci_reset(ehci); | 30 | ehci_reset(ehci); |
31 | 31 | ||
32 | retval = ehci_init(hcd); | 32 | retval = ehci_init(hcd); |
@@ -58,6 +58,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { | |||
58 | .bus_suspend = ehci_bus_suspend, | 58 | .bus_suspend = ehci_bus_suspend, |
59 | .bus_resume = ehci_bus_resume, | 59 | .bus_resume = ehci_bus_resume, |
60 | #endif | 60 | #endif |
61 | .relinquish_port = ehci_relinquish_port, | ||
62 | .port_handed_over = ehci_port_handed_over, | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | 65 | static int ixp4xx_ehci_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index d187d0313742..ab625f0ba1d9 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -115,6 +115,8 @@ static int ehci_orion_setup(struct usb_hcd *hcd) | |||
115 | if (retval) | 115 | if (retval) |
116 | return retval; | 116 | return retval; |
117 | 117 | ||
118 | hcd->has_tt = 1; | ||
119 | |||
118 | ehci_reset(ehci); | 120 | ehci_reset(ehci); |
119 | ehci_port_power(ehci, 0); | 121 | ehci_port_power(ehci, 0); |
120 | 122 | ||
@@ -137,10 +139,6 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
137 | */ | 139 | */ |
138 | .reset = ehci_orion_setup, | 140 | .reset = ehci_orion_setup, |
139 | .start = ehci_run, | 141 | .start = ehci_run, |
140 | #ifdef CONFIG_PM | ||
141 | .suspend = ehci_bus_suspend, | ||
142 | .resume = ehci_bus_resume, | ||
143 | #endif | ||
144 | .stop = ehci_stop, | 142 | .stop = ehci_stop, |
145 | .shutdown = ehci_shutdown, | 143 | .shutdown = ehci_shutdown, |
146 | 144 | ||
@@ -163,6 +161,8 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
163 | .hub_control = ehci_hub_control, | 161 | .hub_control = ehci_hub_control, |
164 | .bus_suspend = ehci_bus_suspend, | 162 | .bus_suspend = ehci_bus_suspend, |
165 | .bus_resume = ehci_bus_resume, | 163 | .bus_resume = ehci_bus_resume, |
164 | .relinquish_port = ehci_relinquish_port, | ||
165 | .port_handed_over = ehci_port_handed_over, | ||
166 | }; | 166 | }; |
167 | 167 | ||
168 | static void __init | 168 | static void __init |
@@ -248,7 +248,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev) | |||
248 | ehci->regs = hcd->regs + 0x100 + | 248 | ehci->regs = hcd->regs + 0x100 + |
249 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 249 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
250 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 250 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
251 | ehci->is_tdi_rh_tt = 1; | 251 | hcd->has_tt = 1; |
252 | ehci->sbrn = 0x20; | 252 | ehci->sbrn = 0x20; |
253 | 253 | ||
254 | /* | 254 | /* |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 5bb7f6bb13f3..c46a58f9181d 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -129,7 +129,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
129 | switch (pdev->vendor) { | 129 | switch (pdev->vendor) { |
130 | case PCI_VENDOR_ID_TDI: | 130 | case PCI_VENDOR_ID_TDI: |
131 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 131 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { |
132 | ehci->is_tdi_rh_tt = 1; | ||
133 | hcd->has_tt = 1; | 132 | hcd->has_tt = 1; |
134 | tdi_reset(ehci); | 133 | tdi_reset(ehci); |
135 | } | 134 | } |
@@ -379,7 +378,8 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
379 | .hub_control = ehci_hub_control, | 378 | .hub_control = ehci_hub_control, |
380 | .bus_suspend = ehci_bus_suspend, | 379 | .bus_suspend = ehci_bus_suspend, |
381 | .bus_resume = ehci_bus_resume, | 380 | .bus_resume = ehci_bus_resume, |
382 | .relinquish_port = ehci_relinquish_port, | 381 | .relinquish_port = ehci_relinquish_port, |
382 | .port_handed_over = ehci_port_handed_over, | ||
383 | }; | 383 | }; |
384 | 384 | ||
385 | /*-------------------------------------------------------------------------*/ | 385 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ee305b1f99ff..b018deed2e8f 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -76,6 +76,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { | |||
76 | .bus_suspend = ehci_bus_suspend, | 76 | .bus_suspend = ehci_bus_suspend, |
77 | .bus_resume = ehci_bus_resume, | 77 | .bus_resume = ehci_bus_resume, |
78 | #endif | 78 | #endif |
79 | .relinquish_port = ehci_relinquish_port, | ||
80 | .port_handed_over = ehci_port_handed_over, | ||
79 | }; | 81 | }; |
80 | 82 | ||
81 | 83 | ||
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index 6c76036783a1..529590eb4037 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c | |||
@@ -163,6 +163,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
163 | .bus_suspend = ehci_bus_suspend, | 163 | .bus_suspend = ehci_bus_suspend, |
164 | .bus_resume = ehci_bus_resume, | 164 | .bus_resume = ehci_bus_resume, |
165 | .relinquish_port = ehci_relinquish_port, | 165 | .relinquish_port = ehci_relinquish_port, |
166 | .port_handed_over = ehci_port_handed_over, | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | 169 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 69782221bcf3..37e6abeb794c 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -73,6 +73,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
73 | .bus_resume = ehci_bus_resume, | 73 | .bus_resume = ehci_bus_resume, |
74 | #endif | 74 | #endif |
75 | .relinquish_port = ehci_relinquish_port, | 75 | .relinquish_port = ehci_relinquish_port, |
76 | .port_handed_over = ehci_port_handed_over, | ||
76 | }; | 77 | }; |
77 | 78 | ||
78 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) | 79 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index be575e46eac3..b7853c8bac0f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1349,18 +1349,27 @@ iso_stream_schedule ( | |||
1349 | /* when's the last uframe this urb could start? */ | 1349 | /* when's the last uframe this urb could start? */ |
1350 | max = now + mod; | 1350 | max = now + mod; |
1351 | 1351 | ||
1352 | /* typical case: reuse current schedule. stream is still active, | 1352 | /* Typical case: reuse current schedule, stream is still active. |
1353 | * and no gaps from host falling behind (irq delays etc) | 1353 | * Hopefully there are no gaps from the host falling behind |
1354 | * (irq delays etc), but if there are we'll take the next | ||
1355 | * slot in the schedule, implicitly assuming URB_ISO_ASAP. | ||
1354 | */ | 1356 | */ |
1355 | if (likely (!list_empty (&stream->td_list))) { | 1357 | if (likely (!list_empty (&stream->td_list))) { |
1356 | start = stream->next_uframe; | 1358 | start = stream->next_uframe; |
1357 | if (start < now) | 1359 | if (start < now) |
1358 | start += mod; | 1360 | start += mod; |
1359 | if (likely ((start + sched->span) < max)) | 1361 | |
1360 | goto ready; | 1362 | /* Fell behind (by up to twice the slop amount)? */ |
1361 | /* else fell behind; someday, try to reschedule */ | 1363 | if (start >= max - 2 * 8 * SCHEDULE_SLOP) |
1362 | status = -EL2NSYNC; | 1364 | start += stream->interval * DIV_ROUND_UP( |
1363 | goto fail; | 1365 | max - start, stream->interval) - mod; |
1366 | |||
1367 | /* Tried to schedule too far into the future? */ | ||
1368 | if (unlikely((start + sched->span) >= max)) { | ||
1369 | status = -EFBIG; | ||
1370 | goto fail; | ||
1371 | } | ||
1372 | goto ready; | ||
1364 | } | 1373 | } |
1365 | 1374 | ||
1366 | /* need to schedule; when's the next (u)frame we could start? | 1375 | /* need to schedule; when's the next (u)frame we could start? |
@@ -1613,6 +1622,9 @@ itd_complete ( | |||
1613 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { | 1622 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { |
1614 | desc->status = 0; | 1623 | desc->status = 0; |
1615 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1624 | desc->actual_length = EHCI_ITD_LENGTH (t); |
1625 | } else { | ||
1626 | /* URB was too late */ | ||
1627 | desc->status = -EXDEV; | ||
1616 | } | 1628 | } |
1617 | } | 1629 | } |
1618 | 1630 | ||
@@ -2095,7 +2107,7 @@ done: | |||
2095 | static void | 2107 | static void |
2096 | scan_periodic (struct ehci_hcd *ehci) | 2108 | scan_periodic (struct ehci_hcd *ehci) |
2097 | { | 2109 | { |
2098 | unsigned frame, clock, now_uframe, mod; | 2110 | unsigned now_uframe, frame, clock, clock_frame, mod; |
2099 | unsigned modified; | 2111 | unsigned modified; |
2100 | 2112 | ||
2101 | mod = ehci->periodic_size << 3; | 2113 | mod = ehci->periodic_size << 3; |
@@ -2111,6 +2123,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2111 | else | 2123 | else |
2112 | clock = now_uframe + mod - 1; | 2124 | clock = now_uframe + mod - 1; |
2113 | clock %= mod; | 2125 | clock %= mod; |
2126 | clock_frame = clock >> 3; | ||
2114 | 2127 | ||
2115 | for (;;) { | 2128 | for (;;) { |
2116 | union ehci_shadow q, *q_p; | 2129 | union ehci_shadow q, *q_p; |
@@ -2157,22 +2170,26 @@ restart: | |||
2157 | case Q_TYPE_ITD: | 2170 | case Q_TYPE_ITD: |
2158 | /* If this ITD is still active, leave it for | 2171 | /* If this ITD is still active, leave it for |
2159 | * later processing ... check the next entry. | 2172 | * later processing ... check the next entry. |
2173 | * No need to check for activity unless the | ||
2174 | * frame is current. | ||
2160 | */ | 2175 | */ |
2161 | rmb (); | 2176 | if (frame == clock_frame && live) { |
2162 | for (uf = 0; uf < 8 && live; uf++) { | 2177 | rmb(); |
2163 | if (0 == (q.itd->hw_transaction [uf] | 2178 | for (uf = 0; uf < 8; uf++) { |
2164 | & ITD_ACTIVE(ehci))) | 2179 | if (q.itd->hw_transaction[uf] & |
2165 | continue; | 2180 | ITD_ACTIVE(ehci)) |
2166 | incomplete = true; | 2181 | break; |
2167 | q_p = &q.itd->itd_next; | 2182 | } |
2168 | hw_p = &q.itd->hw_next; | 2183 | if (uf < 8) { |
2169 | type = Q_NEXT_TYPE(ehci, | 2184 | incomplete = true; |
2185 | q_p = &q.itd->itd_next; | ||
2186 | hw_p = &q.itd->hw_next; | ||
2187 | type = Q_NEXT_TYPE(ehci, | ||
2170 | q.itd->hw_next); | 2188 | q.itd->hw_next); |
2171 | q = *q_p; | 2189 | q = *q_p; |
2172 | break; | 2190 | break; |
2191 | } | ||
2173 | } | 2192 | } |
2174 | if (uf < 8 && live) | ||
2175 | break; | ||
2176 | 2193 | ||
2177 | /* Take finished ITDs out of the schedule | 2194 | /* Take finished ITDs out of the schedule |
2178 | * and process them: recycle, maybe report | 2195 | * and process them: recycle, maybe report |
@@ -2189,9 +2206,12 @@ restart: | |||
2189 | case Q_TYPE_SITD: | 2206 | case Q_TYPE_SITD: |
2190 | /* If this SITD is still active, leave it for | 2207 | /* If this SITD is still active, leave it for |
2191 | * later processing ... check the next entry. | 2208 | * later processing ... check the next entry. |
2209 | * No need to check for activity unless the | ||
2210 | * frame is current. | ||
2192 | */ | 2211 | */ |
2193 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) | 2212 | if (frame == clock_frame && live && |
2194 | && live) { | 2213 | (q.sitd->hw_results & |
2214 | SITD_ACTIVE(ehci))) { | ||
2195 | incomplete = true; | 2215 | incomplete = true; |
2196 | q_p = &q.sitd->sitd_next; | 2216 | q_p = &q.sitd->sitd_next; |
2197 | hw_p = &q.sitd->hw_next; | 2217 | hw_p = &q.sitd->hw_next; |
@@ -2260,6 +2280,7 @@ restart: | |||
2260 | 2280 | ||
2261 | /* rescan the rest of this frame, then ... */ | 2281 | /* rescan the rest of this frame, then ... */ |
2262 | clock = now; | 2282 | clock = now; |
2283 | clock_frame = clock >> 3; | ||
2263 | } else { | 2284 | } else { |
2264 | now_uframe++; | 2285 | now_uframe++; |
2265 | now_uframe %= mod; | 2286 | now_uframe %= mod; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index bf92d209a1a9..90245fd8bac4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */ | |||
97 | dedicated to the companion controller */ | 97 | dedicated to the companion controller */ |
98 | unsigned long owned_ports; /* which ports are | 98 | unsigned long owned_ports; /* which ports are |
99 | owned by the companion during a bus suspend */ | 99 | owned by the companion during a bus suspend */ |
100 | unsigned long port_c_suspend; /* which ports have | ||
101 | the change-suspend feature turned on */ | ||
100 | 102 | ||
101 | /* per-HC memory pools (could be per-bus, but ...) */ | 103 | /* per-HC memory pools (could be per-bus, but ...) */ |
102 | struct dma_pool *qh_pool; /* qh per active urb */ | 104 | struct dma_pool *qh_pool; /* qh per active urb */ |
@@ -112,7 +114,6 @@ struct ehci_hcd { /* one per controller */ | |||
112 | u32 command; | 114 | u32 command; |
113 | 115 | ||
114 | /* SILICON QUIRKS */ | 116 | /* SILICON QUIRKS */ |
115 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ | ||
116 | unsigned no_selective_suspend:1; | 117 | unsigned no_selective_suspend:1; |
117 | unsigned has_fsl_port_bug:1; /* FreeScale */ | 118 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
118 | unsigned big_endian_mmio:1; | 119 | unsigned big_endian_mmio:1; |
@@ -176,6 +177,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
176 | static inline void | 177 | static inline void |
177 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | 178 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) |
178 | { | 179 | { |
180 | /* Don't override timeouts which shrink or (later) disable | ||
181 | * the async ring; just the I/O watchdog. Note that if a | ||
182 | * SHRINK were pending, OFF would never be requested. | ||
183 | */ | ||
184 | if (timer_pending(&ehci->watchdog) | ||
185 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
186 | & ehci->actions)) | ||
187 | return; | ||
188 | |||
179 | if (!test_and_set_bit (action, &ehci->actions)) { | 189 | if (!test_and_set_bit (action, &ehci->actions)) { |
180 | unsigned long t; | 190 | unsigned long t; |
181 | 191 | ||
@@ -191,15 +201,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
191 | t = EHCI_SHRINK_JIFFIES; | 201 | t = EHCI_SHRINK_JIFFIES; |
192 | break; | 202 | break; |
193 | } | 203 | } |
194 | t += jiffies; | 204 | mod_timer(&ehci->watchdog, t + jiffies); |
195 | // all timings except IAA watchdog can be overridden. | ||
196 | // async queue SHRINK often precedes IAA. while it's ready | ||
197 | // to go OFF neither can matter, and afterwards the IO | ||
198 | // watchdog stops unless there's still periodic traffic. | ||
199 | if (time_before_eq(t, ehci->watchdog.expires) | ||
200 | && timer_pending (&ehci->watchdog)) | ||
201 | return; | ||
202 | mod_timer (&ehci->watchdog, t); | ||
203 | } | 205 | } |
204 | } | 206 | } |
205 | 207 | ||
@@ -678,7 +680,7 @@ struct ehci_fstn { | |||
678 | * needed (mostly in root hub code). | 680 | * needed (mostly in root hub code). |
679 | */ | 681 | */ |
680 | 682 | ||
681 | #define ehci_is_TDI(e) ((e)->is_tdi_rh_tt) | 683 | #define ehci_is_TDI(e) (ehci_to_hcd(e)->has_tt) |
682 | 684 | ||
683 | /* Returns the speed of a device attached to a port on the root hub. */ | 685 | /* Returns the speed of a device attached to a port on the root hub. */ |
684 | static inline unsigned int | 686 | static inline unsigned int |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c new file mode 100644 index 000000000000..65aa5ecf569a --- /dev/null +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -0,0 +1,2231 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1760 chip | ||
3 | * | ||
4 | * However, the code might contain some bugs. What doesn't work for sure is: | ||
5 | * - ISO | ||
6 | * - OTG | ||
7 | e The interrupt line is configured as active low, level. | ||
8 | * | ||
9 | * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> | ||
10 | * | ||
11 | */ | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/usb.h> | ||
17 | #include <linux/debugfs.h> | ||
18 | #include <linux/uaccess.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <asm/unaligned.h> | ||
21 | |||
22 | #include "../core/hcd.h" | ||
23 | #include "isp1760-hcd.h" | ||
24 | |||
25 | static struct kmem_cache *qtd_cachep; | ||
26 | static struct kmem_cache *qh_cachep; | ||
27 | |||
28 | struct isp1760_hcd { | ||
29 | u32 hcs_params; | ||
30 | spinlock_t lock; | ||
31 | struct inter_packet_info atl_ints[32]; | ||
32 | struct inter_packet_info int_ints[32]; | ||
33 | struct memory_chunk memory_pool[BLOCKS]; | ||
34 | |||
35 | /* periodic schedule support */ | ||
36 | #define DEFAULT_I_TDPS 1024 | ||
37 | unsigned periodic_size; | ||
38 | unsigned i_thresh; | ||
39 | unsigned long reset_done; | ||
40 | unsigned long next_statechange; | ||
41 | }; | ||
42 | |||
43 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | ||
44 | { | ||
45 | return (struct isp1760_hcd *) (hcd->hcd_priv); | ||
46 | } | ||
47 | static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv) | ||
48 | { | ||
49 | return container_of((void *) priv, struct usb_hcd, hcd_priv); | ||
50 | } | ||
51 | |||
52 | /* Section 2.2 Host Controller Capability Registers */ | ||
53 | #define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ | ||
54 | #define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ | ||
55 | #define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ | ||
56 | #define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */ | ||
57 | #define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */ | ||
58 | #define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */ | ||
59 | #define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */ | ||
60 | |||
61 | /* Section 2.3 Host Controller Operational Registers */ | ||
62 | #define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */ | ||
63 | #define CMD_RESET (1<<1) /* reset HC not bus */ | ||
64 | #define CMD_RUN (1<<0) /* start/stop HC */ | ||
65 | #define STS_PCD (1<<2) /* port change detect */ | ||
66 | #define FLAG_CF (1<<0) /* true: we'll support "high speed" */ | ||
67 | |||
68 | #define PORT_OWNER (1<<13) /* true: companion hc owns this port */ | ||
69 | #define PORT_POWER (1<<12) /* true: has power (see PPC) */ | ||
70 | #define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */ | ||
71 | #define PORT_RESET (1<<8) /* reset port */ | ||
72 | #define PORT_SUSPEND (1<<7) /* suspend port */ | ||
73 | #define PORT_RESUME (1<<6) /* resume it */ | ||
74 | #define PORT_PE (1<<2) /* port enable */ | ||
75 | #define PORT_CSC (1<<1) /* connect status change */ | ||
76 | #define PORT_CONNECT (1<<0) /* device connected */ | ||
77 | #define PORT_RWC_BITS (PORT_CSC) | ||
78 | |||
79 | struct isp1760_qtd { | ||
80 | struct isp1760_qtd *hw_next; | ||
81 | u8 packet_type; | ||
82 | u8 toggle; | ||
83 | |||
84 | void *data_buffer; | ||
85 | /* the rest is HCD-private */ | ||
86 | struct list_head qtd_list; | ||
87 | struct urb *urb; | ||
88 | size_t length; | ||
89 | |||
90 | /* isp special*/ | ||
91 | u32 status; | ||
92 | #define URB_COMPLETE_NOTIFY (1 << 0) | ||
93 | #define URB_ENQUEUED (1 << 1) | ||
94 | #define URB_TYPE_ATL (1 << 2) | ||
95 | #define URB_TYPE_INT (1 << 3) | ||
96 | }; | ||
97 | |||
98 | struct isp1760_qh { | ||
99 | /* first part defined by EHCI spec */ | ||
100 | struct list_head qtd_list; | ||
101 | struct isp1760_hcd *priv; | ||
102 | |||
103 | /* periodic schedule info */ | ||
104 | unsigned short period; /* polling interval */ | ||
105 | struct usb_device *dev; | ||
106 | |||
107 | u32 toggle; | ||
108 | u32 ping; | ||
109 | }; | ||
110 | |||
111 | #define ehci_port_speed(priv, portsc) (1 << USB_PORT_FEAT_HIGHSPEED) | ||
112 | |||
113 | static unsigned int isp1760_readl(__u32 __iomem *regs) | ||
114 | { | ||
115 | return readl(regs); | ||
116 | } | ||
117 | |||
118 | static void isp1760_writel(const unsigned int val, __u32 __iomem *regs) | ||
119 | { | ||
120 | writel(val, regs); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * The next two copy via MMIO data to/from the device. memcpy_{to|from}io() | ||
125 | * doesn't quite work because some people have to enforce 32-bit access | ||
126 | */ | ||
127 | static void priv_read_copy(struct isp1760_hcd *priv, u32 *src, | ||
128 | __u32 __iomem *dst, u32 offset, u32 len) | ||
129 | { | ||
130 | struct usb_hcd *hcd = priv_to_hcd(priv); | ||
131 | u32 val; | ||
132 | u8 *buff8; | ||
133 | |||
134 | if (!src) { | ||
135 | printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len); | ||
136 | return; | ||
137 | } | ||
138 | isp1760_writel(offset, hcd->regs + HC_MEMORY_REG); | ||
139 | /* XXX | ||
140 | * 90nsec delay, the spec says something how this could be avoided. | ||
141 | */ | ||
142 | mdelay(1); | ||
143 | |||
144 | while (len >= 4) { | ||
145 | *src = __raw_readl(dst); | ||
146 | len -= 4; | ||
147 | src++; | ||
148 | dst++; | ||
149 | } | ||
150 | |||
151 | if (!len) | ||
152 | return; | ||
153 | |||
154 | /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully | ||
155 | * allocated. | ||
156 | */ | ||
157 | val = isp1760_readl(dst); | ||
158 | |||
159 | buff8 = (u8 *)src; | ||
160 | while (len) { | ||
161 | |||
162 | *buff8 = val; | ||
163 | val >>= 8; | ||
164 | len--; | ||
165 | buff8++; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | static void priv_write_copy(const struct isp1760_hcd *priv, const u32 *src, | ||
170 | __u32 __iomem *dst, u32 len) | ||
171 | { | ||
172 | while (len >= 4) { | ||
173 | __raw_writel(*src, dst); | ||
174 | len -= 4; | ||
175 | src++; | ||
176 | dst++; | ||
177 | } | ||
178 | |||
179 | if (!len) | ||
180 | return; | ||
181 | /* in case we have 3, 2 or 1 by left. The buffer is allocated and the | ||
182 | * extra bytes should not be read by the HW | ||
183 | */ | ||
184 | |||
185 | __raw_writel(*src, dst); | ||
186 | } | ||
187 | |||
188 | /* memory management of the 60kb on the chip from 0x1000 to 0xffff */ | ||
189 | static void init_memory(struct isp1760_hcd *priv) | ||
190 | { | ||
191 | int i; | ||
192 | u32 payload; | ||
193 | |||
194 | payload = 0x1000; | ||
195 | for (i = 0; i < BLOCK_1_NUM; i++) { | ||
196 | priv->memory_pool[i].start = payload; | ||
197 | priv->memory_pool[i].size = BLOCK_1_SIZE; | ||
198 | priv->memory_pool[i].free = 1; | ||
199 | payload += priv->memory_pool[i].size; | ||
200 | } | ||
201 | |||
202 | |||
203 | for (i = BLOCK_1_NUM; i < BLOCK_1_NUM + BLOCK_2_NUM; i++) { | ||
204 | priv->memory_pool[i].start = payload; | ||
205 | priv->memory_pool[i].size = BLOCK_2_SIZE; | ||
206 | priv->memory_pool[i].free = 1; | ||
207 | payload += priv->memory_pool[i].size; | ||
208 | } | ||
209 | |||
210 | |||
211 | for (i = BLOCK_1_NUM + BLOCK_2_NUM; i < BLOCKS; i++) { | ||
212 | priv->memory_pool[i].start = payload; | ||
213 | priv->memory_pool[i].size = BLOCK_3_SIZE; | ||
214 | priv->memory_pool[i].free = 1; | ||
215 | payload += priv->memory_pool[i].size; | ||
216 | } | ||
217 | |||
218 | BUG_ON(payload - priv->memory_pool[i - 1].size > PAYLOAD_SIZE); | ||
219 | } | ||
220 | |||
221 | static u32 alloc_mem(struct isp1760_hcd *priv, u32 size) | ||
222 | { | ||
223 | int i; | ||
224 | |||
225 | if (!size) | ||
226 | return ISP1760_NULL_POINTER; | ||
227 | |||
228 | for (i = 0; i < BLOCKS; i++) { | ||
229 | if (priv->memory_pool[i].size >= size && | ||
230 | priv->memory_pool[i].free) { | ||
231 | |||
232 | priv->memory_pool[i].free = 0; | ||
233 | return priv->memory_pool[i].start; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | printk(KERN_ERR "ISP1760 MEM: can not allocate %d bytes of memory\n", | ||
238 | size); | ||
239 | printk(KERN_ERR "Current memory map:\n"); | ||
240 | for (i = 0; i < BLOCKS; i++) { | ||
241 | printk(KERN_ERR "Pool %2d size %4d status: %d\n", | ||
242 | i, priv->memory_pool[i].size, | ||
243 | priv->memory_pool[i].free); | ||
244 | } | ||
245 | /* XXX maybe -ENOMEM could be possible */ | ||
246 | BUG(); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static void free_mem(struct isp1760_hcd *priv, u32 mem) | ||
251 | { | ||
252 | int i; | ||
253 | |||
254 | if (mem == ISP1760_NULL_POINTER) | ||
255 | return; | ||
256 | |||
257 | for (i = 0; i < BLOCKS; i++) { | ||
258 | if (priv->memory_pool[i].start == mem) { | ||
259 | |||
260 | BUG_ON(priv->memory_pool[i].free); | ||
261 | |||
262 | priv->memory_pool[i].free = 1; | ||
263 | return ; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | printk(KERN_ERR "Trying to free not-here-allocated memory :%08x\n", | ||
268 | mem); | ||
269 | BUG(); | ||
270 | } | ||
271 | |||
272 | static void isp1760_init_regs(struct usb_hcd *hcd) | ||
273 | { | ||
274 | isp1760_writel(0, hcd->regs + HC_BUFFER_STATUS_REG); | ||
275 | isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + | ||
276 | HC_ATL_PTD_SKIPMAP_REG); | ||
277 | isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + | ||
278 | HC_INT_PTD_SKIPMAP_REG); | ||
279 | isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + | ||
280 | HC_ISO_PTD_SKIPMAP_REG); | ||
281 | |||
282 | isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + | ||
283 | HC_ATL_PTD_DONEMAP_REG); | ||
284 | isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + | ||
285 | HC_INT_PTD_DONEMAP_REG); | ||
286 | isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + | ||
287 | HC_ISO_PTD_DONEMAP_REG); | ||
288 | } | ||
289 | |||
290 | static int handshake(struct isp1760_hcd *priv, void __iomem *ptr, | ||
291 | u32 mask, u32 done, int usec) | ||
292 | { | ||
293 | u32 result; | ||
294 | |||
295 | do { | ||
296 | result = isp1760_readl(ptr); | ||
297 | if (result == ~0) | ||
298 | return -ENODEV; | ||
299 | result &= mask; | ||
300 | if (result == done) | ||
301 | return 0; | ||
302 | udelay(1); | ||
303 | usec--; | ||
304 | } while (usec > 0); | ||
305 | return -ETIMEDOUT; | ||
306 | } | ||
307 | |||
308 | /* reset a non-running (STS_HALT == 1) controller */ | ||
309 | static int ehci_reset(struct isp1760_hcd *priv) | ||
310 | { | ||
311 | int retval; | ||
312 | struct usb_hcd *hcd = priv_to_hcd(priv); | ||
313 | u32 command = isp1760_readl(hcd->regs + HC_USBCMD); | ||
314 | |||
315 | command |= CMD_RESET; | ||
316 | isp1760_writel(command, hcd->regs + HC_USBCMD); | ||
317 | hcd->state = HC_STATE_HALT; | ||
318 | priv->next_statechange = jiffies; | ||
319 | retval = handshake(priv, hcd->regs + HC_USBCMD, | ||
320 | CMD_RESET, 0, 250 * 1000); | ||
321 | return retval; | ||
322 | } | ||
323 | |||
324 | static void qh_destroy(struct isp1760_qh *qh) | ||
325 | { | ||
326 | BUG_ON(!list_empty(&qh->qtd_list)); | ||
327 | kmem_cache_free(qh_cachep, qh); | ||
328 | } | ||
329 | |||
330 | static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv, | ||
331 | gfp_t flags) | ||
332 | { | ||
333 | struct isp1760_qh *qh; | ||
334 | |||
335 | qh = kmem_cache_zalloc(qh_cachep, flags); | ||
336 | if (!qh) | ||
337 | return qh; | ||
338 | |||
339 | INIT_LIST_HEAD(&qh->qtd_list); | ||
340 | qh->priv = priv; | ||
341 | return qh; | ||
342 | } | ||
343 | |||
344 | /* magic numbers that can affect system performance */ | ||
345 | #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ | ||
346 | #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ | ||
347 | #define EHCI_TUNE_RL_TT 0 | ||
348 | #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ | ||
349 | #define EHCI_TUNE_MULT_TT 1 | ||
350 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ | ||
351 | |||
352 | /* one-time init, only for memory state */ | ||
353 | static int priv_init(struct usb_hcd *hcd) | ||
354 | { | ||
355 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
356 | u32 hcc_params; | ||
357 | |||
358 | spin_lock_init(&priv->lock); | ||
359 | |||
360 | /* | ||
361 | * hw default: 1K periodic list heads, one per frame. | ||
362 | * periodic_size can shrink by USBCMD update if hcc_params allows. | ||
363 | */ | ||
364 | priv->periodic_size = DEFAULT_I_TDPS; | ||
365 | |||
366 | /* controllers may cache some of the periodic schedule ... */ | ||
367 | hcc_params = isp1760_readl(hcd->regs + HC_HCCPARAMS); | ||
368 | /* full frame cache */ | ||
369 | if (HCC_ISOC_CACHE(hcc_params)) | ||
370 | priv->i_thresh = 8; | ||
371 | else /* N microframes cached */ | ||
372 | priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int isp1760_hc_setup(struct usb_hcd *hcd) | ||
378 | { | ||
379 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
380 | int result; | ||
381 | u32 scratch; | ||
382 | |||
383 | isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); | ||
384 | scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); | ||
385 | if (scratch != 0xdeadbabe) { | ||
386 | printk(KERN_ERR "ISP1760: Scratch test failed.\n"); | ||
387 | return -ENODEV; | ||
388 | } | ||
389 | |||
390 | /* pre reset */ | ||
391 | isp1760_init_regs(hcd); | ||
392 | |||
393 | /* reset */ | ||
394 | isp1760_writel(SW_RESET_RESET_ALL, hcd->regs + HC_RESET_REG); | ||
395 | mdelay(100); | ||
396 | |||
397 | isp1760_writel(SW_RESET_RESET_HC, hcd->regs + HC_RESET_REG); | ||
398 | mdelay(100); | ||
399 | |||
400 | result = ehci_reset(priv); | ||
401 | if (result) | ||
402 | return result; | ||
403 | |||
404 | /* Step 11 passed */ | ||
405 | |||
406 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); | ||
407 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); | ||
408 | |||
409 | /* ATL reset */ | ||
410 | scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); | ||
411 | isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); | ||
412 | mdelay(10); | ||
413 | isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL); | ||
414 | |||
415 | isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL); | ||
416 | mdelay(10); | ||
417 | |||
418 | priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); | ||
419 | |||
420 | return priv_init(hcd); | ||
421 | } | ||
422 | |||
423 | static void isp1760_init_maps(struct usb_hcd *hcd) | ||
424 | { | ||
425 | /*set last maps, for iso its only 1, else 32 tds bitmap*/ | ||
426 | isp1760_writel(0x80000000, hcd->regs + HC_ATL_PTD_LASTPTD_REG); | ||
427 | isp1760_writel(0x80000000, hcd->regs + HC_INT_PTD_LASTPTD_REG); | ||
428 | isp1760_writel(0x00000001, hcd->regs + HC_ISO_PTD_LASTPTD_REG); | ||
429 | } | ||
430 | |||
431 | static void isp1760_enable_interrupts(struct usb_hcd *hcd) | ||
432 | { | ||
433 | isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_AND_REG); | ||
434 | isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); | ||
435 | isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_AND_REG); | ||
436 | isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_OR_REG); | ||
437 | isp1760_writel(0, hcd->regs + HC_ISO_IRQ_MASK_AND_REG); | ||
438 | isp1760_writel(0xffffffff, hcd->regs + HC_ISO_IRQ_MASK_OR_REG); | ||
439 | /* step 23 passed */ | ||
440 | } | ||
441 | |||
442 | static int isp1760_run(struct usb_hcd *hcd) | ||
443 | { | ||
444 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
445 | int retval; | ||
446 | u32 temp; | ||
447 | u32 command; | ||
448 | u32 chipid; | ||
449 | |||
450 | hcd->uses_new_polling = 1; | ||
451 | hcd->poll_rh = 0; | ||
452 | |||
453 | hcd->state = HC_STATE_RUNNING; | ||
454 | isp1760_enable_interrupts(hcd); | ||
455 | temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); | ||
456 | temp |= FINAL_HW_CONFIG; | ||
457 | isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL); | ||
458 | |||
459 | command = isp1760_readl(hcd->regs + HC_USBCMD); | ||
460 | command &= ~(CMD_LRESET|CMD_RESET); | ||
461 | command |= CMD_RUN; | ||
462 | isp1760_writel(command, hcd->regs + HC_USBCMD); | ||
463 | |||
464 | retval = handshake(priv, hcd->regs + HC_USBCMD, CMD_RUN, CMD_RUN, | ||
465 | 250 * 1000); | ||
466 | if (retval) | ||
467 | return retval; | ||
468 | |||
469 | /* | ||
470 | * XXX | ||
471 | * Spec says to write FLAG_CF as last config action, priv code grabs | ||
472 | * the semaphore while doing so. | ||
473 | */ | ||
474 | down_write(&ehci_cf_port_reset_rwsem); | ||
475 | isp1760_writel(FLAG_CF, hcd->regs + HC_CONFIGFLAG); | ||
476 | |||
477 | retval = handshake(priv, hcd->regs + HC_CONFIGFLAG, FLAG_CF, FLAG_CF, | ||
478 | 250 * 1000); | ||
479 | up_write(&ehci_cf_port_reset_rwsem); | ||
480 | if (retval) | ||
481 | return retval; | ||
482 | |||
483 | chipid = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); | ||
484 | isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff, | ||
485 | chipid >> 16); | ||
486 | |||
487 | /* PTD Register Init Part 2, Step 28 */ | ||
488 | /* enable INTs */ | ||
489 | isp1760_init_maps(hcd); | ||
490 | |||
491 | /* GRR this is run-once init(), being done every time the HC starts. | ||
492 | * So long as they're part of class devices, we can't do it init() | ||
493 | * since the class device isn't created that early. | ||
494 | */ | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static u32 base_to_chip(u32 base) | ||
499 | { | ||
500 | return ((base - 0x400) >> 3); | ||
501 | } | ||
502 | |||
503 | static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, | ||
504 | struct isp1760_qtd *qtd, struct urb *urb, | ||
505 | u32 payload, struct ptd *ptd) | ||
506 | { | ||
507 | u32 dw0; | ||
508 | u32 dw1; | ||
509 | u32 dw2; | ||
510 | u32 dw3; | ||
511 | u32 maxpacket; | ||
512 | u32 multi; | ||
513 | u32 pid_code; | ||
514 | u32 rl = RL_COUNTER; | ||
515 | u32 nak = NAK_COUNTER; | ||
516 | |||
517 | /* according to 3.6.2, max packet len can not be > 0x400 */ | ||
518 | maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); | ||
519 | multi = 1 + ((maxpacket >> 11) & 0x3); | ||
520 | maxpacket &= 0x7ff; | ||
521 | |||
522 | /* DW0 */ | ||
523 | dw0 = PTD_VALID; | ||
524 | dw0 |= PTD_LENGTH(qtd->length); | ||
525 | dw0 |= PTD_MAXPACKET(maxpacket); | ||
526 | dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); | ||
527 | dw1 = usb_pipeendpoint(urb->pipe) >> 1; | ||
528 | |||
529 | /* DW1 */ | ||
530 | dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); | ||
531 | |||
532 | pid_code = qtd->packet_type; | ||
533 | dw1 |= PTD_PID_TOKEN(pid_code); | ||
534 | |||
535 | if (usb_pipebulk(urb->pipe)) | ||
536 | dw1 |= PTD_TRANS_BULK; | ||
537 | else if (usb_pipeint(urb->pipe)) | ||
538 | dw1 |= PTD_TRANS_INT; | ||
539 | |||
540 | if (urb->dev->speed != USB_SPEED_HIGH) { | ||
541 | /* split transaction */ | ||
542 | |||
543 | dw1 |= PTD_TRANS_SPLIT; | ||
544 | if (urb->dev->speed == USB_SPEED_LOW) | ||
545 | dw1 |= PTD_SE_USB_LOSPEED; | ||
546 | |||
547 | dw1 |= PTD_PORT_NUM(urb->dev->ttport); | ||
548 | dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); | ||
549 | |||
550 | /* SE bit for Split INT transfers */ | ||
551 | if (usb_pipeint(urb->pipe) && | ||
552 | (urb->dev->speed == USB_SPEED_LOW)) | ||
553 | dw1 |= 2 << 16; | ||
554 | |||
555 | dw3 = 0; | ||
556 | rl = 0; | ||
557 | nak = 0; | ||
558 | } else { | ||
559 | dw0 |= PTD_MULTI(multi); | ||
560 | if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) | ||
561 | dw3 = qh->ping; | ||
562 | else | ||
563 | dw3 = 0; | ||
564 | } | ||
565 | /* DW2 */ | ||
566 | dw2 = 0; | ||
567 | dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); | ||
568 | dw2 |= PTD_RL_CNT(rl); | ||
569 | dw3 |= PTD_NAC_CNT(nak); | ||
570 | |||
571 | /* DW3 */ | ||
572 | if (usb_pipecontrol(urb->pipe)) | ||
573 | dw3 |= PTD_DATA_TOGGLE(qtd->toggle); | ||
574 | else | ||
575 | dw3 |= qh->toggle; | ||
576 | |||
577 | |||
578 | dw3 |= PTD_ACTIVE; | ||
579 | /* Cerr */ | ||
580 | dw3 |= PTD_CERR(ERR_COUNTER); | ||
581 | |||
582 | memset(ptd, 0, sizeof(*ptd)); | ||
583 | |||
584 | ptd->dw0 = cpu_to_le32(dw0); | ||
585 | ptd->dw1 = cpu_to_le32(dw1); | ||
586 | ptd->dw2 = cpu_to_le32(dw2); | ||
587 | ptd->dw3 = cpu_to_le32(dw3); | ||
588 | } | ||
589 | |||
590 | static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, | ||
591 | struct isp1760_qtd *qtd, struct urb *urb, | ||
592 | u32 payload, struct ptd *ptd) | ||
593 | { | ||
594 | u32 maxpacket; | ||
595 | u32 multi; | ||
596 | u32 numberofusofs; | ||
597 | u32 i; | ||
598 | u32 usofmask, usof; | ||
599 | u32 period; | ||
600 | |||
601 | maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); | ||
602 | multi = 1 + ((maxpacket >> 11) & 0x3); | ||
603 | maxpacket &= 0x7ff; | ||
604 | /* length of the data per uframe */ | ||
605 | maxpacket = multi * maxpacket; | ||
606 | |||
607 | numberofusofs = urb->transfer_buffer_length / maxpacket; | ||
608 | if (urb->transfer_buffer_length % maxpacket) | ||
609 | numberofusofs += 1; | ||
610 | |||
611 | usofmask = 1; | ||
612 | usof = 0; | ||
613 | for (i = 0; i < numberofusofs; i++) { | ||
614 | usof |= usofmask; | ||
615 | usofmask <<= 1; | ||
616 | } | ||
617 | |||
618 | if (urb->dev->speed != USB_SPEED_HIGH) { | ||
619 | /* split */ | ||
620 | ptd->dw5 = __constant_cpu_to_le32(0x1c); | ||
621 | |||
622 | if (qh->period >= 32) | ||
623 | period = qh->period / 2; | ||
624 | else | ||
625 | period = qh->period; | ||
626 | |||
627 | } else { | ||
628 | |||
629 | if (qh->period >= 8) | ||
630 | period = qh->period/8; | ||
631 | else | ||
632 | period = qh->period; | ||
633 | |||
634 | if (period >= 32) | ||
635 | period = 16; | ||
636 | |||
637 | if (qh->period >= 8) { | ||
638 | /* millisecond period */ | ||
639 | period = (period << 3); | ||
640 | } else { | ||
641 | /* usof based tranmsfers */ | ||
642 | /* minimum 4 usofs */ | ||
643 | usof = 0x11; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | ptd->dw2 |= cpu_to_le32(period); | ||
648 | ptd->dw4 = cpu_to_le32(usof); | ||
649 | } | ||
650 | |||
651 | static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, | ||
652 | struct isp1760_qtd *qtd, struct urb *urb, | ||
653 | u32 payload, struct ptd *ptd) | ||
654 | { | ||
655 | transform_into_atl(priv, qh, qtd, urb, payload, ptd); | ||
656 | transform_add_int(priv, qh, qtd, urb, payload, ptd); | ||
657 | } | ||
658 | |||
659 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, | ||
660 | u32 token) | ||
661 | { | ||
662 | int count; | ||
663 | |||
664 | qtd->data_buffer = databuffer; | ||
665 | qtd->packet_type = GET_QTD_TOKEN_TYPE(token); | ||
666 | qtd->toggle = GET_DATA_TOGGLE(token); | ||
667 | |||
668 | if (len > HC_ATL_PL_SIZE) | ||
669 | count = HC_ATL_PL_SIZE; | ||
670 | else | ||
671 | count = len; | ||
672 | |||
673 | qtd->length = count; | ||
674 | return count; | ||
675 | } | ||
676 | |||
677 | static int check_error(struct ptd *ptd) | ||
678 | { | ||
679 | int error = 0; | ||
680 | u32 dw3; | ||
681 | |||
682 | dw3 = le32_to_cpu(ptd->dw3); | ||
683 | if (dw3 & DW3_HALT_BIT) | ||
684 | error = -EPIPE; | ||
685 | |||
686 | if (dw3 & DW3_ERROR_BIT) { | ||
687 | printk(KERN_ERR "error bit is set in DW3\n"); | ||
688 | error = -EPIPE; | ||
689 | } | ||
690 | |||
691 | if (dw3 & DW3_QTD_ACTIVE) { | ||
692 | printk(KERN_ERR "transfer active bit is set DW3\n"); | ||
693 | printk(KERN_ERR "nak counter: %d, rl: %d\n", (dw3 >> 19) & 0xf, | ||
694 | (le32_to_cpu(ptd->dw2) >> 25) & 0xf); | ||
695 | } | ||
696 | |||
697 | return error; | ||
698 | } | ||
699 | |||
700 | static void check_int_err_status(u32 dw4) | ||
701 | { | ||
702 | u32 i; | ||
703 | |||
704 | dw4 >>= 8; | ||
705 | |||
706 | for (i = 0; i < 8; i++) { | ||
707 | switch (dw4 & 0x7) { | ||
708 | case INT_UNDERRUN: | ||
709 | printk(KERN_ERR "ERROR: under run , %d\n", i); | ||
710 | break; | ||
711 | |||
712 | case INT_EXACT: | ||
713 | printk(KERN_ERR "ERROR: transaction error, %d\n", i); | ||
714 | break; | ||
715 | |||
716 | case INT_BABBLE: | ||
717 | printk(KERN_ERR "ERROR: babble error, %d\n", i); | ||
718 | break; | ||
719 | } | ||
720 | dw4 >>= 3; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv, | ||
725 | u32 payload) | ||
726 | { | ||
727 | u32 token; | ||
728 | struct usb_hcd *hcd = priv_to_hcd(priv); | ||
729 | |||
730 | token = qtd->packet_type; | ||
731 | |||
732 | if (qtd->length && (qtd->length <= HC_ATL_PL_SIZE)) { | ||
733 | switch (token) { | ||
734 | case IN_PID: | ||
735 | break; | ||
736 | case OUT_PID: | ||
737 | case SETUP_PID: | ||
738 | priv_write_copy(priv, qtd->data_buffer, | ||
739 | hcd->regs + payload, | ||
740 | qtd->length); | ||
741 | } | ||
742 | } | ||
743 | } | ||
744 | |||
745 | static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, | ||
746 | struct isp1760_hcd *priv, struct isp1760_qh *qh, | ||
747 | struct urb *urb, u32 slot, struct isp1760_qtd *qtd) | ||
748 | { | ||
749 | struct ptd ptd; | ||
750 | struct usb_hcd *hcd = priv_to_hcd(priv); | ||
751 | |||
752 | transform_into_atl(priv, qh, qtd, urb, payload, &ptd); | ||
753 | priv_write_copy(priv, (u32 *)&ptd, hcd->regs + atl_regs, sizeof(ptd)); | ||
754 | enqueue_one_qtd(qtd, priv, payload); | ||
755 | |||
756 | priv->atl_ints[slot].urb = urb; | ||
757 | priv->atl_ints[slot].qh = qh; | ||
758 | priv->atl_ints[slot].qtd = qtd; | ||
759 | priv->atl_ints[slot].data_buffer = qtd->data_buffer; | ||
760 | priv->atl_ints[slot].payload = payload; | ||
761 | qtd->status |= URB_ENQUEUED | URB_TYPE_ATL; | ||
762 | qtd->status |= slot << 16; | ||
763 | } | ||
764 | |||
765 | static void enqueue_one_int_qtd(u32 int_regs, u32 payload, | ||
766 | struct isp1760_hcd *priv, struct isp1760_qh *qh, | ||
767 | struct urb *urb, u32 slot, struct isp1760_qtd *qtd) | ||
768 | { | ||
769 | struct ptd ptd; | ||
770 | struct usb_hcd *hcd = priv_to_hcd(priv); | ||
771 | |||
772 | transform_into_int(priv, qh, qtd, urb, payload, &ptd); | ||
773 | priv_write_copy(priv, (u32 *)&ptd, hcd->regs + int_regs, sizeof(ptd)); | ||
774 | enqueue_one_qtd(qtd, priv, payload); | ||
775 | |||
776 | priv->int_ints[slot].urb = urb; | ||
777 | priv->int_ints[slot].qh = qh; | ||
778 | priv->int_ints[slot].qtd = qtd; | ||
779 | priv->int_ints[slot].data_buffer = qtd->data_buffer; | ||
780 | priv->int_ints[slot].payload = payload; | ||
781 | qtd->status |= URB_ENQUEUED | URB_TYPE_INT; | ||
782 | qtd->status |= slot << 16; | ||
783 | } | ||
784 | |||
785 | void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
786 | struct isp1760_qtd *qtd) | ||
787 | { | ||
788 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
789 | u32 skip_map, or_map; | ||
790 | u32 queue_entry; | ||
791 | u32 slot; | ||
792 | u32 atl_regs, payload; | ||
793 | u32 buffstatus; | ||
794 | |||
795 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | ||
796 | |||
797 | BUG_ON(!skip_map); | ||
798 | slot = __ffs(skip_map); | ||
799 | queue_entry = 1 << slot; | ||
800 | |||
801 | atl_regs = ATL_REGS_OFFSET + slot * sizeof(struct ptd); | ||
802 | |||
803 | payload = alloc_mem(priv, qtd->length); | ||
804 | |||
805 | enqueue_one_atl_qtd(atl_regs, payload, priv, qh, qtd->urb, slot, qtd); | ||
806 | |||
807 | or_map = isp1760_readl(hcd->regs + HC_ATL_IRQ_MASK_OR_REG); | ||
808 | or_map |= queue_entry; | ||
809 | isp1760_writel(or_map, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); | ||
810 | |||
811 | skip_map &= ~queue_entry; | ||
812 | isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | ||
813 | |||
814 | buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); | ||
815 | buffstatus |= ATL_BUFFER; | ||
816 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); | ||
817 | } | ||
818 | |||
819 | void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
820 | struct isp1760_qtd *qtd) | ||
821 | { | ||
822 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
823 | u32 skip_map, or_map; | ||
824 | u32 queue_entry; | ||
825 | u32 slot; | ||
826 | u32 int_regs, payload; | ||
827 | u32 buffstatus; | ||
828 | |||
829 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | ||
830 | |||
831 | BUG_ON(!skip_map); | ||
832 | slot = __ffs(skip_map); | ||
833 | queue_entry = 1 << slot; | ||
834 | |||
835 | int_regs = INT_REGS_OFFSET + slot * sizeof(struct ptd); | ||
836 | |||
837 | payload = alloc_mem(priv, qtd->length); | ||
838 | |||
839 | enqueue_one_int_qtd(int_regs, payload, priv, qh, qtd->urb, slot, qtd); | ||
840 | |||
841 | or_map = isp1760_readl(hcd->regs + HC_INT_IRQ_MASK_OR_REG); | ||
842 | or_map |= queue_entry; | ||
843 | isp1760_writel(or_map, hcd->regs + HC_INT_IRQ_MASK_OR_REG); | ||
844 | |||
845 | skip_map &= ~queue_entry; | ||
846 | isp1760_writel(skip_map, hcd->regs + HC_INT_PTD_SKIPMAP_REG); | ||
847 | |||
848 | buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); | ||
849 | buffstatus |= INT_BUFFER; | ||
850 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); | ||
851 | } | ||
852 | |||
853 | static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, int status) | ||
854 | __releases(priv->lock) | ||
855 | __acquires(priv->lock) | ||
856 | { | ||
857 | if (!urb->unlinked) { | ||
858 | if (status == -EINPROGRESS) | ||
859 | status = 0; | ||
860 | } | ||
861 | |||
862 | /* complete() can reenter this HCD */ | ||
863 | usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); | ||
864 | spin_unlock(&priv->lock); | ||
865 | usb_hcd_giveback_urb(priv_to_hcd(priv), urb, status); | ||
866 | spin_lock(&priv->lock); | ||
867 | } | ||
868 | |||
869 | static void isp1760_qtd_free(struct isp1760_qtd *qtd) | ||
870 | { | ||
871 | kmem_cache_free(qtd_cachep, qtd); | ||
872 | } | ||
873 | |||
874 | static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd) | ||
875 | { | ||
876 | struct isp1760_qtd *tmp_qtd; | ||
877 | |||
878 | tmp_qtd = qtd->hw_next; | ||
879 | list_del(&qtd->qtd_list); | ||
880 | isp1760_qtd_free(qtd); | ||
881 | return tmp_qtd; | ||
882 | } | ||
883 | |||
884 | /* | ||
885 | * Remove this QTD from the QH list and free its memory. If this QTD | ||
886 | * isn't the last one than remove also his successor(s). | ||
887 | * Returns the QTD which is part of an new URB and should be enqueued. | ||
888 | */ | ||
889 | static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd) | ||
890 | { | ||
891 | struct isp1760_qtd *tmp_qtd; | ||
892 | int last_one; | ||
893 | |||
894 | do { | ||
895 | tmp_qtd = qtd->hw_next; | ||
896 | last_one = qtd->status & URB_COMPLETE_NOTIFY; | ||
897 | list_del(&qtd->qtd_list); | ||
898 | isp1760_qtd_free(qtd); | ||
899 | qtd = tmp_qtd; | ||
900 | } while (!last_one && qtd); | ||
901 | |||
902 | return qtd; | ||
903 | } | ||
904 | |||
905 | static void do_atl_int(struct usb_hcd *usb_hcd) | ||
906 | { | ||
907 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); | ||
908 | u32 done_map, skip_map; | ||
909 | struct ptd ptd; | ||
910 | struct urb *urb = NULL; | ||
911 | u32 atl_regs_base; | ||
912 | u32 atl_regs; | ||
913 | u32 queue_entry; | ||
914 | u32 payload; | ||
915 | u32 length; | ||
916 | u32 or_map; | ||
917 | u32 status = -EINVAL; | ||
918 | int error; | ||
919 | struct isp1760_qtd *qtd; | ||
920 | struct isp1760_qh *qh; | ||
921 | u32 rl; | ||
922 | u32 nakcount; | ||
923 | |||
924 | done_map = isp1760_readl(usb_hcd->regs + | ||
925 | HC_ATL_PTD_DONEMAP_REG); | ||
926 | skip_map = isp1760_readl(usb_hcd->regs + | ||
927 | HC_ATL_PTD_SKIPMAP_REG); | ||
928 | |||
929 | or_map = isp1760_readl(usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); | ||
930 | or_map &= ~done_map; | ||
931 | isp1760_writel(or_map, usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); | ||
932 | |||
933 | atl_regs_base = ATL_REGS_OFFSET; | ||
934 | while (done_map) { | ||
935 | u32 dw1; | ||
936 | u32 dw2; | ||
937 | u32 dw3; | ||
938 | |||
939 | status = 0; | ||
940 | |||
941 | queue_entry = __ffs(done_map); | ||
942 | done_map &= ~(1 << queue_entry); | ||
943 | skip_map |= 1 << queue_entry; | ||
944 | |||
945 | atl_regs = atl_regs_base + queue_entry * sizeof(struct ptd); | ||
946 | |||
947 | urb = priv->atl_ints[queue_entry].urb; | ||
948 | qtd = priv->atl_ints[queue_entry].qtd; | ||
949 | qh = priv->atl_ints[queue_entry].qh; | ||
950 | payload = priv->atl_ints[queue_entry].payload; | ||
951 | |||
952 | if (!qh) { | ||
953 | printk(KERN_ERR "qh is 0\n"); | ||
954 | continue; | ||
955 | } | ||
956 | priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs, | ||
957 | atl_regs, sizeof(ptd)); | ||
958 | |||
959 | dw1 = le32_to_cpu(ptd.dw1); | ||
960 | dw2 = le32_to_cpu(ptd.dw2); | ||
961 | dw3 = le32_to_cpu(ptd.dw3); | ||
962 | rl = (dw2 >> 25) & 0x0f; | ||
963 | nakcount = (dw3 >> 19) & 0xf; | ||
964 | |||
965 | /* Transfer Error, *but* active and no HALT -> reload */ | ||
966 | if ((dw3 & DW3_ERROR_BIT) && (dw3 & DW3_QTD_ACTIVE) && | ||
967 | !(dw3 & DW3_HALT_BIT)) { | ||
968 | |||
969 | /* according to ppriv code, we have to | ||
970 | * reload this one if trasfered bytes != requested bytes | ||
971 | * else act like everything went smooth.. | ||
972 | * XXX This just doesn't feel right and hasn't | ||
973 | * triggered so far. | ||
974 | */ | ||
975 | |||
976 | length = PTD_XFERRED_LENGTH(dw3); | ||
977 | printk(KERN_ERR "Should reload now.... transfered %d " | ||
978 | "of %zu\n", length, qtd->length); | ||
979 | BUG(); | ||
980 | } | ||
981 | |||
982 | if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { | ||
983 | u32 buffstatus; | ||
984 | |||
985 | /* XXX | ||
986 | * NAKs are handled in HW by the chip. Usually if the | ||
987 | * device is not able to send data fast enough. | ||
988 | * This did not trigger for a long time now. | ||
989 | */ | ||
990 | printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: " | ||
991 | "%d of %zu done: %08x cur: %08x\n", qtd, | ||
992 | urb, qh, PTD_XFERRED_LENGTH(dw3), | ||
993 | qtd->length, done_map, | ||
994 | (1 << queue_entry)); | ||
995 | |||
996 | /* RL counter = ERR counter */ | ||
997 | dw3 &= ~(0xf << 19); | ||
998 | dw3 |= rl << 19; | ||
999 | dw3 &= ~(3 << (55 - 32)); | ||
1000 | dw3 |= ERR_COUNTER << (55 - 32); | ||
1001 | |||
1002 | /* | ||
1003 | * It is not needed to write skip map back because it | ||
1004 | * is unchanged. Just make sure that this entry is | ||
1005 | * unskipped once it gets written to the HW. | ||
1006 | */ | ||
1007 | skip_map &= ~(1 << queue_entry); | ||
1008 | or_map = isp1760_readl(usb_hcd->regs + | ||
1009 | HC_ATL_IRQ_MASK_OR_REG); | ||
1010 | or_map |= 1 << queue_entry; | ||
1011 | isp1760_writel(or_map, usb_hcd->regs + | ||
1012 | HC_ATL_IRQ_MASK_OR_REG); | ||
1013 | |||
1014 | ptd.dw3 = cpu_to_le32(dw3); | ||
1015 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | ||
1016 | atl_regs, sizeof(ptd)); | ||
1017 | |||
1018 | ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID); | ||
1019 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | ||
1020 | atl_regs, sizeof(ptd)); | ||
1021 | |||
1022 | buffstatus = isp1760_readl(usb_hcd->regs + | ||
1023 | HC_BUFFER_STATUS_REG); | ||
1024 | buffstatus |= ATL_BUFFER; | ||
1025 | isp1760_writel(buffstatus, usb_hcd->regs + | ||
1026 | HC_BUFFER_STATUS_REG); | ||
1027 | continue; | ||
1028 | } | ||
1029 | |||
1030 | error = check_error(&ptd); | ||
1031 | if (error) { | ||
1032 | status = error; | ||
1033 | priv->atl_ints[queue_entry].qh->toggle = 0; | ||
1034 | priv->atl_ints[queue_entry].qh->ping = 0; | ||
1035 | urb->status = -EPIPE; | ||
1036 | |||
1037 | #if 0 | ||
1038 | printk(KERN_ERR "Error in %s().\n", __func__); | ||
1039 | printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " | ||
1040 | "dw3: %08x dw4: %08x dw5: %08x dw6: " | ||
1041 | "%08x dw7: %08x\n", | ||
1042 | ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, | ||
1043 | ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); | ||
1044 | #endif | ||
1045 | } else { | ||
1046 | if (usb_pipetype(urb->pipe) == PIPE_BULK) { | ||
1047 | priv->atl_ints[queue_entry].qh->toggle = dw3 & | ||
1048 | (1 << 25); | ||
1049 | priv->atl_ints[queue_entry].qh->ping = dw3 & | ||
1050 | (1 << 26); | ||
1051 | } | ||
1052 | } | ||
1053 | |||
1054 | length = PTD_XFERRED_LENGTH(dw3); | ||
1055 | if (length) { | ||
1056 | switch (DW1_GET_PID(dw1)) { | ||
1057 | case IN_PID: | ||
1058 | priv_read_copy(priv, | ||
1059 | priv->atl_ints[queue_entry].data_buffer, | ||
1060 | usb_hcd->regs + payload, payload, | ||
1061 | length); | ||
1062 | |||
1063 | case OUT_PID: | ||
1064 | |||
1065 | urb->actual_length += length; | ||
1066 | |||
1067 | case SETUP_PID: | ||
1068 | break; | ||
1069 | } | ||
1070 | } | ||
1071 | |||
1072 | priv->atl_ints[queue_entry].data_buffer = NULL; | ||
1073 | priv->atl_ints[queue_entry].urb = NULL; | ||
1074 | priv->atl_ints[queue_entry].qtd = NULL; | ||
1075 | priv->atl_ints[queue_entry].qh = NULL; | ||
1076 | |||
1077 | free_mem(priv, payload); | ||
1078 | |||
1079 | isp1760_writel(skip_map, usb_hcd->regs + | ||
1080 | HC_ATL_PTD_SKIPMAP_REG); | ||
1081 | |||
1082 | if (urb->status == -EPIPE) { | ||
1083 | /* HALT was received */ | ||
1084 | |||
1085 | qtd = clean_up_qtdlist(qtd); | ||
1086 | isp1760_urb_done(priv, urb, urb->status); | ||
1087 | |||
1088 | } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { | ||
1089 | /* short BULK received */ | ||
1090 | |||
1091 | printk(KERN_ERR "short bulk, %d instead %zu\n", length, | ||
1092 | qtd->length); | ||
1093 | if (urb->transfer_flags & URB_SHORT_NOT_OK) { | ||
1094 | urb->status = -EREMOTEIO; | ||
1095 | printk(KERN_ERR "not okey\n"); | ||
1096 | } | ||
1097 | |||
1098 | if (urb->status == -EINPROGRESS) | ||
1099 | urb->status = 0; | ||
1100 | |||
1101 | qtd = clean_up_qtdlist(qtd); | ||
1102 | |||
1103 | isp1760_urb_done(priv, urb, urb->status); | ||
1104 | |||
1105 | } else if (qtd->status & URB_COMPLETE_NOTIFY) { | ||
1106 | /* that was the last qtd of that URB */ | ||
1107 | |||
1108 | if (urb->status == -EINPROGRESS) | ||
1109 | urb->status = 0; | ||
1110 | |||
1111 | qtd = clean_this_qtd(qtd); | ||
1112 | isp1760_urb_done(priv, urb, urb->status); | ||
1113 | |||
1114 | } else { | ||
1115 | /* next QTD of this URB */ | ||
1116 | |||
1117 | qtd = clean_this_qtd(qtd); | ||
1118 | BUG_ON(!qtd); | ||
1119 | } | ||
1120 | |||
1121 | if (qtd) | ||
1122 | enqueue_an_ATL_packet(usb_hcd, qh, qtd); | ||
1123 | |||
1124 | skip_map = isp1760_readl(usb_hcd->regs + | ||
1125 | HC_ATL_PTD_SKIPMAP_REG); | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | static void do_intl_int(struct usb_hcd *usb_hcd) | ||
1130 | { | ||
1131 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); | ||
1132 | u32 done_map, skip_map; | ||
1133 | struct ptd ptd; | ||
1134 | struct urb *urb = NULL; | ||
1135 | u32 int_regs; | ||
1136 | u32 int_regs_base; | ||
1137 | u32 payload; | ||
1138 | u32 length; | ||
1139 | u32 or_map; | ||
1140 | int error; | ||
1141 | u32 queue_entry; | ||
1142 | struct isp1760_qtd *qtd; | ||
1143 | struct isp1760_qh *qh; | ||
1144 | |||
1145 | done_map = isp1760_readl(usb_hcd->regs + | ||
1146 | HC_INT_PTD_DONEMAP_REG); | ||
1147 | skip_map = isp1760_readl(usb_hcd->regs + | ||
1148 | HC_INT_PTD_SKIPMAP_REG); | ||
1149 | |||
1150 | or_map = isp1760_readl(usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); | ||
1151 | or_map &= ~done_map; | ||
1152 | isp1760_writel(or_map, usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); | ||
1153 | |||
1154 | int_regs_base = INT_REGS_OFFSET; | ||
1155 | |||
1156 | while (done_map) { | ||
1157 | u32 dw1; | ||
1158 | u32 dw3; | ||
1159 | |||
1160 | queue_entry = __ffs(done_map); | ||
1161 | done_map &= ~(1 << queue_entry); | ||
1162 | skip_map |= 1 << queue_entry; | ||
1163 | |||
1164 | int_regs = int_regs_base + queue_entry * sizeof(struct ptd); | ||
1165 | urb = priv->int_ints[queue_entry].urb; | ||
1166 | qtd = priv->int_ints[queue_entry].qtd; | ||
1167 | qh = priv->int_ints[queue_entry].qh; | ||
1168 | payload = priv->int_ints[queue_entry].payload; | ||
1169 | |||
1170 | if (!qh) { | ||
1171 | printk(KERN_ERR "(INT) qh is 0\n"); | ||
1172 | continue; | ||
1173 | } | ||
1174 | |||
1175 | priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs, | ||
1176 | int_regs, sizeof(ptd)); | ||
1177 | dw1 = le32_to_cpu(ptd.dw1); | ||
1178 | dw3 = le32_to_cpu(ptd.dw3); | ||
1179 | check_int_err_status(le32_to_cpu(ptd.dw4)); | ||
1180 | |||
1181 | error = check_error(&ptd); | ||
1182 | if (error) { | ||
1183 | #if 0 | ||
1184 | printk(KERN_ERR "Error in %s().\n", __func__); | ||
1185 | printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " | ||
1186 | "dw3: %08x dw4: %08x dw5: %08x dw6: " | ||
1187 | "%08x dw7: %08x\n", | ||
1188 | ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, | ||
1189 | ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); | ||
1190 | #endif | ||
1191 | urb->status = -EPIPE; | ||
1192 | priv->int_ints[queue_entry].qh->toggle = 0; | ||
1193 | priv->int_ints[queue_entry].qh->ping = 0; | ||
1194 | |||
1195 | } else { | ||
1196 | priv->int_ints[queue_entry].qh->toggle = | ||
1197 | dw3 & (1 << 25); | ||
1198 | priv->int_ints[queue_entry].qh->ping = dw3 & (1 << 26); | ||
1199 | } | ||
1200 | |||
1201 | if (urb->dev->speed != USB_SPEED_HIGH) | ||
1202 | length = PTD_XFERRED_LENGTH_LO(dw3); | ||
1203 | else | ||
1204 | length = PTD_XFERRED_LENGTH(dw3); | ||
1205 | |||
1206 | if (length) { | ||
1207 | switch (DW1_GET_PID(dw1)) { | ||
1208 | case IN_PID: | ||
1209 | priv_read_copy(priv, | ||
1210 | priv->int_ints[queue_entry].data_buffer, | ||
1211 | usb_hcd->regs + payload , payload, | ||
1212 | length); | ||
1213 | case OUT_PID: | ||
1214 | |||
1215 | urb->actual_length += length; | ||
1216 | |||
1217 | case SETUP_PID: | ||
1218 | break; | ||
1219 | } | ||
1220 | } | ||
1221 | |||
1222 | priv->int_ints[queue_entry].data_buffer = NULL; | ||
1223 | priv->int_ints[queue_entry].urb = NULL; | ||
1224 | priv->int_ints[queue_entry].qtd = NULL; | ||
1225 | priv->int_ints[queue_entry].qh = NULL; | ||
1226 | |||
1227 | isp1760_writel(skip_map, usb_hcd->regs + | ||
1228 | HC_INT_PTD_SKIPMAP_REG); | ||
1229 | free_mem(priv, payload); | ||
1230 | |||
1231 | if (urb->status == -EPIPE) { | ||
1232 | /* HALT received */ | ||
1233 | |||
1234 | qtd = clean_up_qtdlist(qtd); | ||
1235 | isp1760_urb_done(priv, urb, urb->status); | ||
1236 | |||
1237 | } else if (qtd->status & URB_COMPLETE_NOTIFY) { | ||
1238 | |||
1239 | if (urb->status == -EINPROGRESS) | ||
1240 | urb->status = 0; | ||
1241 | |||
1242 | qtd = clean_this_qtd(qtd); | ||
1243 | isp1760_urb_done(priv, urb, urb->status); | ||
1244 | |||
1245 | } else { | ||
1246 | /* next QTD of this URB */ | ||
1247 | |||
1248 | qtd = clean_this_qtd(qtd); | ||
1249 | BUG_ON(!qtd); | ||
1250 | } | ||
1251 | |||
1252 | if (qtd) | ||
1253 | enqueue_an_INT_packet(usb_hcd, qh, qtd); | ||
1254 | |||
1255 | skip_map = isp1760_readl(usb_hcd->regs + | ||
1256 | HC_INT_PTD_SKIPMAP_REG); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) | ||
1261 | static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, | ||
1262 | gfp_t flags) | ||
1263 | { | ||
1264 | struct isp1760_qh *qh; | ||
1265 | int is_input, type; | ||
1266 | |||
1267 | qh = isp1760_qh_alloc(priv, flags); | ||
1268 | if (!qh) | ||
1269 | return qh; | ||
1270 | |||
1271 | /* | ||
1272 | * init endpoint/device data for this QH | ||
1273 | */ | ||
1274 | is_input = usb_pipein(urb->pipe); | ||
1275 | type = usb_pipetype(urb->pipe); | ||
1276 | |||
1277 | if (type == PIPE_INTERRUPT) { | ||
1278 | |||
1279 | if (urb->dev->speed == USB_SPEED_HIGH) { | ||
1280 | |||
1281 | qh->period = urb->interval >> 3; | ||
1282 | if (qh->period == 0 && urb->interval != 1) { | ||
1283 | /* NOTE interval 2 or 4 uframes could work. | ||
1284 | * But interval 1 scheduling is simpler, and | ||
1285 | * includes high bandwidth. | ||
1286 | */ | ||
1287 | printk(KERN_ERR "intr period %d uframes, NYET!", | ||
1288 | urb->interval); | ||
1289 | qh_destroy(qh); | ||
1290 | return NULL; | ||
1291 | } | ||
1292 | } else { | ||
1293 | qh->period = urb->interval; | ||
1294 | } | ||
1295 | } | ||
1296 | |||
1297 | /* support for tt scheduling, and access to toggles */ | ||
1298 | qh->dev = urb->dev; | ||
1299 | |||
1300 | if (!usb_pipecontrol(urb->pipe)) | ||
1301 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, | ||
1302 | 1); | ||
1303 | return qh; | ||
1304 | } | ||
1305 | |||
1306 | /* | ||
1307 | * For control/bulk/interrupt, return QH with these TDs appended. | ||
1308 | * Allocates and initializes the QH if necessary. | ||
1309 | * Returns null if it can't allocate a QH it needs to. | ||
1310 | * If the QH has TDs (urbs) already, that's great. | ||
1311 | */ | ||
1312 | static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, | ||
1313 | struct urb *urb, struct list_head *qtd_list, int epnum, | ||
1314 | void **ptr) | ||
1315 | { | ||
1316 | struct isp1760_qh *qh; | ||
1317 | struct isp1760_qtd *qtd; | ||
1318 | struct isp1760_qtd *prev_qtd; | ||
1319 | |||
1320 | qh = (struct isp1760_qh *)*ptr; | ||
1321 | if (!qh) { | ||
1322 | /* can't sleep here, we have priv->lock... */ | ||
1323 | qh = qh_make(priv, urb, GFP_ATOMIC); | ||
1324 | if (!qh) | ||
1325 | return qh; | ||
1326 | *ptr = qh; | ||
1327 | } | ||
1328 | |||
1329 | qtd = list_entry(qtd_list->next, struct isp1760_qtd, | ||
1330 | qtd_list); | ||
1331 | if (!list_empty(&qh->qtd_list)) | ||
1332 | prev_qtd = list_entry(qh->qtd_list.prev, | ||
1333 | struct isp1760_qtd, qtd_list); | ||
1334 | else | ||
1335 | prev_qtd = NULL; | ||
1336 | |||
1337 | list_splice(qtd_list, qh->qtd_list.prev); | ||
1338 | if (prev_qtd) { | ||
1339 | BUG_ON(prev_qtd->hw_next); | ||
1340 | prev_qtd->hw_next = qtd; | ||
1341 | } | ||
1342 | |||
1343 | urb->hcpriv = qh; | ||
1344 | return qh; | ||
1345 | } | ||
1346 | |||
1347 | static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb, | ||
1348 | struct list_head *qtd_list) | ||
1349 | { | ||
1350 | struct list_head *entry, *temp; | ||
1351 | |||
1352 | list_for_each_safe(entry, temp, qtd_list) { | ||
1353 | struct isp1760_qtd *qtd; | ||
1354 | |||
1355 | qtd = list_entry(entry, struct isp1760_qtd, qtd_list); | ||
1356 | list_del(&qtd->qtd_list); | ||
1357 | isp1760_qtd_free(qtd); | ||
1358 | } | ||
1359 | } | ||
1360 | |||
1361 | static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, | ||
1362 | struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p) | ||
1363 | { | ||
1364 | struct isp1760_qtd *qtd; | ||
1365 | int epnum; | ||
1366 | unsigned long flags; | ||
1367 | struct isp1760_qh *qh = NULL; | ||
1368 | int rc; | ||
1369 | int qh_busy; | ||
1370 | |||
1371 | qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list); | ||
1372 | epnum = urb->ep->desc.bEndpointAddress; | ||
1373 | |||
1374 | spin_lock_irqsave(&priv->lock, flags); | ||
1375 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &priv_to_hcd(priv)->flags)) { | ||
1376 | rc = -ESHUTDOWN; | ||
1377 | goto done; | ||
1378 | } | ||
1379 | rc = usb_hcd_link_urb_to_ep(priv_to_hcd(priv), urb); | ||
1380 | if (rc) | ||
1381 | goto done; | ||
1382 | |||
1383 | qh = urb->ep->hcpriv; | ||
1384 | if (qh) | ||
1385 | qh_busy = !list_empty(&qh->qtd_list); | ||
1386 | else | ||
1387 | qh_busy = 0; | ||
1388 | |||
1389 | qh = qh_append_tds(priv, urb, qtd_list, epnum, &urb->ep->hcpriv); | ||
1390 | if (!qh) { | ||
1391 | usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); | ||
1392 | rc = -ENOMEM; | ||
1393 | goto done; | ||
1394 | } | ||
1395 | |||
1396 | if (!qh_busy) | ||
1397 | p(priv_to_hcd(priv), qh, qtd); | ||
1398 | |||
1399 | done: | ||
1400 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1401 | if (!qh) | ||
1402 | qtd_list_free(priv, urb, qtd_list); | ||
1403 | return rc; | ||
1404 | } | ||
1405 | |||
1406 | static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, | ||
1407 | gfp_t flags) | ||
1408 | { | ||
1409 | struct isp1760_qtd *qtd; | ||
1410 | |||
1411 | qtd = kmem_cache_zalloc(qtd_cachep, flags); | ||
1412 | if (qtd) | ||
1413 | INIT_LIST_HEAD(&qtd->qtd_list); | ||
1414 | |||
1415 | return qtd; | ||
1416 | } | ||
1417 | |||
1418 | /* | ||
1419 | * create a list of filled qtds for this URB; won't link into qh. | ||
1420 | */ | ||
1421 | static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, | ||
1422 | struct urb *urb, struct list_head *head, gfp_t flags) | ||
1423 | { | ||
1424 | struct isp1760_qtd *qtd, *qtd_prev; | ||
1425 | void *buf; | ||
1426 | int len, maxpacket; | ||
1427 | int is_input; | ||
1428 | u32 token; | ||
1429 | |||
1430 | /* | ||
1431 | * URBs map to sequences of QTDs: one logical transaction | ||
1432 | */ | ||
1433 | qtd = isp1760_qtd_alloc(priv, flags); | ||
1434 | if (!qtd) | ||
1435 | return NULL; | ||
1436 | |||
1437 | list_add_tail(&qtd->qtd_list, head); | ||
1438 | qtd->urb = urb; | ||
1439 | urb->status = -EINPROGRESS; | ||
1440 | |||
1441 | token = 0; | ||
1442 | /* for split transactions, SplitXState initialized to zero */ | ||
1443 | |||
1444 | len = urb->transfer_buffer_length; | ||
1445 | is_input = usb_pipein(urb->pipe); | ||
1446 | if (usb_pipecontrol(urb->pipe)) { | ||
1447 | /* SETUP pid */ | ||
1448 | qtd_fill(qtd, urb->setup_packet, | ||
1449 | sizeof(struct usb_ctrlrequest), | ||
1450 | token | SETUP_PID); | ||
1451 | |||
1452 | /* ... and always at least one more pid */ | ||
1453 | token ^= DATA_TOGGLE; | ||
1454 | qtd_prev = qtd; | ||
1455 | qtd = isp1760_qtd_alloc(priv, flags); | ||
1456 | if (!qtd) | ||
1457 | goto cleanup; | ||
1458 | qtd->urb = urb; | ||
1459 | qtd_prev->hw_next = qtd; | ||
1460 | list_add_tail(&qtd->qtd_list, head); | ||
1461 | |||
1462 | /* for zero length DATA stages, STATUS is always IN */ | ||
1463 | if (len == 0) | ||
1464 | token |= IN_PID; | ||
1465 | } | ||
1466 | |||
1467 | /* | ||
1468 | * data transfer stage: buffer setup | ||
1469 | */ | ||
1470 | buf = urb->transfer_buffer; | ||
1471 | |||
1472 | if (is_input) | ||
1473 | token |= IN_PID; | ||
1474 | else | ||
1475 | token |= OUT_PID; | ||
1476 | |||
1477 | maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input)); | ||
1478 | |||
1479 | /* | ||
1480 | * buffer gets wrapped in one or more qtds; | ||
1481 | * last one may be "short" (including zero len) | ||
1482 | * and may serve as a control status ack | ||
1483 | */ | ||
1484 | for (;;) { | ||
1485 | int this_qtd_len; | ||
1486 | |||
1487 | if (!buf && len) { | ||
1488 | /* XXX This looks like usb storage / SCSI bug */ | ||
1489 | printk(KERN_ERR "buf is null, dma is %08lx len is %d\n", | ||
1490 | (long unsigned)urb->transfer_dma, len); | ||
1491 | WARN_ON(1); | ||
1492 | } | ||
1493 | |||
1494 | this_qtd_len = qtd_fill(qtd, buf, len, token); | ||
1495 | len -= this_qtd_len; | ||
1496 | buf += this_qtd_len; | ||
1497 | |||
1498 | /* qh makes control packets use qtd toggle; maybe switch it */ | ||
1499 | if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) | ||
1500 | token ^= DATA_TOGGLE; | ||
1501 | |||
1502 | if (len <= 0) | ||
1503 | break; | ||
1504 | |||
1505 | qtd_prev = qtd; | ||
1506 | qtd = isp1760_qtd_alloc(priv, flags); | ||
1507 | if (!qtd) | ||
1508 | goto cleanup; | ||
1509 | qtd->urb = urb; | ||
1510 | qtd_prev->hw_next = qtd; | ||
1511 | list_add_tail(&qtd->qtd_list, head); | ||
1512 | } | ||
1513 | |||
1514 | /* | ||
1515 | * control requests may need a terminating data "status" ack; | ||
1516 | * bulk ones may need a terminating short packet (zero length). | ||
1517 | */ | ||
1518 | if (urb->transfer_buffer_length != 0) { | ||
1519 | int one_more = 0; | ||
1520 | |||
1521 | if (usb_pipecontrol(urb->pipe)) { | ||
1522 | one_more = 1; | ||
1523 | /* "in" <--> "out" */ | ||
1524 | token ^= IN_PID; | ||
1525 | /* force DATA1 */ | ||
1526 | token |= DATA_TOGGLE; | ||
1527 | } else if (usb_pipebulk(urb->pipe) | ||
1528 | && (urb->transfer_flags & URB_ZERO_PACKET) | ||
1529 | && !(urb->transfer_buffer_length % maxpacket)) { | ||
1530 | one_more = 1; | ||
1531 | } | ||
1532 | if (one_more) { | ||
1533 | qtd_prev = qtd; | ||
1534 | qtd = isp1760_qtd_alloc(priv, flags); | ||
1535 | if (!qtd) | ||
1536 | goto cleanup; | ||
1537 | qtd->urb = urb; | ||
1538 | qtd_prev->hw_next = qtd; | ||
1539 | list_add_tail(&qtd->qtd_list, head); | ||
1540 | |||
1541 | /* never any data in such packets */ | ||
1542 | qtd_fill(qtd, NULL, 0, token); | ||
1543 | } | ||
1544 | } | ||
1545 | |||
1546 | qtd->status = URB_COMPLETE_NOTIFY; | ||
1547 | return head; | ||
1548 | |||
1549 | cleanup: | ||
1550 | qtd_list_free(priv, urb, head); | ||
1551 | return NULL; | ||
1552 | } | ||
1553 | |||
1554 | static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
1555 | gfp_t mem_flags) | ||
1556 | { | ||
1557 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
1558 | struct list_head qtd_list; | ||
1559 | packet_enqueue *pe; | ||
1560 | |||
1561 | INIT_LIST_HEAD(&qtd_list); | ||
1562 | |||
1563 | switch (usb_pipetype(urb->pipe)) { | ||
1564 | case PIPE_CONTROL: | ||
1565 | case PIPE_BULK: | ||
1566 | |||
1567 | if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) | ||
1568 | return -ENOMEM; | ||
1569 | pe = enqueue_an_ATL_packet; | ||
1570 | break; | ||
1571 | |||
1572 | case PIPE_INTERRUPT: | ||
1573 | if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) | ||
1574 | return -ENOMEM; | ||
1575 | pe = enqueue_an_INT_packet; | ||
1576 | break; | ||
1577 | |||
1578 | case PIPE_ISOCHRONOUS: | ||
1579 | printk(KERN_ERR "PIPE_ISOCHRONOUS ain't supported\n"); | ||
1580 | default: | ||
1581 | return -EPIPE; | ||
1582 | } | ||
1583 | |||
1584 | isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe); | ||
1585 | return 0; | ||
1586 | } | ||
1587 | |||
1588 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | ||
1589 | int status) | ||
1590 | { | ||
1591 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
1592 | struct inter_packet_info *ints; | ||
1593 | u32 i; | ||
1594 | u32 reg_base, or_reg, skip_reg; | ||
1595 | int flags; | ||
1596 | struct ptd ptd; | ||
1597 | |||
1598 | switch (usb_pipetype(urb->pipe)) { | ||
1599 | case PIPE_ISOCHRONOUS: | ||
1600 | return -EPIPE; | ||
1601 | break; | ||
1602 | |||
1603 | case PIPE_INTERRUPT: | ||
1604 | ints = priv->int_ints; | ||
1605 | reg_base = INT_REGS_OFFSET; | ||
1606 | or_reg = HC_INT_IRQ_MASK_OR_REG; | ||
1607 | skip_reg = HC_INT_PTD_SKIPMAP_REG; | ||
1608 | break; | ||
1609 | |||
1610 | default: | ||
1611 | ints = priv->atl_ints; | ||
1612 | reg_base = ATL_REGS_OFFSET; | ||
1613 | or_reg = HC_ATL_IRQ_MASK_OR_REG; | ||
1614 | skip_reg = HC_ATL_PTD_SKIPMAP_REG; | ||
1615 | break; | ||
1616 | } | ||
1617 | |||
1618 | memset(&ptd, 0, sizeof(ptd)); | ||
1619 | spin_lock_irqsave(&priv->lock, flags); | ||
1620 | |||
1621 | for (i = 0; i < 32; i++) { | ||
1622 | if (ints->urb == urb) { | ||
1623 | u32 skip_map; | ||
1624 | u32 or_map; | ||
1625 | struct isp1760_qtd *qtd; | ||
1626 | |||
1627 | skip_map = isp1760_readl(hcd->regs + skip_reg); | ||
1628 | skip_map |= 1 << i; | ||
1629 | isp1760_writel(skip_map, hcd->regs + skip_reg); | ||
1630 | |||
1631 | or_map = isp1760_readl(hcd->regs + or_reg); | ||
1632 | or_map &= ~(1 << i); | ||
1633 | isp1760_writel(or_map, hcd->regs + or_reg); | ||
1634 | |||
1635 | priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base | ||
1636 | + i * sizeof(ptd), sizeof(ptd)); | ||
1637 | qtd = ints->qtd; | ||
1638 | |||
1639 | clean_up_qtdlist(qtd); | ||
1640 | |||
1641 | free_mem(priv, ints->payload); | ||
1642 | |||
1643 | ints->urb = NULL; | ||
1644 | ints->qh = NULL; | ||
1645 | ints->qtd = NULL; | ||
1646 | ints->data_buffer = NULL; | ||
1647 | ints->payload = 0; | ||
1648 | |||
1649 | isp1760_urb_done(priv, urb, status); | ||
1650 | break; | ||
1651 | } | ||
1652 | ints++; | ||
1653 | } | ||
1654 | |||
1655 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1656 | return 0; | ||
1657 | } | ||
1658 | |||
1659 | static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) | ||
1660 | { | ||
1661 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); | ||
1662 | u32 imask; | ||
1663 | irqreturn_t irqret = IRQ_NONE; | ||
1664 | |||
1665 | spin_lock(&priv->lock); | ||
1666 | |||
1667 | if (!(usb_hcd->state & HC_STATE_RUNNING)) | ||
1668 | goto leave; | ||
1669 | |||
1670 | imask = isp1760_readl(usb_hcd->regs + HC_INTERRUPT_REG); | ||
1671 | if (unlikely(!imask)) | ||
1672 | goto leave; | ||
1673 | |||
1674 | isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); | ||
1675 | if (imask & HC_ATL_INT) | ||
1676 | do_atl_int(usb_hcd); | ||
1677 | |||
1678 | if (imask & HC_INTL_INT) | ||
1679 | do_intl_int(usb_hcd); | ||
1680 | |||
1681 | irqret = IRQ_HANDLED; | ||
1682 | leave: | ||
1683 | spin_unlock(&priv->lock); | ||
1684 | return irqret; | ||
1685 | } | ||
1686 | |||
1687 | static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
1688 | { | ||
1689 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
1690 | u32 temp, status = 0; | ||
1691 | u32 mask; | ||
1692 | int retval = 1; | ||
1693 | unsigned long flags; | ||
1694 | |||
1695 | /* if !USB_SUSPEND, root hub timers won't get shut down ... */ | ||
1696 | if (!HC_IS_RUNNING(hcd->state)) | ||
1697 | return 0; | ||
1698 | |||
1699 | /* init status to no-changes */ | ||
1700 | buf[0] = 0; | ||
1701 | mask = PORT_CSC; | ||
1702 | |||
1703 | spin_lock_irqsave(&priv->lock, flags); | ||
1704 | temp = isp1760_readl(hcd->regs + HC_PORTSC1); | ||
1705 | |||
1706 | if (temp & PORT_OWNER) { | ||
1707 | if (temp & PORT_CSC) { | ||
1708 | temp &= ~PORT_CSC; | ||
1709 | isp1760_writel(temp, hcd->regs + HC_PORTSC1); | ||
1710 | goto done; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1714 | /* | ||
1715 | * Return status information even for ports with OWNER set. | ||
1716 | * Otherwise khubd wouldn't see the disconnect event when a | ||
1717 | * high-speed device is switched over to the companion | ||
1718 | * controller by the user. | ||
1719 | */ | ||
1720 | |||
1721 | if ((temp & mask) != 0 | ||
1722 | || ((temp & PORT_RESUME) != 0 | ||
1723 | && time_after_eq(jiffies, | ||
1724 | priv->reset_done))) { | ||
1725 | buf [0] |= 1 << (0 + 1); | ||
1726 | status = STS_PCD; | ||
1727 | } | ||
1728 | /* FIXME autosuspend idle root hubs */ | ||
1729 | done: | ||
1730 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1731 | return status ? retval : 0; | ||
1732 | } | ||
1733 | |||
1734 | static void isp1760_hub_descriptor(struct isp1760_hcd *priv, | ||
1735 | struct usb_hub_descriptor *desc) | ||
1736 | { | ||
1737 | int ports = HCS_N_PORTS(priv->hcs_params); | ||
1738 | u16 temp; | ||
1739 | |||
1740 | desc->bDescriptorType = 0x29; | ||
1741 | /* priv 1.0, 2.3.9 says 20ms max */ | ||
1742 | desc->bPwrOn2PwrGood = 10; | ||
1743 | desc->bHubContrCurrent = 0; | ||
1744 | |||
1745 | desc->bNbrPorts = ports; | ||
1746 | temp = 1 + (ports / 8); | ||
1747 | desc->bDescLength = 7 + 2 * temp; | ||
1748 | |||
1749 | /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ | ||
1750 | memset(&desc->bitmap[0], 0, temp); | ||
1751 | memset(&desc->bitmap[temp], 0xff, temp); | ||
1752 | |||
1753 | /* per-port overcurrent reporting */ | ||
1754 | temp = 0x0008; | ||
1755 | if (HCS_PPC(priv->hcs_params)) | ||
1756 | /* per-port power control */ | ||
1757 | temp |= 0x0001; | ||
1758 | else | ||
1759 | /* no power switching */ | ||
1760 | temp |= 0x0002; | ||
1761 | desc->wHubCharacteristics = cpu_to_le16(temp); | ||
1762 | } | ||
1763 | |||
1764 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) | ||
1765 | |||
1766 | static int check_reset_complete(struct isp1760_hcd *priv, int index, | ||
1767 | u32 __iomem *status_reg, int port_status) | ||
1768 | { | ||
1769 | if (!(port_status & PORT_CONNECT)) | ||
1770 | return port_status; | ||
1771 | |||
1772 | /* if reset finished and it's still not enabled -- handoff */ | ||
1773 | if (!(port_status & PORT_PE)) { | ||
1774 | |||
1775 | printk(KERN_ERR "port %d full speed --> companion\n", | ||
1776 | index + 1); | ||
1777 | |||
1778 | port_status |= PORT_OWNER; | ||
1779 | port_status &= ~PORT_RWC_BITS; | ||
1780 | isp1760_writel(port_status, status_reg); | ||
1781 | |||
1782 | } else | ||
1783 | printk(KERN_ERR "port %d high speed\n", index + 1); | ||
1784 | |||
1785 | return port_status; | ||
1786 | } | ||
1787 | |||
1788 | static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, | ||
1789 | u16 wValue, u16 wIndex, char *buf, u16 wLength) | ||
1790 | { | ||
1791 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
1792 | int ports = HCS_N_PORTS(priv->hcs_params); | ||
1793 | u32 __iomem *status_reg = hcd->regs + HC_PORTSC1; | ||
1794 | u32 temp, status; | ||
1795 | unsigned long flags; | ||
1796 | int retval = 0; | ||
1797 | unsigned selector; | ||
1798 | |||
1799 | /* | ||
1800 | * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. | ||
1801 | * HCS_INDICATOR may say we can change LEDs to off/amber/green. | ||
1802 | * (track current state ourselves) ... blink for diagnostics, | ||
1803 | * power, "this is the one", etc. EHCI spec supports this. | ||
1804 | */ | ||
1805 | |||
1806 | spin_lock_irqsave(&priv->lock, flags); | ||
1807 | switch (typeReq) { | ||
1808 | case ClearHubFeature: | ||
1809 | switch (wValue) { | ||
1810 | case C_HUB_LOCAL_POWER: | ||
1811 | case C_HUB_OVER_CURRENT: | ||
1812 | /* no hub-wide feature/status flags */ | ||
1813 | break; | ||
1814 | default: | ||
1815 | goto error; | ||
1816 | } | ||
1817 | break; | ||
1818 | case ClearPortFeature: | ||
1819 | if (!wIndex || wIndex > ports) | ||
1820 | goto error; | ||
1821 | wIndex--; | ||
1822 | temp = isp1760_readl(status_reg); | ||
1823 | |||
1824 | /* | ||
1825 | * Even if OWNER is set, so the port is owned by the | ||
1826 | * companion controller, khubd needs to be able to clear | ||
1827 | * the port-change status bits (especially | ||
1828 | * USB_PORT_FEAT_C_CONNECTION). | ||
1829 | */ | ||
1830 | |||
1831 | switch (wValue) { | ||
1832 | case USB_PORT_FEAT_ENABLE: | ||
1833 | isp1760_writel(temp & ~PORT_PE, status_reg); | ||
1834 | break; | ||
1835 | case USB_PORT_FEAT_C_ENABLE: | ||
1836 | /* XXX error? */ | ||
1837 | break; | ||
1838 | case USB_PORT_FEAT_SUSPEND: | ||
1839 | if (temp & PORT_RESET) | ||
1840 | goto error; | ||
1841 | |||
1842 | if (temp & PORT_SUSPEND) { | ||
1843 | if ((temp & PORT_PE) == 0) | ||
1844 | goto error; | ||
1845 | /* resume signaling for 20 msec */ | ||
1846 | temp &= ~(PORT_RWC_BITS); | ||
1847 | isp1760_writel(temp | PORT_RESUME, | ||
1848 | status_reg); | ||
1849 | priv->reset_done = jiffies + | ||
1850 | msecs_to_jiffies(20); | ||
1851 | } | ||
1852 | break; | ||
1853 | case USB_PORT_FEAT_C_SUSPEND: | ||
1854 | /* we auto-clear this feature */ | ||
1855 | break; | ||
1856 | case USB_PORT_FEAT_POWER: | ||
1857 | if (HCS_PPC(priv->hcs_params)) | ||
1858 | isp1760_writel(temp & ~PORT_POWER, status_reg); | ||
1859 | break; | ||
1860 | case USB_PORT_FEAT_C_CONNECTION: | ||
1861 | isp1760_writel(temp | PORT_CSC, | ||
1862 | status_reg); | ||
1863 | break; | ||
1864 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
1865 | /* XXX error ?*/ | ||
1866 | break; | ||
1867 | case USB_PORT_FEAT_C_RESET: | ||
1868 | /* GetPortStatus clears reset */ | ||
1869 | break; | ||
1870 | default: | ||
1871 | goto error; | ||
1872 | } | ||
1873 | isp1760_readl(hcd->regs + HC_USBCMD); | ||
1874 | break; | ||
1875 | case GetHubDescriptor: | ||
1876 | isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *) | ||
1877 | buf); | ||
1878 | break; | ||
1879 | case GetHubStatus: | ||
1880 | /* no hub-wide feature/status flags */ | ||
1881 | memset(buf, 0, 4); | ||
1882 | break; | ||
1883 | case GetPortStatus: | ||
1884 | if (!wIndex || wIndex > ports) | ||
1885 | goto error; | ||
1886 | wIndex--; | ||
1887 | status = 0; | ||
1888 | temp = isp1760_readl(status_reg); | ||
1889 | |||
1890 | /* wPortChange bits */ | ||
1891 | if (temp & PORT_CSC) | ||
1892 | status |= 1 << USB_PORT_FEAT_C_CONNECTION; | ||
1893 | |||
1894 | |||
1895 | /* whoever resumes must GetPortStatus to complete it!! */ | ||
1896 | if (temp & PORT_RESUME) { | ||
1897 | printk(KERN_ERR "Port resume should be skipped.\n"); | ||
1898 | |||
1899 | /* Remote Wakeup received? */ | ||
1900 | if (!priv->reset_done) { | ||
1901 | /* resume signaling for 20 msec */ | ||
1902 | priv->reset_done = jiffies | ||
1903 | + msecs_to_jiffies(20); | ||
1904 | /* check the port again */ | ||
1905 | mod_timer(&priv_to_hcd(priv)->rh_timer, | ||
1906 | priv->reset_done); | ||
1907 | } | ||
1908 | |||
1909 | /* resume completed? */ | ||
1910 | else if (time_after_eq(jiffies, | ||
1911 | priv->reset_done)) { | ||
1912 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
1913 | priv->reset_done = 0; | ||
1914 | |||
1915 | /* stop resume signaling */ | ||
1916 | temp = isp1760_readl(status_reg); | ||
1917 | isp1760_writel( | ||
1918 | temp & ~(PORT_RWC_BITS | PORT_RESUME), | ||
1919 | status_reg); | ||
1920 | retval = handshake(priv, status_reg, | ||
1921 | PORT_RESUME, 0, 2000 /* 2msec */); | ||
1922 | if (retval != 0) { | ||
1923 | isp1760_err(priv, | ||
1924 | "port %d resume error %d\n", | ||
1925 | wIndex + 1, retval); | ||
1926 | goto error; | ||
1927 | } | ||
1928 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | /* whoever resets must GetPortStatus to complete it!! */ | ||
1933 | if ((temp & PORT_RESET) | ||
1934 | && time_after_eq(jiffies, | ||
1935 | priv->reset_done)) { | ||
1936 | status |= 1 << USB_PORT_FEAT_C_RESET; | ||
1937 | priv->reset_done = 0; | ||
1938 | |||
1939 | /* force reset to complete */ | ||
1940 | isp1760_writel(temp & ~PORT_RESET, | ||
1941 | status_reg); | ||
1942 | /* REVISIT: some hardware needs 550+ usec to clear | ||
1943 | * this bit; seems too long to spin routinely... | ||
1944 | */ | ||
1945 | retval = handshake(priv, status_reg, | ||
1946 | PORT_RESET, 0, 750); | ||
1947 | if (retval != 0) { | ||
1948 | isp1760_err(priv, "port %d reset error %d\n", | ||
1949 | wIndex + 1, retval); | ||
1950 | goto error; | ||
1951 | } | ||
1952 | |||
1953 | /* see what we found out */ | ||
1954 | temp = check_reset_complete(priv, wIndex, status_reg, | ||
1955 | isp1760_readl(status_reg)); | ||
1956 | } | ||
1957 | /* | ||
1958 | * Even if OWNER is set, there's no harm letting khubd | ||
1959 | * see the wPortStatus values (they should all be 0 except | ||
1960 | * for PORT_POWER anyway). | ||
1961 | */ | ||
1962 | |||
1963 | if (temp & PORT_OWNER) | ||
1964 | printk(KERN_ERR "Warning: PORT_OWNER is set\n"); | ||
1965 | |||
1966 | if (temp & PORT_CONNECT) { | ||
1967 | status |= 1 << USB_PORT_FEAT_CONNECTION; | ||
1968 | /* status may be from integrated TT */ | ||
1969 | status |= ehci_port_speed(priv, temp); | ||
1970 | } | ||
1971 | if (temp & PORT_PE) | ||
1972 | status |= 1 << USB_PORT_FEAT_ENABLE; | ||
1973 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | ||
1974 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
1975 | if (temp & PORT_RESET) | ||
1976 | status |= 1 << USB_PORT_FEAT_RESET; | ||
1977 | if (temp & PORT_POWER) | ||
1978 | status |= 1 << USB_PORT_FEAT_POWER; | ||
1979 | |||
1980 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); | ||
1981 | break; | ||
1982 | case SetHubFeature: | ||
1983 | switch (wValue) { | ||
1984 | case C_HUB_LOCAL_POWER: | ||
1985 | case C_HUB_OVER_CURRENT: | ||
1986 | /* no hub-wide feature/status flags */ | ||
1987 | break; | ||
1988 | default: | ||
1989 | goto error; | ||
1990 | } | ||
1991 | break; | ||
1992 | case SetPortFeature: | ||
1993 | selector = wIndex >> 8; | ||
1994 | wIndex &= 0xff; | ||
1995 | if (!wIndex || wIndex > ports) | ||
1996 | goto error; | ||
1997 | wIndex--; | ||
1998 | temp = isp1760_readl(status_reg); | ||
1999 | if (temp & PORT_OWNER) | ||
2000 | break; | ||
2001 | |||
2002 | /* temp &= ~PORT_RWC_BITS; */ | ||
2003 | switch (wValue) { | ||
2004 | case USB_PORT_FEAT_ENABLE: | ||
2005 | isp1760_writel(temp | PORT_PE, status_reg); | ||
2006 | break; | ||
2007 | |||
2008 | case USB_PORT_FEAT_SUSPEND: | ||
2009 | if ((temp & PORT_PE) == 0 | ||
2010 | || (temp & PORT_RESET) != 0) | ||
2011 | goto error; | ||
2012 | |||
2013 | isp1760_writel(temp | PORT_SUSPEND, status_reg); | ||
2014 | break; | ||
2015 | case USB_PORT_FEAT_POWER: | ||
2016 | if (HCS_PPC(priv->hcs_params)) | ||
2017 | isp1760_writel(temp | PORT_POWER, | ||
2018 | status_reg); | ||
2019 | break; | ||
2020 | case USB_PORT_FEAT_RESET: | ||
2021 | if (temp & PORT_RESUME) | ||
2022 | goto error; | ||
2023 | /* line status bits may report this as low speed, | ||
2024 | * which can be fine if this root hub has a | ||
2025 | * transaction translator built in. | ||
2026 | */ | ||
2027 | if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT | ||
2028 | && PORT_USB11(temp)) { | ||
2029 | temp |= PORT_OWNER; | ||
2030 | } else { | ||
2031 | temp |= PORT_RESET; | ||
2032 | temp &= ~PORT_PE; | ||
2033 | |||
2034 | /* | ||
2035 | * caller must wait, then call GetPortStatus | ||
2036 | * usb 2.0 spec says 50 ms resets on root | ||
2037 | */ | ||
2038 | priv->reset_done = jiffies + | ||
2039 | msecs_to_jiffies(50); | ||
2040 | } | ||
2041 | isp1760_writel(temp, status_reg); | ||
2042 | break; | ||
2043 | default: | ||
2044 | goto error; | ||
2045 | } | ||
2046 | isp1760_readl(hcd->regs + HC_USBCMD); | ||
2047 | break; | ||
2048 | |||
2049 | default: | ||
2050 | error: | ||
2051 | /* "stall" on error */ | ||
2052 | retval = -EPIPE; | ||
2053 | } | ||
2054 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2055 | return retval; | ||
2056 | } | ||
2057 | |||
2058 | static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, | ||
2059 | struct usb_host_endpoint *ep) | ||
2060 | { | ||
2061 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); | ||
2062 | struct isp1760_qh *qh; | ||
2063 | struct isp1760_qtd *qtd; | ||
2064 | u32 flags; | ||
2065 | |||
2066 | spin_lock_irqsave(&priv->lock, flags); | ||
2067 | qh = ep->hcpriv; | ||
2068 | if (!qh) | ||
2069 | goto out; | ||
2070 | |||
2071 | ep->hcpriv = NULL; | ||
2072 | do { | ||
2073 | /* more than entry might get removed */ | ||
2074 | if (list_empty(&qh->qtd_list)) | ||
2075 | break; | ||
2076 | |||
2077 | qtd = list_first_entry(&qh->qtd_list, struct isp1760_qtd, | ||
2078 | qtd_list); | ||
2079 | |||
2080 | if (qtd->status & URB_ENQUEUED) { | ||
2081 | |||
2082 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2083 | isp1760_urb_dequeue(usb_hcd, qtd->urb, -ECONNRESET); | ||
2084 | spin_lock_irqsave(&priv->lock, flags); | ||
2085 | } else { | ||
2086 | struct urb *urb; | ||
2087 | |||
2088 | urb = qtd->urb; | ||
2089 | clean_up_qtdlist(qtd); | ||
2090 | isp1760_urb_done(priv, urb, -ECONNRESET); | ||
2091 | } | ||
2092 | } while (1); | ||
2093 | |||
2094 | qh_destroy(qh); | ||
2095 | /* remove requests and leak them. | ||
2096 | * ATL are pretty fast done, INT could take a while... | ||
2097 | * The latter shoule be removed | ||
2098 | */ | ||
2099 | out: | ||
2100 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2101 | } | ||
2102 | |||
2103 | static int isp1760_get_frame(struct usb_hcd *hcd) | ||
2104 | { | ||
2105 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
2106 | u32 fr; | ||
2107 | |||
2108 | fr = isp1760_readl(hcd->regs + HC_FRINDEX); | ||
2109 | return (fr >> 3) % priv->periodic_size; | ||
2110 | } | ||
2111 | |||
2112 | static void isp1760_stop(struct usb_hcd *hcd) | ||
2113 | { | ||
2114 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | ||
2115 | |||
2116 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, | ||
2117 | NULL, 0); | ||
2118 | mdelay(20); | ||
2119 | |||
2120 | spin_lock_irq(&priv->lock); | ||
2121 | ehci_reset(priv); | ||
2122 | /* Disable IRQ */ | ||
2123 | isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); | ||
2124 | spin_unlock_irq(&priv->lock); | ||
2125 | |||
2126 | isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); | ||
2127 | } | ||
2128 | |||
2129 | static void isp1760_shutdown(struct usb_hcd *hcd) | ||
2130 | { | ||
2131 | u32 command; | ||
2132 | |||
2133 | isp1760_stop(hcd); | ||
2134 | isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); | ||
2135 | |||
2136 | command = isp1760_readl(hcd->regs + HC_USBCMD); | ||
2137 | command &= ~CMD_RUN; | ||
2138 | isp1760_writel(command, hcd->regs + HC_USBCMD); | ||
2139 | } | ||
2140 | |||
2141 | static const struct hc_driver isp1760_hc_driver = { | ||
2142 | .description = "isp1760-hcd", | ||
2143 | .product_desc = "NXP ISP1760 USB Host Controller", | ||
2144 | .hcd_priv_size = sizeof(struct isp1760_hcd), | ||
2145 | .irq = isp1760_irq, | ||
2146 | .flags = HCD_MEMORY | HCD_USB2, | ||
2147 | .reset = isp1760_hc_setup, | ||
2148 | .start = isp1760_run, | ||
2149 | .stop = isp1760_stop, | ||
2150 | .shutdown = isp1760_shutdown, | ||
2151 | .urb_enqueue = isp1760_urb_enqueue, | ||
2152 | .urb_dequeue = isp1760_urb_dequeue, | ||
2153 | .endpoint_disable = isp1760_endpoint_disable, | ||
2154 | .get_frame_number = isp1760_get_frame, | ||
2155 | .hub_status_data = isp1760_hub_status_data, | ||
2156 | .hub_control = isp1760_hub_control, | ||
2157 | }; | ||
2158 | |||
2159 | int __init init_kmem_once(void) | ||
2160 | { | ||
2161 | qtd_cachep = kmem_cache_create("isp1760_qtd", | ||
2162 | sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY | | ||
2163 | SLAB_MEM_SPREAD, NULL); | ||
2164 | |||
2165 | if (!qtd_cachep) | ||
2166 | return -ENOMEM; | ||
2167 | |||
2168 | qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh), | ||
2169 | 0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL); | ||
2170 | |||
2171 | if (!qh_cachep) { | ||
2172 | kmem_cache_destroy(qtd_cachep); | ||
2173 | return -ENOMEM; | ||
2174 | } | ||
2175 | |||
2176 | return 0; | ||
2177 | } | ||
2178 | |||
2179 | void deinit_kmem_cache(void) | ||
2180 | { | ||
2181 | kmem_cache_destroy(qtd_cachep); | ||
2182 | kmem_cache_destroy(qh_cachep); | ||
2183 | } | ||
2184 | |||
2185 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | ||
2186 | u64 irqflags, struct device *dev, const char *busname) | ||
2187 | { | ||
2188 | struct usb_hcd *hcd; | ||
2189 | struct isp1760_hcd *priv; | ||
2190 | int ret; | ||
2191 | |||
2192 | if (usb_disabled()) | ||
2193 | return ERR_PTR(-ENODEV); | ||
2194 | |||
2195 | /* prevent usb-core allocating DMA pages */ | ||
2196 | dev->dma_mask = NULL; | ||
2197 | |||
2198 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id); | ||
2199 | if (!hcd) | ||
2200 | return ERR_PTR(-ENOMEM); | ||
2201 | |||
2202 | priv = hcd_to_priv(hcd); | ||
2203 | init_memory(priv); | ||
2204 | hcd->regs = ioremap(res_start, res_len); | ||
2205 | if (!hcd->regs) { | ||
2206 | ret = -EIO; | ||
2207 | goto err_put; | ||
2208 | } | ||
2209 | |||
2210 | hcd->irq = irq; | ||
2211 | hcd->rsrc_start = res_start; | ||
2212 | hcd->rsrc_len = res_len; | ||
2213 | |||
2214 | ret = usb_add_hcd(hcd, irq, irqflags); | ||
2215 | if (ret) | ||
2216 | goto err_unmap; | ||
2217 | |||
2218 | return hcd; | ||
2219 | |||
2220 | err_unmap: | ||
2221 | iounmap(hcd->regs); | ||
2222 | |||
2223 | err_put: | ||
2224 | usb_put_hcd(hcd); | ||
2225 | |||
2226 | return ERR_PTR(ret); | ||
2227 | } | ||
2228 | |||
2229 | MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); | ||
2230 | MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>"); | ||
2231 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h new file mode 100644 index 000000000000..3d86d0f6b147 --- /dev/null +++ b/drivers/usb/host/isp1760-hcd.h | |||
@@ -0,0 +1,206 @@ | |||
1 | #ifndef _ISP1760_HCD_H_ | ||
2 | #define _ISP1760_HCD_H_ | ||
3 | |||
4 | /* exports for if */ | ||
5 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | ||
6 | u64 irqflags, struct device *dev, const char *busname); | ||
7 | int init_kmem_once(void); | ||
8 | void deinit_kmem_cache(void); | ||
9 | |||
10 | /* EHCI capability registers */ | ||
11 | #define HC_CAPLENGTH 0x00 | ||
12 | #define HC_HCSPARAMS 0x04 | ||
13 | #define HC_HCCPARAMS 0x08 | ||
14 | |||
15 | /* EHCI operational registers */ | ||
16 | #define HC_USBCMD 0x20 | ||
17 | #define HC_USBSTS 0x24 | ||
18 | #define HC_FRINDEX 0x2c | ||
19 | #define HC_CONFIGFLAG 0x60 | ||
20 | #define HC_PORTSC1 0x64 | ||
21 | #define HC_ISO_PTD_DONEMAP_REG 0x130 | ||
22 | #define HC_ISO_PTD_SKIPMAP_REG 0x134 | ||
23 | #define HC_ISO_PTD_LASTPTD_REG 0x138 | ||
24 | #define HC_INT_PTD_DONEMAP_REG 0x140 | ||
25 | #define HC_INT_PTD_SKIPMAP_REG 0x144 | ||
26 | #define HC_INT_PTD_LASTPTD_REG 0x148 | ||
27 | #define HC_ATL_PTD_DONEMAP_REG 0x150 | ||
28 | #define HC_ATL_PTD_SKIPMAP_REG 0x154 | ||
29 | #define HC_ATL_PTD_LASTPTD_REG 0x158 | ||
30 | |||
31 | /* Configuration Register */ | ||
32 | #define HC_HW_MODE_CTRL 0x300 | ||
33 | #define ALL_ATX_RESET (1 << 31) | ||
34 | #define HW_DATA_BUS_32BIT (1 << 8) | ||
35 | #define HW_DACK_POL_HIGH (1 << 6) | ||
36 | #define HW_DREQ_POL_HIGH (1 << 5) | ||
37 | #define HW_INTR_HIGH_ACT (1 << 2) | ||
38 | #define HW_INTR_EDGE_TRIG (1 << 1) | ||
39 | #define HW_GLOBAL_INTR_EN (1 << 0) | ||
40 | |||
41 | #define HC_CHIP_ID_REG 0x304 | ||
42 | #define HC_SCRATCH_REG 0x308 | ||
43 | |||
44 | #define HC_RESET_REG 0x30c | ||
45 | #define SW_RESET_RESET_HC (1 << 1) | ||
46 | #define SW_RESET_RESET_ALL (1 << 0) | ||
47 | |||
48 | #define HC_BUFFER_STATUS_REG 0x334 | ||
49 | #define ATL_BUFFER 0x1 | ||
50 | #define INT_BUFFER 0x2 | ||
51 | #define ISO_BUFFER 0x4 | ||
52 | #define BUFFER_MAP 0x7 | ||
53 | |||
54 | #define HC_MEMORY_REG 0x33c | ||
55 | #define HC_PORT1_CTRL 0x374 | ||
56 | #define PORT1_POWER (3 << 3) | ||
57 | #define PORT1_INIT1 (1 << 7) | ||
58 | #define PORT1_INIT2 (1 << 23) | ||
59 | |||
60 | /* Interrupt Register */ | ||
61 | #define HC_INTERRUPT_REG 0x310 | ||
62 | |||
63 | #define HC_INTERRUPT_ENABLE 0x314 | ||
64 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) | ||
65 | #define FINAL_HW_CONFIG (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT) | ||
66 | |||
67 | #define HC_ISO_INT (1 << 9) | ||
68 | #define HC_ATL_INT (1 << 8) | ||
69 | #define HC_INTL_INT (1 << 7) | ||
70 | #define HC_EOT_INT (1 << 3) | ||
71 | #define HC_SOT_INT (1 << 1) | ||
72 | |||
73 | #define HC_ISO_IRQ_MASK_OR_REG 0x318 | ||
74 | #define HC_INT_IRQ_MASK_OR_REG 0x31C | ||
75 | #define HC_ATL_IRQ_MASK_OR_REG 0x320 | ||
76 | #define HC_ISO_IRQ_MASK_AND_REG 0x324 | ||
77 | #define HC_INT_IRQ_MASK_AND_REG 0x328 | ||
78 | #define HC_ATL_IRQ_MASK_AND_REG 0x32C | ||
79 | |||
80 | /* Register sets */ | ||
81 | #define HC_BEGIN_OF_ATL 0x0c00 | ||
82 | #define HC_BEGIN_OF_INT 0x0800 | ||
83 | #define HC_BEGIN_OF_ISO 0x0400 | ||
84 | #define HC_BEGIN_OF_PAYLOAD 0x1000 | ||
85 | |||
86 | /* urb state*/ | ||
87 | #define DELETE_URB (0x0008) | ||
88 | #define NO_TRANSFER_ACTIVE (0xffffffff) | ||
89 | |||
90 | #define ATL_REGS_OFFSET (0xc00) | ||
91 | #define INT_REGS_OFFSET (0x800) | ||
92 | |||
93 | /* Philips Transfer Descriptor (PTD) */ | ||
94 | struct ptd { | ||
95 | __le32 dw0; | ||
96 | __le32 dw1; | ||
97 | __le32 dw2; | ||
98 | __le32 dw3; | ||
99 | __le32 dw4; | ||
100 | __le32 dw5; | ||
101 | __le32 dw6; | ||
102 | __le32 dw7; | ||
103 | }; | ||
104 | |||
105 | struct inter_packet_info { | ||
106 | void *data_buffer; | ||
107 | u32 payload; | ||
108 | #define PTD_FIRE_NEXT (1 << 0) | ||
109 | #define PTD_URB_FINISHED (1 << 1) | ||
110 | struct urb *urb; | ||
111 | struct isp1760_qh *qh; | ||
112 | struct isp1760_qtd *qtd; | ||
113 | }; | ||
114 | |||
115 | |||
116 | typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
117 | struct isp1760_qtd *qtd); | ||
118 | |||
119 | #define isp1760_info(priv, fmt, args...) \ | ||
120 | dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args) | ||
121 | |||
122 | #define isp1760_err(priv, fmt, args...) \ | ||
123 | dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args) | ||
124 | |||
125 | /* chip memory management */ | ||
126 | struct memory_chunk { | ||
127 | unsigned int start; | ||
128 | unsigned int size; | ||
129 | unsigned int free; | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * 60kb divided in: | ||
134 | * - 32 blocks @ 256 bytes | ||
135 | * - 20 blocks @ 1024 bytes | ||
136 | * - 4 blocks @ 8192 bytes | ||
137 | */ | ||
138 | |||
139 | #define BLOCK_1_NUM 32 | ||
140 | #define BLOCK_2_NUM 20 | ||
141 | #define BLOCK_3_NUM 4 | ||
142 | |||
143 | #define BLOCK_1_SIZE 256 | ||
144 | #define BLOCK_2_SIZE 1024 | ||
145 | #define BLOCK_3_SIZE 8192 | ||
146 | #define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) | ||
147 | #define PAYLOAD_SIZE 0xf000 | ||
148 | |||
149 | /* I saw if some reloads if the pointer was negative */ | ||
150 | #define ISP1760_NULL_POINTER (0x400) | ||
151 | |||
152 | /* ATL */ | ||
153 | /* DW0 */ | ||
154 | #define PTD_VALID 1 | ||
155 | #define PTD_LENGTH(x) (((u32) x) << 3) | ||
156 | #define PTD_MAXPACKET(x) (((u32) x) << 18) | ||
157 | #define PTD_MULTI(x) (((u32) x) << 29) | ||
158 | #define PTD_ENDPOINT(x) (((u32) x) << 31) | ||
159 | /* DW1 */ | ||
160 | #define PTD_DEVICE_ADDR(x) (((u32) x) << 3) | ||
161 | #define PTD_PID_TOKEN(x) (((u32) x) << 10) | ||
162 | #define PTD_TRANS_BULK ((u32) 2 << 12) | ||
163 | #define PTD_TRANS_INT ((u32) 3 << 12) | ||
164 | #define PTD_TRANS_SPLIT ((u32) 1 << 14) | ||
165 | #define PTD_SE_USB_LOSPEED ((u32) 2 << 16) | ||
166 | #define PTD_PORT_NUM(x) (((u32) x) << 18) | ||
167 | #define PTD_HUB_NUM(x) (((u32) x) << 25) | ||
168 | #define PTD_PING(x) (((u32) x) << 26) | ||
169 | /* DW2 */ | ||
170 | #define PTD_RL_CNT(x) (((u32) x) << 25) | ||
171 | #define PTD_DATA_START_ADDR(x) (((u32) x) << 8) | ||
172 | #define BASE_ADDR 0x1000 | ||
173 | /* DW3 */ | ||
174 | #define PTD_CERR(x) (((u32) x) << 23) | ||
175 | #define PTD_NAC_CNT(x) (((u32) x) << 19) | ||
176 | #define PTD_ACTIVE ((u32) 1 << 31) | ||
177 | #define PTD_DATA_TOGGLE(x) (((u32) x) << 25) | ||
178 | |||
179 | #define DW3_HALT_BIT (1 << 30) | ||
180 | #define DW3_ERROR_BIT (1 << 28) | ||
181 | #define DW3_QTD_ACTIVE (1 << 31) | ||
182 | |||
183 | #define INT_UNDERRUN (1 << 2) | ||
184 | #define INT_BABBLE (1 << 1) | ||
185 | #define INT_EXACT (1 << 0) | ||
186 | |||
187 | #define DW1_GET_PID(x) (((x) >> 10) & 0x3) | ||
188 | #define PTD_XFERRED_LENGTH(x) ((x) & 0x7fff) | ||
189 | #define PTD_XFERRED_LENGTH_LO(x) ((x) & 0x7ff) | ||
190 | |||
191 | #define SETUP_PID (2) | ||
192 | #define IN_PID (1) | ||
193 | #define OUT_PID (0) | ||
194 | #define GET_QTD_TOKEN_TYPE(x) ((x) & 0x3) | ||
195 | |||
196 | #define DATA_TOGGLE (1 << 31) | ||
197 | #define GET_DATA_TOGGLE(x) ((x) >> 31) | ||
198 | |||
199 | /* Errata 1 */ | ||
200 | #define RL_COUNTER (0) | ||
201 | #define NAK_COUNTER (0) | ||
202 | #define ERR_COUNTER (2) | ||
203 | |||
204 | #define HC_ATL_PL_SIZE (8192) | ||
205 | |||
206 | #endif | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c new file mode 100644 index 000000000000..c9db3fe98726 --- /dev/null +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * Glue code for the ISP1760 driver and bus | ||
3 | * Currently there is support for | ||
4 | * - OpenFirmware | ||
5 | * - PCI | ||
6 | * | ||
7 | * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/usb.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include "../core/hcd.h" | ||
15 | #include "isp1760-hcd.h" | ||
16 | |||
17 | #ifdef CONFIG_USB_ISP1760_OF | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #endif | ||
21 | |||
22 | #ifdef CONFIG_USB_ISP1760_PCI | ||
23 | #include <linux/pci.h> | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_USB_ISP1760_OF | ||
27 | static int of_isp1760_probe(struct of_device *dev, | ||
28 | const struct of_device_id *match) | ||
29 | { | ||
30 | struct usb_hcd *hcd; | ||
31 | struct device_node *dp = dev->node; | ||
32 | struct resource *res; | ||
33 | struct resource memory; | ||
34 | struct of_irq oirq; | ||
35 | int virq; | ||
36 | u64 res_len; | ||
37 | int ret; | ||
38 | |||
39 | ret = of_address_to_resource(dp, 0, &memory); | ||
40 | if (ret) | ||
41 | return -ENXIO; | ||
42 | |||
43 | res = request_mem_region(memory.start, memory.end - memory.start + 1, | ||
44 | dev->dev.bus_id); | ||
45 | if (!res) | ||
46 | return -EBUSY; | ||
47 | |||
48 | res_len = memory.end - memory.start + 1; | ||
49 | |||
50 | if (of_irq_map_one(dp, 0, &oirq)) { | ||
51 | ret = -ENODEV; | ||
52 | goto release_reg; | ||
53 | } | ||
54 | |||
55 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | ||
56 | oirq.size); | ||
57 | |||
58 | hcd = isp1760_register(memory.start, res_len, virq, | ||
59 | IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); | ||
60 | if (IS_ERR(hcd)) { | ||
61 | ret = PTR_ERR(hcd); | ||
62 | goto release_reg; | ||
63 | } | ||
64 | |||
65 | dev_set_drvdata(&dev->dev, hcd); | ||
66 | return ret; | ||
67 | |||
68 | release_reg: | ||
69 | release_mem_region(memory.start, memory.end - memory.start + 1); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | static int of_isp1760_remove(struct of_device *dev) | ||
74 | { | ||
75 | struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); | ||
76 | |||
77 | dev_set_drvdata(&dev->dev, NULL); | ||
78 | |||
79 | usb_remove_hcd(hcd); | ||
80 | iounmap(hcd->regs); | ||
81 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
82 | usb_put_hcd(hcd); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static struct of_device_id of_isp1760_match[] = { | ||
87 | { | ||
88 | .compatible = "nxp,usb-isp1760", | ||
89 | }, | ||
90 | { }, | ||
91 | }; | ||
92 | MODULE_DEVICE_TABLE(of, of_isp1760_match); | ||
93 | |||
94 | static struct of_platform_driver isp1760_of_driver = { | ||
95 | .name = "nxp-isp1760", | ||
96 | .match_table = of_isp1760_match, | ||
97 | .probe = of_isp1760_probe, | ||
98 | .remove = of_isp1760_remove, | ||
99 | }; | ||
100 | #endif | ||
101 | |||
102 | #ifdef CONFIG_USB_ISP1760_PCI | ||
103 | static u32 nxp_pci_io_base; | ||
104 | static u32 iolength; | ||
105 | static u32 pci_mem_phy0; | ||
106 | static u32 length; | ||
107 | static u8 __iomem *chip_addr; | ||
108 | static u8 __iomem *iobase; | ||
109 | |||
110 | static int __devinit isp1761_pci_probe(struct pci_dev *dev, | ||
111 | const struct pci_device_id *id) | ||
112 | { | ||
113 | u8 latency, limit; | ||
114 | __u32 reg_data; | ||
115 | int retry_count; | ||
116 | int length; | ||
117 | int status = 1; | ||
118 | struct usb_hcd *hcd; | ||
119 | |||
120 | if (usb_disabled()) | ||
121 | return -ENODEV; | ||
122 | |||
123 | if (pci_enable_device(dev) < 0) | ||
124 | return -ENODEV; | ||
125 | |||
126 | if (!dev->irq) | ||
127 | return -ENODEV; | ||
128 | |||
129 | /* Grab the PLX PCI mem maped port start address we need */ | ||
130 | nxp_pci_io_base = pci_resource_start(dev, 0); | ||
131 | iolength = pci_resource_len(dev, 0); | ||
132 | |||
133 | if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { | ||
134 | printk(KERN_ERR "request region #1\n"); | ||
135 | return -EBUSY; | ||
136 | } | ||
137 | |||
138 | iobase = ioremap_nocache(nxp_pci_io_base, iolength); | ||
139 | if (!iobase) { | ||
140 | printk(KERN_ERR "ioremap #1\n"); | ||
141 | release_mem_region(nxp_pci_io_base, iolength); | ||
142 | return -ENOMEM; | ||
143 | } | ||
144 | /* Grab the PLX PCI shared memory of the ISP 1761 we need */ | ||
145 | pci_mem_phy0 = pci_resource_start(dev, 3); | ||
146 | length = pci_resource_len(dev, 3); | ||
147 | |||
148 | if (length < 0xffff) { | ||
149 | printk(KERN_ERR "memory length for this resource is less than " | ||
150 | "required\n"); | ||
151 | release_mem_region(nxp_pci_io_base, iolength); | ||
152 | iounmap(iobase); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | |||
156 | if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { | ||
157 | printk(KERN_ERR "host controller already in use\n"); | ||
158 | release_mem_region(nxp_pci_io_base, iolength); | ||
159 | iounmap(iobase); | ||
160 | return -EBUSY; | ||
161 | } | ||
162 | |||
163 | /* bad pci latencies can contribute to overruns */ | ||
164 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); | ||
165 | if (latency) { | ||
166 | pci_read_config_byte(dev, PCI_MAX_LAT, &limit); | ||
167 | if (limit && limit < latency) | ||
168 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); | ||
169 | } | ||
170 | |||
171 | /* Try to check whether we can access Scratch Register of | ||
172 | * Host Controller or not. The initial PCI access is retried until | ||
173 | * local init for the PCI bridge is completed | ||
174 | */ | ||
175 | retry_count = 20; | ||
176 | reg_data = 0; | ||
177 | while ((reg_data != 0xFACE) && retry_count) { | ||
178 | /*by default host is in 16bit mode, so | ||
179 | * io operations at this stage must be 16 bit | ||
180 | * */ | ||
181 | writel(0xface, chip_addr + HC_SCRATCH_REG); | ||
182 | udelay(100); | ||
183 | reg_data = readl(chip_addr + HC_SCRATCH_REG); | ||
184 | retry_count--; | ||
185 | } | ||
186 | |||
187 | /* Host Controller presence is detected by writing to scratch register | ||
188 | * and reading back and checking the contents are same or not | ||
189 | */ | ||
190 | if (reg_data != 0xFACE) { | ||
191 | err("scratch register mismatch %x", reg_data); | ||
192 | goto clean; | ||
193 | } | ||
194 | |||
195 | pci_set_master(dev); | ||
196 | |||
197 | status = readl(iobase + 0x68); | ||
198 | status |= 0x900; | ||
199 | writel(status, iobase + 0x68); | ||
200 | |||
201 | dev->dev.dma_mask = NULL; | ||
202 | hcd = isp1760_register(pci_mem_phy0, length, dev->irq, | ||
203 | IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); | ||
204 | pci_set_drvdata(dev, hcd); | ||
205 | if (!hcd) | ||
206 | return 0; | ||
207 | clean: | ||
208 | status = -ENODEV; | ||
209 | iounmap(iobase); | ||
210 | release_mem_region(pci_mem_phy0, length); | ||
211 | release_mem_region(nxp_pci_io_base, iolength); | ||
212 | return status; | ||
213 | } | ||
214 | static void isp1761_pci_remove(struct pci_dev *dev) | ||
215 | { | ||
216 | struct usb_hcd *hcd; | ||
217 | |||
218 | hcd = pci_get_drvdata(dev); | ||
219 | |||
220 | usb_remove_hcd(hcd); | ||
221 | iounmap(hcd->regs); | ||
222 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
223 | usb_put_hcd(hcd); | ||
224 | |||
225 | pci_disable_device(dev); | ||
226 | |||
227 | iounmap(iobase); | ||
228 | iounmap(chip_addr); | ||
229 | |||
230 | release_mem_region(nxp_pci_io_base, iolength); | ||
231 | release_mem_region(pci_mem_phy0, length); | ||
232 | } | ||
233 | |||
234 | static void isp1761_pci_shutdown(struct pci_dev *dev) | ||
235 | { | ||
236 | printk(KERN_ERR "ips1761_pci_shutdown\n"); | ||
237 | } | ||
238 | |||
239 | static const struct pci_device_id isp1760_plx [] = { { | ||
240 | /* handle any USB 2.0 EHCI controller */ | ||
241 | PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), | ||
242 | .driver_data = 0, | ||
243 | }, | ||
244 | { /* end: all zeroes */ } | ||
245 | }; | ||
246 | MODULE_DEVICE_TABLE(pci, isp1760_plx); | ||
247 | |||
248 | static struct pci_driver isp1761_pci_driver = { | ||
249 | .name = "isp1760", | ||
250 | .id_table = isp1760_plx, | ||
251 | .probe = isp1761_pci_probe, | ||
252 | .remove = isp1761_pci_remove, | ||
253 | .shutdown = isp1761_pci_shutdown, | ||
254 | }; | ||
255 | #endif | ||
256 | |||
257 | static int __init isp1760_init(void) | ||
258 | { | ||
259 | int ret = -ENODEV; | ||
260 | |||
261 | init_kmem_once(); | ||
262 | |||
263 | #ifdef CONFIG_USB_ISP1760_OF | ||
264 | ret = of_register_platform_driver(&isp1760_of_driver); | ||
265 | if (ret) { | ||
266 | deinit_kmem_cache(); | ||
267 | return ret; | ||
268 | } | ||
269 | #endif | ||
270 | #ifdef CONFIG_USB_ISP1760_PCI | ||
271 | ret = pci_register_driver(&isp1761_pci_driver); | ||
272 | if (ret) | ||
273 | goto unreg_of; | ||
274 | #endif | ||
275 | return ret; | ||
276 | |||
277 | #ifdef CONFIG_USB_ISP1760_PCI | ||
278 | unreg_of: | ||
279 | #endif | ||
280 | #ifdef CONFIG_USB_ISP1760_OF | ||
281 | of_unregister_platform_driver(&isp1760_of_driver); | ||
282 | #endif | ||
283 | deinit_kmem_cache(); | ||
284 | return ret; | ||
285 | } | ||
286 | module_init(isp1760_init); | ||
287 | |||
288 | static void __exit isp1760_exit(void) | ||
289 | { | ||
290 | #ifdef CONFIG_USB_ISP1760_OF | ||
291 | of_unregister_platform_driver(&isp1760_of_driver); | ||
292 | #endif | ||
293 | #ifdef CONFIG_USB_ISP1760_PCI | ||
294 | pci_unregister_driver(&isp1761_pci_driver); | ||
295 | #endif | ||
296 | deinit_kmem_cache(); | ||
297 | } | ||
298 | module_exit(isp1760_exit); | ||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index c96db1153dcf..e534f9de0f05 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -261,6 +261,7 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
261 | */ | 261 | */ |
262 | .hub_status_data = ohci_hub_status_data, | 262 | .hub_status_data = ohci_hub_status_data, |
263 | .hub_control = ohci_hub_control, | 263 | .hub_control = ohci_hub_control, |
264 | .hub_irq_enable = ohci_rhsc_enable, | ||
264 | #ifdef CONFIG_PM | 265 | #ifdef CONFIG_PM |
265 | .bus_suspend = ohci_bus_suspend, | 266 | .bus_suspend = ohci_bus_suspend, |
266 | .bus_resume = ohci_bus_resume, | 267 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 1b9abdba920b..f90fe0c7373f 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -288,6 +288,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
288 | */ | 288 | */ |
289 | .hub_status_data = ohci_hub_status_data, | 289 | .hub_status_data = ohci_hub_status_data, |
290 | .hub_control = ohci_hub_control, | 290 | .hub_control = ohci_hub_control, |
291 | .hub_irq_enable = ohci_rhsc_enable, | ||
291 | #ifdef CONFIG_PM | 292 | #ifdef CONFIG_PM |
292 | .bus_suspend = ohci_bus_suspend, | 293 | .bus_suspend = ohci_bus_suspend, |
293 | .bus_resume = ohci_bus_resume, | 294 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 06aadfb0ec29..5adaf36e47d0 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -135,6 +135,7 @@ static struct hc_driver ohci_ep93xx_hc_driver = { | |||
135 | .get_frame_number = ohci_get_frame, | 135 | .get_frame_number = ohci_get_frame, |
136 | .hub_status_data = ohci_hub_status_data, | 136 | .hub_status_data = ohci_hub_status_data, |
137 | .hub_control = ohci_hub_control, | 137 | .hub_control = ohci_hub_control, |
138 | .hub_irq_enable = ohci_rhsc_enable, | ||
138 | #ifdef CONFIG_PM | 139 | #ifdef CONFIG_PM |
139 | .bus_suspend = ohci_bus_suspend, | 140 | .bus_suspend = ohci_bus_suspend, |
140 | .bus_resume = ohci_bus_resume, | 141 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 33f1c1c32edf..a8160d65f32b 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1054,7 +1054,7 @@ MODULE_LICENSE ("GPL"); | |||
1054 | 1054 | ||
1055 | #ifdef CONFIG_MFD_SM501 | 1055 | #ifdef CONFIG_MFD_SM501 |
1056 | #include "ohci-sm501.c" | 1056 | #include "ohci-sm501.c" |
1057 | #define PLATFORM_DRIVER ohci_hcd_sm501_driver | 1057 | #define SM501_OHCI_DRIVER ohci_hcd_sm501_driver |
1058 | #endif | 1058 | #endif |
1059 | 1059 | ||
1060 | #if !defined(PCI_DRIVER) && \ | 1060 | #if !defined(PCI_DRIVER) && \ |
@@ -1062,6 +1062,7 @@ MODULE_LICENSE ("GPL"); | |||
1062 | !defined(OF_PLATFORM_DRIVER) && \ | 1062 | !defined(OF_PLATFORM_DRIVER) && \ |
1063 | !defined(SA1111_DRIVER) && \ | 1063 | !defined(SA1111_DRIVER) && \ |
1064 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ | 1064 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ |
1065 | !defined(SM501_OHCI_DRIVER) && \ | ||
1065 | !defined(SSB_OHCI_DRIVER) | 1066 | !defined(SSB_OHCI_DRIVER) |
1066 | #error "missing bus glue for ohci-hcd" | 1067 | #error "missing bus glue for ohci-hcd" |
1067 | #endif | 1068 | #endif |
@@ -1121,9 +1122,18 @@ static int __init ohci_hcd_mod_init(void) | |||
1121 | goto error_ssb; | 1122 | goto error_ssb; |
1122 | #endif | 1123 | #endif |
1123 | 1124 | ||
1125 | #ifdef SM501_OHCI_DRIVER | ||
1126 | retval = platform_driver_register(&SM501_OHCI_DRIVER); | ||
1127 | if (retval < 0) | ||
1128 | goto error_sm501; | ||
1129 | #endif | ||
1130 | |||
1124 | return retval; | 1131 | return retval; |
1125 | 1132 | ||
1126 | /* Error path */ | 1133 | /* Error path */ |
1134 | #ifdef SM501_OHCI_DRIVER | ||
1135 | error_sm501: | ||
1136 | #endif | ||
1127 | #ifdef SSB_OHCI_DRIVER | 1137 | #ifdef SSB_OHCI_DRIVER |
1128 | error_ssb: | 1138 | error_ssb: |
1129 | #endif | 1139 | #endif |
@@ -1159,6 +1169,9 @@ module_init(ohci_hcd_mod_init); | |||
1159 | 1169 | ||
1160 | static void __exit ohci_hcd_mod_exit(void) | 1170 | static void __exit ohci_hcd_mod_exit(void) |
1161 | { | 1171 | { |
1172 | #ifdef SM501_OHCI_DRIVER | ||
1173 | platform_driver_unregister(&SM501_OHCI_DRIVER); | ||
1174 | #endif | ||
1162 | #ifdef SSB_OHCI_DRIVER | 1175 | #ifdef SSB_OHCI_DRIVER |
1163 | ssb_driver_unregister(&SSB_OHCI_DRIVER); | 1176 | ssb_driver_unregister(&SSB_OHCI_DRIVER); |
1164 | #endif | 1177 | #endif |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 17dc2eccda83..b56739221d11 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -36,6 +36,18 @@ | |||
36 | 36 | ||
37 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
38 | 38 | ||
39 | /* hcd->hub_irq_enable() */ | ||
40 | static void ohci_rhsc_enable (struct usb_hcd *hcd) | ||
41 | { | ||
42 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
43 | |||
44 | spin_lock_irq(&ohci->lock); | ||
45 | if (!ohci->autostop) | ||
46 | del_timer(&hcd->rh_timer); /* Prevent next poll */ | ||
47 | ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); | ||
48 | spin_unlock_irq(&ohci->lock); | ||
49 | } | ||
50 | |||
39 | #define OHCI_SCHED_ENABLES \ | 51 | #define OHCI_SCHED_ENABLES \ |
40 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) | 52 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) |
41 | 53 | ||
@@ -362,28 +374,18 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, | |||
362 | int any_connected) | 374 | int any_connected) |
363 | { | 375 | { |
364 | int poll_rh = 1; | 376 | int poll_rh = 1; |
365 | int rhsc; | ||
366 | 377 | ||
367 | rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC; | ||
368 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 378 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
369 | 379 | ||
370 | case OHCI_USB_OPER: | 380 | case OHCI_USB_OPER: |
371 | /* If no status changes are pending, enable status-change | 381 | /* keep on polling until we know a device is connected |
372 | * interrupts. | 382 | * and RHSC is enabled */ |
373 | */ | ||
374 | if (!rhsc && !changed) { | ||
375 | rhsc = OHCI_INTR_RHSC; | ||
376 | ohci_writel(ohci, rhsc, &ohci->regs->intrenable); | ||
377 | } | ||
378 | |||
379 | /* Keep on polling until we know a device is connected | ||
380 | * and RHSC is enabled, or until we autostop. | ||
381 | */ | ||
382 | if (!ohci->autostop) { | 383 | if (!ohci->autostop) { |
383 | if (any_connected || | 384 | if (any_connected || |
384 | !device_may_wakeup(&ohci_to_hcd(ohci) | 385 | !device_may_wakeup(&ohci_to_hcd(ohci) |
385 | ->self.root_hub->dev)) { | 386 | ->self.root_hub->dev)) { |
386 | if (rhsc) | 387 | if (ohci_readl(ohci, &ohci->regs->intrenable) & |
388 | OHCI_INTR_RHSC) | ||
387 | poll_rh = 0; | 389 | poll_rh = 0; |
388 | } else { | 390 | } else { |
389 | ohci->autostop = 1; | 391 | ohci->autostop = 1; |
@@ -396,13 +398,12 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, | |||
396 | ohci->autostop = 0; | 398 | ohci->autostop = 0; |
397 | ohci->next_statechange = jiffies + | 399 | ohci->next_statechange = jiffies + |
398 | STATECHANGE_DELAY; | 400 | STATECHANGE_DELAY; |
399 | } else if (rhsc && time_after_eq(jiffies, | 401 | } else if (time_after_eq(jiffies, |
400 | ohci->next_statechange) | 402 | ohci->next_statechange) |
401 | && !ohci->ed_rm_list | 403 | && !ohci->ed_rm_list |
402 | && !(ohci->hc_control & | 404 | && !(ohci->hc_control & |
403 | OHCI_SCHED_ENABLES)) { | 405 | OHCI_SCHED_ENABLES)) { |
404 | ohci_rh_suspend(ohci, 1); | 406 | ohci_rh_suspend(ohci, 1); |
405 | poll_rh = 0; | ||
406 | } | 407 | } |
407 | } | 408 | } |
408 | break; | 409 | break; |
@@ -416,12 +417,6 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, | |||
416 | else | 417 | else |
417 | usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); | 418 | usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); |
418 | } else { | 419 | } else { |
419 | if (!rhsc && (ohci->autostop || | ||
420 | ohci_to_hcd(ohci)->self.root_hub-> | ||
421 | do_remote_wakeup)) | ||
422 | ohci_writel(ohci, OHCI_INTR_RHSC, | ||
423 | &ohci->regs->intrenable); | ||
424 | |||
425 | /* everything is idle, no need for polling */ | 420 | /* everything is idle, no need for polling */ |
426 | poll_rh = 0; | 421 | poll_rh = 0; |
427 | } | 422 | } |
@@ -443,16 +438,12 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci) | |||
443 | static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, | 438 | static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, |
444 | int any_connected) | 439 | int any_connected) |
445 | { | 440 | { |
446 | /* If RHSC is enabled, don't poll */ | 441 | int poll_rh = 1; |
447 | if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) | ||
448 | return 0; | ||
449 | 442 | ||
450 | /* If no status changes are pending, enable status-change interrupts */ | 443 | /* keep on polling until RHSC is enabled */ |
451 | if (!changed) { | 444 | if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) |
452 | ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); | 445 | poll_rh = 0; |
453 | return 0; | 446 | return poll_rh; |
454 | } | ||
455 | return 1; | ||
456 | } | 447 | } |
457 | 448 | ||
458 | #endif /* CONFIG_PM */ | 449 | #endif /* CONFIG_PM */ |
@@ -613,7 +604,7 @@ static void start_hnp(struct ohci_hcd *ohci); | |||
613 | static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) | 604 | static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) |
614 | { | 605 | { |
615 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; | 606 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; |
616 | u32 temp; | 607 | u32 temp = 0; |
617 | u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); | 608 | u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); |
618 | u16 reset_done = now + PORT_RESET_MSEC; | 609 | u16 reset_done = now + PORT_RESET_MSEC; |
619 | int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC); | 610 | int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC); |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 96d14fa1d833..13c12ed22252 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -193,6 +193,7 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
193 | */ | 193 | */ |
194 | .hub_status_data = ohci_hub_status_data, | 194 | .hub_status_data = ohci_hub_status_data, |
195 | .hub_control = ohci_hub_control, | 195 | .hub_control = ohci_hub_control, |
196 | .hub_irq_enable = ohci_rhsc_enable, | ||
196 | #ifdef CONFIG_PM | 197 | #ifdef CONFIG_PM |
197 | .bus_suspend = ohci_bus_suspend, | 198 | .bus_suspend = ohci_bus_suspend, |
198 | .bus_resume = ohci_bus_resume, | 199 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 6859fb5f1d6f..3a7c24c03671 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -466,6 +466,7 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
466 | */ | 466 | */ |
467 | .hub_status_data = ohci_hub_status_data, | 467 | .hub_status_data = ohci_hub_status_data, |
468 | .hub_control = ohci_hub_control, | 468 | .hub_control = ohci_hub_control, |
469 | .hub_irq_enable = ohci_rhsc_enable, | ||
469 | #ifdef CONFIG_PM | 470 | #ifdef CONFIG_PM |
470 | .bus_suspend = ohci_bus_suspend, | 471 | .bus_suspend = ohci_bus_suspend, |
471 | .bus_resume = ohci_bus_resume, | 472 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 3bf175d95a23..4696cc912e16 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -327,6 +327,7 @@ static const struct hc_driver ohci_pci_hc_driver = { | |||
327 | */ | 327 | */ |
328 | .hub_status_data = ohci_hub_status_data, | 328 | .hub_status_data = ohci_hub_status_data, |
329 | .hub_control = ohci_hub_control, | 329 | .hub_control = ohci_hub_control, |
330 | .hub_irq_enable = ohci_rhsc_enable, | ||
330 | #ifdef CONFIG_PM | 331 | #ifdef CONFIG_PM |
331 | .bus_suspend = ohci_bus_suspend, | 332 | .bus_suspend = ohci_bus_suspend, |
332 | .bus_resume = ohci_bus_resume, | 333 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 664f07ee8732..28b458f20cc3 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -280,6 +280,7 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { | |||
280 | */ | 280 | */ |
281 | .hub_status_data = ohci_hub_status_data, | 281 | .hub_status_data = ohci_hub_status_data, |
282 | .hub_control = ohci_hub_control, | 282 | .hub_control = ohci_hub_control, |
283 | .hub_irq_enable = ohci_rhsc_enable, | ||
283 | #ifdef CONFIG_PM | 284 | #ifdef CONFIG_PM |
284 | .bus_suspend = ohci_bus_suspend, | 285 | .bus_suspend = ohci_bus_suspend, |
285 | .bus_resume = ohci_bus_resume, | 286 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c index 28467e288a93..605d59cba28e 100644 --- a/drivers/usb/host/ohci-pnx8550.c +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -201,6 +201,7 @@ static const struct hc_driver ohci_pnx8550_hc_driver = { | |||
201 | */ | 201 | */ |
202 | .hub_status_data = ohci_hub_status_data, | 202 | .hub_status_data = ohci_hub_status_data, |
203 | .hub_control = ohci_hub_control, | 203 | .hub_control = ohci_hub_control, |
204 | .hub_irq_enable = ohci_rhsc_enable, | ||
204 | #ifdef CONFIG_PM | 205 | #ifdef CONFIG_PM |
205 | .bus_suspend = ohci_bus_suspend, | 206 | .bus_suspend = ohci_bus_suspend, |
206 | .bus_resume = ohci_bus_resume, | 207 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 50e55db13636..a67252791223 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -72,6 +72,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { | |||
72 | */ | 72 | */ |
73 | .hub_status_data = ohci_hub_status_data, | 73 | .hub_status_data = ohci_hub_status_data, |
74 | .hub_control = ohci_hub_control, | 74 | .hub_control = ohci_hub_control, |
75 | .hub_irq_enable = ohci_rhsc_enable, | ||
75 | #ifdef CONFIG_PM | 76 | #ifdef CONFIG_PM |
76 | .bus_suspend = ohci_bus_suspend, | 77 | .bus_suspend = ohci_bus_suspend, |
77 | .bus_resume = ohci_bus_resume, | 78 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index cd3398b675b2..523c30125577 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -172,6 +172,7 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
172 | */ | 172 | */ |
173 | .hub_status_data = ohci_hub_status_data, | 173 | .hub_status_data = ohci_hub_status_data, |
174 | .hub_control = ohci_hub_control, | 174 | .hub_control = ohci_hub_control, |
175 | .hub_irq_enable = ohci_rhsc_enable, | ||
175 | #ifdef CONFIG_PM | 176 | #ifdef CONFIG_PM |
176 | .bus_suspend = ohci_bus_suspend, | 177 | .bus_suspend = ohci_bus_suspend, |
177 | .bus_resume = ohci_bus_resume, | 178 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index bfdeb0d22d05..c1935ae537f8 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c | |||
@@ -68,6 +68,7 @@ static const struct hc_driver ps3_ohci_hc_driver = { | |||
68 | .get_frame_number = ohci_get_frame, | 68 | .get_frame_number = ohci_get_frame, |
69 | .hub_status_data = ohci_hub_status_data, | 69 | .hub_status_data = ohci_hub_status_data, |
70 | .hub_control = ohci_hub_control, | 70 | .hub_control = ohci_hub_control, |
71 | .hub_irq_enable = ohci_rhsc_enable, | ||
71 | .start_port_reset = ohci_start_port_reset, | 72 | .start_port_reset = ohci_start_port_reset, |
72 | #if defined(CONFIG_PM) | 73 | #if defined(CONFIG_PM) |
73 | .bus_suspend = ohci_bus_suspend, | 74 | .bus_suspend = ohci_bus_suspend, |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 70b0d4b459e7..d4ee27d92be8 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -298,6 +298,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
298 | */ | 298 | */ |
299 | .hub_status_data = ohci_hub_status_data, | 299 | .hub_status_data = ohci_hub_status_data, |
300 | .hub_control = ohci_hub_control, | 300 | .hub_control = ohci_hub_control, |
301 | .hub_irq_enable = ohci_rhsc_enable, | ||
301 | #ifdef CONFIG_PM | 302 | #ifdef CONFIG_PM |
302 | .bus_suspend = ohci_bus_suspend, | 303 | .bus_suspend = ohci_bus_suspend, |
303 | .bus_resume = ohci_bus_resume, | 304 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 9c9f3b59186f..9b547407c934 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -952,6 +952,7 @@ rescan_this: | |||
952 | struct urb *urb; | 952 | struct urb *urb; |
953 | urb_priv_t *urb_priv; | 953 | urb_priv_t *urb_priv; |
954 | __hc32 savebits; | 954 | __hc32 savebits; |
955 | u32 tdINFO; | ||
955 | 956 | ||
956 | td = list_entry (entry, struct td, td_list); | 957 | td = list_entry (entry, struct td, td_list); |
957 | urb = td->urb; | 958 | urb = td->urb; |
@@ -966,6 +967,17 @@ rescan_this: | |||
966 | savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK); | 967 | savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK); |
967 | *prev = td->hwNextTD | savebits; | 968 | *prev = td->hwNextTD | savebits; |
968 | 969 | ||
970 | /* If this was unlinked, the TD may not have been | ||
971 | * retired ... so manually save the data toggle. | ||
972 | * The controller ignores the value we save for | ||
973 | * control and ISO endpoints. | ||
974 | */ | ||
975 | tdINFO = hc32_to_cpup(ohci, &td->hwINFO); | ||
976 | if ((tdINFO & TD_T) == TD_T_DATA0) | ||
977 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_C); | ||
978 | else if ((tdINFO & TD_T) == TD_T_DATA1) | ||
979 | ed->hwHeadP |= cpu_to_hc32(ohci, ED_C); | ||
980 | |||
969 | /* HC may have partly processed this TD */ | 981 | /* HC may have partly processed this TD */ |
970 | td_done (ohci, urb, td); | 982 | td_done (ohci, urb, td); |
971 | urb_priv->td_cnt++; | 983 | urb_priv->td_cnt++; |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index a73d2ff322e2..ead4772f0f27 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -466,6 +466,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
466 | */ | 466 | */ |
467 | .hub_status_data = ohci_s3c2410_hub_status_data, | 467 | .hub_status_data = ohci_s3c2410_hub_status_data, |
468 | .hub_control = ohci_s3c2410_hub_control, | 468 | .hub_control = ohci_s3c2410_hub_control, |
469 | .hub_irq_enable = ohci_rhsc_enable, | ||
469 | #ifdef CONFIG_PM | 470 | #ifdef CONFIG_PM |
470 | .bus_suspend = ohci_bus_suspend, | 471 | .bus_suspend = ohci_bus_suspend, |
471 | .bus_resume = ohci_bus_resume, | 472 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 99438c65981b..0f48f2d99226 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -231,6 +231,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = { | |||
231 | */ | 231 | */ |
232 | .hub_status_data = ohci_hub_status_data, | 232 | .hub_status_data = ohci_hub_status_data, |
233 | .hub_control = ohci_hub_control, | 233 | .hub_control = ohci_hub_control, |
234 | .hub_irq_enable = ohci_rhsc_enable, | ||
234 | #ifdef CONFIG_PM | 235 | #ifdef CONFIG_PM |
235 | .bus_suspend = ohci_bus_suspend, | 236 | .bus_suspend = ohci_bus_suspend, |
236 | .bus_resume = ohci_bus_resume, | 237 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index 60f03cc7ec4f..e7ee607278fe 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c | |||
@@ -68,6 +68,7 @@ static const struct hc_driver ohci_sh_hc_driver = { | |||
68 | */ | 68 | */ |
69 | .hub_status_data = ohci_hub_status_data, | 69 | .hub_status_data = ohci_hub_status_data, |
70 | .hub_control = ohci_hub_control, | 70 | .hub_control = ohci_hub_control, |
71 | .hub_irq_enable = ohci_rhsc_enable, | ||
71 | #ifdef CONFIG_PM | 72 | #ifdef CONFIG_PM |
72 | .bus_suspend = ohci_bus_suspend, | 73 | .bus_suspend = ohci_bus_suspend, |
73 | .bus_resume = ohci_bus_resume, | 74 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 77204f001b9a..e610698c6b60 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -75,6 +75,7 @@ static const struct hc_driver ohci_sm501_hc_driver = { | |||
75 | */ | 75 | */ |
76 | .hub_status_data = ohci_hub_status_data, | 76 | .hub_status_data = ohci_hub_status_data, |
77 | .hub_control = ohci_hub_control, | 77 | .hub_control = ohci_hub_control, |
78 | .hub_irq_enable = ohci_rhsc_enable, | ||
78 | #ifdef CONFIG_PM | 79 | #ifdef CONFIG_PM |
79 | .bus_suspend = ohci_bus_suspend, | 80 | .bus_suspend = ohci_bus_suspend, |
80 | .bus_resume = ohci_bus_resume, | 81 | .bus_resume = ohci_bus_resume, |
@@ -90,7 +91,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | |||
90 | struct device *dev = &pdev->dev; | 91 | struct device *dev = &pdev->dev; |
91 | struct resource *res, *mem; | 92 | struct resource *res, *mem; |
92 | int retval, irq; | 93 | int retval, irq; |
93 | struct usb_hcd *hcd = 0; | 94 | struct usb_hcd *hcd = NULL; |
94 | 95 | ||
95 | irq = retval = platform_get_irq(pdev, 0); | 96 | irq = retval = platform_get_irq(pdev, 0); |
96 | if (retval < 0) | 97 | if (retval < 0) |
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index c4265caec780..7275186db315 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c | |||
@@ -81,6 +81,7 @@ static const struct hc_driver ssb_ohci_hc_driver = { | |||
81 | 81 | ||
82 | .hub_status_data = ohci_hub_status_data, | 82 | .hub_status_data = ohci_hub_status_data, |
83 | .hub_control = ohci_hub_control, | 83 | .hub_control = ohci_hub_control, |
84 | .hub_irq_enable = ohci_rhsc_enable, | ||
84 | #ifdef CONFIG_PM | 85 | #ifdef CONFIG_PM |
85 | .bus_suspend = ohci_bus_suspend, | 86 | .bus_suspend = ohci_bus_suspend, |
86 | .bus_resume = ohci_bus_resume, | 87 | .bus_resume = ohci_bus_resume, |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index f29307405bb3..9b6323f768b2 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -2934,6 +2934,16 @@ static int u132_start_port_reset(struct usb_hcd *hcd, unsigned port_num) | |||
2934 | return 0; | 2934 | return 0; |
2935 | } | 2935 | } |
2936 | 2936 | ||
2937 | static void u132_hub_irq_enable(struct usb_hcd *hcd) | ||
2938 | { | ||
2939 | struct u132 *u132 = hcd_to_u132(hcd); | ||
2940 | if (u132->going > 1) { | ||
2941 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | ||
2942 | , u132->going); | ||
2943 | } else if (u132->going > 0) | ||
2944 | dev_err(&u132->platform_dev->dev, "device is being removed\n"); | ||
2945 | } | ||
2946 | |||
2937 | 2947 | ||
2938 | #ifdef CONFIG_PM | 2948 | #ifdef CONFIG_PM |
2939 | static int u132_bus_suspend(struct usb_hcd *hcd) | 2949 | static int u132_bus_suspend(struct usb_hcd *hcd) |
@@ -2985,6 +2995,7 @@ static struct hc_driver u132_hc_driver = { | |||
2985 | .bus_suspend = u132_bus_suspend, | 2995 | .bus_suspend = u132_bus_suspend, |
2986 | .bus_resume = u132_bus_resume, | 2996 | .bus_resume = u132_bus_resume, |
2987 | .start_port_reset = u132_start_port_reset, | 2997 | .start_port_reset = u132_start_port_reset, |
2998 | .hub_irq_enable = u132_hub_irq_enable, | ||
2988 | }; | 2999 | }; |
2989 | 3000 | ||
2990 | /* | 3001 | /* |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index d3e0d8aa3980..3a7bfe7a8874 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -234,7 +234,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) | 237 | static int global_suspend_mode_is_broken(struct uhci_hcd *uhci) |
238 | { | 238 | { |
239 | int port; | 239 | int port; |
240 | const char *sys_info; | 240 | const char *sys_info; |
@@ -261,27 +261,60 @@ __releases(uhci->lock) | |||
261 | __acquires(uhci->lock) | 261 | __acquires(uhci->lock) |
262 | { | 262 | { |
263 | int auto_stop; | 263 | int auto_stop; |
264 | int int_enable, egsm_enable; | 264 | int int_enable, egsm_enable, wakeup_enable; |
265 | struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; | 265 | struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; |
266 | 266 | ||
267 | auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); | 267 | auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); |
268 | dev_dbg(&rhdev->dev, "%s%s\n", __func__, | 268 | dev_dbg(&rhdev->dev, "%s%s\n", __func__, |
269 | (auto_stop ? " (auto-stop)" : "")); | 269 | (auto_stop ? " (auto-stop)" : "")); |
270 | 270 | ||
271 | /* Enable resume-detect interrupts if they work. | 271 | /* Start off by assuming Resume-Detect interrupts and EGSM work |
272 | * Then enter Global Suspend mode if _it_ works, still configured. | 272 | * and that remote wakeups should be enabled. |
273 | */ | 273 | */ |
274 | egsm_enable = USBCMD_EGSM; | 274 | egsm_enable = USBCMD_EGSM; |
275 | uhci->working_RD = 1; | 275 | uhci->RD_enable = 1; |
276 | int_enable = USBINTR_RESUME; | 276 | int_enable = USBINTR_RESUME; |
277 | if (remote_wakeup_is_broken(uhci)) | 277 | wakeup_enable = 1; |
278 | egsm_enable = 0; | 278 | |
279 | if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || | 279 | /* In auto-stop mode wakeups must always be detected, but |
280 | * Resume-Detect interrupts may be prohibited. (In the absence | ||
281 | * of CONFIG_PM, they are always disallowed.) | ||
282 | */ | ||
283 | if (auto_stop) { | ||
284 | if (!device_may_wakeup(&rhdev->dev)) | ||
285 | int_enable = 0; | ||
286 | |||
287 | /* In bus-suspend mode wakeups may be disabled, but if they are | ||
288 | * allowed then so are Resume-Detect interrupts. | ||
289 | */ | ||
290 | } else { | ||
280 | #ifdef CONFIG_PM | 291 | #ifdef CONFIG_PM |
281 | (!auto_stop && !rhdev->do_remote_wakeup) || | 292 | if (!rhdev->do_remote_wakeup) |
293 | wakeup_enable = 0; | ||
282 | #endif | 294 | #endif |
283 | (auto_stop && !device_may_wakeup(&rhdev->dev))) | 295 | } |
284 | uhci->working_RD = int_enable = 0; | 296 | |
297 | /* EGSM causes the root hub to echo a 'K' signal (resume) out any | ||
298 | * port which requests a remote wakeup. According to the USB spec, | ||
299 | * every hub is supposed to do this. But if we are ignoring | ||
300 | * remote-wakeup requests anyway then there's no point to it. | ||
301 | * We also shouldn't enable EGSM if it's broken. | ||
302 | */ | ||
303 | if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) | ||
304 | egsm_enable = 0; | ||
305 | |||
306 | /* If we're ignoring wakeup events then there's no reason to | ||
307 | * enable Resume-Detect interrupts. We also shouldn't enable | ||
308 | * them if they are broken or disallowed. | ||
309 | * | ||
310 | * This logic may lead us to enabling RD but not EGSM. The UHCI | ||
311 | * spec foolishly says that RD works only when EGSM is on, but | ||
312 | * there's no harm in enabling it anyway -- perhaps some chips | ||
313 | * will implement it! | ||
314 | */ | ||
315 | if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || | ||
316 | !int_enable) | ||
317 | uhci->RD_enable = int_enable = 0; | ||
285 | 318 | ||
286 | outw(int_enable, uhci->io_addr + USBINTR); | 319 | outw(int_enable, uhci->io_addr + USBINTR); |
287 | outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); | 320 | outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); |
@@ -308,7 +341,11 @@ __acquires(uhci->lock) | |||
308 | 341 | ||
309 | uhci->rh_state = new_state; | 342 | uhci->rh_state = new_state; |
310 | uhci->is_stopped = UHCI_IS_STOPPED; | 343 | uhci->is_stopped = UHCI_IS_STOPPED; |
311 | uhci_to_hcd(uhci)->poll_rh = !int_enable; | 344 | |
345 | /* If interrupts don't work and remote wakeup is enabled then | ||
346 | * the suspended root hub needs to be polled. | ||
347 | */ | ||
348 | uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable); | ||
312 | 349 | ||
313 | uhci_scan_schedule(uhci); | 350 | uhci_scan_schedule(uhci); |
314 | uhci_fsbr_off(uhci); | 351 | uhci_fsbr_off(uhci); |
@@ -344,9 +381,12 @@ __acquires(uhci->lock) | |||
344 | * for 20 ms. | 381 | * for 20 ms. |
345 | */ | 382 | */ |
346 | if (uhci->rh_state == UHCI_RH_SUSPENDED) { | 383 | if (uhci->rh_state == UHCI_RH_SUSPENDED) { |
384 | unsigned egsm; | ||
385 | |||
386 | /* Keep EGSM on if it was set before */ | ||
387 | egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM; | ||
347 | uhci->rh_state = UHCI_RH_RESUMING; | 388 | uhci->rh_state = UHCI_RH_RESUMING; |
348 | outw(USBCMD_FGR | USBCMD_EGSM | USBCMD_CF, | 389 | outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD); |
349 | uhci->io_addr + USBCMD); | ||
350 | spin_unlock_irq(&uhci->lock); | 390 | spin_unlock_irq(&uhci->lock); |
351 | msleep(20); | 391 | msleep(20); |
352 | spin_lock_irq(&uhci->lock); | 392 | spin_lock_irq(&uhci->lock); |
@@ -801,8 +841,10 @@ static int uhci_pci_resume(struct usb_hcd *hcd) | |||
801 | 841 | ||
802 | spin_unlock_irq(&uhci->lock); | 842 | spin_unlock_irq(&uhci->lock); |
803 | 843 | ||
804 | if (!uhci->working_RD) { | 844 | /* If interrupts don't work and remote wakeup is enabled then |
805 | /* Suspended root hub needs to be polled */ | 845 | * the suspended root hub needs to be polled. |
846 | */ | ||
847 | if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) { | ||
806 | hcd->poll_rh = 1; | 848 | hcd->poll_rh = 1; |
807 | usb_hcd_poll_rh_status(hcd); | 849 | usb_hcd_poll_rh_status(hcd); |
808 | } | 850 | } |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 340d6ed3e6e9..7d01c5677f92 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -400,8 +400,9 @@ struct uhci_hcd { | |||
400 | unsigned int scan_in_progress:1; /* Schedule scan is running */ | 400 | unsigned int scan_in_progress:1; /* Schedule scan is running */ |
401 | unsigned int need_rescan:1; /* Redo the schedule scan */ | 401 | unsigned int need_rescan:1; /* Redo the schedule scan */ |
402 | unsigned int dead:1; /* Controller has died */ | 402 | unsigned int dead:1; /* Controller has died */ |
403 | unsigned int working_RD:1; /* Suspended root hub doesn't | 403 | unsigned int RD_enable:1; /* Suspended root hub with |
404 | need to be polled */ | 404 | Resume-Detect interrupts |
405 | enabled */ | ||
405 | unsigned int is_initialized:1; /* Data structure is usable */ | 406 | unsigned int is_initialized:1; /* Data structure is usable */ |
406 | unsigned int fsbr_is_on:1; /* FSBR is turned on */ | 407 | unsigned int fsbr_is_on:1; /* FSBR is turned on */ |
407 | unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ | 408 | unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index a53db1d4e07a..001789c9a11a 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -269,3 +269,15 @@ config USB_TEST | |||
269 | See <http://www.linux-usb.org/usbtest/> for more information, | 269 | See <http://www.linux-usb.org/usbtest/> for more information, |
270 | including sample test device firmware and "how to use it". | 270 | including sample test device firmware and "how to use it". |
271 | 271 | ||
272 | config USB_ISIGHTFW | ||
273 | tristate "iSight firmware loading support" | ||
274 | depends on USB | ||
275 | select FW_LOADER | ||
276 | help | ||
277 | This driver loads firmware for USB Apple iSight cameras, allowing | ||
278 | them to be driven by the USB video class driver available at | ||
279 | http://linux-uvc.berlios.de | ||
280 | |||
281 | The firmware for this driver must be extracted from the MacOS | ||
282 | driver beforehand. Tools for doing so are available at | ||
283 | http://bersace03.free.fr | ||
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index b68e6b774f1a..aba091cb5ec0 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_EMI62) += emi62.o | |||
14 | obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o | 14 | obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o |
15 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o | 15 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o |
16 | obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o | 16 | obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o |
17 | obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o | ||
17 | obj-$(CONFIG_USB_LCD) += usblcd.o | 18 | obj-$(CONFIG_USB_LCD) += usblcd.o |
18 | obj-$(CONFIG_USB_LD) += ldusb.o | 19 | obj-$(CONFIG_USB_LD) += ldusb.o |
19 | obj-$(CONFIG_USB_LED) += usbled.o | 20 | obj-$(CONFIG_USB_LED) += usbled.o |
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c new file mode 100644 index 000000000000..9f30aa1f8a5d --- /dev/null +++ b/drivers/usb/misc/isight_firmware.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Driver for loading USB isight firmware | ||
3 | * | ||
4 | * Copyright (C) 2008 Matthew Garrett <mjg@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation, version 2. | ||
9 | * | ||
10 | * The USB isight cameras in recent Apples are roughly compatible with the USB | ||
11 | * video class specification, and can be driven by uvcvideo. However, they | ||
12 | * need firmware to be loaded beforehand. After firmware loading, the device | ||
13 | * detaches from the USB bus and reattaches with a new device ID. It can then | ||
14 | * be claimed by the uvc driver. | ||
15 | * | ||
16 | * The firmware is non-free and must be extracted by the user. Tools to do this | ||
17 | * are available at http://bersace03.free.fr/ift/ | ||
18 | * | ||
19 | * The isight firmware loading was reverse engineered by Johannes Berg | ||
20 | * <johannes@sipsolutions.de>, and this driver is based on code by Ronald | ||
21 | * Bultje <rbultje@ronald.bitfreak.net> | ||
22 | */ | ||
23 | |||
24 | #include <linux/usb.h> | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | static struct usb_device_id id_table[] = { | ||
30 | {USB_DEVICE(0x05ac, 0x8300)}, | ||
31 | {}, | ||
32 | }; | ||
33 | |||
34 | MODULE_DEVICE_TABLE(usb, id_table); | ||
35 | |||
36 | static int isight_firmware_load(struct usb_interface *intf, | ||
37 | const struct usb_device_id *id) | ||
38 | { | ||
39 | struct usb_device *dev = interface_to_usbdev(intf); | ||
40 | int llen, len, req, ret = 0; | ||
41 | const struct firmware *firmware; | ||
42 | unsigned char *buf = kmalloc(50, GFP_KERNEL); | ||
43 | unsigned char data[4]; | ||
44 | u8 *ptr; | ||
45 | |||
46 | if (!buf) | ||
47 | return -ENOMEM; | ||
48 | |||
49 | if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { | ||
50 | printk(KERN_ERR "Unable to load isight firmware\n"); | ||
51 | return -ENODEV; | ||
52 | } | ||
53 | |||
54 | ptr = firmware->data; | ||
55 | |||
56 | if (usb_control_msg | ||
57 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, | ||
58 | 300) != 1) { | ||
59 | printk(KERN_ERR | ||
60 | "Failed to initialise isight firmware loader\n"); | ||
61 | ret = -ENODEV; | ||
62 | goto out; | ||
63 | } | ||
64 | |||
65 | while (ptr+4 <= firmware->data+firmware->size) { | ||
66 | memcpy(data, ptr, 4); | ||
67 | len = (data[0] << 8 | data[1]); | ||
68 | req = (data[2] << 8 | data[3]); | ||
69 | ptr += 4; | ||
70 | |||
71 | if (len == 0x8001) | ||
72 | break; /* success */ | ||
73 | else if (len == 0) | ||
74 | continue; | ||
75 | |||
76 | for (; len > 0; req += 50) { | ||
77 | llen = min(len, 50); | ||
78 | len -= llen; | ||
79 | if (ptr+llen > firmware->data+firmware->size) { | ||
80 | printk(KERN_ERR | ||
81 | "Malformed isight firmware"); | ||
82 | ret = -ENODEV; | ||
83 | goto out; | ||
84 | } | ||
85 | memcpy(buf, ptr, llen); | ||
86 | |||
87 | ptr += llen; | ||
88 | |||
89 | if (usb_control_msg | ||
90 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0, | ||
91 | buf, llen, 300) != llen) { | ||
92 | printk(KERN_ERR | ||
93 | "Failed to load isight firmware\n"); | ||
94 | kfree(buf); | ||
95 | ret = -ENODEV; | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | } | ||
100 | } | ||
101 | |||
102 | if (usb_control_msg | ||
103 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, | ||
104 | 300) != 1) { | ||
105 | printk(KERN_ERR "isight firmware loading completion failed\n"); | ||
106 | ret = -ENODEV; | ||
107 | } | ||
108 | |||
109 | out: | ||
110 | kfree(buf); | ||
111 | release_firmware(firmware); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | static void isight_firmware_disconnect(struct usb_interface *intf) | ||
116 | { | ||
117 | } | ||
118 | |||
119 | static struct usb_driver isight_firmware_driver = { | ||
120 | .name = "isight_firmware", | ||
121 | .probe = isight_firmware_load, | ||
122 | .disconnect = isight_firmware_disconnect, | ||
123 | .id_table = id_table, | ||
124 | }; | ||
125 | |||
126 | static int __init isight_firmware_init(void) | ||
127 | { | ||
128 | return usb_register(&isight_firmware_driver); | ||
129 | } | ||
130 | |||
131 | static void __exit isight_firmware_exit(void) | ||
132 | { | ||
133 | usb_deregister(&isight_firmware_driver); | ||
134 | } | ||
135 | |||
136 | module_init(isight_firmware_init); | ||
137 | module_exit(isight_firmware_exit); | ||
138 | |||
139 | MODULE_LICENSE("GPL"); | ||
140 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | ||
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 11580e81e2c6..189a9db03509 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -63,9 +63,6 @@ | |||
63 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 63 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
64 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 | 64 | #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 |
65 | 65 | ||
66 | #define USB_VENDOR_ID_MICROCHIP 0x04d8 | ||
67 | #define USB_DEVICE_ID_PICDEM 0x000c | ||
68 | |||
69 | #ifdef CONFIG_USB_DYNAMIC_MINORS | 66 | #ifdef CONFIG_USB_DYNAMIC_MINORS |
70 | #define USB_LD_MINOR_BASE 0 | 67 | #define USB_LD_MINOR_BASE 0 |
71 | #else | 68 | #else |
@@ -92,7 +89,6 @@ static struct usb_device_id ld_usb_table [] = { | |||
92 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 89 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
93 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 90 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
94 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | 91 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, |
95 | { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, | ||
96 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, | 92 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, |
97 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
98 | }; | 94 | }; |
@@ -148,7 +144,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in | |||
148 | 144 | ||
149 | /* Structure to hold all of our device specific stuff */ | 145 | /* Structure to hold all of our device specific stuff */ |
150 | struct ld_usb { | 146 | struct ld_usb { |
151 | struct semaphore sem; /* locks this structure */ | 147 | struct mutex mutex; /* locks this structure */ |
152 | struct usb_interface* intf; /* save off the usb interface pointer */ | 148 | struct usb_interface* intf; /* save off the usb interface pointer */ |
153 | 149 | ||
154 | int open_count; /* number of times this port has been opened */ | 150 | int open_count; /* number of times this port has been opened */ |
@@ -319,7 +315,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) | |||
319 | return -ENODEV; | 315 | return -ENODEV; |
320 | 316 | ||
321 | /* lock this device */ | 317 | /* lock this device */ |
322 | if (down_interruptible(&dev->sem)) | 318 | if (mutex_lock_interruptible(&dev->mutex)) |
323 | return -ERESTARTSYS; | 319 | return -ERESTARTSYS; |
324 | 320 | ||
325 | /* allow opening only once */ | 321 | /* allow opening only once */ |
@@ -358,7 +354,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) | |||
358 | file->private_data = dev; | 354 | file->private_data = dev; |
359 | 355 | ||
360 | unlock_exit: | 356 | unlock_exit: |
361 | up(&dev->sem); | 357 | mutex_unlock(&dev->mutex); |
362 | 358 | ||
363 | return retval; | 359 | return retval; |
364 | } | 360 | } |
@@ -378,7 +374,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) | |||
378 | goto exit; | 374 | goto exit; |
379 | } | 375 | } |
380 | 376 | ||
381 | if (down_interruptible(&dev->sem)) { | 377 | if (mutex_lock_interruptible(&dev->mutex)) { |
382 | retval = -ERESTARTSYS; | 378 | retval = -ERESTARTSYS; |
383 | goto exit; | 379 | goto exit; |
384 | } | 380 | } |
@@ -389,7 +385,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) | |||
389 | } | 385 | } |
390 | if (dev->intf == NULL) { | 386 | if (dev->intf == NULL) { |
391 | /* the device was unplugged before the file was released */ | 387 | /* the device was unplugged before the file was released */ |
392 | up(&dev->sem); | 388 | mutex_unlock(&dev->mutex); |
393 | /* unlock here as ld_usb_delete frees dev */ | 389 | /* unlock here as ld_usb_delete frees dev */ |
394 | ld_usb_delete(dev); | 390 | ld_usb_delete(dev); |
395 | goto exit; | 391 | goto exit; |
@@ -402,7 +398,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) | |||
402 | dev->open_count = 0; | 398 | dev->open_count = 0; |
403 | 399 | ||
404 | unlock_exit: | 400 | unlock_exit: |
405 | up(&dev->sem); | 401 | mutex_unlock(&dev->mutex); |
406 | 402 | ||
407 | exit: | 403 | exit: |
408 | return retval; | 404 | return retval; |
@@ -448,7 +444,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, | |||
448 | goto exit; | 444 | goto exit; |
449 | 445 | ||
450 | /* lock this object */ | 446 | /* lock this object */ |
451 | if (down_interruptible(&dev->sem)) { | 447 | if (mutex_lock_interruptible(&dev->mutex)) { |
452 | retval = -ERESTARTSYS; | 448 | retval = -ERESTARTSYS; |
453 | goto exit; | 449 | goto exit; |
454 | } | 450 | } |
@@ -505,7 +501,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, | |||
505 | 501 | ||
506 | unlock_exit: | 502 | unlock_exit: |
507 | /* unlock the device */ | 503 | /* unlock the device */ |
508 | up(&dev->sem); | 504 | mutex_unlock(&dev->mutex); |
509 | 505 | ||
510 | exit: | 506 | exit: |
511 | return retval; | 507 | return retval; |
@@ -528,7 +524,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, | |||
528 | goto exit; | 524 | goto exit; |
529 | 525 | ||
530 | /* lock this object */ | 526 | /* lock this object */ |
531 | if (down_interruptible(&dev->sem)) { | 527 | if (mutex_lock_interruptible(&dev->mutex)) { |
532 | retval = -ERESTARTSYS; | 528 | retval = -ERESTARTSYS; |
533 | goto exit; | 529 | goto exit; |
534 | } | 530 | } |
@@ -602,7 +598,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, | |||
602 | 598 | ||
603 | unlock_exit: | 599 | unlock_exit: |
604 | /* unlock the device */ | 600 | /* unlock the device */ |
605 | up(&dev->sem); | 601 | mutex_unlock(&dev->mutex); |
606 | 602 | ||
607 | exit: | 603 | exit: |
608 | return retval; | 604 | return retval; |
@@ -651,7 +647,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
651 | dev_err(&intf->dev, "Out of memory\n"); | 647 | dev_err(&intf->dev, "Out of memory\n"); |
652 | goto exit; | 648 | goto exit; |
653 | } | 649 | } |
654 | init_MUTEX(&dev->sem); | 650 | mutex_init(&dev->mutex); |
655 | spin_lock_init(&dev->rbsl); | 651 | spin_lock_init(&dev->rbsl); |
656 | dev->intf = intf; | 652 | dev->intf = intf; |
657 | init_waitqueue_head(&dev->read_wait); | 653 | init_waitqueue_head(&dev->read_wait); |
@@ -765,15 +761,15 @@ static void ld_usb_disconnect(struct usb_interface *intf) | |||
765 | /* give back our minor */ | 761 | /* give back our minor */ |
766 | usb_deregister_dev(intf, &ld_usb_class); | 762 | usb_deregister_dev(intf, &ld_usb_class); |
767 | 763 | ||
768 | down(&dev->sem); | 764 | mutex_lock(&dev->mutex); |
769 | 765 | ||
770 | /* if the device is not opened, then we clean up right now */ | 766 | /* if the device is not opened, then we clean up right now */ |
771 | if (!dev->open_count) { | 767 | if (!dev->open_count) { |
772 | up(&dev->sem); | 768 | mutex_unlock(&dev->mutex); |
773 | ld_usb_delete(dev); | 769 | ld_usb_delete(dev); |
774 | } else { | 770 | } else { |
775 | dev->intf = NULL; | 771 | dev->intf = NULL; |
776 | up(&dev->sem); | 772 | mutex_unlock(&dev->mutex); |
777 | } | 773 | } |
778 | 774 | ||
779 | dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", | 775 | dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 24230c638b8e..4cfa25b0f44e 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -595,14 +595,14 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
595 | } while(value); | 595 | } while(value); |
596 | kit->dev_no = bit; | 596 | kit->dev_no = bit; |
597 | 597 | ||
598 | kit->dev = device_create(phidget_class, &kit->udev->dev, 0, | 598 | kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev, |
599 | "interfacekit%d", kit->dev_no); | 599 | MKDEV(0, 0), kit, |
600 | "interfacekit%d", kit->dev_no); | ||
600 | if (IS_ERR(kit->dev)) { | 601 | if (IS_ERR(kit->dev)) { |
601 | rc = PTR_ERR(kit->dev); | 602 | rc = PTR_ERR(kit->dev); |
602 | kit->dev = NULL; | 603 | kit->dev = NULL; |
603 | goto out; | 604 | goto out; |
604 | } | 605 | } |
605 | dev_set_drvdata(kit->dev, kit); | ||
606 | 606 | ||
607 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { | 607 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { |
608 | rc = -EIO; | 608 | rc = -EIO; |
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index f0113c17cc5a..9b4696f21b22 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -365,16 +365,15 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic | |||
365 | } while(value); | 365 | } while(value); |
366 | mc->dev_no = bit; | 366 | mc->dev_no = bit; |
367 | 367 | ||
368 | mc->dev = device_create(phidget_class, &mc->udev->dev, 0, | 368 | mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev, |
369 | "motorcontrol%d", mc->dev_no); | 369 | MKDEV(0, 0), mc, |
370 | "motorcontrol%d", mc->dev_no); | ||
370 | if (IS_ERR(mc->dev)) { | 371 | if (IS_ERR(mc->dev)) { |
371 | rc = PTR_ERR(mc->dev); | 372 | rc = PTR_ERR(mc->dev); |
372 | mc->dev = NULL; | 373 | mc->dev = NULL; |
373 | goto out; | 374 | goto out; |
374 | } | 375 | } |
375 | 376 | ||
376 | dev_set_drvdata(mc->dev, mc); | ||
377 | |||
378 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { | 377 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { |
379 | rc = -EIO; | 378 | rc = -EIO; |
380 | goto out; | 379 | goto out; |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 7d590c09434a..1ca7ddb41d4d 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -275,14 +275,14 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | |||
275 | } while (value); | 275 | } while (value); |
276 | dev->dev_no = bit; | 276 | dev->dev_no = bit; |
277 | 277 | ||
278 | dev->dev = device_create(phidget_class, &dev->udev->dev, 0, | 278 | dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev, |
279 | "servo%d", dev->dev_no); | 279 | MKDEV(0, 0), dev, |
280 | "servo%d", dev->dev_no); | ||
280 | if (IS_ERR(dev->dev)) { | 281 | if (IS_ERR(dev->dev)) { |
281 | rc = PTR_ERR(dev->dev); | 282 | rc = PTR_ERR(dev->dev); |
282 | dev->dev = NULL; | 283 | dev->dev = NULL; |
283 | goto out; | 284 | goto out; |
284 | } | 285 | } |
285 | dev_set_drvdata(dev->dev, dev); | ||
286 | 286 | ||
287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | 287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; |
288 | 288 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index cb7fa0eaf3ae..33182f4c2267 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -3264,8 +3264,6 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3264 | 3264 | ||
3265 | /* decrement our usage count */ | 3265 | /* decrement our usage count */ |
3266 | kref_put(&sisusb->kref, sisusb_delete); | 3266 | kref_put(&sisusb->kref, sisusb_delete); |
3267 | |||
3268 | dev_info(&sisusb->sisusb_dev->dev, "Disconnected\n"); | ||
3269 | } | 3267 | } |
3270 | 3268 | ||
3271 | static struct usb_device_id sisusb_table [] = { | 3269 | static struct usb_device_id sisusb_table [] = { |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index a51983854ca0..054dedd28127 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -79,30 +79,10 @@ static struct usb_device *testdev_to_usbdev (struct usbtest_dev *test) | |||
79 | /* set up all urbs so they can be used with either bulk or interrupt */ | 79 | /* set up all urbs so they can be used with either bulk or interrupt */ |
80 | #define INTERRUPT_RATE 1 /* msec/transfer */ | 80 | #define INTERRUPT_RATE 1 /* msec/transfer */ |
81 | 81 | ||
82 | #define xprintk(tdev,level,fmt,args...) \ | 82 | #define ERROR(tdev, fmt, args...) \ |
83 | dev_printk(level , &(tdev)->intf->dev , fmt , ## args) | 83 | dev_err(&(tdev)->intf->dev , fmt , ## args) |
84 | 84 | #define WARN(tdev, fmt, args...) \ | |
85 | #ifdef DEBUG | 85 | dev_warn(&(tdev)->intf->dev , fmt , ## args) |
86 | #define DBG(dev,fmt,args...) \ | ||
87 | xprintk(dev , KERN_DEBUG , fmt , ## args) | ||
88 | #else | ||
89 | #define DBG(dev,fmt,args...) \ | ||
90 | do { } while (0) | ||
91 | #endif /* DEBUG */ | ||
92 | |||
93 | #ifdef VERBOSE | ||
94 | #define VDBG DBG | ||
95 | #else | ||
96 | #define VDBG(dev,fmt,args...) \ | ||
97 | do { } while (0) | ||
98 | #endif /* VERBOSE */ | ||
99 | |||
100 | #define ERROR(dev,fmt,args...) \ | ||
101 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
102 | #define WARN(dev,fmt,args...) \ | ||
103 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
104 | #define INFO(dev,fmt,args...) \ | ||
105 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
106 | 86 | ||
107 | /*-------------------------------------------------------------------------*/ | 87 | /*-------------------------------------------------------------------------*/ |
108 | 88 | ||
@@ -236,7 +216,7 @@ static struct urb *simple_alloc_urb ( | |||
236 | 216 | ||
237 | static unsigned pattern = 0; | 217 | static unsigned pattern = 0; |
238 | module_param (pattern, uint, S_IRUGO); | 218 | module_param (pattern, uint, S_IRUGO); |
239 | // MODULE_PARM_DESC (pattern, "i/o pattern (0 == zeroes)"); | 219 | MODULE_PARM_DESC(pattern, "i/o pattern (0 == zeroes)"); |
240 | 220 | ||
241 | static inline void simple_fill_buf (struct urb *urb) | 221 | static inline void simple_fill_buf (struct urb *urb) |
242 | { | 222 | { |
@@ -257,7 +237,7 @@ static inline void simple_fill_buf (struct urb *urb) | |||
257 | } | 237 | } |
258 | } | 238 | } |
259 | 239 | ||
260 | static inline int simple_check_buf (struct urb *urb) | 240 | static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) |
261 | { | 241 | { |
262 | unsigned i; | 242 | unsigned i; |
263 | u8 expected; | 243 | u8 expected; |
@@ -285,7 +265,7 @@ static inline int simple_check_buf (struct urb *urb) | |||
285 | } | 265 | } |
286 | if (*buf == expected) | 266 | if (*buf == expected) |
287 | continue; | 267 | continue; |
288 | dbg ("buf[%d] = %d (not %d)", i, *buf, expected); | 268 | ERROR(tdev, "buf[%d] = %d (not %d)\n", i, *buf, expected); |
289 | return -EINVAL; | 269 | return -EINVAL; |
290 | } | 270 | } |
291 | return 0; | 271 | return 0; |
@@ -299,6 +279,7 @@ static void simple_free_urb (struct urb *urb) | |||
299 | } | 279 | } |
300 | 280 | ||
301 | static int simple_io ( | 281 | static int simple_io ( |
282 | struct usbtest_dev *tdev, | ||
302 | struct urb *urb, | 283 | struct urb *urb, |
303 | int iterations, | 284 | int iterations, |
304 | int vary, | 285 | int vary, |
@@ -324,7 +305,7 @@ static int simple_io ( | |||
324 | retval = urb->status; | 305 | retval = urb->status; |
325 | urb->dev = udev; | 306 | urb->dev = udev; |
326 | if (retval == 0 && usb_pipein (urb->pipe)) | 307 | if (retval == 0 && usb_pipein (urb->pipe)) |
327 | retval = simple_check_buf (urb); | 308 | retval = simple_check_buf(tdev, urb); |
328 | 309 | ||
329 | if (vary) { | 310 | if (vary) { |
330 | int len = urb->transfer_buffer_length; | 311 | int len = urb->transfer_buffer_length; |
@@ -341,7 +322,7 @@ static int simple_io ( | |||
341 | urb->transfer_buffer_length = max; | 322 | urb->transfer_buffer_length = max; |
342 | 323 | ||
343 | if (expected != retval) | 324 | if (expected != retval) |
344 | dev_dbg (&udev->dev, | 325 | dev_err(&udev->dev, |
345 | "%s failed, iterations left %d, status %d (not %d)\n", | 326 | "%s failed, iterations left %d, status %d (not %d)\n", |
346 | label, iterations, retval, expected); | 327 | label, iterations, retval, expected); |
347 | return retval; | 328 | return retval; |
@@ -357,7 +338,7 @@ static int simple_io ( | |||
357 | static void free_sglist (struct scatterlist *sg, int nents) | 338 | static void free_sglist (struct scatterlist *sg, int nents) |
358 | { | 339 | { |
359 | unsigned i; | 340 | unsigned i; |
360 | 341 | ||
361 | if (!sg) | 342 | if (!sg) |
362 | return; | 343 | return; |
363 | for (i = 0; i < nents; i++) { | 344 | for (i = 0; i < nents; i++) { |
@@ -415,7 +396,7 @@ alloc_sglist (int nents, int max, int vary) | |||
415 | } | 396 | } |
416 | 397 | ||
417 | static int perform_sglist ( | 398 | static int perform_sglist ( |
418 | struct usb_device *udev, | 399 | struct usbtest_dev *tdev, |
419 | unsigned iterations, | 400 | unsigned iterations, |
420 | int pipe, | 401 | int pipe, |
421 | struct usb_sg_request *req, | 402 | struct usb_sg_request *req, |
@@ -423,6 +404,7 @@ static int perform_sglist ( | |||
423 | int nents | 404 | int nents |
424 | ) | 405 | ) |
425 | { | 406 | { |
407 | struct usb_device *udev = testdev_to_usbdev(tdev); | ||
426 | int retval = 0; | 408 | int retval = 0; |
427 | 409 | ||
428 | while (retval == 0 && iterations-- > 0) { | 410 | while (retval == 0 && iterations-- > 0) { |
@@ -431,7 +413,7 @@ static int perform_sglist ( | |||
431 | ? (INTERRUPT_RATE << 3) | 413 | ? (INTERRUPT_RATE << 3) |
432 | : INTERRUPT_RATE, | 414 | : INTERRUPT_RATE, |
433 | sg, nents, 0, GFP_KERNEL); | 415 | sg, nents, 0, GFP_KERNEL); |
434 | 416 | ||
435 | if (retval) | 417 | if (retval) |
436 | break; | 418 | break; |
437 | usb_sg_wait (req); | 419 | usb_sg_wait (req); |
@@ -446,7 +428,8 @@ static int perform_sglist ( | |||
446 | // failure if retval is as we expected ... | 428 | // failure if retval is as we expected ... |
447 | 429 | ||
448 | if (retval) | 430 | if (retval) |
449 | dbg ("perform_sglist failed, iterations left %d, status %d", | 431 | ERROR(tdev, "perform_sglist failed, " |
432 | "iterations left %d, status %d\n", | ||
450 | iterations, retval); | 433 | iterations, retval); |
451 | return retval; | 434 | return retval; |
452 | } | 435 | } |
@@ -505,28 +488,28 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) | |||
505 | alternate); | 488 | alternate); |
506 | } | 489 | } |
507 | 490 | ||
508 | static int is_good_config (char *buf, int len) | 491 | static int is_good_config(struct usbtest_dev *tdev, int len) |
509 | { | 492 | { |
510 | struct usb_config_descriptor *config; | 493 | struct usb_config_descriptor *config; |
511 | 494 | ||
512 | if (len < sizeof *config) | 495 | if (len < sizeof *config) |
513 | return 0; | 496 | return 0; |
514 | config = (struct usb_config_descriptor *) buf; | 497 | config = (struct usb_config_descriptor *) tdev->buf; |
515 | 498 | ||
516 | switch (config->bDescriptorType) { | 499 | switch (config->bDescriptorType) { |
517 | case USB_DT_CONFIG: | 500 | case USB_DT_CONFIG: |
518 | case USB_DT_OTHER_SPEED_CONFIG: | 501 | case USB_DT_OTHER_SPEED_CONFIG: |
519 | if (config->bLength != 9) { | 502 | if (config->bLength != 9) { |
520 | dbg ("bogus config descriptor length"); | 503 | ERROR(tdev, "bogus config descriptor length\n"); |
521 | return 0; | 504 | return 0; |
522 | } | 505 | } |
523 | /* this bit 'must be 1' but often isn't */ | 506 | /* this bit 'must be 1' but often isn't */ |
524 | if (!realworld && !(config->bmAttributes & 0x80)) { | 507 | if (!realworld && !(config->bmAttributes & 0x80)) { |
525 | dbg ("high bit of config attributes not set"); | 508 | ERROR(tdev, "high bit of config attributes not set\n"); |
526 | return 0; | 509 | return 0; |
527 | } | 510 | } |
528 | if (config->bmAttributes & 0x1f) { /* reserved == 0 */ | 511 | if (config->bmAttributes & 0x1f) { /* reserved == 0 */ |
529 | dbg ("reserved config bits set"); | 512 | ERROR(tdev, "reserved config bits set\n"); |
530 | return 0; | 513 | return 0; |
531 | } | 514 | } |
532 | break; | 515 | break; |
@@ -538,7 +521,7 @@ static int is_good_config (char *buf, int len) | |||
538 | return 1; | 521 | return 1; |
539 | if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */ | 522 | if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */ |
540 | return 1; | 523 | return 1; |
541 | dbg ("bogus config descriptor read size"); | 524 | ERROR(tdev, "bogus config descriptor read size\n"); |
542 | return 0; | 525 | return 0; |
543 | } | 526 | } |
544 | 527 | ||
@@ -571,7 +554,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
571 | /* 9.2.3 constrains the range here */ | 554 | /* 9.2.3 constrains the range here */ |
572 | alt = iface->altsetting [i].desc.bAlternateSetting; | 555 | alt = iface->altsetting [i].desc.bAlternateSetting; |
573 | if (alt < 0 || alt >= iface->num_altsetting) { | 556 | if (alt < 0 || alt >= iface->num_altsetting) { |
574 | dev_dbg (&iface->dev, | 557 | dev_err(&iface->dev, |
575 | "invalid alt [%d].bAltSetting = %d\n", | 558 | "invalid alt [%d].bAltSetting = %d\n", |
576 | i, alt); | 559 | i, alt); |
577 | } | 560 | } |
@@ -583,7 +566,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
583 | /* [9.4.10] set_interface */ | 566 | /* [9.4.10] set_interface */ |
584 | retval = set_altsetting (dev, alt); | 567 | retval = set_altsetting (dev, alt); |
585 | if (retval) { | 568 | if (retval) { |
586 | dev_dbg (&iface->dev, "can't set_interface = %d, %d\n", | 569 | dev_err(&iface->dev, "can't set_interface = %d, %d\n", |
587 | alt, retval); | 570 | alt, retval); |
588 | return retval; | 571 | return retval; |
589 | } | 572 | } |
@@ -591,7 +574,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
591 | /* [9.4.4] get_interface always works */ | 574 | /* [9.4.4] get_interface always works */ |
592 | retval = get_altsetting (dev); | 575 | retval = get_altsetting (dev); |
593 | if (retval != alt) { | 576 | if (retval != alt) { |
594 | dev_dbg (&iface->dev, "get alt should be %d, was %d\n", | 577 | dev_err(&iface->dev, "get alt should be %d, was %d\n", |
595 | alt, retval); | 578 | alt, retval); |
596 | return (retval < 0) ? retval : -EDOM; | 579 | return (retval < 0) ? retval : -EDOM; |
597 | } | 580 | } |
@@ -611,7 +594,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
611 | USB_DIR_IN | USB_RECIP_DEVICE, | 594 | USB_DIR_IN | USB_RECIP_DEVICE, |
612 | 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT); | 595 | 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT); |
613 | if (retval != 1 || dev->buf [0] != expected) { | 596 | if (retval != 1 || dev->buf [0] != expected) { |
614 | dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n", | 597 | dev_err(&iface->dev, "get config --> %d %d (1 %d)\n", |
615 | retval, dev->buf[0], expected); | 598 | retval, dev->buf[0], expected); |
616 | return (retval < 0) ? retval : -EDOM; | 599 | return (retval < 0) ? retval : -EDOM; |
617 | } | 600 | } |
@@ -621,7 +604,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
621 | retval = usb_get_descriptor (udev, USB_DT_DEVICE, 0, | 604 | retval = usb_get_descriptor (udev, USB_DT_DEVICE, 0, |
622 | dev->buf, sizeof udev->descriptor); | 605 | dev->buf, sizeof udev->descriptor); |
623 | if (retval != sizeof udev->descriptor) { | 606 | if (retval != sizeof udev->descriptor) { |
624 | dev_dbg (&iface->dev, "dev descriptor --> %d\n", retval); | 607 | dev_err(&iface->dev, "dev descriptor --> %d\n", retval); |
625 | return (retval < 0) ? retval : -EDOM; | 608 | return (retval < 0) ? retval : -EDOM; |
626 | } | 609 | } |
627 | 610 | ||
@@ -629,8 +612,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
629 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { | 612 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { |
630 | retval = usb_get_descriptor (udev, USB_DT_CONFIG, i, | 613 | retval = usb_get_descriptor (udev, USB_DT_CONFIG, i, |
631 | dev->buf, TBUF_SIZE); | 614 | dev->buf, TBUF_SIZE); |
632 | if (!is_good_config (dev->buf, retval)) { | 615 | if (!is_good_config(dev, retval)) { |
633 | dev_dbg (&iface->dev, | 616 | dev_err(&iface->dev, |
634 | "config [%d] descriptor --> %d\n", | 617 | "config [%d] descriptor --> %d\n", |
635 | i, retval); | 618 | i, retval); |
636 | return (retval < 0) ? retval : -EDOM; | 619 | return (retval < 0) ? retval : -EDOM; |
@@ -650,14 +633,14 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
650 | sizeof (struct usb_qualifier_descriptor)); | 633 | sizeof (struct usb_qualifier_descriptor)); |
651 | if (retval == -EPIPE) { | 634 | if (retval == -EPIPE) { |
652 | if (udev->speed == USB_SPEED_HIGH) { | 635 | if (udev->speed == USB_SPEED_HIGH) { |
653 | dev_dbg (&iface->dev, | 636 | dev_err(&iface->dev, |
654 | "hs dev qualifier --> %d\n", | 637 | "hs dev qualifier --> %d\n", |
655 | retval); | 638 | retval); |
656 | return (retval < 0) ? retval : -EDOM; | 639 | return (retval < 0) ? retval : -EDOM; |
657 | } | 640 | } |
658 | /* usb2.0 but not high-speed capable; fine */ | 641 | /* usb2.0 but not high-speed capable; fine */ |
659 | } else if (retval != sizeof (struct usb_qualifier_descriptor)) { | 642 | } else if (retval != sizeof (struct usb_qualifier_descriptor)) { |
660 | dev_dbg (&iface->dev, "dev qualifier --> %d\n", retval); | 643 | dev_err(&iface->dev, "dev qualifier --> %d\n", retval); |
661 | return (retval < 0) ? retval : -EDOM; | 644 | return (retval < 0) ? retval : -EDOM; |
662 | } else | 645 | } else |
663 | d = (struct usb_qualifier_descriptor *) dev->buf; | 646 | d = (struct usb_qualifier_descriptor *) dev->buf; |
@@ -669,8 +652,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
669 | retval = usb_get_descriptor (udev, | 652 | retval = usb_get_descriptor (udev, |
670 | USB_DT_OTHER_SPEED_CONFIG, i, | 653 | USB_DT_OTHER_SPEED_CONFIG, i, |
671 | dev->buf, TBUF_SIZE); | 654 | dev->buf, TBUF_SIZE); |
672 | if (!is_good_config (dev->buf, retval)) { | 655 | if (!is_good_config(dev, retval)) { |
673 | dev_dbg (&iface->dev, | 656 | dev_err(&iface->dev, |
674 | "other speed config --> %d\n", | 657 | "other speed config --> %d\n", |
675 | retval); | 658 | retval); |
676 | return (retval < 0) ? retval : -EDOM; | 659 | return (retval < 0) ? retval : -EDOM; |
@@ -683,7 +666,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
683 | /* [9.4.5] get_status always works */ | 666 | /* [9.4.5] get_status always works */ |
684 | retval = usb_get_status (udev, USB_RECIP_DEVICE, 0, dev->buf); | 667 | retval = usb_get_status (udev, USB_RECIP_DEVICE, 0, dev->buf); |
685 | if (retval != 2) { | 668 | if (retval != 2) { |
686 | dev_dbg (&iface->dev, "get dev status --> %d\n", retval); | 669 | dev_err(&iface->dev, "get dev status --> %d\n", retval); |
687 | return (retval < 0) ? retval : -EDOM; | 670 | return (retval < 0) ? retval : -EDOM; |
688 | } | 671 | } |
689 | 672 | ||
@@ -693,11 +676,11 @@ static int ch9_postconfig (struct usbtest_dev *dev) | |||
693 | retval = usb_get_status (udev, USB_RECIP_INTERFACE, | 676 | retval = usb_get_status (udev, USB_RECIP_INTERFACE, |
694 | iface->altsetting [0].desc.bInterfaceNumber, dev->buf); | 677 | iface->altsetting [0].desc.bInterfaceNumber, dev->buf); |
695 | if (retval != 2) { | 678 | if (retval != 2) { |
696 | dev_dbg (&iface->dev, "get interface status --> %d\n", retval); | 679 | dev_err(&iface->dev, "get interface status --> %d\n", retval); |
697 | return (retval < 0) ? retval : -EDOM; | 680 | return (retval < 0) ? retval : -EDOM; |
698 | } | 681 | } |
699 | // FIXME get status for each endpoint in the interface | 682 | // FIXME get status for each endpoint in the interface |
700 | 683 | ||
701 | return 0; | 684 | return 0; |
702 | } | 685 | } |
703 | 686 | ||
@@ -752,8 +735,9 @@ static void ctrl_complete (struct urb *urb) | |||
752 | */ | 735 | */ |
753 | if (subcase->number > 0) { | 736 | if (subcase->number > 0) { |
754 | if ((subcase->number - ctx->last) != 1) { | 737 | if ((subcase->number - ctx->last) != 1) { |
755 | dbg ("subcase %d completed out of order, last %d", | 738 | ERROR(ctx->dev, |
756 | subcase->number, ctx->last); | 739 | "subcase %d completed out of order, last %d\n", |
740 | subcase->number, ctx->last); | ||
757 | status = -EDOM; | 741 | status = -EDOM; |
758 | ctx->last = subcase->number; | 742 | ctx->last = subcase->number; |
759 | goto error; | 743 | goto error; |
@@ -777,7 +761,7 @@ static void ctrl_complete (struct urb *urb) | |||
777 | else if (subcase->number == 12 && status == -EPIPE) | 761 | else if (subcase->number == 12 && status == -EPIPE) |
778 | status = 0; | 762 | status = 0; |
779 | else | 763 | else |
780 | dbg ("subtest %d error, status %d", | 764 | ERROR(ctx->dev, "subtest %d error, status %d\n", |
781 | subcase->number, status); | 765 | subcase->number, status); |
782 | } | 766 | } |
783 | 767 | ||
@@ -788,9 +772,12 @@ error: | |||
788 | int i; | 772 | int i; |
789 | 773 | ||
790 | ctx->status = status; | 774 | ctx->status = status; |
791 | info ("control queue %02x.%02x, err %d, %d left", | 775 | ERROR(ctx->dev, "control queue %02x.%02x, err %d, " |
776 | "%d left, subcase %d, len %d/%d\n", | ||
792 | reqp->bRequestType, reqp->bRequest, | 777 | reqp->bRequestType, reqp->bRequest, |
793 | status, ctx->count); | 778 | status, ctx->count, subcase->number, |
779 | urb->actual_length, | ||
780 | urb->transfer_buffer_length); | ||
794 | 781 | ||
795 | /* FIXME this "unlink everything" exit route should | 782 | /* FIXME this "unlink everything" exit route should |
796 | * be a separate test case. | 783 | * be a separate test case. |
@@ -799,7 +786,8 @@ error: | |||
799 | /* unlink whatever's still pending */ | 786 | /* unlink whatever's still pending */ |
800 | for (i = 1; i < ctx->param->sglen; i++) { | 787 | for (i = 1; i < ctx->param->sglen; i++) { |
801 | struct urb *u = ctx->urb [ | 788 | struct urb *u = ctx->urb [ |
802 | (i + subcase->number) % ctx->param->sglen]; | 789 | (i + subcase->number) |
790 | % ctx->param->sglen]; | ||
803 | 791 | ||
804 | if (u == urb || !u->dev) | 792 | if (u == urb || !u->dev) |
805 | continue; | 793 | continue; |
@@ -812,7 +800,8 @@ error: | |||
812 | case -EIDRM: | 800 | case -EIDRM: |
813 | continue; | 801 | continue; |
814 | default: | 802 | default: |
815 | dbg ("urb unlink --> %d", status); | 803 | ERROR(ctx->dev, "urb unlink --> %d\n", |
804 | status); | ||
816 | } | 805 | } |
817 | } | 806 | } |
818 | status = ctx->status; | 807 | status = ctx->status; |
@@ -822,14 +811,15 @@ error: | |||
822 | /* resubmit if we need to, else mark this as done */ | 811 | /* resubmit if we need to, else mark this as done */ |
823 | if ((status == 0) && (ctx->pending < ctx->count)) { | 812 | if ((status == 0) && (ctx->pending < ctx->count)) { |
824 | if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { | 813 | if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { |
825 | dbg ("can't resubmit ctrl %02x.%02x, err %d", | 814 | ERROR(ctx->dev, |
815 | "can't resubmit ctrl %02x.%02x, err %d\n", | ||
826 | reqp->bRequestType, reqp->bRequest, status); | 816 | reqp->bRequestType, reqp->bRequest, status); |
827 | urb->dev = NULL; | 817 | urb->dev = NULL; |
828 | } else | 818 | } else |
829 | ctx->pending++; | 819 | ctx->pending++; |
830 | } else | 820 | } else |
831 | urb->dev = NULL; | 821 | urb->dev = NULL; |
832 | 822 | ||
833 | /* signal completion when nothing's queued */ | 823 | /* signal completion when nothing's queued */ |
834 | if (ctx->pending == 0) | 824 | if (ctx->pending == 0) |
835 | complete (&ctx->complete); | 825 | complete (&ctx->complete); |
@@ -866,6 +856,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
866 | struct urb *u; | 856 | struct urb *u; |
867 | struct usb_ctrlrequest req; | 857 | struct usb_ctrlrequest req; |
868 | struct subcase *reqp; | 858 | struct subcase *reqp; |
859 | |||
860 | /* sign of this variable means: | ||
861 | * -: tested code must return this (negative) error code | ||
862 | * +: tested code may return this (negative too) error code | ||
863 | */ | ||
869 | int expected = 0; | 864 | int expected = 0; |
870 | 865 | ||
871 | /* requests here are mostly expected to succeed on any | 866 | /* requests here are mostly expected to succeed on any |
@@ -918,11 +913,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
918 | req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8); | 913 | req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8); |
919 | // interface == 0 | 914 | // interface == 0 |
920 | len = sizeof (struct usb_interface_descriptor); | 915 | len = sizeof (struct usb_interface_descriptor); |
921 | expected = EPIPE; | 916 | expected = -EPIPE; |
922 | break; | 917 | break; |
923 | // NOTE: two consecutive stalls in the queue here. | 918 | // NOTE: two consecutive stalls in the queue here. |
924 | // that tests fault recovery a bit more aggressively. | 919 | // that tests fault recovery a bit more aggressively. |
925 | case 8: // clear endpoint halt (USUALLY STALLS) | 920 | case 8: // clear endpoint halt (MAY STALL) |
926 | req.bRequest = USB_REQ_CLEAR_FEATURE; | 921 | req.bRequest = USB_REQ_CLEAR_FEATURE; |
927 | req.bRequestType = USB_RECIP_ENDPOINT; | 922 | req.bRequestType = USB_RECIP_ENDPOINT; |
928 | // wValue 0 == ep halt | 923 | // wValue 0 == ep halt |
@@ -965,7 +960,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
965 | break; | 960 | break; |
966 | case 14: // short read; try to fill the last packet | 961 | case 14: // short read; try to fill the last packet |
967 | req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0); | 962 | req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0); |
968 | // device descriptor size == 18 bytes | 963 | /* device descriptor size == 18 bytes */ |
969 | len = udev->descriptor.bMaxPacketSize0; | 964 | len = udev->descriptor.bMaxPacketSize0; |
970 | switch (len) { | 965 | switch (len) { |
971 | case 8: len = 24; break; | 966 | case 8: len = 24; break; |
@@ -974,7 +969,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
974 | expected = -EREMOTEIO; | 969 | expected = -EREMOTEIO; |
975 | break; | 970 | break; |
976 | default: | 971 | default: |
977 | err ("bogus number of ctrl queue testcases!"); | 972 | ERROR(dev, "bogus number of ctrl queue testcases!\n"); |
978 | context.status = -EINVAL; | 973 | context.status = -EINVAL; |
979 | goto cleanup; | 974 | goto cleanup; |
980 | } | 975 | } |
@@ -1003,7 +998,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
1003 | for (i = 0; i < param->sglen; i++) { | 998 | for (i = 0; i < param->sglen; i++) { |
1004 | context.status = usb_submit_urb (urb [i], GFP_ATOMIC); | 999 | context.status = usb_submit_urb (urb [i], GFP_ATOMIC); |
1005 | if (context.status != 0) { | 1000 | if (context.status != 0) { |
1006 | dbg ("can't submit urb[%d], status %d", | 1001 | ERROR(dev, "can't submit urb[%d], status %d\n", |
1007 | i, context.status); | 1002 | i, context.status); |
1008 | context.count = context.pending; | 1003 | context.count = context.pending; |
1009 | break; | 1004 | break; |
@@ -1070,7 +1065,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) | |||
1070 | * due to errors, or is just NAKing requests. | 1065 | * due to errors, or is just NAKing requests. |
1071 | */ | 1066 | */ |
1072 | if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) { | 1067 | if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) { |
1073 | dev_dbg (&dev->intf->dev, "submit fail %d\n", retval); | 1068 | dev_err(&dev->intf->dev, "submit fail %d\n", retval); |
1074 | return retval; | 1069 | return retval; |
1075 | } | 1070 | } |
1076 | 1071 | ||
@@ -1087,13 +1082,13 @@ retry: | |||
1087 | * "normal" drivers would prevent resubmission, but | 1082 | * "normal" drivers would prevent resubmission, but |
1088 | * since we're testing unlink paths, we can't. | 1083 | * since we're testing unlink paths, we can't. |
1089 | */ | 1084 | */ |
1090 | dev_dbg (&dev->intf->dev, "unlink retry\n"); | 1085 | ERROR(dev, "unlink retry\n"); |
1091 | goto retry; | 1086 | goto retry; |
1092 | } | 1087 | } |
1093 | } else | 1088 | } else |
1094 | usb_kill_urb (urb); | 1089 | usb_kill_urb (urb); |
1095 | if (!(retval == 0 || retval == -EINPROGRESS)) { | 1090 | if (!(retval == 0 || retval == -EINPROGRESS)) { |
1096 | dev_dbg (&dev->intf->dev, "unlink fail %d\n", retval); | 1091 | dev_err(&dev->intf->dev, "unlink fail %d\n", retval); |
1097 | return retval; | 1092 | return retval; |
1098 | } | 1093 | } |
1099 | 1094 | ||
@@ -1121,7 +1116,7 @@ static int unlink_simple (struct usbtest_dev *dev, int pipe, int len) | |||
1121 | 1116 | ||
1122 | /*-------------------------------------------------------------------------*/ | 1117 | /*-------------------------------------------------------------------------*/ |
1123 | 1118 | ||
1124 | static int verify_not_halted (int ep, struct urb *urb) | 1119 | static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) |
1125 | { | 1120 | { |
1126 | int retval; | 1121 | int retval; |
1127 | u16 status; | 1122 | u16 status; |
@@ -1129,20 +1124,21 @@ static int verify_not_halted (int ep, struct urb *urb) | |||
1129 | /* shouldn't look or act halted */ | 1124 | /* shouldn't look or act halted */ |
1130 | retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); | 1125 | retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); |
1131 | if (retval < 0) { | 1126 | if (retval < 0) { |
1132 | dbg ("ep %02x couldn't get no-halt status, %d", ep, retval); | 1127 | ERROR(tdev, "ep %02x couldn't get no-halt status, %d\n", |
1128 | ep, retval); | ||
1133 | return retval; | 1129 | return retval; |
1134 | } | 1130 | } |
1135 | if (status != 0) { | 1131 | if (status != 0) { |
1136 | dbg ("ep %02x bogus status: %04x != 0", ep, status); | 1132 | ERROR(tdev, "ep %02x bogus status: %04x != 0\n", ep, status); |
1137 | return -EINVAL; | 1133 | return -EINVAL; |
1138 | } | 1134 | } |
1139 | retval = simple_io (urb, 1, 0, 0, __func__); | 1135 | retval = simple_io(tdev, urb, 1, 0, 0, __func__); |
1140 | if (retval != 0) | 1136 | if (retval != 0) |
1141 | return -EINVAL; | 1137 | return -EINVAL; |
1142 | return 0; | 1138 | return 0; |
1143 | } | 1139 | } |
1144 | 1140 | ||
1145 | static int verify_halted (int ep, struct urb *urb) | 1141 | static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) |
1146 | { | 1142 | { |
1147 | int retval; | 1143 | int retval; |
1148 | u16 status; | 1144 | u16 status; |
@@ -1150,29 +1146,30 @@ static int verify_halted (int ep, struct urb *urb) | |||
1150 | /* should look and act halted */ | 1146 | /* should look and act halted */ |
1151 | retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); | 1147 | retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); |
1152 | if (retval < 0) { | 1148 | if (retval < 0) { |
1153 | dbg ("ep %02x couldn't get halt status, %d", ep, retval); | 1149 | ERROR(tdev, "ep %02x couldn't get halt status, %d\n", |
1150 | ep, retval); | ||
1154 | return retval; | 1151 | return retval; |
1155 | } | 1152 | } |
1156 | le16_to_cpus(&status); | 1153 | le16_to_cpus(&status); |
1157 | if (status != 1) { | 1154 | if (status != 1) { |
1158 | dbg ("ep %02x bogus status: %04x != 1", ep, status); | 1155 | ERROR(tdev, "ep %02x bogus status: %04x != 1\n", ep, status); |
1159 | return -EINVAL; | 1156 | return -EINVAL; |
1160 | } | 1157 | } |
1161 | retval = simple_io (urb, 1, 0, -EPIPE, __func__); | 1158 | retval = simple_io(tdev, urb, 1, 0, -EPIPE, __func__); |
1162 | if (retval != -EPIPE) | 1159 | if (retval != -EPIPE) |
1163 | return -EINVAL; | 1160 | return -EINVAL; |
1164 | retval = simple_io (urb, 1, 0, -EPIPE, "verify_still_halted"); | 1161 | retval = simple_io(tdev, urb, 1, 0, -EPIPE, "verify_still_halted"); |
1165 | if (retval != -EPIPE) | 1162 | if (retval != -EPIPE) |
1166 | return -EINVAL; | 1163 | return -EINVAL; |
1167 | return 0; | 1164 | return 0; |
1168 | } | 1165 | } |
1169 | 1166 | ||
1170 | static int test_halt (int ep, struct urb *urb) | 1167 | static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) |
1171 | { | 1168 | { |
1172 | int retval; | 1169 | int retval; |
1173 | 1170 | ||
1174 | /* shouldn't look or act halted now */ | 1171 | /* shouldn't look or act halted now */ |
1175 | retval = verify_not_halted (ep, urb); | 1172 | retval = verify_not_halted(tdev, ep, urb); |
1176 | if (retval < 0) | 1173 | if (retval < 0) |
1177 | return retval; | 1174 | return retval; |
1178 | 1175 | ||
@@ -1182,20 +1179,20 @@ static int test_halt (int ep, struct urb *urb) | |||
1182 | USB_ENDPOINT_HALT, ep, | 1179 | USB_ENDPOINT_HALT, ep, |
1183 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 1180 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
1184 | if (retval < 0) { | 1181 | if (retval < 0) { |
1185 | dbg ("ep %02x couldn't set halt, %d", ep, retval); | 1182 | ERROR(tdev, "ep %02x couldn't set halt, %d\n", ep, retval); |
1186 | return retval; | 1183 | return retval; |
1187 | } | 1184 | } |
1188 | retval = verify_halted (ep, urb); | 1185 | retval = verify_halted(tdev, ep, urb); |
1189 | if (retval < 0) | 1186 | if (retval < 0) |
1190 | return retval; | 1187 | return retval; |
1191 | 1188 | ||
1192 | /* clear halt (tests API + protocol), verify it worked */ | 1189 | /* clear halt (tests API + protocol), verify it worked */ |
1193 | retval = usb_clear_halt (urb->dev, urb->pipe); | 1190 | retval = usb_clear_halt (urb->dev, urb->pipe); |
1194 | if (retval < 0) { | 1191 | if (retval < 0) { |
1195 | dbg ("ep %02x couldn't clear halt, %d", ep, retval); | 1192 | ERROR(tdev, "ep %02x couldn't clear halt, %d\n", ep, retval); |
1196 | return retval; | 1193 | return retval; |
1197 | } | 1194 | } |
1198 | retval = verify_not_halted (ep, urb); | 1195 | retval = verify_not_halted(tdev, ep, urb); |
1199 | if (retval < 0) | 1196 | if (retval < 0) |
1200 | return retval; | 1197 | return retval; |
1201 | 1198 | ||
@@ -1217,7 +1214,7 @@ static int halt_simple (struct usbtest_dev *dev) | |||
1217 | if (dev->in_pipe) { | 1214 | if (dev->in_pipe) { |
1218 | ep = usb_pipeendpoint (dev->in_pipe) | USB_DIR_IN; | 1215 | ep = usb_pipeendpoint (dev->in_pipe) | USB_DIR_IN; |
1219 | urb->pipe = dev->in_pipe; | 1216 | urb->pipe = dev->in_pipe; |
1220 | retval = test_halt (ep, urb); | 1217 | retval = test_halt(dev, ep, urb); |
1221 | if (retval < 0) | 1218 | if (retval < 0) |
1222 | goto done; | 1219 | goto done; |
1223 | } | 1220 | } |
@@ -1225,7 +1222,7 @@ static int halt_simple (struct usbtest_dev *dev) | |||
1225 | if (dev->out_pipe) { | 1222 | if (dev->out_pipe) { |
1226 | ep = usb_pipeendpoint (dev->out_pipe); | 1223 | ep = usb_pipeendpoint (dev->out_pipe); |
1227 | urb->pipe = dev->out_pipe; | 1224 | urb->pipe = dev->out_pipe; |
1228 | retval = test_halt (ep, urb); | 1225 | retval = test_halt(dev, ep, urb); |
1229 | } | 1226 | } |
1230 | done: | 1227 | done: |
1231 | simple_free_urb (urb); | 1228 | simple_free_urb (urb); |
@@ -1275,7 +1272,7 @@ static int ctrl_out (struct usbtest_dev *dev, | |||
1275 | if (retval != len) { | 1272 | if (retval != len) { |
1276 | what = "write"; | 1273 | what = "write"; |
1277 | if (retval >= 0) { | 1274 | if (retval >= 0) { |
1278 | INFO(dev, "ctrl_out, wlen %d (expected %d)\n", | 1275 | ERROR(dev, "ctrl_out, wlen %d (expected %d)\n", |
1279 | retval, len); | 1276 | retval, len); |
1280 | retval = -EBADMSG; | 1277 | retval = -EBADMSG; |
1281 | } | 1278 | } |
@@ -1289,7 +1286,7 @@ static int ctrl_out (struct usbtest_dev *dev, | |||
1289 | if (retval != len) { | 1286 | if (retval != len) { |
1290 | what = "read"; | 1287 | what = "read"; |
1291 | if (retval >= 0) { | 1288 | if (retval >= 0) { |
1292 | INFO(dev, "ctrl_out, rlen %d (expected %d)\n", | 1289 | ERROR(dev, "ctrl_out, rlen %d (expected %d)\n", |
1293 | retval, len); | 1290 | retval, len); |
1294 | retval = -EBADMSG; | 1291 | retval = -EBADMSG; |
1295 | } | 1292 | } |
@@ -1299,7 +1296,7 @@ static int ctrl_out (struct usbtest_dev *dev, | |||
1299 | /* fail if we can't verify */ | 1296 | /* fail if we can't verify */ |
1300 | for (j = 0; j < len; j++) { | 1297 | for (j = 0; j < len; j++) { |
1301 | if (buf [j] != (u8) (i + j)) { | 1298 | if (buf [j] != (u8) (i + j)) { |
1302 | INFO (dev, "ctrl_out, byte %d is %d not %d\n", | 1299 | ERROR(dev, "ctrl_out, byte %d is %d not %d\n", |
1303 | j, buf [j], (u8) i + j); | 1300 | j, buf [j], (u8) i + j); |
1304 | retval = -EBADMSG; | 1301 | retval = -EBADMSG; |
1305 | break; | 1302 | break; |
@@ -1321,7 +1318,7 @@ static int ctrl_out (struct usbtest_dev *dev, | |||
1321 | } | 1318 | } |
1322 | 1319 | ||
1323 | if (retval < 0) | 1320 | if (retval < 0) |
1324 | INFO (dev, "ctrl_out %s failed, code %d, count %d\n", | 1321 | ERROR (dev, "ctrl_out %s failed, code %d, count %d\n", |
1325 | what, retval, i); | 1322 | what, retval, i); |
1326 | 1323 | ||
1327 | kfree (buf); | 1324 | kfree (buf); |
@@ -1366,7 +1363,7 @@ static void iso_callback (struct urb *urb) | |||
1366 | case 0: | 1363 | case 0: |
1367 | goto done; | 1364 | goto done; |
1368 | default: | 1365 | default: |
1369 | dev_dbg (&ctx->dev->intf->dev, | 1366 | dev_err(&ctx->dev->intf->dev, |
1370 | "iso resubmit err %d\n", | 1367 | "iso resubmit err %d\n", |
1371 | status); | 1368 | status); |
1372 | /* FALLTHROUGH */ | 1369 | /* FALLTHROUGH */ |
@@ -1381,7 +1378,7 @@ static void iso_callback (struct urb *urb) | |||
1381 | ctx->pending--; | 1378 | ctx->pending--; |
1382 | if (ctx->pending == 0) { | 1379 | if (ctx->pending == 0) { |
1383 | if (ctx->errors) | 1380 | if (ctx->errors) |
1384 | dev_dbg (&ctx->dev->intf->dev, | 1381 | dev_err(&ctx->dev->intf->dev, |
1385 | "iso test, %lu errors out of %lu\n", | 1382 | "iso test, %lu errors out of %lu\n", |
1386 | ctx->errors, ctx->packet_count); | 1383 | ctx->errors, ctx->packet_count); |
1387 | complete (&ctx->done); | 1384 | complete (&ctx->done); |
@@ -1458,7 +1455,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, | |||
1458 | 1455 | ||
1459 | memset (urbs, 0, sizeof urbs); | 1456 | memset (urbs, 0, sizeof urbs); |
1460 | udev = testdev_to_usbdev (dev); | 1457 | udev = testdev_to_usbdev (dev); |
1461 | dev_dbg (&dev->intf->dev, | 1458 | dev_info(&dev->intf->dev, |
1462 | "... iso period %d %sframes, wMaxPacket %04x\n", | 1459 | "... iso period %d %sframes, wMaxPacket %04x\n", |
1463 | 1 << (desc->bInterval - 1), | 1460 | 1 << (desc->bInterval - 1), |
1464 | (udev->speed == USB_SPEED_HIGH) ? "micro" : "", | 1461 | (udev->speed == USB_SPEED_HIGH) ? "micro" : "", |
@@ -1475,7 +1472,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, | |||
1475 | urbs [i]->context = &context; | 1472 | urbs [i]->context = &context; |
1476 | } | 1473 | } |
1477 | packets *= param->iterations; | 1474 | packets *= param->iterations; |
1478 | dev_dbg (&dev->intf->dev, | 1475 | dev_info(&dev->intf->dev, |
1479 | "... total %lu msec (%lu packets)\n", | 1476 | "... total %lu msec (%lu packets)\n", |
1480 | (packets * (1 << (desc->bInterval - 1))) | 1477 | (packets * (1 << (desc->bInterval - 1))) |
1481 | / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), | 1478 | / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), |
@@ -1537,6 +1534,13 @@ fail: | |||
1537 | * except indirectly by consuming USB bandwidth and CPU resources for test | 1534 | * except indirectly by consuming USB bandwidth and CPU resources for test |
1538 | * threads and request completion. But the only way to know that for sure | 1535 | * threads and request completion. But the only way to know that for sure |
1539 | * is to test when HC queues are in use by many devices. | 1536 | * is to test when HC queues are in use by many devices. |
1537 | * | ||
1538 | * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), | ||
1539 | * it locks out usbcore in certain code paths. Notably, if you disconnect | ||
1540 | * the device-under-test, khubd will wait block forever waiting for the | ||
1541 | * ioctl to complete ... so that usb_disconnect() can abort the pending | ||
1542 | * urbs and then call usbtest_disconnect(). To abort a test, you're best | ||
1543 | * off just killing the userspace task and waiting for it to exit. | ||
1540 | */ | 1544 | */ |
1541 | 1545 | ||
1542 | static int | 1546 | static int |
@@ -1575,7 +1579,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1575 | * altsettings; force a default so most tests don't need to check. | 1579 | * altsettings; force a default so most tests don't need to check. |
1576 | */ | 1580 | */ |
1577 | if (dev->info->alt >= 0) { | 1581 | if (dev->info->alt >= 0) { |
1578 | int res; | 1582 | int res; |
1579 | 1583 | ||
1580 | if (intf->altsetting->desc.bInterfaceNumber) { | 1584 | if (intf->altsetting->desc.bInterfaceNumber) { |
1581 | mutex_unlock(&dev->lock); | 1585 | mutex_unlock(&dev->lock); |
@@ -1604,7 +1608,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1604 | switch (param->test_num) { | 1608 | switch (param->test_num) { |
1605 | 1609 | ||
1606 | case 0: | 1610 | case 0: |
1607 | dev_dbg (&intf->dev, "TEST 0: NOP\n"); | 1611 | dev_info(&intf->dev, "TEST 0: NOP\n"); |
1608 | retval = 0; | 1612 | retval = 0; |
1609 | break; | 1613 | break; |
1610 | 1614 | ||
@@ -1612,7 +1616,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1612 | case 1: | 1616 | case 1: |
1613 | if (dev->out_pipe == 0) | 1617 | if (dev->out_pipe == 0) |
1614 | break; | 1618 | break; |
1615 | dev_dbg (&intf->dev, | 1619 | dev_info(&intf->dev, |
1616 | "TEST 1: write %d bytes %u times\n", | 1620 | "TEST 1: write %d bytes %u times\n", |
1617 | param->length, param->iterations); | 1621 | param->length, param->iterations); |
1618 | urb = simple_alloc_urb (udev, dev->out_pipe, param->length); | 1622 | urb = simple_alloc_urb (udev, dev->out_pipe, param->length); |
@@ -1621,13 +1625,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1621 | break; | 1625 | break; |
1622 | } | 1626 | } |
1623 | // FIRMWARE: bulk sink (maybe accepts short writes) | 1627 | // FIRMWARE: bulk sink (maybe accepts short writes) |
1624 | retval = simple_io (urb, param->iterations, 0, 0, "test1"); | 1628 | retval = simple_io(dev, urb, param->iterations, 0, 0, "test1"); |
1625 | simple_free_urb (urb); | 1629 | simple_free_urb (urb); |
1626 | break; | 1630 | break; |
1627 | case 2: | 1631 | case 2: |
1628 | if (dev->in_pipe == 0) | 1632 | if (dev->in_pipe == 0) |
1629 | break; | 1633 | break; |
1630 | dev_dbg (&intf->dev, | 1634 | dev_info(&intf->dev, |
1631 | "TEST 2: read %d bytes %u times\n", | 1635 | "TEST 2: read %d bytes %u times\n", |
1632 | param->length, param->iterations); | 1636 | param->length, param->iterations); |
1633 | urb = simple_alloc_urb (udev, dev->in_pipe, param->length); | 1637 | urb = simple_alloc_urb (udev, dev->in_pipe, param->length); |
@@ -1636,13 +1640,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1636 | break; | 1640 | break; |
1637 | } | 1641 | } |
1638 | // FIRMWARE: bulk source (maybe generates short writes) | 1642 | // FIRMWARE: bulk source (maybe generates short writes) |
1639 | retval = simple_io (urb, param->iterations, 0, 0, "test2"); | 1643 | retval = simple_io(dev, urb, param->iterations, 0, 0, "test2"); |
1640 | simple_free_urb (urb); | 1644 | simple_free_urb (urb); |
1641 | break; | 1645 | break; |
1642 | case 3: | 1646 | case 3: |
1643 | if (dev->out_pipe == 0 || param->vary == 0) | 1647 | if (dev->out_pipe == 0 || param->vary == 0) |
1644 | break; | 1648 | break; |
1645 | dev_dbg (&intf->dev, | 1649 | dev_info(&intf->dev, |
1646 | "TEST 3: write/%d 0..%d bytes %u times\n", | 1650 | "TEST 3: write/%d 0..%d bytes %u times\n", |
1647 | param->vary, param->length, param->iterations); | 1651 | param->vary, param->length, param->iterations); |
1648 | urb = simple_alloc_urb (udev, dev->out_pipe, param->length); | 1652 | urb = simple_alloc_urb (udev, dev->out_pipe, param->length); |
@@ -1651,14 +1655,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1651 | break; | 1655 | break; |
1652 | } | 1656 | } |
1653 | // FIRMWARE: bulk sink (maybe accepts short writes) | 1657 | // FIRMWARE: bulk sink (maybe accepts short writes) |
1654 | retval = simple_io (urb, param->iterations, param->vary, | 1658 | retval = simple_io(dev, urb, param->iterations, param->vary, |
1655 | 0, "test3"); | 1659 | 0, "test3"); |
1656 | simple_free_urb (urb); | 1660 | simple_free_urb (urb); |
1657 | break; | 1661 | break; |
1658 | case 4: | 1662 | case 4: |
1659 | if (dev->in_pipe == 0 || param->vary == 0) | 1663 | if (dev->in_pipe == 0 || param->vary == 0) |
1660 | break; | 1664 | break; |
1661 | dev_dbg (&intf->dev, | 1665 | dev_info(&intf->dev, |
1662 | "TEST 4: read/%d 0..%d bytes %u times\n", | 1666 | "TEST 4: read/%d 0..%d bytes %u times\n", |
1663 | param->vary, param->length, param->iterations); | 1667 | param->vary, param->length, param->iterations); |
1664 | urb = simple_alloc_urb (udev, dev->in_pipe, param->length); | 1668 | urb = simple_alloc_urb (udev, dev->in_pipe, param->length); |
@@ -1667,7 +1671,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1667 | break; | 1671 | break; |
1668 | } | 1672 | } |
1669 | // FIRMWARE: bulk source (maybe generates short writes) | 1673 | // FIRMWARE: bulk source (maybe generates short writes) |
1670 | retval = simple_io (urb, param->iterations, param->vary, | 1674 | retval = simple_io(dev, urb, param->iterations, param->vary, |
1671 | 0, "test4"); | 1675 | 0, "test4"); |
1672 | simple_free_urb (urb); | 1676 | simple_free_urb (urb); |
1673 | break; | 1677 | break; |
@@ -1676,7 +1680,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1676 | case 5: | 1680 | case 5: |
1677 | if (dev->out_pipe == 0 || param->sglen == 0) | 1681 | if (dev->out_pipe == 0 || param->sglen == 0) |
1678 | break; | 1682 | break; |
1679 | dev_dbg (&intf->dev, | 1683 | dev_info(&intf->dev, |
1680 | "TEST 5: write %d sglists %d entries of %d bytes\n", | 1684 | "TEST 5: write %d sglists %d entries of %d bytes\n", |
1681 | param->iterations, | 1685 | param->iterations, |
1682 | param->sglen, param->length); | 1686 | param->sglen, param->length); |
@@ -1686,7 +1690,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1686 | break; | 1690 | break; |
1687 | } | 1691 | } |
1688 | // FIRMWARE: bulk sink (maybe accepts short writes) | 1692 | // FIRMWARE: bulk sink (maybe accepts short writes) |
1689 | retval = perform_sglist (udev, param->iterations, dev->out_pipe, | 1693 | retval = perform_sglist(dev, param->iterations, dev->out_pipe, |
1690 | &req, sg, param->sglen); | 1694 | &req, sg, param->sglen); |
1691 | free_sglist (sg, param->sglen); | 1695 | free_sglist (sg, param->sglen); |
1692 | break; | 1696 | break; |
@@ -1694,7 +1698,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1694 | case 6: | 1698 | case 6: |
1695 | if (dev->in_pipe == 0 || param->sglen == 0) | 1699 | if (dev->in_pipe == 0 || param->sglen == 0) |
1696 | break; | 1700 | break; |
1697 | dev_dbg (&intf->dev, | 1701 | dev_info(&intf->dev, |
1698 | "TEST 6: read %d sglists %d entries of %d bytes\n", | 1702 | "TEST 6: read %d sglists %d entries of %d bytes\n", |
1699 | param->iterations, | 1703 | param->iterations, |
1700 | param->sglen, param->length); | 1704 | param->sglen, param->length); |
@@ -1704,14 +1708,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1704 | break; | 1708 | break; |
1705 | } | 1709 | } |
1706 | // FIRMWARE: bulk source (maybe generates short writes) | 1710 | // FIRMWARE: bulk source (maybe generates short writes) |
1707 | retval = perform_sglist (udev, param->iterations, dev->in_pipe, | 1711 | retval = perform_sglist(dev, param->iterations, dev->in_pipe, |
1708 | &req, sg, param->sglen); | 1712 | &req, sg, param->sglen); |
1709 | free_sglist (sg, param->sglen); | 1713 | free_sglist (sg, param->sglen); |
1710 | break; | 1714 | break; |
1711 | case 7: | 1715 | case 7: |
1712 | if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0) | 1716 | if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0) |
1713 | break; | 1717 | break; |
1714 | dev_dbg (&intf->dev, | 1718 | dev_info(&intf->dev, |
1715 | "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n", | 1719 | "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n", |
1716 | param->vary, param->iterations, | 1720 | param->vary, param->iterations, |
1717 | param->sglen, param->length); | 1721 | param->sglen, param->length); |
@@ -1721,14 +1725,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1721 | break; | 1725 | break; |
1722 | } | 1726 | } |
1723 | // FIRMWARE: bulk sink (maybe accepts short writes) | 1727 | // FIRMWARE: bulk sink (maybe accepts short writes) |
1724 | retval = perform_sglist (udev, param->iterations, dev->out_pipe, | 1728 | retval = perform_sglist(dev, param->iterations, dev->out_pipe, |
1725 | &req, sg, param->sglen); | 1729 | &req, sg, param->sglen); |
1726 | free_sglist (sg, param->sglen); | 1730 | free_sglist (sg, param->sglen); |
1727 | break; | 1731 | break; |
1728 | case 8: | 1732 | case 8: |
1729 | if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0) | 1733 | if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0) |
1730 | break; | 1734 | break; |
1731 | dev_dbg (&intf->dev, | 1735 | dev_info(&intf->dev, |
1732 | "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n", | 1736 | "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n", |
1733 | param->vary, param->iterations, | 1737 | param->vary, param->iterations, |
1734 | param->sglen, param->length); | 1738 | param->sglen, param->length); |
@@ -1738,7 +1742,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1738 | break; | 1742 | break; |
1739 | } | 1743 | } |
1740 | // FIRMWARE: bulk source (maybe generates short writes) | 1744 | // FIRMWARE: bulk source (maybe generates short writes) |
1741 | retval = perform_sglist (udev, param->iterations, dev->in_pipe, | 1745 | retval = perform_sglist(dev, param->iterations, dev->in_pipe, |
1742 | &req, sg, param->sglen); | 1746 | &req, sg, param->sglen); |
1743 | free_sglist (sg, param->sglen); | 1747 | free_sglist (sg, param->sglen); |
1744 | break; | 1748 | break; |
@@ -1746,13 +1750,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1746 | /* non-queued sanity tests for control (chapter 9 subset) */ | 1750 | /* non-queued sanity tests for control (chapter 9 subset) */ |
1747 | case 9: | 1751 | case 9: |
1748 | retval = 0; | 1752 | retval = 0; |
1749 | dev_dbg (&intf->dev, | 1753 | dev_info(&intf->dev, |
1750 | "TEST 9: ch9 (subset) control tests, %d times\n", | 1754 | "TEST 9: ch9 (subset) control tests, %d times\n", |
1751 | param->iterations); | 1755 | param->iterations); |
1752 | for (i = param->iterations; retval == 0 && i--; /* NOP */) | 1756 | for (i = param->iterations; retval == 0 && i--; /* NOP */) |
1753 | retval = ch9_postconfig (dev); | 1757 | retval = ch9_postconfig (dev); |
1754 | if (retval) | 1758 | if (retval) |
1755 | dbg ("ch9 subset failed, iterations left %d", i); | 1759 | dev_err(&intf->dev, "ch9 subset failed, " |
1760 | "iterations left %d\n", i); | ||
1756 | break; | 1761 | break; |
1757 | 1762 | ||
1758 | /* queued control messaging */ | 1763 | /* queued control messaging */ |
@@ -1760,7 +1765,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1760 | if (param->sglen == 0) | 1765 | if (param->sglen == 0) |
1761 | break; | 1766 | break; |
1762 | retval = 0; | 1767 | retval = 0; |
1763 | dev_dbg (&intf->dev, | 1768 | dev_info(&intf->dev, |
1764 | "TEST 10: queue %d control calls, %d times\n", | 1769 | "TEST 10: queue %d control calls, %d times\n", |
1765 | param->sglen, | 1770 | param->sglen, |
1766 | param->iterations); | 1771 | param->iterations); |
@@ -1772,26 +1777,26 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1772 | if (dev->in_pipe == 0 || !param->length) | 1777 | if (dev->in_pipe == 0 || !param->length) |
1773 | break; | 1778 | break; |
1774 | retval = 0; | 1779 | retval = 0; |
1775 | dev_dbg (&intf->dev, "TEST 11: unlink %d reads of %d\n", | 1780 | dev_info(&intf->dev, "TEST 11: unlink %d reads of %d\n", |
1776 | param->iterations, param->length); | 1781 | param->iterations, param->length); |
1777 | for (i = param->iterations; retval == 0 && i--; /* NOP */) | 1782 | for (i = param->iterations; retval == 0 && i--; /* NOP */) |
1778 | retval = unlink_simple (dev, dev->in_pipe, | 1783 | retval = unlink_simple (dev, dev->in_pipe, |
1779 | param->length); | 1784 | param->length); |
1780 | if (retval) | 1785 | if (retval) |
1781 | dev_dbg (&intf->dev, "unlink reads failed %d, " | 1786 | dev_err(&intf->dev, "unlink reads failed %d, " |
1782 | "iterations left %d\n", retval, i); | 1787 | "iterations left %d\n", retval, i); |
1783 | break; | 1788 | break; |
1784 | case 12: | 1789 | case 12: |
1785 | if (dev->out_pipe == 0 || !param->length) | 1790 | if (dev->out_pipe == 0 || !param->length) |
1786 | break; | 1791 | break; |
1787 | retval = 0; | 1792 | retval = 0; |
1788 | dev_dbg (&intf->dev, "TEST 12: unlink %d writes of %d\n", | 1793 | dev_info(&intf->dev, "TEST 12: unlink %d writes of %d\n", |
1789 | param->iterations, param->length); | 1794 | param->iterations, param->length); |
1790 | for (i = param->iterations; retval == 0 && i--; /* NOP */) | 1795 | for (i = param->iterations; retval == 0 && i--; /* NOP */) |
1791 | retval = unlink_simple (dev, dev->out_pipe, | 1796 | retval = unlink_simple (dev, dev->out_pipe, |
1792 | param->length); | 1797 | param->length); |
1793 | if (retval) | 1798 | if (retval) |
1794 | dev_dbg (&intf->dev, "unlink writes failed %d, " | 1799 | dev_err(&intf->dev, "unlink writes failed %d, " |
1795 | "iterations left %d\n", retval, i); | 1800 | "iterations left %d\n", retval, i); |
1796 | break; | 1801 | break; |
1797 | 1802 | ||
@@ -1800,24 +1805,24 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1800 | if (dev->out_pipe == 0 && dev->in_pipe == 0) | 1805 | if (dev->out_pipe == 0 && dev->in_pipe == 0) |
1801 | break; | 1806 | break; |
1802 | retval = 0; | 1807 | retval = 0; |
1803 | dev_dbg (&intf->dev, "TEST 13: set/clear %d halts\n", | 1808 | dev_info(&intf->dev, "TEST 13: set/clear %d halts\n", |
1804 | param->iterations); | 1809 | param->iterations); |
1805 | for (i = param->iterations; retval == 0 && i--; /* NOP */) | 1810 | for (i = param->iterations; retval == 0 && i--; /* NOP */) |
1806 | retval = halt_simple (dev); | 1811 | retval = halt_simple (dev); |
1807 | 1812 | ||
1808 | if (retval) | 1813 | if (retval) |
1809 | DBG (dev, "halts failed, iterations left %d\n", i); | 1814 | ERROR(dev, "halts failed, iterations left %d\n", i); |
1810 | break; | 1815 | break; |
1811 | 1816 | ||
1812 | /* control write tests */ | 1817 | /* control write tests */ |
1813 | case 14: | 1818 | case 14: |
1814 | if (!dev->info->ctrl_out) | 1819 | if (!dev->info->ctrl_out) |
1815 | break; | 1820 | break; |
1816 | dev_dbg (&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", | 1821 | dev_info(&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", |
1817 | param->iterations, | 1822 | param->iterations, |
1818 | realworld ? 1 : 0, param->length, | 1823 | realworld ? 1 : 0, param->length, |
1819 | param->vary); | 1824 | param->vary); |
1820 | retval = ctrl_out (dev, param->iterations, | 1825 | retval = ctrl_out(dev, param->iterations, |
1821 | param->length, param->vary); | 1826 | param->length, param->vary); |
1822 | break; | 1827 | break; |
1823 | 1828 | ||
@@ -1825,7 +1830,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1825 | case 15: | 1830 | case 15: |
1826 | if (dev->out_iso_pipe == 0 || param->sglen == 0) | 1831 | if (dev->out_iso_pipe == 0 || param->sglen == 0) |
1827 | break; | 1832 | break; |
1828 | dev_dbg (&intf->dev, | 1833 | dev_info(&intf->dev, |
1829 | "TEST 15: write %d iso, %d entries of %d bytes\n", | 1834 | "TEST 15: write %d iso, %d entries of %d bytes\n", |
1830 | param->iterations, | 1835 | param->iterations, |
1831 | param->sglen, param->length); | 1836 | param->sglen, param->length); |
@@ -1838,7 +1843,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) | |||
1838 | case 16: | 1843 | case 16: |
1839 | if (dev->in_iso_pipe == 0 || param->sglen == 0) | 1844 | if (dev->in_iso_pipe == 0 || param->sglen == 0) |
1840 | break; | 1845 | break; |
1841 | dev_dbg (&intf->dev, | 1846 | dev_info(&intf->dev, |
1842 | "TEST 16: read %d iso, %d entries of %d bytes\n", | 1847 | "TEST 16: read %d iso, %d entries of %d bytes\n", |
1843 | param->iterations, | 1848 | param->iterations, |
1844 | param->sglen, param->length); | 1849 | param->sglen, param->length); |
@@ -1898,7 +1903,8 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) | |||
1898 | return -ENODEV; | 1903 | return -ENODEV; |
1899 | if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product) | 1904 | if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product) |
1900 | return -ENODEV; | 1905 | return -ENODEV; |
1901 | dbg ("matched module params, vend=0x%04x prod=0x%04x", | 1906 | dev_info(&intf->dev, "matched module params, " |
1907 | "vend=0x%04x prod=0x%04x\n", | ||
1902 | le16_to_cpu(udev->descriptor.idVendor), | 1908 | le16_to_cpu(udev->descriptor.idVendor), |
1903 | le16_to_cpu(udev->descriptor.idProduct)); | 1909 | le16_to_cpu(udev->descriptor.idProduct)); |
1904 | } | 1910 | } |
@@ -1940,7 +1946,8 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) | |||
1940 | 1946 | ||
1941 | status = get_endpoints (dev, intf); | 1947 | status = get_endpoints (dev, intf); |
1942 | if (status < 0) { | 1948 | if (status < 0) { |
1943 | dbg ("couldn't get endpoints, %d\n", status); | 1949 | WARN(dev, "couldn't get endpoints, %d\n", |
1950 | status); | ||
1944 | return status; | 1951 | return status; |
1945 | } | 1952 | } |
1946 | /* may find bulk or ISO pipes */ | 1953 | /* may find bulk or ISO pipes */ |
@@ -2082,21 +2089,9 @@ static struct usbtest_info generic_info = { | |||
2082 | }; | 2089 | }; |
2083 | #endif | 2090 | #endif |
2084 | 2091 | ||
2085 | // FIXME remove this | ||
2086 | static struct usbtest_info hact_info = { | ||
2087 | .name = "FX2/hact", | ||
2088 | //.ep_in = 6, | ||
2089 | .ep_out = 2, | ||
2090 | .alt = -1, | ||
2091 | }; | ||
2092 | |||
2093 | 2092 | ||
2094 | static struct usb_device_id id_table [] = { | 2093 | static struct usb_device_id id_table [] = { |
2095 | 2094 | ||
2096 | { USB_DEVICE (0x0547, 0x1002), | ||
2097 | .driver_info = (unsigned long) &hact_info, | ||
2098 | }, | ||
2099 | |||
2100 | /*-------------------------------------------------------------*/ | 2095 | /*-------------------------------------------------------------*/ |
2101 | 2096 | ||
2102 | /* EZ-USB devices which download firmware to replace (or in our | 2097 | /* EZ-USB devices which download firmware to replace (or in our |
@@ -2185,7 +2180,7 @@ static int __init usbtest_init (void) | |||
2185 | { | 2180 | { |
2186 | #ifdef GENERIC | 2181 | #ifdef GENERIC |
2187 | if (vendor) | 2182 | if (vendor) |
2188 | dbg ("params: vend=0x%04x prod=0x%04x", vendor, product); | 2183 | pr_debug("params: vend=0x%04x prod=0x%04x\n", vendor, product); |
2189 | #endif | 2184 | #endif |
2190 | return usb_register (&usbtest_driver); | 2185 | return usb_register (&usbtest_driver); |
2191 | } | 2186 | } |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 2cffec85ee7e..9ba64ccc1359 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -447,6 +447,15 @@ config USB_SERIAL_MOS7840 | |||
447 | To compile this driver as a module, choose M here: the | 447 | To compile this driver as a module, choose M here: the |
448 | module will be called mos7840. If unsure, choose N. | 448 | module will be called mos7840. If unsure, choose N. |
449 | 449 | ||
450 | config USB_SERIAL_MOTOROLA | ||
451 | tristate "USB Motorola Phone modem driver" | ||
452 | ---help--- | ||
453 | Say Y here if you want to use a Motorola phone with a USB | ||
454 | connector as a modem link. | ||
455 | |||
456 | To compile this driver as a module, choose M here: the | ||
457 | module will be called moto_modem. If unsure, choose N. | ||
458 | |||
450 | config USB_SERIAL_NAVMAN | 459 | config USB_SERIAL_NAVMAN |
451 | tristate "USB Navman GPS device" | 460 | tristate "USB Navman GPS device" |
452 | help | 461 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 756859510d8c..17a762ab6769 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | |||
39 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 39 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
40 | obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o | 40 | obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o |
41 | obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o | 41 | obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o |
42 | obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o | ||
42 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o | 43 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o |
43 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 44 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
44 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 9b1bb347dc2d..db6f97a93c02 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -147,7 +147,7 @@ static void serial_buf_free(struct circ_buf *cb) | |||
147 | */ | 147 | */ |
148 | static int serial_buf_data_avail(struct circ_buf *cb) | 148 | static int serial_buf_data_avail(struct circ_buf *cb) |
149 | { | 149 | { |
150 | return CIRC_CNT(cb->head,cb->tail,AIRCABLE_BUF_SIZE); | 150 | return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* | 153 | /* |
@@ -171,7 +171,7 @@ static int serial_buf_put(struct circ_buf *cb, const char *buf, int count) | |||
171 | cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1); | 171 | cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1); |
172 | buf += c; | 172 | buf += c; |
173 | count -= c; | 173 | count -= c; |
174 | ret= c; | 174 | ret = c; |
175 | } | 175 | } |
176 | return ret; | 176 | return ret; |
177 | } | 177 | } |
@@ -197,7 +197,7 @@ static int serial_buf_get(struct circ_buf *cb, char *buf, int count) | |||
197 | cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1); | 197 | cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1); |
198 | buf += c; | 198 | buf += c; |
199 | count -= c; | 199 | count -= c; |
200 | ret= c; | 200 | ret = c; |
201 | } | 201 | } |
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
@@ -208,7 +208,7 @@ static void aircable_send(struct usb_serial_port *port) | |||
208 | { | 208 | { |
209 | int count, result; | 209 | int count, result; |
210 | struct aircable_private *priv = usb_get_serial_port_data(port); | 210 | struct aircable_private *priv = usb_get_serial_port_data(port); |
211 | unsigned char* buf; | 211 | unsigned char *buf; |
212 | __le16 *dbuf; | 212 | __le16 *dbuf; |
213 | dbg("%s - port %d", __func__, port->number); | 213 | dbg("%s - port %d", __func__, port->number); |
214 | if (port->write_urb_busy) | 214 | if (port->write_urb_busy) |
@@ -229,7 +229,8 @@ static void aircable_send(struct usb_serial_port *port) | |||
229 | buf[1] = TX_HEADER_1; | 229 | buf[1] = TX_HEADER_1; |
230 | dbuf = (__le16 *)&buf[2]; | 230 | dbuf = (__le16 *)&buf[2]; |
231 | *dbuf = cpu_to_le16((u16)count); | 231 | *dbuf = cpu_to_le16((u16)count); |
232 | serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE); | 232 | serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH, |
233 | MAX_HCI_FRAMESIZE); | ||
233 | 234 | ||
234 | memcpy(port->write_urb->transfer_buffer, buf, | 235 | memcpy(port->write_urb->transfer_buffer, buf, |
235 | count + HCI_HEADER_LENGTH); | 236 | count + HCI_HEADER_LENGTH); |
@@ -261,7 +262,7 @@ static void aircable_read(struct work_struct *work) | |||
261 | struct tty_struct *tty; | 262 | struct tty_struct *tty; |
262 | unsigned char *data; | 263 | unsigned char *data; |
263 | int count; | 264 | int count; |
264 | if (priv->rx_flags & THROTTLED){ | 265 | if (priv->rx_flags & THROTTLED) { |
265 | if (priv->rx_flags & ACTUALLY_THROTTLED) | 266 | if (priv->rx_flags & ACTUALLY_THROTTLED) |
266 | schedule_work(&priv->rx_work); | 267 | schedule_work(&priv->rx_work); |
267 | return; | 268 | return; |
@@ -282,10 +283,10 @@ static void aircable_read(struct work_struct *work) | |||
282 | count = min(64, serial_buf_data_avail(priv->rx_buf)); | 283 | count = min(64, serial_buf_data_avail(priv->rx_buf)); |
283 | 284 | ||
284 | if (count <= 0) | 285 | if (count <= 0) |
285 | return; //We have finished sending everything. | 286 | return; /* We have finished sending everything. */ |
286 | 287 | ||
287 | tty_prepare_flip_string(tty, &data, count); | 288 | tty_prepare_flip_string(tty, &data, count); |
288 | if (!data){ | 289 | if (!data) { |
289 | err("%s- kzalloc(%d) failed.", __func__, count); | 290 | err("%s- kzalloc(%d) failed.", __func__, count); |
290 | return; | 291 | return; |
291 | } | 292 | } |
@@ -304,9 +305,10 @@ static void aircable_read(struct work_struct *work) | |||
304 | static int aircable_probe(struct usb_serial *serial, | 305 | static int aircable_probe(struct usb_serial *serial, |
305 | const struct usb_device_id *id) | 306 | const struct usb_device_id *id) |
306 | { | 307 | { |
307 | struct usb_host_interface *iface_desc = serial->interface->cur_altsetting; | 308 | struct usb_host_interface *iface_desc = serial->interface-> |
309 | cur_altsetting; | ||
308 | struct usb_endpoint_descriptor *endpoint; | 310 | struct usb_endpoint_descriptor *endpoint; |
309 | int num_bulk_out=0; | 311 | int num_bulk_out = 0; |
310 | int i; | 312 | int i; |
311 | 313 | ||
312 | for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { | 314 | for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { |
@@ -325,13 +327,13 @@ static int aircable_probe(struct usb_serial *serial, | |||
325 | return 0; | 327 | return 0; |
326 | } | 328 | } |
327 | 329 | ||
328 | static int aircable_attach (struct usb_serial *serial) | 330 | static int aircable_attach(struct usb_serial *serial) |
329 | { | 331 | { |
330 | struct usb_serial_port *port = serial->port[0]; | 332 | struct usb_serial_port *port = serial->port[0]; |
331 | struct aircable_private *priv; | 333 | struct aircable_private *priv; |
332 | 334 | ||
333 | priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); | 335 | priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); |
334 | if (!priv){ | 336 | if (!priv) { |
335 | err("%s- kmalloc(%Zd) failed.", __func__, | 337 | err("%s- kmalloc(%Zd) failed.", __func__, |
336 | sizeof(struct aircable_private)); | 338 | sizeof(struct aircable_private)); |
337 | return -ENOMEM; | 339 | return -ENOMEM; |
@@ -392,7 +394,7 @@ static int aircable_write(struct usb_serial_port *port, | |||
392 | 394 | ||
393 | usb_serial_debug_data(debug, &port->dev, __func__, count, source); | 395 | usb_serial_debug_data(debug, &port->dev, __func__, count, source); |
394 | 396 | ||
395 | if (!count){ | 397 | if (!count) { |
396 | dbg("%s - write request of 0 bytes", __func__); | 398 | dbg("%s - write request of 0 bytes", __func__); |
397 | return count; | 399 | return count; |
398 | } | 400 | } |
@@ -418,31 +420,31 @@ static void aircable_write_bulk_callback(struct urb *urb) | |||
418 | 420 | ||
419 | /* This has been taken from cypress_m8.c cypress_write_int_callback */ | 421 | /* This has been taken from cypress_m8.c cypress_write_int_callback */ |
420 | switch (status) { | 422 | switch (status) { |
421 | case 0: | 423 | case 0: |
422 | /* success */ | 424 | /* success */ |
423 | break; | 425 | break; |
424 | case -ECONNRESET: | 426 | case -ECONNRESET: |
425 | case -ENOENT: | 427 | case -ENOENT: |
426 | case -ESHUTDOWN: | 428 | case -ESHUTDOWN: |
427 | /* this urb is terminated, clean up */ | 429 | /* this urb is terminated, clean up */ |
428 | dbg("%s - urb shutting down with status: %d", | 430 | dbg("%s - urb shutting down with status: %d", |
429 | __func__, status); | 431 | __func__, status); |
430 | port->write_urb_busy = 0; | 432 | port->write_urb_busy = 0; |
433 | return; | ||
434 | default: | ||
435 | /* error in the urb, so we have to resubmit it */ | ||
436 | dbg("%s - Overflow in write", __func__); | ||
437 | dbg("%s - nonzero write bulk status received: %d", | ||
438 | __func__, status); | ||
439 | port->write_urb->transfer_buffer_length = 1; | ||
440 | port->write_urb->dev = port->serial->dev; | ||
441 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
442 | if (result) | ||
443 | dev_err(&urb->dev->dev, | ||
444 | "%s - failed resubmitting write urb, error %d\n", | ||
445 | __func__, result); | ||
446 | else | ||
431 | return; | 447 | return; |
432 | default: | ||
433 | /* error in the urb, so we have to resubmit it */ | ||
434 | dbg("%s - Overflow in write", __func__); | ||
435 | dbg("%s - nonzero write bulk status received: %d", | ||
436 | __func__, status); | ||
437 | port->write_urb->transfer_buffer_length = 1; | ||
438 | port->write_urb->dev = port->serial->dev; | ||
439 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
440 | if (result) | ||
441 | dev_err(&urb->dev->dev, | ||
442 | "%s - failed resubmitting write urb, error %d\n", | ||
443 | __func__, result); | ||
444 | else | ||
445 | return; | ||
446 | } | 448 | } |
447 | 449 | ||
448 | port->write_urb_busy = 0; | 450 | port->write_urb_busy = 0; |
@@ -472,11 +474,11 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
472 | dbg("%s - caught -EPROTO, resubmitting the urb", | 474 | dbg("%s - caught -EPROTO, resubmitting the urb", |
473 | __func__); | 475 | __func__); |
474 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 476 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
475 | usb_rcvbulkpipe(port->serial->dev, | 477 | usb_rcvbulkpipe(port->serial->dev, |
476 | port->bulk_in_endpointAddress), | 478 | port->bulk_in_endpointAddress), |
477 | port->read_urb->transfer_buffer, | 479 | port->read_urb->transfer_buffer, |
478 | port->read_urb->transfer_buffer_length, | 480 | port->read_urb->transfer_buffer_length, |
479 | aircable_read_bulk_callback, port); | 481 | aircable_read_bulk_callback, port); |
480 | 482 | ||
481 | result = usb_submit_urb(urb, GFP_ATOMIC); | 483 | result = usb_submit_urb(urb, GFP_ATOMIC); |
482 | if (result) | 484 | if (result) |
@@ -490,7 +492,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
490 | } | 492 | } |
491 | 493 | ||
492 | usb_serial_debug_data(debug, &port->dev, __func__, | 494 | usb_serial_debug_data(debug, &port->dev, __func__, |
493 | urb->actual_length,urb->transfer_buffer); | 495 | urb->actual_length, urb->transfer_buffer); |
494 | 496 | ||
495 | tty = port->tty; | 497 | tty = port->tty; |
496 | if (tty && urb->actual_length) { | 498 | if (tty && urb->actual_length) { |
@@ -507,9 +509,9 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
507 | no_packages = urb->actual_length / (HCI_COMPLETE_FRAME); | 509 | no_packages = urb->actual_length / (HCI_COMPLETE_FRAME); |
508 | 510 | ||
509 | if (urb->actual_length % HCI_COMPLETE_FRAME != 0) | 511 | if (urb->actual_length % HCI_COMPLETE_FRAME != 0) |
510 | no_packages+=1; | 512 | no_packages++; |
511 | 513 | ||
512 | for (i = 0; i < no_packages ;i++) { | 514 | for (i = 0; i < no_packages; i++) { |
513 | if (remaining > (HCI_COMPLETE_FRAME)) | 515 | if (remaining > (HCI_COMPLETE_FRAME)) |
514 | package_length = HCI_COMPLETE_FRAME; | 516 | package_length = HCI_COMPLETE_FRAME; |
515 | else | 517 | else |
@@ -529,7 +531,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
529 | if (port->open_count) { | 531 | if (port->open_count) { |
530 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 532 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
531 | usb_rcvbulkpipe(port->serial->dev, | 533 | usb_rcvbulkpipe(port->serial->dev, |
532 | port->bulk_in_endpointAddress), | 534 | port->bulk_in_endpointAddress), |
533 | port->read_urb->transfer_buffer, | 535 | port->read_urb->transfer_buffer, |
534 | port->read_urb->transfer_buffer_length, | 536 | port->read_urb->transfer_buffer_length, |
535 | aircable_read_bulk_callback, port); | 537 | aircable_read_bulk_callback, port); |
@@ -602,7 +604,7 @@ static struct usb_serial_driver aircable_device = { | |||
602 | .unthrottle = aircable_unthrottle, | 604 | .unthrottle = aircable_unthrottle, |
603 | }; | 605 | }; |
604 | 606 | ||
605 | static int __init aircable_init (void) | 607 | static int __init aircable_init(void) |
606 | { | 608 | { |
607 | int retval; | 609 | int retval; |
608 | retval = usb_serial_register(&aircable_device); | 610 | retval = usb_serial_register(&aircable_device); |
@@ -619,7 +621,7 @@ failed_usb_register: | |||
619 | return retval; | 621 | return retval; |
620 | } | 622 | } |
621 | 623 | ||
622 | static void __exit aircable_exit (void) | 624 | static void __exit aircable_exit(void) |
623 | { | 625 | { |
624 | usb_deregister(&aircable_driver); | 626 | usb_deregister(&aircable_driver); |
625 | usb_serial_deregister(&aircable_device); | 627 | usb_serial_deregister(&aircable_device); |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 725b6b94c274..0798c14ce787 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -68,8 +68,9 @@ static int airprime_send_setup(struct usb_serial_port *port) | |||
68 | val |= 0x02; | 68 | val |= 0x02; |
69 | 69 | ||
70 | return usb_control_msg(serial->dev, | 70 | return usb_control_msg(serial->dev, |
71 | usb_rcvctrlpipe(serial->dev, 0), | 71 | usb_rcvctrlpipe(serial->dev, 0), |
72 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | 72 | 0x22, 0x21, val, 0, NULL, 0, |
73 | USB_CTRL_SET_TIMEOUT); | ||
73 | } | 74 | } |
74 | 75 | ||
75 | return 0; | 76 | return 0; |
@@ -90,17 +91,19 @@ static void airprime_read_bulk_callback(struct urb *urb) | |||
90 | __func__, status); | 91 | __func__, status); |
91 | return; | 92 | return; |
92 | } | 93 | } |
93 | usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); | 94 | usb_serial_debug_data(debug, &port->dev, __func__, |
95 | urb->actual_length, data); | ||
94 | 96 | ||
95 | tty = port->tty; | 97 | tty = port->tty; |
96 | if (tty && urb->actual_length) { | 98 | if (tty && urb->actual_length) { |
97 | tty_insert_flip_string (tty, data, urb->actual_length); | 99 | tty_insert_flip_string(tty, data, urb->actual_length); |
98 | tty_flip_buffer_push (tty); | 100 | tty_flip_buffer_push(tty); |
99 | } | 101 | } |
100 | 102 | ||
101 | result = usb_submit_urb (urb, GFP_ATOMIC); | 103 | result = usb_submit_urb(urb, GFP_ATOMIC); |
102 | if (result) | 104 | if (result) |
103 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", | 105 | dev_err(&port->dev, |
106 | "%s - failed resubmitting read urb, error %d\n", | ||
104 | __func__, result); | 107 | __func__, result); |
105 | return; | 108 | return; |
106 | } | 109 | } |
@@ -115,7 +118,7 @@ static void airprime_write_bulk_callback(struct urb *urb) | |||
115 | dbg("%s - port %d", __func__, port->number); | 118 | dbg("%s - port %d", __func__, port->number); |
116 | 119 | ||
117 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 120 | /* free up the transfer buffer, as usb_free_urb() does not do this */ |
118 | kfree (urb->transfer_buffer); | 121 | kfree(urb->transfer_buffer); |
119 | 122 | ||
120 | if (status) | 123 | if (status) |
121 | dbg("%s - nonzero write bulk status received: %d", | 124 | dbg("%s - nonzero write bulk status received: %d", |
@@ -171,7 +174,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) | |||
171 | } | 174 | } |
172 | usb_fill_bulk_urb(urb, serial->dev, | 175 | usb_fill_bulk_urb(urb, serial->dev, |
173 | usb_rcvbulkpipe(serial->dev, | 176 | usb_rcvbulkpipe(serial->dev, |
174 | port->bulk_out_endpointAddress), | 177 | port->bulk_out_endpointAddress), |
175 | buffer, buffer_size, | 178 | buffer, buffer_size, |
176 | airprime_read_bulk_callback, port); | 179 | airprime_read_bulk_callback, port); |
177 | result = usb_submit_urb(urb, GFP_KERNEL); | 180 | result = usb_submit_urb(urb, GFP_KERNEL); |
@@ -183,7 +186,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) | |||
183 | __func__, i, port->number, result); | 186 | __func__, i, port->number, result); |
184 | goto errout; | 187 | goto errout; |
185 | } | 188 | } |
186 | /* remember this urb so we can kill it when the port is closed */ | 189 | /* remember this urb so we can kill it when the |
190 | port is closed */ | ||
187 | priv->read_urbp[i] = urb; | 191 | priv->read_urbp[i] = urb; |
188 | } | 192 | } |
189 | 193 | ||
@@ -192,22 +196,22 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) | |||
192 | goto out; | 196 | goto out; |
193 | 197 | ||
194 | errout: | 198 | errout: |
195 | /* some error happened, cancel any submitted urbs and clean up anything that | 199 | /* some error happened, cancel any submitted urbs and clean up |
196 | got allocated successfully */ | 200 | anything that got allocated successfully */ |
197 | 201 | ||
198 | while (i-- != 0) { | 202 | while (i-- != 0) { |
199 | urb = priv->read_urbp[i]; | 203 | urb = priv->read_urbp[i]; |
200 | buffer = urb->transfer_buffer; | 204 | buffer = urb->transfer_buffer; |
201 | usb_kill_urb (urb); | 205 | usb_kill_urb(urb); |
202 | usb_free_urb (urb); | 206 | usb_free_urb(urb); |
203 | kfree (buffer); | 207 | kfree(buffer); |
204 | } | 208 | } |
205 | 209 | ||
206 | out: | 210 | out: |
207 | return result; | 211 | return result; |
208 | } | 212 | } |
209 | 213 | ||
210 | static void airprime_close(struct usb_serial_port *port, struct file * filp) | 214 | static void airprime_close(struct usb_serial_port *port, struct file *filp) |
211 | { | 215 | { |
212 | struct airprime_private *priv = usb_get_serial_port_data(port); | 216 | struct airprime_private *priv = usb_get_serial_port_data(port); |
213 | int i; | 217 | int i; |
@@ -220,16 +224,16 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) | |||
220 | mutex_lock(&port->serial->disc_mutex); | 224 | mutex_lock(&port->serial->disc_mutex); |
221 | if (!port->serial->disconnected) | 225 | if (!port->serial->disconnected) |
222 | airprime_send_setup(port); | 226 | airprime_send_setup(port); |
223 | mutex_lock(&port->serial->disc_mutex); | 227 | mutex_unlock(&port->serial->disc_mutex); |
224 | 228 | ||
225 | for (i = 0; i < NUM_READ_URBS; ++i) { | 229 | for (i = 0; i < NUM_READ_URBS; ++i) { |
226 | usb_kill_urb (priv->read_urbp[i]); | 230 | usb_kill_urb(priv->read_urbp[i]); |
227 | kfree (priv->read_urbp[i]->transfer_buffer); | 231 | kfree(priv->read_urbp[i]->transfer_buffer); |
228 | usb_free_urb (priv->read_urbp[i]); | 232 | usb_free_urb(priv->read_urbp[i]); |
229 | } | 233 | } |
230 | 234 | ||
231 | /* free up private structure */ | 235 | /* free up private structure */ |
232 | kfree (priv); | 236 | kfree(priv); |
233 | usb_set_serial_port_data(port, NULL); | 237 | usb_set_serial_port_data(port, NULL); |
234 | } | 238 | } |
235 | 239 | ||
@@ -259,10 +263,10 @@ static int airprime_write(struct usb_serial_port *port, | |||
259 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 263 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
260 | if (!urb) { | 264 | if (!urb) { |
261 | dev_err(&port->dev, "no more free urbs\n"); | 265 | dev_err(&port->dev, "no more free urbs\n"); |
262 | kfree (buffer); | 266 | kfree(buffer); |
263 | return -ENOMEM; | 267 | return -ENOMEM; |
264 | } | 268 | } |
265 | memcpy (buffer, buf, count); | 269 | memcpy(buffer, buf, count); |
266 | 270 | ||
267 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | 271 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); |
268 | 272 | ||
@@ -279,7 +283,7 @@ static int airprime_write(struct usb_serial_port *port, | |||
279 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", | 283 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", |
280 | __func__, status); | 284 | __func__, status); |
281 | count = status; | 285 | count = status; |
282 | kfree (buffer); | 286 | kfree(buffer); |
283 | } else { | 287 | } else { |
284 | spin_lock_irqsave(&priv->lock, flags); | 288 | spin_lock_irqsave(&priv->lock, flags); |
285 | ++priv->outstanding_urbs; | 289 | ++priv->outstanding_urbs; |
@@ -287,7 +291,7 @@ static int airprime_write(struct usb_serial_port *port, | |||
287 | } | 291 | } |
288 | /* we are done with this urb, so let the host driver | 292 | /* we are done with this urb, so let the host driver |
289 | * really free it when it is finished with it */ | 293 | * really free it when it is finished with it */ |
290 | usb_free_urb (urb); | 294 | usb_free_urb(urb); |
291 | return count; | 295 | return count; |
292 | } | 296 | } |
293 | 297 | ||
@@ -315,8 +319,10 @@ static int __init airprime_init(void) | |||
315 | { | 319 | { |
316 | int retval; | 320 | int retval; |
317 | 321 | ||
318 | airprime_device.num_ports = | 322 | airprime_device.num_ports = endpoints; |
319 | (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS; | 323 | if (endpoints < 0 || endpoints >= MAX_BULK_EPS) |
324 | airprime_device.num_ports = NUM_BULK_EPS; | ||
325 | |||
320 | retval = usb_serial_register(&airprime_device); | 326 | retval = usb_serial_register(&airprime_device); |
321 | if (retval) | 327 | if (retval) |
322 | return retval; | 328 | return retval; |
@@ -341,6 +347,7 @@ MODULE_LICENSE("GPL"); | |||
341 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 347 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
342 | MODULE_PARM_DESC(debug, "Debug enabled"); | 348 | MODULE_PARM_DESC(debug, "Debug enabled"); |
343 | module_param(buffer_size, int, 0); | 349 | module_param(buffer_size, int, 0); |
344 | MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)"); | 350 | MODULE_PARM_DESC(buffer_size, |
351 | "Size of the transfer buffers in bytes (default 4096)"); | ||
345 | module_param(endpoints, int, 0); | 352 | module_param(endpoints, int, 0); |
346 | MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)"); | 353 | MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)"); |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 599ab2e548a7..77895c8f8f31 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
25 | #include <linux/usb/serial.h> | 25 | #include <linux/usb/serial.h> |
26 | #include <linux/serial.h> | 26 | #include <linux/serial.h> |
27 | #include <asm/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | 28 | ||
29 | 29 | ||
30 | static int debug; | 30 | static int debug; |
@@ -246,29 +246,29 @@ static void ark3116_set_termios(struct usb_serial_port *port, | |||
246 | baud = tty_get_baud_rate(port->tty); | 246 | baud = tty_get_baud_rate(port->tty); |
247 | 247 | ||
248 | switch (baud) { | 248 | switch (baud) { |
249 | case 75: | 249 | case 75: |
250 | case 150: | 250 | case 150: |
251 | case 300: | 251 | case 300: |
252 | case 600: | 252 | case 600: |
253 | case 1200: | 253 | case 1200: |
254 | case 1800: | 254 | case 1800: |
255 | case 2400: | 255 | case 2400: |
256 | case 4800: | 256 | case 4800: |
257 | case 9600: | 257 | case 9600: |
258 | case 19200: | 258 | case 19200: |
259 | case 38400: | 259 | case 38400: |
260 | case 57600: | 260 | case 57600: |
261 | case 115200: | 261 | case 115200: |
262 | case 230400: | 262 | case 230400: |
263 | case 460800: | 263 | case 460800: |
264 | /* Report the resulting rate back to the caller */ | 264 | /* Report the resulting rate back to the caller */ |
265 | tty_encode_baud_rate(port->tty, baud, baud); | 265 | tty_encode_baud_rate(port->tty, baud, baud); |
266 | break; | 266 | break; |
267 | /* set 9600 as default (if given baudrate is invalid for example) */ | 267 | /* set 9600 as default (if given baudrate is invalid for example) */ |
268 | default: | 268 | default: |
269 | tty_encode_baud_rate(port->tty, 9600, 9600); | 269 | tty_encode_baud_rate(port->tty, 9600, 9600); |
270 | case 0: | 270 | case 0: |
271 | baud = 9600; | 271 | baud = 9600; |
272 | } | 272 | } |
273 | 273 | ||
274 | /* | 274 | /* |
@@ -380,19 +380,19 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, | |||
380 | switch (cmd) { | 380 | switch (cmd) { |
381 | case TIOCGSERIAL: | 381 | case TIOCGSERIAL: |
382 | /* XXX: Some of these values are probably wrong. */ | 382 | /* XXX: Some of these values are probably wrong. */ |
383 | memset(&serstruct, 0, sizeof (serstruct)); | 383 | memset(&serstruct, 0, sizeof(serstruct)); |
384 | serstruct.type = PORT_16654; | 384 | serstruct.type = PORT_16654; |
385 | serstruct.line = port->serial->minor; | 385 | serstruct.line = port->serial->minor; |
386 | serstruct.port = port->number; | 386 | serstruct.port = port->number; |
387 | serstruct.custom_divisor = 0; | 387 | serstruct.custom_divisor = 0; |
388 | serstruct.baud_base = 460800; | 388 | serstruct.baud_base = 460800; |
389 | 389 | ||
390 | if (copy_to_user(user_arg, &serstruct, sizeof (serstruct))) | 390 | if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) |
391 | return -EFAULT; | 391 | return -EFAULT; |
392 | 392 | ||
393 | return 0; | 393 | return 0; |
394 | case TIOCSSERIAL: | 394 | case TIOCSSERIAL: |
395 | if (copy_from_user(&serstruct, user_arg, sizeof (serstruct))) | 395 | if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) |
396 | return -EFAULT; | 396 | return -EFAULT; |
397 | return 0; | 397 | return 0; |
398 | default: | 398 | default: |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index d947d955bceb..1f7c86bd8297 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -28,6 +28,7 @@ static int debug; | |||
28 | 28 | ||
29 | static struct usb_device_id id_table [] = { | 29 | static struct usb_device_id id_table [] = { |
30 | { USB_DEVICE(0x4348, 0x5523) }, | 30 | { USB_DEVICE(0x4348, 0x5523) }, |
31 | { USB_DEVICE(0x1a86, 0x7523) }, | ||
31 | { }, | 32 | { }, |
32 | }; | 33 | }; |
33 | MODULE_DEVICE_TABLE(usb, id_table); | 34 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -130,7 +131,7 @@ static int ch341_get_status(struct usb_device *dev) | |||
130 | return -ENOMEM; | 131 | return -ENOMEM; |
131 | 132 | ||
132 | r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); | 133 | r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); |
133 | if ( r < 0) | 134 | if (r < 0) |
134 | goto out; | 135 | goto out; |
135 | 136 | ||
136 | /* Not having the datasheet for the CH341, we ignore the bytes returned | 137 | /* Not having the datasheet for the CH341, we ignore the bytes returned |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index dc0ea08ed231..f5b57b196c5a 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -73,6 +73,7 @@ static struct usb_device_id id_table [] = { | |||
73 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 73 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
74 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 74 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
75 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 75 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
76 | { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ | ||
76 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ | 77 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ |
77 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | 78 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ |
78 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | 79 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c7329f43d9c9..0ff4a3971e45 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -133,6 +133,14 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | |||
133 | static struct usb_device_id id_table_combined [] = { | 133 | static struct usb_device_id id_table_combined [] = { |
134 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 134 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
135 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 135 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
136 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | ||
137 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, | ||
138 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, | ||
139 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) }, | ||
140 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) }, | ||
141 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) }, | ||
142 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) }, | ||
143 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) }, | ||
136 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, | 144 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, |
137 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, | 145 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, |
138 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, | 146 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, |
@@ -166,8 +174,270 @@ static struct usb_device_id id_table_combined [] = { | |||
166 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 174 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
167 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 175 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
168 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 176 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
169 | { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), | 177 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) }, |
178 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) }, | ||
179 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) }, | ||
180 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) }, | ||
181 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) }, | ||
182 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) }, | ||
183 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) }, | ||
184 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) }, | ||
185 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) }, | ||
186 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) }, | ||
187 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) }, | ||
188 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) }, | ||
189 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) }, | ||
190 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) }, | ||
191 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) }, | ||
192 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) }, | ||
193 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) }, | ||
194 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) }, | ||
195 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) }, | ||
196 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) }, | ||
197 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) }, | ||
198 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) }, | ||
199 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) }, | ||
200 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) }, | ||
201 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) }, | ||
202 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) }, | ||
203 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) }, | ||
204 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) }, | ||
205 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) }, | ||
206 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) }, | ||
207 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) }, | ||
208 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) }, | ||
209 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) }, | ||
210 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) }, | ||
211 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) }, | ||
212 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) }, | ||
213 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) }, | ||
214 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) }, | ||
215 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) }, | ||
216 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID), | ||
170 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | 217 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, |
218 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) }, | ||
219 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) }, | ||
220 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) }, | ||
221 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) }, | ||
222 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID), | ||
223 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
224 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) }, | ||
225 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) }, | ||
226 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) }, | ||
227 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) }, | ||
228 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) }, | ||
229 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) }, | ||
230 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) }, | ||
231 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) }, | ||
232 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) }, | ||
233 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) }, | ||
234 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) }, | ||
235 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) }, | ||
236 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) }, | ||
237 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) }, | ||
238 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) }, | ||
239 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) }, | ||
240 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) }, | ||
241 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) }, | ||
242 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) }, | ||
243 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) }, | ||
244 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) }, | ||
245 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) }, | ||
246 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) }, | ||
247 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) }, | ||
248 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) }, | ||
249 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) }, | ||
250 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) }, | ||
251 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) }, | ||
252 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) }, | ||
253 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) }, | ||
254 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) }, | ||
255 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) }, | ||
256 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) }, | ||
257 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) }, | ||
258 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) }, | ||
259 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) }, | ||
260 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) }, | ||
261 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) }, | ||
262 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID), | ||
263 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
264 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID), | ||
265 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
266 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID), | ||
267 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
268 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID), | ||
269 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
270 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID), | ||
271 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
272 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID), | ||
273 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
274 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) }, | ||
275 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) }, | ||
276 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) }, | ||
277 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) }, | ||
278 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) }, | ||
279 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) }, | ||
280 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) }, | ||
281 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) }, | ||
282 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) }, | ||
283 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) }, | ||
284 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) }, | ||
285 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) }, | ||
286 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) }, | ||
287 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) }, | ||
288 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) }, | ||
289 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) }, | ||
290 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) }, | ||
291 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) }, | ||
292 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) }, | ||
293 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) }, | ||
294 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) }, | ||
295 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) }, | ||
296 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) }, | ||
297 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) }, | ||
298 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) }, | ||
299 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) }, | ||
300 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) }, | ||
301 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) }, | ||
302 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) }, | ||
303 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) }, | ||
304 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) }, | ||
305 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) }, | ||
306 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) }, | ||
307 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) }, | ||
308 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) }, | ||
309 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) }, | ||
310 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) }, | ||
311 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) }, | ||
312 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) }, | ||
313 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) }, | ||
314 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) }, | ||
315 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) }, | ||
316 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) }, | ||
317 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) }, | ||
318 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) }, | ||
319 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) }, | ||
320 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) }, | ||
321 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) }, | ||
322 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) }, | ||
323 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) }, | ||
324 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) }, | ||
325 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) }, | ||
326 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) }, | ||
327 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) }, | ||
328 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) }, | ||
329 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) }, | ||
330 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) }, | ||
331 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) }, | ||
332 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) }, | ||
333 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) }, | ||
334 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) }, | ||
335 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) }, | ||
336 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) }, | ||
337 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) }, | ||
338 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) }, | ||
339 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) }, | ||
340 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) }, | ||
341 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) }, | ||
342 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) }, | ||
343 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) }, | ||
344 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) }, | ||
345 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) }, | ||
346 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) }, | ||
347 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) }, | ||
348 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) }, | ||
349 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) }, | ||
350 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) }, | ||
351 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) }, | ||
352 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) }, | ||
353 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) }, | ||
354 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) }, | ||
355 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) }, | ||
356 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) }, | ||
357 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) }, | ||
358 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) }, | ||
359 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) }, | ||
360 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) }, | ||
361 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) }, | ||
362 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) }, | ||
363 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) }, | ||
364 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) }, | ||
365 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) }, | ||
366 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) }, | ||
367 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) }, | ||
368 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) }, | ||
369 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) }, | ||
370 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) }, | ||
371 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) }, | ||
372 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) }, | ||
373 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) }, | ||
374 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) }, | ||
375 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) }, | ||
376 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) }, | ||
377 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) }, | ||
378 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) }, | ||
379 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) }, | ||
380 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) }, | ||
381 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) }, | ||
382 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) }, | ||
383 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) }, | ||
384 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) }, | ||
385 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) }, | ||
386 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) }, | ||
387 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) }, | ||
388 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) }, | ||
389 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) }, | ||
390 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) }, | ||
391 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) }, | ||
392 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) }, | ||
393 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) }, | ||
394 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) }, | ||
395 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) }, | ||
396 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) }, | ||
397 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) }, | ||
398 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) }, | ||
399 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) }, | ||
400 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) }, | ||
401 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) }, | ||
402 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) }, | ||
403 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) }, | ||
404 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) }, | ||
405 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) }, | ||
406 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) }, | ||
407 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) }, | ||
408 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) }, | ||
409 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) }, | ||
410 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) }, | ||
411 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) }, | ||
412 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) }, | ||
413 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) }, | ||
414 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) }, | ||
415 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) }, | ||
416 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) }, | ||
417 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) }, | ||
418 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) }, | ||
419 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) }, | ||
420 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) }, | ||
421 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) }, | ||
422 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) }, | ||
423 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) }, | ||
424 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) }, | ||
425 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) }, | ||
426 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) }, | ||
427 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) }, | ||
428 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) }, | ||
429 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) }, | ||
430 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) }, | ||
431 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) }, | ||
432 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) }, | ||
433 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) }, | ||
434 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) }, | ||
435 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) }, | ||
436 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) }, | ||
437 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) }, | ||
438 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) }, | ||
439 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) }, | ||
440 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) }, | ||
171 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, | 441 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
172 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 442 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
173 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, | 443 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, |
@@ -366,6 +636,8 @@ static struct usb_device_id id_table_combined [] = { | |||
366 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 636 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
367 | { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), | 637 | { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), |
368 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 638 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
639 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
640 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | ||
369 | { }, /* Optional parameter entry */ | 641 | { }, /* Optional parameter entry */ |
370 | { } /* Terminating entry */ | 642 | { } /* Terminating entry */ |
371 | }; | 643 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6da539ede0ee..8302eca893ea 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -40,6 +40,17 @@ | |||
40 | /* AlphaMicro Components AMC-232USB01 device */ | 40 | /* AlphaMicro Components AMC-232USB01 device */ |
41 | #define FTDI_AMC232_PID 0xFF00 /* Product Id */ | 41 | #define FTDI_AMC232_PID 0xFF00 /* Product Id */ |
42 | 42 | ||
43 | /* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ | ||
44 | /* the VID is the standard ftdi vid (FTDI_VID) */ | ||
45 | #define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ | ||
46 | #define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ | ||
47 | #define FTDI_SCS_DEVICE_2_PID 0xD012 | ||
48 | #define FTDI_SCS_DEVICE_3_PID 0xD013 | ||
49 | #define FTDI_SCS_DEVICE_4_PID 0xD014 | ||
50 | #define FTDI_SCS_DEVICE_5_PID 0xD015 | ||
51 | #define FTDI_SCS_DEVICE_6_PID 0xD016 | ||
52 | #define FTDI_SCS_DEVICE_7_PID 0xD017 | ||
53 | |||
43 | /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ | 54 | /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ |
44 | #define FTDI_ACTZWAVE_PID 0xF2D0 | 55 | #define FTDI_ACTZWAVE_PID 0xF2D0 |
45 | 56 | ||
@@ -103,11 +114,268 @@ | |||
103 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | 114 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ |
104 | 115 | ||
105 | /* | 116 | /* |
106 | * The following are the values for the Matrix Orbital VK204-25-USB | 117 | * The following are the values for the Matrix Orbital FTDI Range |
107 | * display, which use the FT232RL. | 118 | * Anything in this range will use an FT232RL. |
108 | */ | 119 | */ |
109 | #define MTXORB_VK_VID 0x1b3d | 120 | #define MTXORB_VID 0x1B3D |
110 | #define MTXORB_VK_PID 0x0158 | 121 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 |
122 | #define MTXORB_FTDI_RANGE_0101_PID 0x0101 | ||
123 | #define MTXORB_FTDI_RANGE_0102_PID 0x0102 | ||
124 | #define MTXORB_FTDI_RANGE_0103_PID 0x0103 | ||
125 | #define MTXORB_FTDI_RANGE_0104_PID 0x0104 | ||
126 | #define MTXORB_FTDI_RANGE_0105_PID 0x0105 | ||
127 | #define MTXORB_FTDI_RANGE_0106_PID 0x0106 | ||
128 | #define MTXORB_FTDI_RANGE_0107_PID 0x0107 | ||
129 | #define MTXORB_FTDI_RANGE_0108_PID 0x0108 | ||
130 | #define MTXORB_FTDI_RANGE_0109_PID 0x0109 | ||
131 | #define MTXORB_FTDI_RANGE_010A_PID 0x010A | ||
132 | #define MTXORB_FTDI_RANGE_010B_PID 0x010B | ||
133 | #define MTXORB_FTDI_RANGE_010C_PID 0x010C | ||
134 | #define MTXORB_FTDI_RANGE_010D_PID 0x010D | ||
135 | #define MTXORB_FTDI_RANGE_010E_PID 0x010E | ||
136 | #define MTXORB_FTDI_RANGE_010F_PID 0x010F | ||
137 | #define MTXORB_FTDI_RANGE_0110_PID 0x0110 | ||
138 | #define MTXORB_FTDI_RANGE_0111_PID 0x0111 | ||
139 | #define MTXORB_FTDI_RANGE_0112_PID 0x0112 | ||
140 | #define MTXORB_FTDI_RANGE_0113_PID 0x0113 | ||
141 | #define MTXORB_FTDI_RANGE_0114_PID 0x0114 | ||
142 | #define MTXORB_FTDI_RANGE_0115_PID 0x0115 | ||
143 | #define MTXORB_FTDI_RANGE_0116_PID 0x0116 | ||
144 | #define MTXORB_FTDI_RANGE_0117_PID 0x0117 | ||
145 | #define MTXORB_FTDI_RANGE_0118_PID 0x0118 | ||
146 | #define MTXORB_FTDI_RANGE_0119_PID 0x0119 | ||
147 | #define MTXORB_FTDI_RANGE_011A_PID 0x011A | ||
148 | #define MTXORB_FTDI_RANGE_011B_PID 0x011B | ||
149 | #define MTXORB_FTDI_RANGE_011C_PID 0x011C | ||
150 | #define MTXORB_FTDI_RANGE_011D_PID 0x011D | ||
151 | #define MTXORB_FTDI_RANGE_011E_PID 0x011E | ||
152 | #define MTXORB_FTDI_RANGE_011F_PID 0x011F | ||
153 | #define MTXORB_FTDI_RANGE_0120_PID 0x0120 | ||
154 | #define MTXORB_FTDI_RANGE_0121_PID 0x0121 | ||
155 | #define MTXORB_FTDI_RANGE_0122_PID 0x0122 | ||
156 | #define MTXORB_FTDI_RANGE_0123_PID 0x0123 | ||
157 | #define MTXORB_FTDI_RANGE_0124_PID 0x0124 | ||
158 | #define MTXORB_FTDI_RANGE_0125_PID 0x0125 | ||
159 | #define MTXORB_FTDI_RANGE_0126_PID 0x0126 | ||
160 | #define MTXORB_FTDI_RANGE_0127_PID 0x0127 | ||
161 | #define MTXORB_FTDI_RANGE_0128_PID 0x0128 | ||
162 | #define MTXORB_FTDI_RANGE_0129_PID 0x0129 | ||
163 | #define MTXORB_FTDI_RANGE_012A_PID 0x012A | ||
164 | #define MTXORB_FTDI_RANGE_012B_PID 0x012B | ||
165 | #define MTXORB_FTDI_RANGE_012C_PID 0x012C | ||
166 | #define MTXORB_FTDI_RANGE_012D_PID 0x012D | ||
167 | #define MTXORB_FTDI_RANGE_012E_PID 0x012E | ||
168 | #define MTXORB_FTDI_RANGE_012F_PID 0x012F | ||
169 | #define MTXORB_FTDI_RANGE_0130_PID 0x0130 | ||
170 | #define MTXORB_FTDI_RANGE_0131_PID 0x0131 | ||
171 | #define MTXORB_FTDI_RANGE_0132_PID 0x0132 | ||
172 | #define MTXORB_FTDI_RANGE_0133_PID 0x0133 | ||
173 | #define MTXORB_FTDI_RANGE_0134_PID 0x0134 | ||
174 | #define MTXORB_FTDI_RANGE_0135_PID 0x0135 | ||
175 | #define MTXORB_FTDI_RANGE_0136_PID 0x0136 | ||
176 | #define MTXORB_FTDI_RANGE_0137_PID 0x0137 | ||
177 | #define MTXORB_FTDI_RANGE_0138_PID 0x0138 | ||
178 | #define MTXORB_FTDI_RANGE_0139_PID 0x0139 | ||
179 | #define MTXORB_FTDI_RANGE_013A_PID 0x013A | ||
180 | #define MTXORB_FTDI_RANGE_013B_PID 0x013B | ||
181 | #define MTXORB_FTDI_RANGE_013C_PID 0x013C | ||
182 | #define MTXORB_FTDI_RANGE_013D_PID 0x013D | ||
183 | #define MTXORB_FTDI_RANGE_013E_PID 0x013E | ||
184 | #define MTXORB_FTDI_RANGE_013F_PID 0x013F | ||
185 | #define MTXORB_FTDI_RANGE_0140_PID 0x0140 | ||
186 | #define MTXORB_FTDI_RANGE_0141_PID 0x0141 | ||
187 | #define MTXORB_FTDI_RANGE_0142_PID 0x0142 | ||
188 | #define MTXORB_FTDI_RANGE_0143_PID 0x0143 | ||
189 | #define MTXORB_FTDI_RANGE_0144_PID 0x0144 | ||
190 | #define MTXORB_FTDI_RANGE_0145_PID 0x0145 | ||
191 | #define MTXORB_FTDI_RANGE_0146_PID 0x0146 | ||
192 | #define MTXORB_FTDI_RANGE_0147_PID 0x0147 | ||
193 | #define MTXORB_FTDI_RANGE_0148_PID 0x0148 | ||
194 | #define MTXORB_FTDI_RANGE_0149_PID 0x0149 | ||
195 | #define MTXORB_FTDI_RANGE_014A_PID 0x014A | ||
196 | #define MTXORB_FTDI_RANGE_014B_PID 0x014B | ||
197 | #define MTXORB_FTDI_RANGE_014C_PID 0x014C | ||
198 | #define MTXORB_FTDI_RANGE_014D_PID 0x014D | ||
199 | #define MTXORB_FTDI_RANGE_014E_PID 0x014E | ||
200 | #define MTXORB_FTDI_RANGE_014F_PID 0x014F | ||
201 | #define MTXORB_FTDI_RANGE_0150_PID 0x0150 | ||
202 | #define MTXORB_FTDI_RANGE_0151_PID 0x0151 | ||
203 | #define MTXORB_FTDI_RANGE_0152_PID 0x0152 | ||
204 | #define MTXORB_FTDI_RANGE_0153_PID 0x0153 | ||
205 | #define MTXORB_FTDI_RANGE_0154_PID 0x0154 | ||
206 | #define MTXORB_FTDI_RANGE_0155_PID 0x0155 | ||
207 | #define MTXORB_FTDI_RANGE_0156_PID 0x0156 | ||
208 | #define MTXORB_FTDI_RANGE_0157_PID 0x0157 | ||
209 | #define MTXORB_FTDI_RANGE_0158_PID 0x0158 | ||
210 | #define MTXORB_FTDI_RANGE_0159_PID 0x0159 | ||
211 | #define MTXORB_FTDI_RANGE_015A_PID 0x015A | ||
212 | #define MTXORB_FTDI_RANGE_015B_PID 0x015B | ||
213 | #define MTXORB_FTDI_RANGE_015C_PID 0x015C | ||
214 | #define MTXORB_FTDI_RANGE_015D_PID 0x015D | ||
215 | #define MTXORB_FTDI_RANGE_015E_PID 0x015E | ||
216 | #define MTXORB_FTDI_RANGE_015F_PID 0x015F | ||
217 | #define MTXORB_FTDI_RANGE_0160_PID 0x0160 | ||
218 | #define MTXORB_FTDI_RANGE_0161_PID 0x0161 | ||
219 | #define MTXORB_FTDI_RANGE_0162_PID 0x0162 | ||
220 | #define MTXORB_FTDI_RANGE_0163_PID 0x0163 | ||
221 | #define MTXORB_FTDI_RANGE_0164_PID 0x0164 | ||
222 | #define MTXORB_FTDI_RANGE_0165_PID 0x0165 | ||
223 | #define MTXORB_FTDI_RANGE_0166_PID 0x0166 | ||
224 | #define MTXORB_FTDI_RANGE_0167_PID 0x0167 | ||
225 | #define MTXORB_FTDI_RANGE_0168_PID 0x0168 | ||
226 | #define MTXORB_FTDI_RANGE_0169_PID 0x0169 | ||
227 | #define MTXORB_FTDI_RANGE_016A_PID 0x016A | ||
228 | #define MTXORB_FTDI_RANGE_016B_PID 0x016B | ||
229 | #define MTXORB_FTDI_RANGE_016C_PID 0x016C | ||
230 | #define MTXORB_FTDI_RANGE_016D_PID 0x016D | ||
231 | #define MTXORB_FTDI_RANGE_016E_PID 0x016E | ||
232 | #define MTXORB_FTDI_RANGE_016F_PID 0x016F | ||
233 | #define MTXORB_FTDI_RANGE_0170_PID 0x0170 | ||
234 | #define MTXORB_FTDI_RANGE_0171_PID 0x0171 | ||
235 | #define MTXORB_FTDI_RANGE_0172_PID 0x0172 | ||
236 | #define MTXORB_FTDI_RANGE_0173_PID 0x0173 | ||
237 | #define MTXORB_FTDI_RANGE_0174_PID 0x0174 | ||
238 | #define MTXORB_FTDI_RANGE_0175_PID 0x0175 | ||
239 | #define MTXORB_FTDI_RANGE_0176_PID 0x0176 | ||
240 | #define MTXORB_FTDI_RANGE_0177_PID 0x0177 | ||
241 | #define MTXORB_FTDI_RANGE_0178_PID 0x0178 | ||
242 | #define MTXORB_FTDI_RANGE_0179_PID 0x0179 | ||
243 | #define MTXORB_FTDI_RANGE_017A_PID 0x017A | ||
244 | #define MTXORB_FTDI_RANGE_017B_PID 0x017B | ||
245 | #define MTXORB_FTDI_RANGE_017C_PID 0x017C | ||
246 | #define MTXORB_FTDI_RANGE_017D_PID 0x017D | ||
247 | #define MTXORB_FTDI_RANGE_017E_PID 0x017E | ||
248 | #define MTXORB_FTDI_RANGE_017F_PID 0x017F | ||
249 | #define MTXORB_FTDI_RANGE_0180_PID 0x0180 | ||
250 | #define MTXORB_FTDI_RANGE_0181_PID 0x0181 | ||
251 | #define MTXORB_FTDI_RANGE_0182_PID 0x0182 | ||
252 | #define MTXORB_FTDI_RANGE_0183_PID 0x0183 | ||
253 | #define MTXORB_FTDI_RANGE_0184_PID 0x0184 | ||
254 | #define MTXORB_FTDI_RANGE_0185_PID 0x0185 | ||
255 | #define MTXORB_FTDI_RANGE_0186_PID 0x0186 | ||
256 | #define MTXORB_FTDI_RANGE_0187_PID 0x0187 | ||
257 | #define MTXORB_FTDI_RANGE_0188_PID 0x0188 | ||
258 | #define MTXORB_FTDI_RANGE_0189_PID 0x0189 | ||
259 | #define MTXORB_FTDI_RANGE_018A_PID 0x018A | ||
260 | #define MTXORB_FTDI_RANGE_018B_PID 0x018B | ||
261 | #define MTXORB_FTDI_RANGE_018C_PID 0x018C | ||
262 | #define MTXORB_FTDI_RANGE_018D_PID 0x018D | ||
263 | #define MTXORB_FTDI_RANGE_018E_PID 0x018E | ||
264 | #define MTXORB_FTDI_RANGE_018F_PID 0x018F | ||
265 | #define MTXORB_FTDI_RANGE_0190_PID 0x0190 | ||
266 | #define MTXORB_FTDI_RANGE_0191_PID 0x0191 | ||
267 | #define MTXORB_FTDI_RANGE_0192_PID 0x0192 | ||
268 | #define MTXORB_FTDI_RANGE_0193_PID 0x0193 | ||
269 | #define MTXORB_FTDI_RANGE_0194_PID 0x0194 | ||
270 | #define MTXORB_FTDI_RANGE_0195_PID 0x0195 | ||
271 | #define MTXORB_FTDI_RANGE_0196_PID 0x0196 | ||
272 | #define MTXORB_FTDI_RANGE_0197_PID 0x0197 | ||
273 | #define MTXORB_FTDI_RANGE_0198_PID 0x0198 | ||
274 | #define MTXORB_FTDI_RANGE_0199_PID 0x0199 | ||
275 | #define MTXORB_FTDI_RANGE_019A_PID 0x019A | ||
276 | #define MTXORB_FTDI_RANGE_019B_PID 0x019B | ||
277 | #define MTXORB_FTDI_RANGE_019C_PID 0x019C | ||
278 | #define MTXORB_FTDI_RANGE_019D_PID 0x019D | ||
279 | #define MTXORB_FTDI_RANGE_019E_PID 0x019E | ||
280 | #define MTXORB_FTDI_RANGE_019F_PID 0x019F | ||
281 | #define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 | ||
282 | #define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 | ||
283 | #define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 | ||
284 | #define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 | ||
285 | #define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 | ||
286 | #define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 | ||
287 | #define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 | ||
288 | #define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 | ||
289 | #define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 | ||
290 | #define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 | ||
291 | #define MTXORB_FTDI_RANGE_01AA_PID 0x01AA | ||
292 | #define MTXORB_FTDI_RANGE_01AB_PID 0x01AB | ||
293 | #define MTXORB_FTDI_RANGE_01AC_PID 0x01AC | ||
294 | #define MTXORB_FTDI_RANGE_01AD_PID 0x01AD | ||
295 | #define MTXORB_FTDI_RANGE_01AE_PID 0x01AE | ||
296 | #define MTXORB_FTDI_RANGE_01AF_PID 0x01AF | ||
297 | #define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 | ||
298 | #define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 | ||
299 | #define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 | ||
300 | #define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 | ||
301 | #define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 | ||
302 | #define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 | ||
303 | #define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 | ||
304 | #define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 | ||
305 | #define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 | ||
306 | #define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 | ||
307 | #define MTXORB_FTDI_RANGE_01BA_PID 0x01BA | ||
308 | #define MTXORB_FTDI_RANGE_01BB_PID 0x01BB | ||
309 | #define MTXORB_FTDI_RANGE_01BC_PID 0x01BC | ||
310 | #define MTXORB_FTDI_RANGE_01BD_PID 0x01BD | ||
311 | #define MTXORB_FTDI_RANGE_01BE_PID 0x01BE | ||
312 | #define MTXORB_FTDI_RANGE_01BF_PID 0x01BF | ||
313 | #define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 | ||
314 | #define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 | ||
315 | #define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 | ||
316 | #define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 | ||
317 | #define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 | ||
318 | #define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 | ||
319 | #define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 | ||
320 | #define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 | ||
321 | #define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 | ||
322 | #define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 | ||
323 | #define MTXORB_FTDI_RANGE_01CA_PID 0x01CA | ||
324 | #define MTXORB_FTDI_RANGE_01CB_PID 0x01CB | ||
325 | #define MTXORB_FTDI_RANGE_01CC_PID 0x01CC | ||
326 | #define MTXORB_FTDI_RANGE_01CD_PID 0x01CD | ||
327 | #define MTXORB_FTDI_RANGE_01CE_PID 0x01CE | ||
328 | #define MTXORB_FTDI_RANGE_01CF_PID 0x01CF | ||
329 | #define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 | ||
330 | #define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 | ||
331 | #define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 | ||
332 | #define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 | ||
333 | #define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 | ||
334 | #define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 | ||
335 | #define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 | ||
336 | #define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 | ||
337 | #define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 | ||
338 | #define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 | ||
339 | #define MTXORB_FTDI_RANGE_01DA_PID 0x01DA | ||
340 | #define MTXORB_FTDI_RANGE_01DB_PID 0x01DB | ||
341 | #define MTXORB_FTDI_RANGE_01DC_PID 0x01DC | ||
342 | #define MTXORB_FTDI_RANGE_01DD_PID 0x01DD | ||
343 | #define MTXORB_FTDI_RANGE_01DE_PID 0x01DE | ||
344 | #define MTXORB_FTDI_RANGE_01DF_PID 0x01DF | ||
345 | #define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 | ||
346 | #define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 | ||
347 | #define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 | ||
348 | #define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 | ||
349 | #define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 | ||
350 | #define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 | ||
351 | #define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 | ||
352 | #define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 | ||
353 | #define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 | ||
354 | #define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 | ||
355 | #define MTXORB_FTDI_RANGE_01EA_PID 0x01EA | ||
356 | #define MTXORB_FTDI_RANGE_01EB_PID 0x01EB | ||
357 | #define MTXORB_FTDI_RANGE_01EC_PID 0x01EC | ||
358 | #define MTXORB_FTDI_RANGE_01ED_PID 0x01ED | ||
359 | #define MTXORB_FTDI_RANGE_01EE_PID 0x01EE | ||
360 | #define MTXORB_FTDI_RANGE_01EF_PID 0x01EF | ||
361 | #define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 | ||
362 | #define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 | ||
363 | #define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 | ||
364 | #define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 | ||
365 | #define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 | ||
366 | #define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 | ||
367 | #define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 | ||
368 | #define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 | ||
369 | #define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 | ||
370 | #define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 | ||
371 | #define MTXORB_FTDI_RANGE_01FA_PID 0x01FA | ||
372 | #define MTXORB_FTDI_RANGE_01FB_PID 0x01FB | ||
373 | #define MTXORB_FTDI_RANGE_01FC_PID 0x01FC | ||
374 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD | ||
375 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE | ||
376 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF | ||
377 | |||
378 | |||
111 | 379 | ||
112 | /* Interbiometrics USB I/O Board */ | 380 | /* Interbiometrics USB I/O Board */ |
113 | /* Developed for Interbiometrics by Rudolf Gugler */ | 381 | /* Developed for Interbiometrics by Rudolf Gugler */ |
@@ -560,6 +828,9 @@ | |||
560 | /* Propox devices */ | 828 | /* Propox devices */ |
561 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 829 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
562 | 830 | ||
831 | /* Rig Expert Ukraine devices */ | ||
832 | #define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ | ||
833 | |||
563 | /* Commands */ | 834 | /* Commands */ |
564 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 835 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
565 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 836 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
@@ -581,6 +852,12 @@ | |||
581 | #define FIC_NEO1973_DEBUG_PID 0x5118 | 852 | #define FIC_NEO1973_DEBUG_PID 0x5118 |
582 | 853 | ||
583 | /* | 854 | /* |
855 | * RATOC REX-USB60F | ||
856 | */ | ||
857 | #define RATOC_VENDOR_ID 0x0584 | ||
858 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
859 | |||
860 | /* | ||
584 | * BmRequestType: 1100 0000b | 861 | * BmRequestType: 1100 0000b |
585 | * bRequest: FTDI_E2_READ | 862 | * bRequest: FTDI_E2_READ |
586 | * wValue: 0 | 863 | * wValue: 0 |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index ea924dc48496..d9fb3768a2d7 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -570,7 +570,12 @@ static struct usb_serial_driver ipaq_device = { | |||
570 | .description = "PocketPC PDA", | 570 | .description = "PocketPC PDA", |
571 | .usb_driver = &ipaq_driver, | 571 | .usb_driver = &ipaq_driver, |
572 | .id_table = ipaq_id_table, | 572 | .id_table = ipaq_id_table, |
573 | .num_ports = 2, | 573 | /* |
574 | * some devices have an extra endpoint, which | ||
575 | * must be ignored as it would make the core | ||
576 | * create a second port which oopses when used | ||
577 | */ | ||
578 | .num_ports = 1, | ||
574 | .open = ipaq_open, | 579 | .open = ipaq_open, |
575 | .close = ipaq_close, | 580 | .close = ipaq_close, |
576 | .attach = ipaq_startup, | 581 | .attach = ipaq_startup, |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 8a217648b250..a01e987c7d32 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -643,7 +643,7 @@ static void read_buf_callback(struct urb *urb) | |||
643 | static int iuu_bulk_write(struct usb_serial_port *port) | 643 | static int iuu_bulk_write(struct usb_serial_port *port) |
644 | { | 644 | { |
645 | struct iuu_private *priv = usb_get_serial_port_data(port); | 645 | struct iuu_private *priv = usb_get_serial_port_data(port); |
646 | unsigned int flags; | 646 | unsigned long flags; |
647 | int result; | 647 | int result; |
648 | int i; | 648 | int i; |
649 | char *buf_ptr = port->write_urb->transfer_buffer; | 649 | char *buf_ptr = port->write_urb->transfer_buffer; |
@@ -694,7 +694,7 @@ static void iuu_uart_read_callback(struct urb *urb) | |||
694 | { | 694 | { |
695 | struct usb_serial_port *port = urb->context; | 695 | struct usb_serial_port *port = urb->context; |
696 | struct iuu_private *priv = usb_get_serial_port_data(port); | 696 | struct iuu_private *priv = usb_get_serial_port_data(port); |
697 | unsigned int flags; | 697 | unsigned long flags; |
698 | int status; | 698 | int status; |
699 | int error = 0; | 699 | int error = 0; |
700 | int len = 0; | 700 | int len = 0; |
@@ -759,7 +759,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, | |||
759 | int count) | 759 | int count) |
760 | { | 760 | { |
761 | struct iuu_private *priv = usb_get_serial_port_data(port); | 761 | struct iuu_private *priv = usb_get_serial_port_data(port); |
762 | unsigned int flags; | 762 | unsigned long flags; |
763 | dbg("%s - enter", __func__); | 763 | dbg("%s - enter", __func__); |
764 | 764 | ||
765 | if (count > 256) | 765 | if (count > 256) |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 6bcb82d3911a..78f2f6db494d 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1713,7 +1713,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, | |||
1713 | { | 1713 | { |
1714 | struct moschip_port *mos7840_port; | 1714 | struct moschip_port *mos7840_port; |
1715 | unsigned int mcr; | 1715 | unsigned int mcr; |
1716 | unsigned int status; | 1716 | int status; |
1717 | 1717 | ||
1718 | dbg("%s - port %d", __func__, port->number); | 1718 | dbg("%s - port %d", __func__, port->number); |
1719 | 1719 | ||
@@ -1740,11 +1740,10 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, | |||
1740 | 1740 | ||
1741 | mos7840_port->shadowMCR = mcr; | 1741 | mos7840_port->shadowMCR = mcr; |
1742 | 1742 | ||
1743 | status = 0; | ||
1744 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); | 1743 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); |
1745 | if (status < 0) { | 1744 | if (status < 0) { |
1746 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); | 1745 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); |
1747 | return -1; | 1746 | return status; |
1748 | } | 1747 | } |
1749 | 1748 | ||
1750 | return 0; | 1749 | return 0; |
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c new file mode 100644 index 000000000000..2e8e05462ef7 --- /dev/null +++ b/drivers/usb/serial/moto_modem.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Motorola USB Phone driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * {sigh} | ||
11 | * Mororola should be using the CDC ACM USB spec, but instead | ||
12 | * they try to just "do their own thing"... This driver should handle a | ||
13 | * few phones in which a basic "dumb serial connection" is needed to be | ||
14 | * able to get a connection through to them. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/tty.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/usb.h> | ||
22 | #include <linux/usb/serial.h> | ||
23 | |||
24 | static struct usb_device_id id_table [] = { | ||
25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ | ||
26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ | ||
27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ | ||
28 | { }, | ||
29 | }; | ||
30 | MODULE_DEVICE_TABLE(usb, id_table); | ||
31 | |||
32 | static struct usb_driver moto_driver = { | ||
33 | .name = "moto-modem", | ||
34 | .probe = usb_serial_probe, | ||
35 | .disconnect = usb_serial_disconnect, | ||
36 | .id_table = id_table, | ||
37 | .no_dynamic_id = 1, | ||
38 | }; | ||
39 | |||
40 | static struct usb_serial_driver moto_device = { | ||
41 | .driver = { | ||
42 | .owner = THIS_MODULE, | ||
43 | .name = "moto-modem", | ||
44 | }, | ||
45 | .id_table = id_table, | ||
46 | .num_ports = 1, | ||
47 | }; | ||
48 | |||
49 | static int __init moto_init(void) | ||
50 | { | ||
51 | int retval; | ||
52 | |||
53 | retval = usb_serial_register(&moto_device); | ||
54 | if (retval) | ||
55 | return retval; | ||
56 | retval = usb_register(&moto_driver); | ||
57 | if (retval) | ||
58 | usb_serial_deregister(&moto_device); | ||
59 | return retval; | ||
60 | } | ||
61 | |||
62 | static void __exit moto_exit(void) | ||
63 | { | ||
64 | usb_deregister(&moto_driver); | ||
65 | usb_serial_deregister(&moto_device); | ||
66 | } | ||
67 | |||
68 | module_init(moto_init); | ||
69 | module_exit(moto_exit); | ||
70 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e4be2d442b1e..a73420dd052a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -154,8 +154,6 @@ static int option_send_setup(struct usb_serial_port *port); | |||
154 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 154 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
155 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 155 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
156 | 156 | ||
157 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | ||
158 | |||
159 | /* FUTURE NOVATEL PRODUCTS */ | 157 | /* FUTURE NOVATEL PRODUCTS */ |
160 | #define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 | 158 | #define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 |
161 | #define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 | 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 |
@@ -184,6 +182,10 @@ static int option_send_setup(struct usb_serial_port *port); | |||
184 | #define AXESSTEL_VENDOR_ID 0x1726 | 182 | #define AXESSTEL_VENDOR_ID 0x1726 |
185 | #define AXESSTEL_PRODUCT_MV110H 0x1000 | 183 | #define AXESSTEL_PRODUCT_MV110H 0x1000 |
186 | 184 | ||
185 | #define ONDA_VENDOR_ID 0x19d2 | ||
186 | #define ONDA_PRODUCT_MSA501HS 0x0001 | ||
187 | #define ONDA_PRODUCT_ET502HS 0x0002 | ||
188 | |||
187 | #define BANDRICH_VENDOR_ID 0x1A8D | 189 | #define BANDRICH_VENDOR_ID 0x1A8D |
188 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 190 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
189 | #define BANDRICH_PRODUCT_C100_2 0x1003 | 191 | #define BANDRICH_PRODUCT_C100_2 0x1003 |
@@ -195,6 +197,9 @@ static int option_send_setup(struct usb_serial_port *port); | |||
195 | 197 | ||
196 | #define MAXON_VENDOR_ID 0x16d8 | 198 | #define MAXON_VENDOR_ID 0x16d8 |
197 | 199 | ||
200 | #define TELIT_VENDOR_ID 0x1bc7 | ||
201 | #define TELIT_PRODUCT_UC864E 0x1003 | ||
202 | |||
198 | static struct usb_device_id option_ids[] = { | 203 | static struct usb_device_id option_ids[] = { |
199 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 204 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
200 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 205 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -231,25 +236,25 @@ static struct usb_device_id option_ids[] = { | |||
231 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, | 236 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, |
232 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, | 237 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, |
233 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, | 238 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, |
234 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 239 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, |
235 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | 240 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, |
236 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | 241 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, |
237 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401) }, | 242 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, |
238 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403) }, | 243 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, |
239 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405) }, | 244 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, |
240 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406) }, | 245 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, |
241 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408) }, | 246 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, |
242 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409) }, | 247 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, |
243 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410) }, | 248 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, |
244 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411) }, | 249 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, |
245 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412) }, | 250 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, |
246 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413) }, | 251 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, |
247 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414) }, | 252 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, |
248 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415) }, | 253 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, |
249 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416) }, | 254 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, |
250 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417) }, | 255 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, |
251 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418) }, | 256 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, |
252 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419) }, | 257 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, |
253 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, | 258 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, |
254 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ | 259 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ |
255 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ | 260 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ |
@@ -269,7 +274,6 @@ static struct usb_device_id option_ids[] = { | |||
269 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ | 274 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ |
270 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 275 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ |
271 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 276 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
272 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel U727 */ | ||
273 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ | 277 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ |
274 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ | 278 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ |
275 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ | 279 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ |
@@ -293,14 +297,19 @@ static struct usb_device_id option_ids[] = { | |||
293 | { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ | 297 | { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ |
294 | { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ | 298 | { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ |
295 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ | 299 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ |
300 | { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ | ||
296 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 301 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
297 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 302 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
298 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, | 303 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, |
304 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, | ||
305 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, | ||
299 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 306 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
300 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 307 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
301 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 308 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
309 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | ||
302 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 310 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
303 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 311 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
312 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | ||
304 | { } /* Terminating entry */ | 313 | { } /* Terminating entry */ |
305 | }; | 314 | }; |
306 | MODULE_DEVICE_TABLE(usb, option_ids); | 315 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c605fb68f807..2a0dd1b50dc4 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -56,6 +56,8 @@ static struct usb_device_id id_table [] = { | |||
56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, | 56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, |
57 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, | 57 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, |
58 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, | 58 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, |
59 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, | ||
60 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, | ||
59 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, | 61 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, |
60 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, | 62 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, |
61 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, | 63 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, |
@@ -66,7 +68,6 @@ static struct usb_device_id id_table [] = { | |||
66 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, | 68 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, |
67 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, | 69 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, |
68 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, | 70 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, |
69 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
70 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, | 71 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, |
71 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, | 72 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, |
72 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, | 73 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 10cf872e5ecb..6ac3bbcf7a22 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #define PL2303_PRODUCT_ID_PHAROS 0xaaa0 | 14 | #define PL2303_PRODUCT_ID_PHAROS 0xaaa0 |
15 | #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 | 15 | #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 |
16 | #define PL2303_PRODUCT_ID_ALDIGA 0x0611 | 16 | #define PL2303_PRODUCT_ID_ALDIGA 0x0611 |
17 | #define PL2303_PRODUCT_ID_MMX 0x0612 | ||
18 | #define PL2303_PRODUCT_ID_GPRS 0x0609 | ||
17 | 19 | ||
18 | #define ATEN_VENDOR_ID 0x0557 | 20 | #define ATEN_VENDOR_ID 0x0557 |
19 | #define ATEN_VENDOR_ID2 0x0547 | 21 | #define ATEN_VENDOR_ID2 0x0547 |
@@ -36,7 +38,6 @@ | |||
36 | 38 | ||
37 | #define RATOC_VENDOR_ID 0x0584 | 39 | #define RATOC_VENDOR_ID 0x0584 |
38 | #define RATOC_PRODUCT_ID 0xb000 | 40 | #define RATOC_PRODUCT_ID 0xb000 |
39 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
40 | 41 | ||
41 | #define TRIPP_VENDOR_ID 0x2478 | 42 | #define TRIPP_VENDOR_ID 0x2478 |
42 | #define TRIPP_PRODUCT_ID 0x2008 | 43 | #define TRIPP_PRODUCT_ID 0x2008 |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 0f6d234d699b..3d9249632ae1 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -123,7 +123,8 @@ config USB_STORAGE_ALAUDA | |||
123 | 123 | ||
124 | config USB_STORAGE_ONETOUCH | 124 | config USB_STORAGE_ONETOUCH |
125 | bool "Support OneTouch Button on Maxtor Hard Drives" | 125 | bool "Support OneTouch Button on Maxtor Hard Drives" |
126 | depends on USB_STORAGE && INPUT_EVDEV | 126 | depends on USB_STORAGE |
127 | depends on INPUT=y || INPUT=USB_STORAGE | ||
127 | help | 128 | help |
128 | Say Y here to include additional code to support the Maxtor OneTouch | 129 | Say Y here to include additional code to support the Maxtor OneTouch |
129 | USB hard drive's onetouch button. | 130 | USB hard drive's onetouch button. |
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index d88824b3511c..898e67d30e56 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
@@ -46,7 +46,7 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); | 48 | memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); |
49 | memset(srb->cmnd, 0, sizeof(srb->cmnd)); | 49 | memset(srb->cmnd, 0, MAX_COMMAND_SIZE); |
50 | 50 | ||
51 | /* check if we support the command */ | 51 | /* check if we support the command */ |
52 | if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ | 52 | if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ |
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 971d13dd5e65..3addcd8f827b 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -292,6 +292,7 @@ struct isd200_info { | |||
292 | 292 | ||
293 | /* maximum number of LUNs supported */ | 293 | /* maximum number of LUNs supported */ |
294 | unsigned char MaxLUNs; | 294 | unsigned char MaxLUNs; |
295 | unsigned char cmnd[BLK_MAX_CDB]; | ||
295 | struct scsi_cmnd srb; | 296 | struct scsi_cmnd srb; |
296 | struct scatterlist sg; | 297 | struct scatterlist sg; |
297 | }; | 298 | }; |
@@ -450,6 +451,7 @@ static int isd200_action( struct us_data *us, int action, | |||
450 | 451 | ||
451 | memset(&ata, 0, sizeof(ata)); | 452 | memset(&ata, 0, sizeof(ata)); |
452 | memset(&srb_dev, 0, sizeof(srb_dev)); | 453 | memset(&srb_dev, 0, sizeof(srb_dev)); |
454 | srb->cmnd = info->cmnd; | ||
453 | srb->device = &srb_dev; | 455 | srb->device = &srb_dev; |
454 | ++srb->serial_number; | 456 | ++srb->serial_number; |
455 | 457 | ||
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index a28d49122e7a..d617e8ae6b00 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c | |||
@@ -135,7 +135,7 @@ static int usu_probe(struct usb_interface *intf, | |||
135 | stat[type].fls |= USU_MOD_FL_THREAD; | 135 | stat[type].fls |= USU_MOD_FL_THREAD; |
136 | spin_unlock_irqrestore(&usu_lock, flags); | 136 | spin_unlock_irqrestore(&usu_lock, flags); |
137 | 137 | ||
138 | task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type); | 138 | task = kthread_run(usu_probe_thread, (void*)type, "libusual_%ld", type); |
139 | if (IS_ERR(task)) { | 139 | if (IS_ERR(task)) { |
140 | rc = PTR_ERR(task); | 140 | rc = PTR_ERR(task); |
141 | printk(KERN_WARNING "libusual: " | 141 | printk(KERN_WARNING "libusual: " |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index dfd42fe9e5f0..98b89ea9e312 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "onetouch.h" | 38 | #include "onetouch.h" |
39 | #include "debug.h" | 39 | #include "debug.h" |
40 | 40 | ||
41 | void onetouch_release_input(void *onetouch_); | 41 | static void onetouch_release_input(void *onetouch_); |
42 | 42 | ||
43 | struct usb_onetouch { | 43 | struct usb_onetouch { |
44 | char name[128]; | 44 | char name[128]; |
@@ -223,7 +223,7 @@ int onetouch_connect_input(struct us_data *ss) | |||
223 | return error; | 223 | return error; |
224 | } | 224 | } |
225 | 225 | ||
226 | void onetouch_release_input(void *onetouch_) | 226 | static void onetouch_release_input(void *onetouch_) |
227 | { | 227 | { |
228 | struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_; | 228 | struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_; |
229 | 229 | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 732bf52a775e..39a7c11795c4 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -44,7 +44,8 @@ | |||
44 | * running with this patch. | 44 | * running with this patch. |
45 | * Send your submission to either Phil Dibowitz <phil@ipom.com> or | 45 | * Send your submission to either Phil Dibowitz <phil@ipom.com> or |
46 | * Alan Stern <stern@rowland.harvard.edu>, and don't forget to CC: the | 46 | * Alan Stern <stern@rowland.harvard.edu>, and don't forget to CC: the |
47 | * USB development list <linux-usb-devel@lists.sourceforge.net>. | 47 | * USB development list <linux-usb@vger.kernel.org> and the USB storage list |
48 | * <usb-storage@lists.one-eyed-alien.net> | ||
48 | */ | 49 | */ |
49 | 50 | ||
50 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> | 51 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> |
@@ -400,6 +401,22 @@ UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100, | |||
400 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 401 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
401 | US_FL_IGNORE_RESIDUE ), | 402 | US_FL_IGNORE_RESIDUE ), |
402 | 403 | ||
404 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
405 | /* CY7C68300 : support atacb */ | ||
406 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
407 | "Cypress", | ||
408 | "Cypress AT2LP", | ||
409 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
410 | 0), | ||
411 | |||
412 | /* CY7C68310 : support atacb and atacb2 */ | ||
413 | UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | ||
414 | "Cypress", | ||
415 | "Cypress ISD-300LP", | ||
416 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
417 | 0), | ||
418 | #endif | ||
419 | |||
403 | /* Reported by Simon Levitt <simon@whattf.com> | 420 | /* Reported by Simon Levitt <simon@whattf.com> |
404 | * This entry needs Sub and Proto fields */ | 421 | * This entry needs Sub and Proto fields */ |
405 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, | 422 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, |
@@ -538,25 +555,31 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, | |||
538 | "CD-RW Device", | 555 | "CD-RW Device", |
539 | US_SC_8020, US_PR_CB, NULL, 0), | 556 | US_SC_8020, US_PR_CB, NULL, 0), |
540 | 557 | ||
558 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
559 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
560 | "Shuttle/SCM", | ||
561 | "USBAT-02", | ||
562 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
563 | US_FL_SINGLE_LUN), | ||
564 | #endif | ||
565 | |||
566 | /* Reported by Dmitry Khlystov <adminimus@gmail.com> */ | ||
567 | UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, | ||
568 | "Samsung", | ||
569 | "YP-U3", | ||
570 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
571 | US_FL_MAX_SECTORS_64), | ||
572 | |||
541 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. | 573 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. |
542 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and | 574 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and |
543 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. | 575 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. |
544 | */ | 576 | */ |
545 | |||
546 | UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, | 577 | UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, |
547 | "Kobian Mercury", | 578 | "Kobian Mercury", |
548 | "Binocam DCB-132", | 579 | "Binocam DCB-132", |
549 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 580 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
550 | US_FL_BULK32), | 581 | US_FL_BULK32), |
551 | 582 | ||
552 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
553 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
554 | "Shuttle/SCM", | ||
555 | "USBAT-02", | ||
556 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
557 | US_FL_SINGLE_LUN), | ||
558 | #endif | ||
559 | |||
560 | /* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */ | 583 | /* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */ |
561 | UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, | 584 | UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, |
562 | "Belkin", | 585 | "Belkin", |
@@ -1200,6 +1223,17 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, | |||
1200 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1223 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1201 | US_FL_BULK32), | 1224 | US_FL_BULK32), |
1202 | 1225 | ||
1226 | /* Andrew Lunn <andrew@lunn.ch> | ||
1227 | * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL | ||
1228 | * on LUN 4. | ||
1229 | * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera" | ||
1230 | */ | ||
1231 | UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, | ||
1232 | "PanDigital", | ||
1233 | "Photo Frame", | ||
1234 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1235 | US_FL_NOT_LOCKABLE), | ||
1236 | |||
1203 | /* Submitted by Jan De Luyck <lkml@kcore.org> */ | 1237 | /* Submitted by Jan De Luyck <lkml@kcore.org> */ |
1204 | UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, | 1238 | UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, |
1205 | "CITIZEN", | 1239 | "CITIZEN", |
@@ -1285,6 +1319,16 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, | |||
1285 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1319 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1286 | US_FL_IGNORE_DEVICE ), | 1320 | US_FL_IGNORE_DEVICE ), |
1287 | 1321 | ||
1322 | /* Reported by F. Aben <f.aben@option.com> | ||
1323 | * This device (wrongly) has a vendor-specific device descriptor. | ||
1324 | * The entry is needed so usb-storage can bind to it's mass-storage | ||
1325 | * interface as an interface driver */ | ||
1326 | UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, | ||
1327 | "Option", | ||
1328 | "GI 0401 SD-Card", | ||
1329 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1330 | 0 ), | ||
1331 | |||
1288 | #ifdef CONFIG_USB_STORAGE_ISD200 | 1332 | #ifdef CONFIG_USB_STORAGE_ISD200 |
1289 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | 1333 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, |
1290 | "ATI", | 1334 | "ATI", |
@@ -1486,7 +1530,7 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, | |||
1486 | "Sony Ericsson", | 1530 | "Sony Ericsson", |
1487 | "M600i", | 1531 | "M600i", |
1488 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1532 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1489 | US_FL_FIX_CAPACITY ), | 1533 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
1490 | 1534 | ||
1491 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> | 1535 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> |
1492 | * Tested on hardware version 1.10. | 1536 | * Tested on hardware version 1.10. |
@@ -1658,6 +1702,16 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, | |||
1658 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1702 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1659 | US_FL_IGNORE_RESIDUE ), | 1703 | US_FL_IGNORE_RESIDUE ), |
1660 | 1704 | ||
1705 | /* Reported by Mauro Andreolini <andreoli@weblab.ing.unimo.it> | ||
1706 | * This entry is needed to bypass the ZeroCD mechanism | ||
1707 | * and to properly load as a modem device. | ||
1708 | */ | ||
1709 | UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000, | ||
1710 | "Onda ET502HS", | ||
1711 | "USB MMC Storage", | ||
1712 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1713 | US_FL_IGNORE_DEVICE), | ||
1714 | |||
1661 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> | 1715 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> |
1662 | * and Renato Perini <rperini@email.it> | 1716 | * and Renato Perini <rperini@email.it> |
1663 | */ | 1717 | */ |
@@ -1670,10 +1724,12 @@ UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001, | |||
1670 | /* | 1724 | /* |
1671 | * Patch by Pete Zaitcev <zaitcev@redhat.com> | 1725 | * Patch by Pete Zaitcev <zaitcev@redhat.com> |
1672 | * Report by Mark Patton. Red Hat bz#208928. | 1726 | * Report by Mark Patton. Red Hat bz#208928. |
1727 | * Added support for rev 0x0002 (Motorola ROKR W5) | ||
1728 | * by Javier Smaldone <javier@smaldone.com.ar> | ||
1673 | */ | 1729 | */ |
1674 | UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0001, | 1730 | UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0002, |
1675 | "Motorola", | 1731 | "Motorola", |
1676 | "RAZR V3i", | 1732 | "RAZR V3i/ROKR W5", |
1677 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1733 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1678 | US_FL_FIX_CAPACITY), | 1734 | US_FL_FIX_CAPACITY), |
1679 | 1735 | ||
@@ -1695,6 +1751,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, | |||
1695 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1751 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1696 | US_FL_GO_SLOW ), | 1752 | US_FL_GO_SLOW ), |
1697 | 1753 | ||
1754 | /* Reported by Rohan Hart <rohan.hart17@gmail.com> */ | ||
1755 | UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010, | ||
1756 | "INTOVA", | ||
1757 | "Pixtreme", | ||
1758 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1759 | US_FL_FIX_CAPACITY ), | ||
1760 | |||
1698 | /* | 1761 | /* |
1699 | * David Härdeman <david@2gen.com> | 1762 | * David Härdeman <david@2gen.com> |
1700 | * The key makes the SCSI stack print confusing (but harmless) messages | 1763 | * The key makes the SCSI stack print confusing (but harmless) messages |
@@ -1719,14 +1782,6 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | |||
1719 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1782 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1720 | US_FL_CAPACITY_HEURISTICS), | 1783 | US_FL_CAPACITY_HEURISTICS), |
1721 | 1784 | ||
1722 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
1723 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
1724 | "Cypress", | ||
1725 | "Cypress AT2LP", | ||
1726 | US_SC_CYP_ATACB, US_PR_BULK, NULL, | ||
1727 | 0), | ||
1728 | #endif | ||
1729 | |||
1730 | /* Control/Bulk transport for all SubClass values */ | 1785 | /* Control/Bulk transport for all SubClass values */ |
1731 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | 1786 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), |
1732 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | 1787 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index a856effad3bd..e268aacb773a 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -539,7 +539,8 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
539 | " has %s in unusual_devs.h (kernel" | 539 | " has %s in unusual_devs.h (kernel" |
540 | " %s)\n" | 540 | " %s)\n" |
541 | " Please send a copy of this message to " | 541 | " Please send a copy of this message to " |
542 | "<linux-usb-devel@lists.sourceforge.net>\n", | 542 | "<linux-usb@vger.kernel.org> and " |
543 | "<usb-storage@lists.one-eyed-alien.net>\n", | ||
543 | le16_to_cpu(ddesc->idVendor), | 544 | le16_to_cpu(ddesc->idVendor), |
544 | le16_to_cpu(ddesc->idProduct), | 545 | le16_to_cpu(ddesc->idProduct), |
545 | le16_to_cpu(ddesc->bcdDevice), | 546 | le16_to_cpu(ddesc->bcdDevice), |