diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2006-01-07 09:40:05 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-01-07 09:40:05 -0500 |
commit | 123656d4cc8c946f578ebd18c2050f5251720428 (patch) | |
tree | 3d5432eff034a3b9cfdc98b37e245abe5695342d /drivers/usb | |
parent | a62c80e559809e6c7851ec04d30575e85ad6f6ed (diff) | |
parent | 0aec63e67c69545ca757a73a66f5dcf05fa484bf (diff) |
Merge with Linus' kernel.
Diffstat (limited to 'drivers/usb')
163 files changed, 6124 insertions, 1978 deletions
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index a50c2bc506f2..3639c3f8d357 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI) += class/ | |||
22 | obj-$(CONFIG_USB_PRINTER) += class/ | 22 | obj-$(CONFIG_USB_PRINTER) += class/ |
23 | 23 | ||
24 | obj-$(CONFIG_USB_STORAGE) += storage/ | 24 | obj-$(CONFIG_USB_STORAGE) += storage/ |
25 | obj-$(CONFIG_USB) += storage/ | ||
25 | 26 | ||
26 | obj-$(CONFIG_USB_AIPTEK) += input/ | 27 | obj-$(CONFIG_USB_AIPTEK) += input/ |
27 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ | 28 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ |
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index f429862e0974..550ddfa71a43 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig | |||
@@ -44,6 +44,19 @@ config USB_CXACRU | |||
44 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
45 | module will be called cxacru. | 45 | module will be called cxacru. |
46 | 46 | ||
47 | config USB_UEAGLEATM | ||
48 | tristate "ADI 930 and eagle USB DSL modem" | ||
49 | depends on USB_ATM | ||
50 | select FW_LOADER | ||
51 | help | ||
52 | Say Y here if you have an ADSL USB modem based on the ADI 930 | ||
53 | or eagle chipset. In order to use your modem you will need to | ||
54 | install firmwares and CMV (Command Management Variables); see | ||
55 | <https://gna.org/projects/ueagleatm/> for details. | ||
56 | |||
57 | To compile this driver as a module, choose M here: the | ||
58 | module will be called ueagle-atm. | ||
59 | |||
47 | config USB_XUSBATM | 60 | config USB_XUSBATM |
48 | tristate "Other USB DSL modem support" | 61 | tristate "Other USB DSL modem support" |
49 | depends on USB_ATM | 62 | depends on USB_ATM |
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile index 85099718c683..4c4a776ab1cd 100644 --- a/drivers/usb/atm/Makefile +++ b/drivers/usb/atm/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o | 5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o |
6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o | 6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o |
7 | obj-$(CONFIG_USB_UEAGLEATM) += ueagle-atm.o | ||
7 | obj-$(CONFIG_USB_ATM) += usbatm.o | 8 | obj-$(CONFIG_USB_ATM) += usbatm.o |
8 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o | 9 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o |
9 | 10 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 9d59dc62e6d2..af0a41e7870e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -853,7 +853,6 @@ static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_ | |||
853 | } | 853 | } |
854 | 854 | ||
855 | static struct usb_driver cxacru_usb_driver = { | 855 | static struct usb_driver cxacru_usb_driver = { |
856 | .owner = THIS_MODULE, | ||
857 | .name = cxacru_driver_name, | 856 | .name = cxacru_driver_name, |
858 | .probe = cxacru_usb_probe, | 857 | .probe = cxacru_usb_probe, |
859 | .disconnect = usbatm_usb_disconnect, | 858 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index d0cbbb7f0385..b28336148658 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -659,7 +659,6 @@ MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); | |||
659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); | 659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); |
660 | 660 | ||
661 | static struct usb_driver speedtch_usb_driver = { | 661 | static struct usb_driver speedtch_usb_driver = { |
662 | .owner = THIS_MODULE, | ||
663 | .name = speedtch_driver_name, | 662 | .name = speedtch_driver_name, |
664 | .probe = speedtch_usb_probe, | 663 | .probe = speedtch_usb_probe, |
665 | .disconnect = usbatm_usb_disconnect, | 664 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c new file mode 100644 index 000000000000..7d2a679989ed --- /dev/null +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -0,0 +1,1820 @@ | |||
1 | /*- | ||
2 | * Copyright (c) 2003, 2004 | ||
3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | ||
4 | * | ||
5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | ||
6 | * | ||
7 | * This software is available to you under a choice of one of two | ||
8 | * licenses. You may choose to be licensed under the terms of the GNU | ||
9 | * General Public License (GPL) Version 2, available from the file | ||
10 | * COPYING in the main directory of this source tree, or the | ||
11 | * BSD license below: | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * 1. Redistributions of source code must retain the above copyright | ||
17 | * notice unmodified, this list of conditions, and the following | ||
18 | * disclaimer. | ||
19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer in the | ||
21 | * documentation and/or other materials provided with the distribution. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
33 | * SUCH DAMAGE. | ||
34 | * | ||
35 | * GPL license : | ||
36 | * This program is free software; you can redistribute it and/or | ||
37 | * modify it under the terms of the GNU General Public License | ||
38 | * as published by the Free Software Foundation; either version 2 | ||
39 | * of the License, or (at your option) any later version. | ||
40 | * | ||
41 | * This program is distributed in the hope that it will be useful, | ||
42 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
43 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
44 | * GNU General Public License for more details. | ||
45 | * | ||
46 | * You should have received a copy of the GNU General Public License | ||
47 | * along with this program; if not, write to the Free Software | ||
48 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
49 | * | ||
50 | * | ||
51 | * HISTORY : some part of the code was base on ueagle 1.3 BSD driver, | ||
52 | * Damien Bergamini agree to put his code under a DUAL GPL/BSD license. | ||
53 | * | ||
54 | * The rest of the code was was rewritten from scratch. | ||
55 | */ | ||
56 | |||
57 | #include <linux/module.h> | ||
58 | #include <linux/moduleparam.h> | ||
59 | #include <linux/init.h> | ||
60 | #include <linux/crc32.h> | ||
61 | #include <linux/usb.h> | ||
62 | #include <linux/firmware.h> | ||
63 | #include <linux/ctype.h> | ||
64 | #include <linux/kthread.h> | ||
65 | #include <linux/version.h> | ||
66 | #include <asm/unaligned.h> | ||
67 | |||
68 | #include "usbatm.h" | ||
69 | |||
70 | #define EAGLEUSBVERSION "ueagle 1.1" | ||
71 | |||
72 | |||
73 | /* | ||
74 | * Debug macros | ||
75 | */ | ||
76 | #define uea_dbg(usb_dev, format, args...) \ | ||
77 | do { \ | ||
78 | if (debug >= 1) \ | ||
79 | dev_dbg(&(usb_dev)->dev, \ | ||
80 | "[ueagle-atm dbg] %s: " format, \ | ||
81 | __FUNCTION__, ##args); \ | ||
82 | } while (0) | ||
83 | |||
84 | #define uea_vdbg(usb_dev, format, args...) \ | ||
85 | do { \ | ||
86 | if (debug >= 2) \ | ||
87 | dev_dbg(&(usb_dev)->dev, \ | ||
88 | "[ueagle-atm vdbg] " format, ##args); \ | ||
89 | } while (0) | ||
90 | |||
91 | #define uea_enters(usb_dev) \ | ||
92 | uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) | ||
93 | |||
94 | #define uea_leaves(usb_dev) \ | ||
95 | uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__) | ||
96 | |||
97 | #define uea_err(usb_dev, format,args...) \ | ||
98 | dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args) | ||
99 | |||
100 | #define uea_warn(usb_dev, format,args...) \ | ||
101 | dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args) | ||
102 | |||
103 | #define uea_info(usb_dev, format,args...) \ | ||
104 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | ||
105 | |||
106 | struct uea_cmvs { | ||
107 | u32 address; | ||
108 | u16 offset; | ||
109 | u32 data; | ||
110 | } __attribute__ ((packed)); | ||
111 | |||
112 | struct uea_softc { | ||
113 | struct usb_device *usb_dev; | ||
114 | struct usbatm_data *usbatm; | ||
115 | |||
116 | int modem_index; | ||
117 | unsigned int driver_info; | ||
118 | |||
119 | int booting; | ||
120 | int reset; | ||
121 | |||
122 | wait_queue_head_t sync_q; | ||
123 | |||
124 | struct task_struct *kthread; | ||
125 | u32 data; | ||
126 | wait_queue_head_t cmv_ack_wait; | ||
127 | int cmv_ack; | ||
128 | |||
129 | struct work_struct task; | ||
130 | u16 pageno; | ||
131 | u16 ovl; | ||
132 | |||
133 | const struct firmware *dsp_firm; | ||
134 | struct urb *urb_int; | ||
135 | |||
136 | u8 cmv_function; | ||
137 | u16 cmv_idx; | ||
138 | u32 cmv_address; | ||
139 | u16 cmv_offset; | ||
140 | |||
141 | /* keep in sync with eaglectl */ | ||
142 | struct uea_stats { | ||
143 | struct { | ||
144 | u32 state; | ||
145 | u32 flags; | ||
146 | u32 mflags; | ||
147 | u32 vidcpe; | ||
148 | u32 vidco; | ||
149 | u32 dsrate; | ||
150 | u32 usrate; | ||
151 | u32 dsunc; | ||
152 | u32 usunc; | ||
153 | u32 dscorr; | ||
154 | u32 uscorr; | ||
155 | u32 txflow; | ||
156 | u32 rxflow; | ||
157 | u32 usattenuation; | ||
158 | u32 dsattenuation; | ||
159 | u32 dsmargin; | ||
160 | u32 usmargin; | ||
161 | u32 firmid; | ||
162 | } phy; | ||
163 | } stats; | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | * Elsa IDs | ||
168 | */ | ||
169 | #define ELSA_VID 0x05CC | ||
170 | #define ELSA_PID_PSTFIRM 0x3350 | ||
171 | #define ELSA_PID_PREFIRM 0x3351 | ||
172 | |||
173 | /* | ||
174 | * Sagem USB IDs | ||
175 | */ | ||
176 | #define EAGLE_VID 0x1110 | ||
177 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | ||
178 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | ||
179 | |||
180 | #define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */ | ||
181 | #define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */ | ||
182 | |||
183 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | ||
184 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | ||
185 | |||
186 | /* | ||
187 | * Eagle III Pid | ||
188 | */ | ||
189 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | ||
190 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | ||
191 | |||
192 | /* | ||
193 | * USR USB IDs | ||
194 | */ | ||
195 | #define USR_VID 0x0BAF | ||
196 | #define MILLER_A_PID_PREFIRM 0x00F2 | ||
197 | #define MILLER_A_PID_PSTFIRM 0x00F1 | ||
198 | #define MILLER_B_PID_PREFIRM 0x00FA | ||
199 | #define MILLER_B_PID_PSTFIRM 0x00F9 | ||
200 | #define HEINEKEN_A_PID_PREFIRM 0x00F6 | ||
201 | #define HEINEKEN_A_PID_PSTFIRM 0x00F5 | ||
202 | #define HEINEKEN_B_PID_PREFIRM 0x00F8 | ||
203 | #define HEINEKEN_B_PID_PSTFIRM 0x00F7 | ||
204 | |||
205 | #define PREFIRM 0 | ||
206 | #define PSTFIRM (1<<7) | ||
207 | enum { | ||
208 | ADI930 = 0, | ||
209 | EAGLE_I, | ||
210 | EAGLE_II, | ||
211 | EAGLE_III | ||
212 | }; | ||
213 | |||
214 | /* macros for both struct usb_device_id and struct uea_softc */ | ||
215 | #define UEA_IS_PREFIRM(x) \ | ||
216 | (!((x)->driver_info & PSTFIRM)) | ||
217 | #define UEA_CHIP_VERSION(x) \ | ||
218 | ((x)->driver_info & 0xf) | ||
219 | |||
220 | #define IS_ISDN(sc) \ | ||
221 | (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80) | ||
222 | |||
223 | #define INS_TO_USBDEV(ins) ins->usb_dev | ||
224 | |||
225 | #define GET_STATUS(data) \ | ||
226 | ((data >> 8) & 0xf) | ||
227 | #define IS_OPERATIONAL(sc) \ | ||
228 | (GET_STATUS(sc->stats.phy.state) == 2) | ||
229 | |||
230 | /* | ||
231 | * Set of macros to handle unaligned data in the firmware blob. | ||
232 | * The FW_GET_BYTE() macro is provided only for consistency. | ||
233 | */ | ||
234 | |||
235 | #define FW_GET_BYTE(p) *((__u8 *) (p)) | ||
236 | #define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p))) | ||
237 | #define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p))) | ||
238 | |||
239 | #define FW_DIR "ueagle-atm/" | ||
240 | #define NB_MODEM 4 | ||
241 | |||
242 | #define BULK_TIMEOUT 300 | ||
243 | #define CTRL_TIMEOUT 1000 | ||
244 | |||
245 | #define ACK_TIMEOUT msecs_to_jiffies(1500) | ||
246 | |||
247 | #define UEA_INTR_IFACE_NO 0 | ||
248 | #define UEA_US_IFACE_NO 1 | ||
249 | #define UEA_DS_IFACE_NO 2 | ||
250 | |||
251 | #define FASTEST_ISO_INTF 8 | ||
252 | |||
253 | #define UEA_BULK_DATA_PIPE 0x02 | ||
254 | #define UEA_IDMA_PIPE 0x04 | ||
255 | #define UEA_INTR_PIPE 0x04 | ||
256 | #define UEA_ISO_DATA_PIPE 0x08 | ||
257 | |||
258 | #define UEA_SET_BLOCK 0x0001 | ||
259 | #define UEA_SET_MODE 0x0003 | ||
260 | #define UEA_SET_2183_DATA 0x0004 | ||
261 | #define UEA_SET_TIMEOUT 0x0011 | ||
262 | |||
263 | #define UEA_LOOPBACK_OFF 0x0002 | ||
264 | #define UEA_LOOPBACK_ON 0x0003 | ||
265 | #define UEA_BOOT_IDMA 0x0006 | ||
266 | #define UEA_START_RESET 0x0007 | ||
267 | #define UEA_END_RESET 0x0008 | ||
268 | |||
269 | #define UEA_SWAP_MAILBOX (0x3fcd | 0x4000) | ||
270 | #define UEA_MPTX_START (0x3fce | 0x4000) | ||
271 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | ||
272 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | ||
273 | |||
274 | /* structure describing a block within a DSP page */ | ||
275 | struct block_info { | ||
276 | __le16 wHdr; | ||
277 | #define UEA_BIHDR 0xabcd | ||
278 | __le16 wAddress; | ||
279 | __le16 wSize; | ||
280 | __le16 wOvlOffset; | ||
281 | __le16 wOvl; /* overlay */ | ||
282 | __le16 wLast; | ||
283 | } __attribute__ ((packed)); | ||
284 | #define BLOCK_INFO_SIZE 12 | ||
285 | |||
286 | /* structure representing a CMV (Configuration and Management Variable) */ | ||
287 | struct cmv { | ||
288 | __le16 wPreamble; | ||
289 | #define PREAMBLE 0x535c | ||
290 | __u8 bDirection; | ||
291 | #define MODEMTOHOST 0x01 | ||
292 | #define HOSTTOMODEM 0x10 | ||
293 | __u8 bFunction; | ||
294 | #define FUNCTION_TYPE(f) ((f) >> 4) | ||
295 | #define MEMACCESS 0x1 | ||
296 | #define ADSLDIRECTIVE 0x7 | ||
297 | |||
298 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
299 | /* for MEMACCESS */ | ||
300 | #define REQUESTREAD 0x0 | ||
301 | #define REQUESTWRITE 0x1 | ||
302 | #define REPLYREAD 0x2 | ||
303 | #define REPLYWRITE 0x3 | ||
304 | /* for ADSLDIRECTIVE */ | ||
305 | #define KERNELREADY 0x0 | ||
306 | #define MODEMREADY 0x1 | ||
307 | |||
308 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | ||
309 | __le16 wIndex; | ||
310 | __le32 dwSymbolicAddress; | ||
311 | #define MAKESA(a, b, c, d) \ | ||
312 | (((c) & 0xff) << 24 | \ | ||
313 | ((d) & 0xff) << 16 | \ | ||
314 | ((a) & 0xff) << 8 | \ | ||
315 | ((b) & 0xff)) | ||
316 | |||
317 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | ||
318 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | ||
319 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | ||
320 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | ||
321 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | ||
322 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | ||
323 | __le16 wOffsetAddress; | ||
324 | __le32 dwData; | ||
325 | } __attribute__ ((packed)); | ||
326 | #define CMV_SIZE 16 | ||
327 | |||
328 | /* structure representing swap information */ | ||
329 | struct swap_info { | ||
330 | __u8 bSwapPageNo; | ||
331 | __u8 bOvl; /* overlay */ | ||
332 | } __attribute__ ((packed)); | ||
333 | |||
334 | /* structure representing interrupt data */ | ||
335 | struct intr_pkt { | ||
336 | __u8 bType; | ||
337 | __u8 bNotification; | ||
338 | __le16 wValue; | ||
339 | __le16 wIndex; | ||
340 | __le16 wLength; | ||
341 | __le16 wInterrupt; | ||
342 | #define INT_LOADSWAPPAGE 0x0001 | ||
343 | #define INT_INCOMINGCMV 0x0002 | ||
344 | union { | ||
345 | struct { | ||
346 | struct swap_info swapinfo; | ||
347 | __le16 wDataSize; | ||
348 | } __attribute__ ((packed)) s1; | ||
349 | |||
350 | struct { | ||
351 | struct cmv cmv; | ||
352 | __le16 wDataSize; | ||
353 | } __attribute__ ((packed)) s2; | ||
354 | } __attribute__ ((packed)) u; | ||
355 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
356 | #define bOvl u.s1.swapinfo.bOvl | ||
357 | } __attribute__ ((packed)); | ||
358 | #define INTR_PKT_SIZE 28 | ||
359 | |||
360 | static struct usb_driver uea_driver; | ||
361 | static DECLARE_MUTEX(uea_semaphore); | ||
362 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | ||
363 | |||
364 | static int modem_index; | ||
365 | static unsigned int debug; | ||
366 | static int sync_wait[NB_MODEM]; | ||
367 | static char *cmv_file[NB_MODEM]; | ||
368 | |||
369 | module_param(debug, uint, 0644); | ||
370 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | ||
371 | module_param_array(sync_wait, bool, NULL, 0644); | ||
372 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | ||
373 | module_param_array(cmv_file, charp, NULL, 0644); | ||
374 | MODULE_PARM_DESC(cmv_file, | ||
375 | "file name with configuration and management variables"); | ||
376 | |||
377 | #define UPDATE_ATM_STAT(type, val) \ | ||
378 | do { \ | ||
379 | if (sc->usbatm->atm_dev) \ | ||
380 | sc->usbatm->atm_dev->type = val; \ | ||
381 | } while (0) | ||
382 | |||
383 | /* Firmware loading */ | ||
384 | #define LOAD_INTERNAL 0xA0 | ||
385 | #define F8051_USBCS 0x7f92 | ||
386 | |||
387 | /** | ||
388 | * uea_send_modem_cmd - Send a command for pre-firmware devices. | ||
389 | */ | ||
390 | static int uea_send_modem_cmd(struct usb_device *usb, | ||
391 | u16 addr, u16 size, u8 * buff) | ||
392 | { | ||
393 | int ret = -ENOMEM; | ||
394 | u8 *xfer_buff; | ||
395 | |||
396 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
397 | if (xfer_buff) { | ||
398 | memcpy(xfer_buff, buff, size); | ||
399 | ret = usb_control_msg(usb, | ||
400 | usb_sndctrlpipe(usb, 0), | ||
401 | LOAD_INTERNAL, | ||
402 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
403 | USB_RECIP_DEVICE, addr, 0, xfer_buff, | ||
404 | size, CTRL_TIMEOUT); | ||
405 | kfree(xfer_buff); | ||
406 | } | ||
407 | |||
408 | if (ret < 0) | ||
409 | return ret; | ||
410 | |||
411 | return (ret == size) ? 0 : -EIO; | ||
412 | } | ||
413 | |||
414 | static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context) | ||
415 | { | ||
416 | struct usb_device *usb = context; | ||
417 | u8 *pfw, value; | ||
418 | u32 crc = 0; | ||
419 | int ret, size; | ||
420 | |||
421 | uea_enters(usb); | ||
422 | if (!fw_entry) { | ||
423 | uea_err(usb, "firmware is not available\n"); | ||
424 | goto err; | ||
425 | } | ||
426 | |||
427 | pfw = fw_entry->data; | ||
428 | size = fw_entry->size; | ||
429 | if (size < 4) | ||
430 | goto err_fw_corrupted; | ||
431 | |||
432 | crc = FW_GET_LONG(pfw); | ||
433 | pfw += 4; | ||
434 | size -= 4; | ||
435 | if (crc32_be(0, pfw, size) != crc) | ||
436 | goto err_fw_corrupted; | ||
437 | |||
438 | /* | ||
439 | * Start to upload formware : send reset | ||
440 | */ | ||
441 | value = 1; | ||
442 | ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value); | ||
443 | |||
444 | if (ret < 0) { | ||
445 | uea_err(usb, "modem reset failed with error %d\n", ret); | ||
446 | goto err; | ||
447 | } | ||
448 | |||
449 | while (size > 3) { | ||
450 | u8 len = FW_GET_BYTE(pfw); | ||
451 | u16 add = FW_GET_WORD(pfw + 1); | ||
452 | |||
453 | size -= len + 3; | ||
454 | if (size < 0) | ||
455 | goto err_fw_corrupted; | ||
456 | |||
457 | ret = uea_send_modem_cmd(usb, add, len, pfw + 3); | ||
458 | if (ret < 0) { | ||
459 | uea_err(usb, "uploading firmware data failed " | ||
460 | "with error %d\n", ret); | ||
461 | goto err; | ||
462 | } | ||
463 | pfw += len + 3; | ||
464 | } | ||
465 | |||
466 | if (size != 0) | ||
467 | goto err_fw_corrupted; | ||
468 | |||
469 | /* | ||
470 | * Tell the modem we finish : de-assert reset | ||
471 | */ | ||
472 | value = 0; | ||
473 | ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value); | ||
474 | if (ret < 0) | ||
475 | uea_err(usb, "modem de-assert failed with error %d\n", ret); | ||
476 | else | ||
477 | uea_info(usb, "firmware uploaded\n"); | ||
478 | |||
479 | uea_leaves(usb); | ||
480 | return; | ||
481 | |||
482 | err_fw_corrupted: | ||
483 | uea_err(usb, "firmware is corrupted\n"); | ||
484 | err: | ||
485 | uea_leaves(usb); | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * uea_load_firmware - Load usb firmware for pre-firmware devices. | ||
490 | */ | ||
491 | static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | ||
492 | { | ||
493 | int ret; | ||
494 | char *fw_name = FW_DIR "eagle.fw"; | ||
495 | |||
496 | uea_enters(usb); | ||
497 | uea_info(usb, "pre-firmware device, uploading firmware\n"); | ||
498 | |||
499 | switch (ver) { | ||
500 | case ADI930: | ||
501 | fw_name = FW_DIR "adi930.fw"; | ||
502 | break; | ||
503 | case EAGLE_I: | ||
504 | fw_name = FW_DIR "eagleI.fw"; | ||
505 | break; | ||
506 | case EAGLE_II: | ||
507 | fw_name = FW_DIR "eagleII.fw"; | ||
508 | break; | ||
509 | case EAGLE_III: | ||
510 | fw_name = FW_DIR "eagleIII.fw"; | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | ||
515 | if (ret) | ||
516 | uea_err(usb, "firmware %s is not available\n", fw_name); | ||
517 | else | ||
518 | uea_info(usb, "loading firmware %s\n", fw_name); | ||
519 | |||
520 | uea_leaves(usb); | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | /* modem management : dsp firmware, send/read CMV, monitoring statistic | ||
525 | */ | ||
526 | |||
527 | /* | ||
528 | * Make sure that the DSP code provided is safe to use. | ||
529 | */ | ||
530 | static int check_dsp(u8 *dsp, unsigned int len) | ||
531 | { | ||
532 | u8 pagecount, blockcount; | ||
533 | u16 blocksize; | ||
534 | u32 pageoffset; | ||
535 | unsigned int i, j, p, pp; | ||
536 | |||
537 | pagecount = FW_GET_BYTE(dsp); | ||
538 | p = 1; | ||
539 | |||
540 | /* enough space for page offsets? */ | ||
541 | if (p + 4 * pagecount > len) | ||
542 | return 1; | ||
543 | |||
544 | for (i = 0; i < pagecount; i++) { | ||
545 | |||
546 | pageoffset = FW_GET_LONG(dsp + p); | ||
547 | p += 4; | ||
548 | |||
549 | if (pageoffset == 0) | ||
550 | continue; | ||
551 | |||
552 | /* enough space for blockcount? */ | ||
553 | if (pageoffset >= len) | ||
554 | return 1; | ||
555 | |||
556 | pp = pageoffset; | ||
557 | blockcount = FW_GET_BYTE(dsp + pp); | ||
558 | pp += 1; | ||
559 | |||
560 | for (j = 0; j < blockcount; j++) { | ||
561 | |||
562 | /* enough space for block header? */ | ||
563 | if (pp + 4 > len) | ||
564 | return 1; | ||
565 | |||
566 | pp += 2; /* skip blockaddr */ | ||
567 | blocksize = FW_GET_WORD(dsp + pp); | ||
568 | pp += 2; | ||
569 | |||
570 | /* enough space for block data? */ | ||
571 | if (pp + blocksize > len) | ||
572 | return 1; | ||
573 | |||
574 | pp += blocksize; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * send data to the idma pipe | ||
583 | * */ | ||
584 | static int uea_idma_write(struct uea_softc *sc, void *data, u32 size) | ||
585 | { | ||
586 | int ret = -ENOMEM; | ||
587 | u8 *xfer_buff; | ||
588 | int bytes_read; | ||
589 | |||
590 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
591 | if (!xfer_buff) { | ||
592 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | memcpy(xfer_buff, data, size); | ||
597 | |||
598 | ret = usb_bulk_msg(sc->usb_dev, | ||
599 | usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE), | ||
600 | xfer_buff, size, &bytes_read, BULK_TIMEOUT); | ||
601 | |||
602 | kfree(xfer_buff); | ||
603 | if (ret < 0) | ||
604 | return ret; | ||
605 | if (size != bytes_read) { | ||
606 | uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size, | ||
607 | bytes_read); | ||
608 | return -EIO; | ||
609 | } | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int request_dsp(struct uea_softc *sc) | ||
615 | { | ||
616 | int ret; | ||
617 | char *dsp_name; | ||
618 | |||
619 | if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
620 | if (IS_ISDN(sc)) | ||
621 | dsp_name = FW_DIR "DSP9i.bin"; | ||
622 | else | ||
623 | dsp_name = FW_DIR "DSP9p.bin"; | ||
624 | } else { | ||
625 | if (IS_ISDN(sc)) | ||
626 | dsp_name = FW_DIR "DSPei.bin"; | ||
627 | else | ||
628 | dsp_name = FW_DIR "DSPep.bin"; | ||
629 | } | ||
630 | |||
631 | ret = request_firmware(&sc->dsp_firm, | ||
632 | dsp_name, &sc->usb_dev->dev); | ||
633 | if (ret < 0) { | ||
634 | uea_err(INS_TO_USBDEV(sc), | ||
635 | "requesting firmware %s failed with error %d\n", | ||
636 | dsp_name, ret); | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | ||
641 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
642 | dsp_name); | ||
643 | release_firmware(sc->dsp_firm); | ||
644 | sc->dsp_firm = NULL; | ||
645 | return -EILSEQ; | ||
646 | } | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | /* | ||
652 | * The uea_load_page() function must be called within a process context | ||
653 | */ | ||
654 | static void uea_load_page(void *xsc) | ||
655 | { | ||
656 | struct uea_softc *sc = xsc; | ||
657 | u16 pageno = sc->pageno; | ||
658 | u16 ovl = sc->ovl; | ||
659 | struct block_info bi; | ||
660 | |||
661 | u8 *p; | ||
662 | u8 pagecount, blockcount; | ||
663 | u16 blockaddr, blocksize; | ||
664 | u32 pageoffset; | ||
665 | int i; | ||
666 | |||
667 | /* reload firmware when reboot start and it's loaded already */ | ||
668 | if (ovl == 0 && pageno == 0 && sc->dsp_firm) { | ||
669 | release_firmware(sc->dsp_firm); | ||
670 | sc->dsp_firm = NULL; | ||
671 | } | ||
672 | |||
673 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
674 | return; | ||
675 | |||
676 | p = sc->dsp_firm->data; | ||
677 | pagecount = FW_GET_BYTE(p); | ||
678 | p += 1; | ||
679 | |||
680 | if (pageno >= pagecount) | ||
681 | goto bad1; | ||
682 | |||
683 | p += 4 * pageno; | ||
684 | pageoffset = FW_GET_LONG(p); | ||
685 | |||
686 | if (pageoffset == 0) | ||
687 | goto bad1; | ||
688 | |||
689 | p = sc->dsp_firm->data + pageoffset; | ||
690 | blockcount = FW_GET_BYTE(p); | ||
691 | p += 1; | ||
692 | |||
693 | uea_dbg(INS_TO_USBDEV(sc), | ||
694 | "sending %u blocks for DSP page %u\n", blockcount, pageno); | ||
695 | |||
696 | bi.wHdr = cpu_to_le16(UEA_BIHDR); | ||
697 | bi.wOvl = cpu_to_le16(ovl); | ||
698 | bi.wOvlOffset = cpu_to_le16(ovl | 0x8000); | ||
699 | |||
700 | for (i = 0; i < blockcount; i++) { | ||
701 | blockaddr = FW_GET_WORD(p); | ||
702 | p += 2; | ||
703 | |||
704 | blocksize = FW_GET_WORD(p); | ||
705 | p += 2; | ||
706 | |||
707 | bi.wSize = cpu_to_le16(blocksize); | ||
708 | bi.wAddress = cpu_to_le16(blockaddr); | ||
709 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | ||
710 | |||
711 | /* send block info through the IDMA pipe */ | ||
712 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | ||
713 | goto bad2; | ||
714 | |||
715 | /* send block data through the IDMA pipe */ | ||
716 | if (uea_idma_write(sc, p, blocksize)) | ||
717 | goto bad2; | ||
718 | |||
719 | p += blocksize; | ||
720 | } | ||
721 | |||
722 | return; | ||
723 | |||
724 | bad2: | ||
725 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); | ||
726 | return; | ||
727 | bad1: | ||
728 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); | ||
729 | } | ||
730 | |||
731 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | ||
732 | { | ||
733 | sc->cmv_ack = 1; | ||
734 | wake_up(&sc->cmv_ack_wait); | ||
735 | } | ||
736 | |||
737 | static inline int wait_cmv_ack(struct uea_softc *sc) | ||
738 | { | ||
739 | int ret = wait_event_timeout(sc->cmv_ack_wait, | ||
740 | sc->cmv_ack, ACK_TIMEOUT); | ||
741 | sc->cmv_ack = 0; | ||
742 | |||
743 | if (ret < 0) | ||
744 | return ret; | ||
745 | |||
746 | return (ret == 0) ? -ETIMEDOUT : 0; | ||
747 | |||
748 | } | ||
749 | |||
750 | #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 | ||
751 | |||
752 | static int uea_request(struct uea_softc *sc, | ||
753 | u16 value, u16 index, u16 size, void *data) | ||
754 | { | ||
755 | u8 *xfer_buff; | ||
756 | int ret = -ENOMEM; | ||
757 | |||
758 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
759 | if (!xfer_buff) { | ||
760 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
761 | return ret; | ||
762 | } | ||
763 | memcpy(xfer_buff, data, size); | ||
764 | |||
765 | ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0), | ||
766 | UCDC_SEND_ENCAPSULATED_COMMAND, | ||
767 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
768 | value, index, xfer_buff, size, CTRL_TIMEOUT); | ||
769 | |||
770 | kfree(xfer_buff); | ||
771 | if (ret < 0) { | ||
772 | uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret); | ||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | if (ret != size) { | ||
777 | uea_err(INS_TO_USBDEV(sc), | ||
778 | "usb_control_msg send only %d bytes (instead of %d)\n", | ||
779 | ret, size); | ||
780 | return -EIO; | ||
781 | } | ||
782 | |||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static int uea_cmv(struct uea_softc *sc, | ||
787 | u8 function, u32 address, u16 offset, u32 data) | ||
788 | { | ||
789 | struct cmv cmv; | ||
790 | int ret; | ||
791 | |||
792 | /* we send a request, but we expect a reply */ | ||
793 | sc->cmv_function = function | 0x2; | ||
794 | sc->cmv_idx++; | ||
795 | sc->cmv_address = address; | ||
796 | sc->cmv_offset = offset; | ||
797 | |||
798 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | ||
799 | cmv.bDirection = HOSTTOMODEM; | ||
800 | cmv.bFunction = function; | ||
801 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | ||
802 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | ||
803 | cmv.wOffsetAddress = cpu_to_le16(offset); | ||
804 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | ||
805 | |||
806 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | ||
807 | if (ret < 0) | ||
808 | return ret; | ||
809 | return wait_cmv_ack(sc); | ||
810 | } | ||
811 | |||
812 | static inline int uea_read_cmv(struct uea_softc *sc, | ||
813 | u32 address, u16 offset, u32 *data) | ||
814 | { | ||
815 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | ||
816 | address, offset, 0); | ||
817 | if (ret < 0) | ||
818 | uea_err(INS_TO_USBDEV(sc), | ||
819 | "reading cmv failed with error %d\n", ret); | ||
820 | else | ||
821 | *data = sc->data; | ||
822 | |||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | static inline int uea_write_cmv(struct uea_softc *sc, | ||
827 | u32 address, u16 offset, u32 data) | ||
828 | { | ||
829 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | ||
830 | address, offset, data); | ||
831 | if (ret < 0) | ||
832 | uea_err(INS_TO_USBDEV(sc), | ||
833 | "writing cmv failed with error %d\n", ret); | ||
834 | |||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * Monitor the modem and update the stat | ||
840 | * return 0 if everything is ok | ||
841 | * return < 0 if an error occurs (-EAGAIN reboot needed) | ||
842 | */ | ||
843 | static int uea_stat(struct uea_softc *sc) | ||
844 | { | ||
845 | u32 data; | ||
846 | int ret; | ||
847 | |||
848 | uea_enters(INS_TO_USBDEV(sc)); | ||
849 | data = sc->stats.phy.state; | ||
850 | |||
851 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | ||
852 | if (ret < 0) | ||
853 | return ret; | ||
854 | |||
855 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
856 | case 0: /* not yet synchronized */ | ||
857 | uea_dbg(INS_TO_USBDEV(sc), | ||
858 | "modem not yet synchronized\n"); | ||
859 | return 0; | ||
860 | |||
861 | case 1: /* initialization */ | ||
862 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
863 | return 0; | ||
864 | |||
865 | case 2: /* operational */ | ||
866 | uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n"); | ||
867 | break; | ||
868 | |||
869 | case 3: /* fail ... */ | ||
870 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n"); | ||
871 | return -EAGAIN; | ||
872 | |||
873 | case 4 ... 6: /* test state */ | ||
874 | uea_warn(INS_TO_USBDEV(sc), | ||
875 | "modem in test mode - not supported\n"); | ||
876 | return -EAGAIN; | ||
877 | |||
878 | case 7: /* fast-retain ... */ | ||
879 | uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n"); | ||
880 | return 0; | ||
881 | default: | ||
882 | uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n", | ||
883 | GET_STATUS(sc->stats.phy.state)); | ||
884 | return -EAGAIN; | ||
885 | } | ||
886 | |||
887 | if (GET_STATUS(data) != 2) { | ||
888 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
889 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
890 | |||
891 | /* release the dsp firmware as it is not needed until | ||
892 | * the next failure | ||
893 | */ | ||
894 | if (sc->dsp_firm) { | ||
895 | release_firmware(sc->dsp_firm); | ||
896 | sc->dsp_firm = NULL; | ||
897 | } | ||
898 | |||
899 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
900 | if (ret < 0) | ||
901 | return ret; | ||
902 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
903 | sc->stats.phy.firmid); | ||
904 | } | ||
905 | |||
906 | /* always update it as atm layer could not be init when we switch to | ||
907 | * operational state | ||
908 | */ | ||
909 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
910 | |||
911 | /* wake up processes waiting for synchronization */ | ||
912 | wake_up(&sc->sync_q); | ||
913 | |||
914 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | ||
915 | if (ret < 0) | ||
916 | return ret; | ||
917 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
918 | |||
919 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
920 | * we check the status again in order to detect the failure earlier | ||
921 | */ | ||
922 | if (sc->stats.phy.flags) { | ||
923 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", | ||
924 | sc->stats.phy.flags); | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | ||
929 | if (ret < 0) | ||
930 | return ret; | ||
931 | |||
932 | /* in bulk mode the modem have problem with high rate | ||
933 | * changing internal timing could improve things, but the | ||
934 | * value is misterious. | ||
935 | * ADI930 don't support it (-EPIPE error). | ||
936 | */ | ||
937 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
938 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
939 | /* Original timming from ADI(used in windows driver) | ||
940 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
941 | */ | ||
942 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
943 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
944 | uea_info(INS_TO_USBDEV(sc), | ||
945 | "setting new timeout %d%s\n", timeout, | ||
946 | ret < 0?" failed":""); | ||
947 | } | ||
948 | sc->stats.phy.dsrate = (data >> 16) * 32; | ||
949 | sc->stats.phy.usrate = (data & 0xffff) * 32; | ||
950 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
951 | |||
952 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | ||
953 | if (ret < 0) | ||
954 | return ret; | ||
955 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | ||
956 | |||
957 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | ||
958 | if (ret < 0) | ||
959 | return ret; | ||
960 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | ||
961 | |||
962 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | ||
963 | if (ret < 0) | ||
964 | return ret; | ||
965 | |||
966 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | ||
967 | if (ret < 0) | ||
968 | return ret; | ||
969 | |||
970 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | ||
971 | if (ret < 0) | ||
972 | return ret; | ||
973 | |||
974 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | ||
975 | if (ret < 0) | ||
976 | return ret; | ||
977 | |||
978 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | ||
979 | if (ret < 0) | ||
980 | return ret; | ||
981 | |||
982 | /* only for atu-c */ | ||
983 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | ||
984 | if (ret < 0) | ||
985 | return ret; | ||
986 | |||
987 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | ||
988 | if (ret < 0) | ||
989 | return ret; | ||
990 | |||
991 | /* only for atu-c */ | ||
992 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | ||
993 | if (ret < 0) | ||
994 | return ret; | ||
995 | |||
996 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | ||
997 | if (ret < 0) | ||
998 | return ret; | ||
999 | |||
1000 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | ||
1001 | if (ret < 0) | ||
1002 | return ret; | ||
1003 | |||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static int request_cmvs(struct uea_softc *sc, | ||
1008 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
1009 | { | ||
1010 | int ret, size; | ||
1011 | u8 *data; | ||
1012 | char *file; | ||
1013 | static char cmv_name[256] = FW_DIR; | ||
1014 | |||
1015 | if (cmv_file[sc->modem_index] == NULL) { | ||
1016 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
1017 | file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin"; | ||
1018 | else | ||
1019 | file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin"; | ||
1020 | } else | ||
1021 | file = cmv_file[sc->modem_index]; | ||
1022 | |||
1023 | strcpy(cmv_name, FW_DIR); | ||
1024 | strlcat(cmv_name, file, sizeof(cmv_name)); | ||
1025 | |||
1026 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
1027 | if (ret < 0) { | ||
1028 | uea_err(INS_TO_USBDEV(sc), | ||
1029 | "requesting firmware %s failed with error %d\n", | ||
1030 | cmv_name, ret); | ||
1031 | return ret; | ||
1032 | } | ||
1033 | |||
1034 | data = (u8 *) (*fw)->data; | ||
1035 | size = *data * sizeof(struct uea_cmvs) + 1; | ||
1036 | if (size != (*fw)->size) { | ||
1037 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
1038 | cmv_name); | ||
1039 | release_firmware(*fw); | ||
1040 | return -EILSEQ; | ||
1041 | } | ||
1042 | |||
1043 | *cmvs = (struct uea_cmvs *)(data + 1); | ||
1044 | return *data; | ||
1045 | } | ||
1046 | |||
1047 | /* Start boot post firmware modem: | ||
1048 | * - send reset commands through usb control pipe | ||
1049 | * - start workqueue for DSP loading | ||
1050 | * - send CMV options to modem | ||
1051 | */ | ||
1052 | |||
1053 | static int uea_start_reset(struct uea_softc *sc) | ||
1054 | { | ||
1055 | u16 zero = 0; /* ;-) */ | ||
1056 | int i, len, ret; | ||
1057 | struct uea_cmvs *cmvs; | ||
1058 | const struct firmware *cmvs_fw; | ||
1059 | |||
1060 | uea_enters(INS_TO_USBDEV(sc)); | ||
1061 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | ||
1062 | |||
1063 | sc->booting = 1; | ||
1064 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); | ||
1065 | |||
1066 | /* reset statistics */ | ||
1067 | memset(&sc->stats, 0, sizeof(struct uea_stats)); | ||
1068 | |||
1069 | /* tell the modem that we want to boot in IDMA mode */ | ||
1070 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
1071 | uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL); | ||
1072 | |||
1073 | /* enter reset mode */ | ||
1074 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | ||
1075 | |||
1076 | /* original driver use 200ms, but windows driver use 100ms */ | ||
1077 | msleep(100); | ||
1078 | |||
1079 | /* leave reset mode */ | ||
1080 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | ||
1081 | |||
1082 | /* clear tx and rx mailboxes */ | ||
1083 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | ||
1084 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | ||
1085 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
1086 | |||
1087 | msleep(1000); | ||
1088 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
1089 | sc->booting = 0; | ||
1090 | |||
1091 | /* start loading DSP */ | ||
1092 | sc->pageno = 0; | ||
1093 | sc->ovl = 0; | ||
1094 | schedule_work(&sc->task); | ||
1095 | |||
1096 | /* wait for modem ready CMV */ | ||
1097 | ret = wait_cmv_ack(sc); | ||
1098 | if (ret < 0) | ||
1099 | return ret; | ||
1100 | |||
1101 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1102 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
1103 | if (ret < 0) | ||
1104 | return ret; | ||
1105 | |||
1106 | /* get options */ | ||
1107 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
1108 | if (ret < 0) | ||
1109 | return ret; | ||
1110 | |||
1111 | /* send options */ | ||
1112 | for (i = 0; i < len; i++) { | ||
1113 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
1114 | FW_GET_WORD(&cmvs[i].offset), | ||
1115 | FW_GET_LONG(&cmvs[i].data)); | ||
1116 | if (ret < 0) | ||
1117 | goto out; | ||
1118 | } | ||
1119 | /* Enter in R-ACT-REQ */ | ||
1120 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
1121 | out: | ||
1122 | release_firmware(cmvs_fw); | ||
1123 | sc->reset = 0; | ||
1124 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1125 | return ret; | ||
1126 | } | ||
1127 | |||
1128 | /* | ||
1129 | * In case of an error wait 1s before rebooting the modem | ||
1130 | * if the modem don't request reboot (-EAGAIN). | ||
1131 | * Monitor the modem every 1s. | ||
1132 | */ | ||
1133 | |||
1134 | static int uea_kthread(void *data) | ||
1135 | { | ||
1136 | struct uea_softc *sc = data; | ||
1137 | int ret = -EAGAIN; | ||
1138 | |||
1139 | uea_enters(INS_TO_USBDEV(sc)); | ||
1140 | while (!kthread_should_stop()) { | ||
1141 | if (ret < 0 || sc->reset) | ||
1142 | ret = uea_start_reset(sc); | ||
1143 | if (!ret) | ||
1144 | ret = uea_stat(sc); | ||
1145 | if (ret != -EAGAIN) | ||
1146 | msleep(1000); | ||
1147 | } | ||
1148 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1149 | return ret; | ||
1150 | } | ||
1151 | |||
1152 | /* Load second usb firmware for ADI930 chip */ | ||
1153 | static int load_XILINX_firmware(struct uea_softc *sc) | ||
1154 | { | ||
1155 | const struct firmware *fw_entry; | ||
1156 | int ret, size, u, ln; | ||
1157 | u8 *pfw, value; | ||
1158 | char *fw_name = FW_DIR "930-fpga.bin"; | ||
1159 | |||
1160 | uea_enters(INS_TO_USBDEV(sc)); | ||
1161 | |||
1162 | ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); | ||
1163 | if (ret) { | ||
1164 | uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n", | ||
1165 | fw_name); | ||
1166 | goto err0; | ||
1167 | } | ||
1168 | |||
1169 | pfw = fw_entry->data; | ||
1170 | size = fw_entry->size; | ||
1171 | if (size != 0x577B) { | ||
1172 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
1173 | fw_name); | ||
1174 | ret = -EILSEQ; | ||
1175 | goto err1; | ||
1176 | } | ||
1177 | for (u = 0; u < size; u += ln) { | ||
1178 | ln = min(size - u, 64); | ||
1179 | ret = uea_request(sc, 0xe, 0, ln, pfw + u); | ||
1180 | if (ret < 0) { | ||
1181 | uea_err(INS_TO_USBDEV(sc), | ||
1182 | "elsa download data failed (%d)\n", ret); | ||
1183 | goto err1; | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | /* finish to send the fpga | ||
1188 | */ | ||
1189 | ret = uea_request(sc, 0xe, 1, 0, NULL); | ||
1190 | if (ret < 0) { | ||
1191 | uea_err(INS_TO_USBDEV(sc), | ||
1192 | "elsa download data failed (%d)\n", ret); | ||
1193 | goto err1; | ||
1194 | } | ||
1195 | |||
1196 | /* | ||
1197 | * Tell the modem we finish : de-assert reset | ||
1198 | */ | ||
1199 | value = 0; | ||
1200 | ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); | ||
1201 | if (ret < 0) | ||
1202 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | ||
1203 | |||
1204 | |||
1205 | err1: | ||
1206 | release_firmware(fw_entry); | ||
1207 | err0: | ||
1208 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1209 | return ret; | ||
1210 | } | ||
1211 | |||
1212 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | ||
1213 | { | ||
1214 | uea_enters(INS_TO_USBDEV(sc)); | ||
1215 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | ||
1216 | goto bad1; | ||
1217 | |||
1218 | if (cmv->bDirection != MODEMTOHOST) | ||
1219 | goto bad1; | ||
1220 | |||
1221 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | ||
1222 | * the first MEMACESS cmv. Ignore it... | ||
1223 | */ | ||
1224 | if (cmv->bFunction != sc->cmv_function) { | ||
1225 | if (UEA_CHIP_VERSION(sc) == ADI930 | ||
1226 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | ||
1227 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | ||
1228 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | ||
1229 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | ||
1230 | } | ||
1231 | else | ||
1232 | goto bad2; | ||
1233 | } | ||
1234 | |||
1235 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | ||
1236 | wake_up_cmv_ack(sc); | ||
1237 | return; | ||
1238 | } | ||
1239 | |||
1240 | /* in case of MEMACCESS */ | ||
1241 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | ||
1242 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | ||
1243 | sc->cmv_address | ||
1244 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
1245 | goto bad2; | ||
1246 | |||
1247 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | ||
1248 | sc->data = sc->data << 16 | sc->data >> 16; | ||
1249 | |||
1250 | wake_up_cmv_ack(sc); | ||
1251 | return; | ||
1252 | |||
1253 | bad2: | ||
1254 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
1255 | "Function : %d, Subfunction : %d\n", | ||
1256 | FUNCTION_TYPE(cmv->bFunction), | ||
1257 | FUNCTION_SUBTYPE(cmv->bFunction)); | ||
1258 | return; | ||
1259 | |||
1260 | bad1: | ||
1261 | uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " | ||
1262 | "wPreamble %d, bDirection %d\n", | ||
1263 | le16_to_cpu(cmv->wPreamble), cmv->bDirection); | ||
1264 | } | ||
1265 | |||
1266 | /* | ||
1267 | * interrupt handler | ||
1268 | */ | ||
1269 | static void uea_intr(struct urb *urb, struct pt_regs *regs) | ||
1270 | { | ||
1271 | struct uea_softc *sc = (struct uea_softc *)urb->context; | ||
1272 | struct intr_pkt *intr; | ||
1273 | uea_enters(INS_TO_USBDEV(sc)); | ||
1274 | |||
1275 | if (urb->status < 0) { | ||
1276 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | ||
1277 | urb->status); | ||
1278 | return; | ||
1279 | } | ||
1280 | |||
1281 | intr = (struct intr_pkt *) urb->transfer_buffer; | ||
1282 | |||
1283 | /* device-to-host interrupt */ | ||
1284 | if (intr->bType != 0x08 || sc->booting) { | ||
1285 | uea_err(INS_TO_USBDEV(sc), "wrong intr\n"); | ||
1286 | // rebooting ? | ||
1287 | // sc->reset = 1; | ||
1288 | goto resubmit; | ||
1289 | } | ||
1290 | |||
1291 | switch (le16_to_cpu(intr->wInterrupt)) { | ||
1292 | case INT_LOADSWAPPAGE: | ||
1293 | sc->pageno = intr->bSwapPageNo; | ||
1294 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
1295 | schedule_work(&sc->task); | ||
1296 | break; | ||
1297 | |||
1298 | case INT_INCOMINGCMV: | ||
1299 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | ||
1300 | break; | ||
1301 | |||
1302 | default: | ||
1303 | uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n", | ||
1304 | le16_to_cpu(intr->wInterrupt)); | ||
1305 | } | ||
1306 | |||
1307 | resubmit: | ||
1308 | usb_submit_urb(sc->urb_int, GFP_ATOMIC); | ||
1309 | } | ||
1310 | |||
1311 | /* | ||
1312 | * Start the modem : init the data and start kernel thread | ||
1313 | */ | ||
1314 | static int uea_boot(struct uea_softc *sc) | ||
1315 | { | ||
1316 | int ret; | ||
1317 | struct intr_pkt *intr; | ||
1318 | |||
1319 | uea_enters(INS_TO_USBDEV(sc)); | ||
1320 | |||
1321 | INIT_WORK(&sc->task, uea_load_page, sc); | ||
1322 | init_waitqueue_head(&sc->sync_q); | ||
1323 | init_waitqueue_head(&sc->cmv_ack_wait); | ||
1324 | |||
1325 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
1326 | load_XILINX_firmware(sc); | ||
1327 | |||
1328 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | ||
1329 | if (!intr) { | ||
1330 | uea_err(INS_TO_USBDEV(sc), | ||
1331 | "cannot allocate interrupt package\n"); | ||
1332 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1333 | return -ENOMEM; | ||
1334 | } | ||
1335 | |||
1336 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | ||
1337 | if (!sc->urb_int) { | ||
1338 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | ||
1339 | goto err; | ||
1340 | } | ||
1341 | |||
1342 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | ||
1343 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | ||
1344 | intr, INTR_PKT_SIZE, uea_intr, sc, | ||
1345 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | ||
1346 | endpoint[0].desc.bInterval); | ||
1347 | |||
1348 | ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); | ||
1349 | if (ret < 0) { | ||
1350 | uea_err(INS_TO_USBDEV(sc), | ||
1351 | "urb submition failed with error %d\n", ret); | ||
1352 | goto err1; | ||
1353 | } | ||
1354 | |||
1355 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | ||
1356 | if (sc->kthread == ERR_PTR(-ENOMEM)) { | ||
1357 | uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); | ||
1358 | goto err2; | ||
1359 | } | ||
1360 | |||
1361 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1362 | return 0; | ||
1363 | |||
1364 | err2: | ||
1365 | usb_kill_urb(sc->urb_int); | ||
1366 | err1: | ||
1367 | kfree(intr); | ||
1368 | err: | ||
1369 | usb_free_urb(sc->urb_int); | ||
1370 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1371 | return -ENOMEM; | ||
1372 | } | ||
1373 | |||
1374 | /* | ||
1375 | * Stop the modem : kill kernel thread and free data | ||
1376 | */ | ||
1377 | static void uea_stop(struct uea_softc *sc) | ||
1378 | { | ||
1379 | int ret; | ||
1380 | uea_enters(INS_TO_USBDEV(sc)); | ||
1381 | ret = kthread_stop(sc->kthread); | ||
1382 | uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | ||
1383 | |||
1384 | /* stop any pending boot process */ | ||
1385 | flush_scheduled_work(); | ||
1386 | |||
1387 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
1388 | |||
1389 | usb_kill_urb(sc->urb_int); | ||
1390 | kfree(sc->urb_int->transfer_buffer); | ||
1391 | usb_free_urb(sc->urb_int); | ||
1392 | |||
1393 | if (sc->dsp_firm) | ||
1394 | release_firmware(sc->dsp_firm); | ||
1395 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1396 | } | ||
1397 | |||
1398 | /* syfs interface */ | ||
1399 | static struct uea_softc *dev_to_uea(struct device *dev) | ||
1400 | { | ||
1401 | struct usb_interface *intf; | ||
1402 | struct usbatm_data *usbatm; | ||
1403 | |||
1404 | intf = to_usb_interface(dev); | ||
1405 | if (!intf) | ||
1406 | return NULL; | ||
1407 | |||
1408 | usbatm = usb_get_intfdata(intf); | ||
1409 | if (!usbatm) | ||
1410 | return NULL; | ||
1411 | |||
1412 | return usbatm->driver_data; | ||
1413 | } | ||
1414 | |||
1415 | static ssize_t read_status(struct device *dev, struct device_attribute *attr, | ||
1416 | char *buf) | ||
1417 | { | ||
1418 | int ret = -ENODEV; | ||
1419 | struct uea_softc *sc; | ||
1420 | |||
1421 | down(&uea_semaphore); | ||
1422 | sc = dev_to_uea(dev); | ||
1423 | if (!sc) | ||
1424 | goto out; | ||
1425 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); | ||
1426 | out: | ||
1427 | up(&uea_semaphore); | ||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | static ssize_t reboot(struct device *dev, struct device_attribute *attr, | ||
1432 | const char *buf, size_t count) | ||
1433 | { | ||
1434 | int ret = -ENODEV; | ||
1435 | struct uea_softc *sc; | ||
1436 | |||
1437 | down(&uea_semaphore); | ||
1438 | sc = dev_to_uea(dev); | ||
1439 | if (!sc) | ||
1440 | goto out; | ||
1441 | sc->reset = 1; | ||
1442 | ret = count; | ||
1443 | out: | ||
1444 | up(&uea_semaphore); | ||
1445 | return ret; | ||
1446 | } | ||
1447 | |||
1448 | static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); | ||
1449 | |||
1450 | static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, | ||
1451 | char *buf) | ||
1452 | { | ||
1453 | int ret = -ENODEV; | ||
1454 | struct uea_softc *sc; | ||
1455 | |||
1456 | down(&uea_semaphore); | ||
1457 | sc = dev_to_uea(dev); | ||
1458 | if (!sc) | ||
1459 | goto out; | ||
1460 | |||
1461 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
1462 | case 0: | ||
1463 | ret = sprintf(buf, "Modem is booting\n"); | ||
1464 | break; | ||
1465 | case 1: | ||
1466 | ret = sprintf(buf, "Modem is initializing\n"); | ||
1467 | break; | ||
1468 | case 2: | ||
1469 | ret = sprintf(buf, "Modem is operational\n"); | ||
1470 | break; | ||
1471 | default: | ||
1472 | ret = sprintf(buf, "Modem synchronization failed\n"); | ||
1473 | break; | ||
1474 | } | ||
1475 | out: | ||
1476 | up(&uea_semaphore); | ||
1477 | return ret; | ||
1478 | } | ||
1479 | |||
1480 | static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL); | ||
1481 | |||
1482 | static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | ||
1483 | char *buf) | ||
1484 | { | ||
1485 | int ret = -ENODEV; | ||
1486 | struct uea_softc *sc; | ||
1487 | |||
1488 | down(&uea_semaphore); | ||
1489 | sc = dev_to_uea(dev); | ||
1490 | if (!sc) | ||
1491 | goto out; | ||
1492 | |||
1493 | if (sc->stats.phy.flags & 0x0C00) | ||
1494 | ret = sprintf(buf, "ERROR\n"); | ||
1495 | else if (sc->stats.phy.flags & 0x0030) | ||
1496 | ret = sprintf(buf, "LOSS\n"); | ||
1497 | else | ||
1498 | ret = sprintf(buf, "GOOD\n"); | ||
1499 | out: | ||
1500 | up(&uea_semaphore); | ||
1501 | return ret; | ||
1502 | } | ||
1503 | |||
1504 | static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); | ||
1505 | |||
1506 | #define UEA_ATTR(name, reset) \ | ||
1507 | \ | ||
1508 | static ssize_t read_##name(struct device *dev, \ | ||
1509 | struct device_attribute *attr, char *buf) \ | ||
1510 | { \ | ||
1511 | int ret = -ENODEV; \ | ||
1512 | struct uea_softc *sc; \ | ||
1513 | \ | ||
1514 | down(&uea_semaphore); \ | ||
1515 | sc = dev_to_uea(dev); \ | ||
1516 | if (!sc) \ | ||
1517 | goto out; \ | ||
1518 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name); \ | ||
1519 | if (reset) \ | ||
1520 | sc->stats.phy.name = 0; \ | ||
1521 | out: \ | ||
1522 | up(&uea_semaphore); \ | ||
1523 | return ret; \ | ||
1524 | } \ | ||
1525 | \ | ||
1526 | static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL) | ||
1527 | |||
1528 | UEA_ATTR(mflags, 1); | ||
1529 | UEA_ATTR(vidcpe, 0); | ||
1530 | UEA_ATTR(usrate, 0); | ||
1531 | UEA_ATTR(dsrate, 0); | ||
1532 | UEA_ATTR(usattenuation, 0); | ||
1533 | UEA_ATTR(dsattenuation, 0); | ||
1534 | UEA_ATTR(usmargin, 0); | ||
1535 | UEA_ATTR(dsmargin, 0); | ||
1536 | UEA_ATTR(txflow, 0); | ||
1537 | UEA_ATTR(rxflow, 0); | ||
1538 | UEA_ATTR(uscorr, 0); | ||
1539 | UEA_ATTR(dscorr, 0); | ||
1540 | UEA_ATTR(usunc, 0); | ||
1541 | UEA_ATTR(dsunc, 0); | ||
1542 | |||
1543 | /* Retrieve the device End System Identifier (MAC) */ | ||
1544 | |||
1545 | #define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10) | ||
1546 | static int uea_getesi(struct uea_softc *sc, u_char * esi) | ||
1547 | { | ||
1548 | unsigned char mac_str[2 * ETH_ALEN + 1]; | ||
1549 | int i; | ||
1550 | if (usb_string | ||
1551 | (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str, | ||
1552 | sizeof(mac_str)) != 2 * ETH_ALEN) | ||
1553 | return 1; | ||
1554 | |||
1555 | for (i = 0; i < ETH_ALEN; i++) | ||
1556 | esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]); | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | /* ATM stuff */ | ||
1562 | static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev) | ||
1563 | { | ||
1564 | struct uea_softc *sc = usbatm->driver_data; | ||
1565 | |||
1566 | return uea_getesi(sc, atm_dev->esi); | ||
1567 | } | ||
1568 | |||
1569 | static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
1570 | { | ||
1571 | struct uea_softc *sc = usbatm->driver_data; | ||
1572 | |||
1573 | wait_event(sc->sync_q, IS_OPERATIONAL(sc)); | ||
1574 | |||
1575 | return 0; | ||
1576 | |||
1577 | } | ||
1578 | |||
1579 | static int claim_interface(struct usb_device *usb_dev, | ||
1580 | struct usbatm_data *usbatm, int ifnum) | ||
1581 | { | ||
1582 | int ret; | ||
1583 | struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum); | ||
1584 | |||
1585 | if (!intf) { | ||
1586 | uea_err(usb_dev, "interface %d not found\n", ifnum); | ||
1587 | return -ENODEV; | ||
1588 | } | ||
1589 | |||
1590 | ret = usb_driver_claim_interface(&uea_driver, intf, usbatm); | ||
1591 | if (ret != 0) | ||
1592 | uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum, | ||
1593 | ret); | ||
1594 | return ret; | ||
1595 | } | ||
1596 | |||
1597 | static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
1598 | { | ||
1599 | /* sysfs interface */ | ||
1600 | device_create_file(&intf->dev, &dev_attr_stat_status); | ||
1601 | device_create_file(&intf->dev, &dev_attr_stat_mflags); | ||
1602 | device_create_file(&intf->dev, &dev_attr_stat_human_status); | ||
1603 | device_create_file(&intf->dev, &dev_attr_stat_delin); | ||
1604 | device_create_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
1605 | device_create_file(&intf->dev, &dev_attr_stat_usrate); | ||
1606 | device_create_file(&intf->dev, &dev_attr_stat_dsrate); | ||
1607 | device_create_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
1608 | device_create_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
1609 | device_create_file(&intf->dev, &dev_attr_stat_usmargin); | ||
1610 | device_create_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
1611 | device_create_file(&intf->dev, &dev_attr_stat_txflow); | ||
1612 | device_create_file(&intf->dev, &dev_attr_stat_rxflow); | ||
1613 | device_create_file(&intf->dev, &dev_attr_stat_uscorr); | ||
1614 | device_create_file(&intf->dev, &dev_attr_stat_dscorr); | ||
1615 | device_create_file(&intf->dev, &dev_attr_stat_usunc); | ||
1616 | device_create_file(&intf->dev, &dev_attr_stat_dsunc); | ||
1617 | } | ||
1618 | |||
1619 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | ||
1620 | const struct usb_device_id *id, int *heavy) | ||
1621 | { | ||
1622 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1623 | struct uea_softc *sc; | ||
1624 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
1625 | |||
1626 | uea_enters(usb); | ||
1627 | |||
1628 | /* interface 0 is for firmware/monitoring */ | ||
1629 | if (ifnum != UEA_INTR_IFACE_NO) | ||
1630 | return -ENODEV; | ||
1631 | |||
1632 | *heavy = sync_wait[modem_index]; | ||
1633 | |||
1634 | /* interface 1 is for outbound traffic */ | ||
1635 | ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); | ||
1636 | if (ret < 0) | ||
1637 | return ret; | ||
1638 | |||
1639 | /* ADI930 has only 2 interfaces and inbound traffic | ||
1640 | * is on interface 1 | ||
1641 | */ | ||
1642 | if (UEA_CHIP_VERSION(id) != ADI930) { | ||
1643 | /* interface 2 is for inbound traffic */ | ||
1644 | ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); | ||
1645 | if (ret < 0) | ||
1646 | return ret; | ||
1647 | } | ||
1648 | |||
1649 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); | ||
1650 | if (!sc) { | ||
1651 | uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); | ||
1652 | return -ENOMEM; | ||
1653 | } | ||
1654 | |||
1655 | sc->usb_dev = usb; | ||
1656 | usbatm->driver_data = sc; | ||
1657 | sc->usbatm = usbatm; | ||
1658 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | ||
1659 | sc->driver_info = id->driver_info; | ||
1660 | |||
1661 | ret = uea_boot(sc); | ||
1662 | if (ret < 0) { | ||
1663 | kfree(sc); | ||
1664 | return ret; | ||
1665 | } | ||
1666 | |||
1667 | create_fs_entries(sc, intf); | ||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
1672 | { | ||
1673 | /* sysfs interface */ | ||
1674 | device_remove_file(&intf->dev, &dev_attr_stat_status); | ||
1675 | device_remove_file(&intf->dev, &dev_attr_stat_mflags); | ||
1676 | device_remove_file(&intf->dev, &dev_attr_stat_human_status); | ||
1677 | device_remove_file(&intf->dev, &dev_attr_stat_delin); | ||
1678 | device_remove_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
1679 | device_remove_file(&intf->dev, &dev_attr_stat_usrate); | ||
1680 | device_remove_file(&intf->dev, &dev_attr_stat_dsrate); | ||
1681 | device_remove_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
1682 | device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
1683 | device_remove_file(&intf->dev, &dev_attr_stat_usmargin); | ||
1684 | device_remove_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
1685 | device_remove_file(&intf->dev, &dev_attr_stat_txflow); | ||
1686 | device_remove_file(&intf->dev, &dev_attr_stat_rxflow); | ||
1687 | device_remove_file(&intf->dev, &dev_attr_stat_uscorr); | ||
1688 | device_remove_file(&intf->dev, &dev_attr_stat_dscorr); | ||
1689 | device_remove_file(&intf->dev, &dev_attr_stat_usunc); | ||
1690 | device_remove_file(&intf->dev, &dev_attr_stat_dsunc); | ||
1691 | } | ||
1692 | |||
1693 | static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
1694 | { | ||
1695 | struct uea_softc *sc = usbatm->driver_data; | ||
1696 | |||
1697 | destroy_fs_entries(sc, intf); | ||
1698 | uea_stop(sc); | ||
1699 | kfree(sc); | ||
1700 | } | ||
1701 | |||
1702 | static struct usbatm_driver uea_usbatm_driver = { | ||
1703 | .driver_name = "ueagle-atm", | ||
1704 | .owner = THIS_MODULE, | ||
1705 | .bind = uea_bind, | ||
1706 | .atm_start = uea_atm_open, | ||
1707 | .unbind = uea_unbind, | ||
1708 | .heavy_init = uea_heavy, | ||
1709 | .in = UEA_BULK_DATA_PIPE, | ||
1710 | .out = UEA_BULK_DATA_PIPE, | ||
1711 | }; | ||
1712 | |||
1713 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
1714 | { | ||
1715 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1716 | |||
1717 | uea_enters(usb); | ||
1718 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n", | ||
1719 | le16_to_cpu(usb->descriptor.idVendor), | ||
1720 | le16_to_cpu(usb->descriptor.idProduct), | ||
1721 | chip_name[UEA_CHIP_VERSION(id)]); | ||
1722 | |||
1723 | usb_reset_device(usb); | ||
1724 | |||
1725 | if (UEA_IS_PREFIRM(id)) | ||
1726 | return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); | ||
1727 | |||
1728 | return usbatm_usb_probe(intf, id, &uea_usbatm_driver); | ||
1729 | } | ||
1730 | |||
1731 | static void uea_disconnect(struct usb_interface *intf) | ||
1732 | { | ||
1733 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1734 | int ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
1735 | uea_enters(usb); | ||
1736 | |||
1737 | /* ADI930 has 2 interfaces and eagle 3 interfaces. | ||
1738 | * Pre-firmware device has one interface | ||
1739 | */ | ||
1740 | if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { | ||
1741 | down(&uea_semaphore); | ||
1742 | usbatm_usb_disconnect(intf); | ||
1743 | up(&uea_semaphore); | ||
1744 | uea_info(usb, "ADSL device removed\n"); | ||
1745 | } | ||
1746 | |||
1747 | uea_leaves(usb); | ||
1748 | } | ||
1749 | |||
1750 | /* | ||
1751 | * List of supported VID/PID | ||
1752 | */ | ||
1753 | static const struct usb_device_id uea_ids[] = { | ||
1754 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
1755 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
1756 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1757 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1758 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1759 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1760 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1761 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1762 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
1763 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
1764 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1765 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1766 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1767 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1768 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
1769 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
1770 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
1771 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
1772 | {} | ||
1773 | }; | ||
1774 | |||
1775 | /* | ||
1776 | * USB driver descriptor | ||
1777 | */ | ||
1778 | static struct usb_driver uea_driver = { | ||
1779 | .name = "ueagle-atm", | ||
1780 | .id_table = uea_ids, | ||
1781 | .probe = uea_probe, | ||
1782 | .disconnect = uea_disconnect, | ||
1783 | }; | ||
1784 | |||
1785 | MODULE_DEVICE_TABLE(usb, uea_ids); | ||
1786 | |||
1787 | /** | ||
1788 | * uea_init - Initialize the module. | ||
1789 | * Register to USB subsystem | ||
1790 | */ | ||
1791 | static int __init uea_init(void) | ||
1792 | { | ||
1793 | printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n"); | ||
1794 | |||
1795 | usb_register(&uea_driver); | ||
1796 | |||
1797 | return 0; | ||
1798 | } | ||
1799 | |||
1800 | module_init(uea_init); | ||
1801 | |||
1802 | /** | ||
1803 | * uea_exit - Destroy module | ||
1804 | * Deregister with USB subsystem | ||
1805 | */ | ||
1806 | static void __exit uea_exit(void) | ||
1807 | { | ||
1808 | /* | ||
1809 | * This calls automatically the uea_disconnect method if necessary: | ||
1810 | */ | ||
1811 | usb_deregister(&uea_driver); | ||
1812 | |||
1813 | printk(KERN_INFO "[ueagle-atm] driver unloaded\n"); | ||
1814 | } | ||
1815 | |||
1816 | module_exit(uea_exit); | ||
1817 | |||
1818 | MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka"); | ||
1819 | MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver"); | ||
1820 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 2e6593e6c1bd..9baa6296fc95 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -646,14 +646,14 @@ static void usbatm_destroy_instance(struct kref *kref) | |||
646 | kfree(instance); | 646 | kfree(instance); |
647 | } | 647 | } |
648 | 648 | ||
649 | void usbatm_get_instance(struct usbatm_data *instance) | 649 | static void usbatm_get_instance(struct usbatm_data *instance) |
650 | { | 650 | { |
651 | dbg("%s", __func__); | 651 | dbg("%s", __func__); |
652 | 652 | ||
653 | kref_get(&instance->refcount); | 653 | kref_get(&instance->refcount); |
654 | } | 654 | } |
655 | 655 | ||
656 | void usbatm_put_instance(struct usbatm_data *instance) | 656 | static void usbatm_put_instance(struct usbatm_data *instance) |
657 | { | 657 | { |
658 | dbg("%s", __func__); | 658 | dbg("%s", __func__); |
659 | 659 | ||
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 7fe7fb484d10..5c76e3aaaa5e 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c | |||
@@ -140,7 +140,6 @@ static int xusbatm_usb_probe(struct usb_interface *intf, | |||
140 | } | 140 | } |
141 | 141 | ||
142 | static struct usb_driver xusbatm_usb_driver = { | 142 | static struct usb_driver xusbatm_usb_driver = { |
143 | .owner = THIS_MODULE, | ||
144 | .name = xusbatm_driver_name, | 143 | .name = xusbatm_driver_name, |
145 | .probe = xusbatm_usb_probe, | 144 | .probe = xusbatm_usb_probe, |
146 | .disconnect = usbatm_usb_disconnect, | 145 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 50858273f8d3..3ad9ee8b84a9 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c | |||
@@ -2732,7 +2732,6 @@ static struct usb_device_id usb_audio_ids [] = { | |||
2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | 2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); |
2733 | 2733 | ||
2734 | static struct usb_driver usb_audio_driver = { | 2734 | static struct usb_driver usb_audio_driver = { |
2735 | .owner = THIS_MODULE, | ||
2736 | .name = "audio", | 2735 | .name = "audio", |
2737 | .probe = usb_audio_probe, | 2736 | .probe = usb_audio_probe, |
2738 | .disconnect = usb_audio_disconnect, | 2737 | .disconnect = usb_audio_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1b4751412970..248279e44c99 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> | 6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> |
7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> |
8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> | 8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> |
9 | * Copyright (c) 2005 David Kubicek <dave@awk.cz> | ||
9 | * | 10 | * |
10 | * USB Abstract Control Model driver for USB modems and ISDN adapters | 11 | * USB Abstract Control Model driver for USB modems and ISDN adapters |
11 | * | 12 | * |
@@ -29,6 +30,7 @@ | |||
29 | * config we want, sysadmin changes bConfigurationValue in sysfs. | 30 | * config we want, sysadmin changes bConfigurationValue in sysfs. |
30 | * v0.23 - use softirq for rx processing, as needed by tty layer | 31 | * v0.23 - use softirq for rx processing, as needed by tty layer |
31 | * v0.24 - change probe method to evaluate CDC union descriptor | 32 | * v0.24 - change probe method to evaluate CDC union descriptor |
33 | * v0.25 - downstream tasks paralelized to maximize throughput | ||
32 | */ | 34 | */ |
33 | 35 | ||
34 | /* | 36 | /* |
@@ -63,14 +65,15 @@ | |||
63 | #include <linux/usb_cdc.h> | 65 | #include <linux/usb_cdc.h> |
64 | #include <asm/byteorder.h> | 66 | #include <asm/byteorder.h> |
65 | #include <asm/unaligned.h> | 67 | #include <asm/unaligned.h> |
68 | #include <linux/list.h> | ||
66 | 69 | ||
67 | #include "cdc-acm.h" | 70 | #include "cdc-acm.h" |
68 | 71 | ||
69 | /* | 72 | /* |
70 | * Version Information | 73 | * Version Information |
71 | */ | 74 | */ |
72 | #define DRIVER_VERSION "v0.23" | 75 | #define DRIVER_VERSION "v0.25" |
73 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" | 76 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" |
74 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" | 77 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" |
75 | 78 | ||
76 | static struct usb_driver acm_driver; | 79 | static struct usb_driver acm_driver; |
@@ -284,7 +287,9 @@ exit: | |||
284 | /* data interface returns incoming bytes, or we got unthrottled */ | 287 | /* data interface returns incoming bytes, or we got unthrottled */ |
285 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | 288 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) |
286 | { | 289 | { |
287 | struct acm *acm = urb->context; | 290 | struct acm_rb *buf; |
291 | struct acm_ru *rcv = urb->context; | ||
292 | struct acm *acm = rcv->instance; | ||
288 | dbg("Entering acm_read_bulk with status %d\n", urb->status); | 293 | dbg("Entering acm_read_bulk with status %d\n", urb->status); |
289 | 294 | ||
290 | if (!ACM_READY(acm)) | 295 | if (!ACM_READY(acm)) |
@@ -293,49 +298,109 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | |||
293 | if (urb->status) | 298 | if (urb->status) |
294 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); | 299 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); |
295 | 300 | ||
296 | /* calling tty_flip_buffer_push() in_irq() isn't allowed */ | 301 | buf = rcv->buffer; |
297 | tasklet_schedule(&acm->bh); | 302 | buf->size = urb->actual_length; |
303 | |||
304 | spin_lock(&acm->read_lock); | ||
305 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | ||
306 | list_add_tail(&buf->list, &acm->filled_read_bufs); | ||
307 | spin_unlock(&acm->read_lock); | ||
308 | |||
309 | tasklet_schedule(&acm->urb_task); | ||
298 | } | 310 | } |
299 | 311 | ||
300 | static void acm_rx_tasklet(unsigned long _acm) | 312 | static void acm_rx_tasklet(unsigned long _acm) |
301 | { | 313 | { |
302 | struct acm *acm = (void *)_acm; | 314 | struct acm *acm = (void *)_acm; |
303 | struct urb *urb = acm->readurb; | 315 | struct acm_rb *buf; |
304 | struct tty_struct *tty = acm->tty; | 316 | struct tty_struct *tty = acm->tty; |
305 | unsigned char *data = urb->transfer_buffer; | 317 | struct acm_ru *rcv; |
318 | //unsigned long flags; | ||
306 | int i = 0; | 319 | int i = 0; |
307 | dbg("Entering acm_rx_tasklet"); | 320 | dbg("Entering acm_rx_tasklet"); |
308 | 321 | ||
309 | if (urb->actual_length > 0 && !acm->throttle) { | 322 | if (!ACM_READY(acm) || acm->throttle) |
310 | for (i = 0; i < urb->actual_length && !acm->throttle; i++) { | 323 | return; |
311 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 324 | |
312 | * we drop them. */ | 325 | next_buffer: |
313 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 326 | spin_lock(&acm->read_lock); |
314 | tty_flip_buffer_push(tty); | 327 | if (list_empty(&acm->filled_read_bufs)) { |
315 | } | 328 | spin_unlock(&acm->read_lock); |
316 | tty_insert_flip_char(tty, data[i], 0); | 329 | goto urbs; |
317 | } | ||
318 | dbg("Handed %d bytes to tty layer", i+1); | ||
319 | tty_flip_buffer_push(tty); | ||
320 | } | 330 | } |
331 | buf = list_entry(acm->filled_read_bufs.next, | ||
332 | struct acm_rb, list); | ||
333 | list_del(&buf->list); | ||
334 | spin_unlock(&acm->read_lock); | ||
335 | |||
336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); | ||
337 | |||
338 | for (i = 0; i < buf->size && !acm->throttle; i++) { | ||
339 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | ||
340 | we drop them. */ | ||
341 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
342 | tty_flip_buffer_push(tty); | ||
343 | } | ||
344 | tty_insert_flip_char(tty, buf->base[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | ||
321 | 347 | ||
322 | spin_lock(&acm->throttle_lock); | 348 | spin_lock(&acm->throttle_lock); |
323 | if (acm->throttle) { | 349 | if (acm->throttle) { |
324 | dbg("Throtteling noticed"); | 350 | dbg("Throtteling noticed"); |
325 | memmove(data, data + i, urb->actual_length - i); | 351 | memmove(buf->base, buf->base + i, buf->size - i); |
326 | urb->actual_length -= i; | 352 | buf->size -= i; |
327 | acm->resubmit_to_unthrottle = 1; | ||
328 | spin_unlock(&acm->throttle_lock); | 353 | spin_unlock(&acm->throttle_lock); |
354 | spin_lock(&acm->read_lock); | ||
355 | list_add(&buf->list, &acm->filled_read_bufs); | ||
356 | spin_unlock(&acm->read_lock); | ||
329 | return; | 357 | return; |
330 | } | 358 | } |
331 | spin_unlock(&acm->throttle_lock); | 359 | spin_unlock(&acm->throttle_lock); |
332 | 360 | ||
333 | urb->actual_length = 0; | 361 | spin_lock(&acm->read_lock); |
334 | urb->dev = acm->dev; | 362 | list_add(&buf->list, &acm->spare_read_bufs); |
335 | 363 | spin_unlock(&acm->read_lock); | |
336 | i = usb_submit_urb(urb, GFP_ATOMIC); | 364 | goto next_buffer; |
337 | if (i) | 365 | |
338 | dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i); | 366 | urbs: |
367 | while (!list_empty(&acm->spare_read_bufs)) { | ||
368 | spin_lock(&acm->read_lock); | ||
369 | if (list_empty(&acm->spare_read_urbs)) { | ||
370 | spin_unlock(&acm->read_lock); | ||
371 | return; | ||
372 | } | ||
373 | rcv = list_entry(acm->spare_read_urbs.next, | ||
374 | struct acm_ru, list); | ||
375 | list_del(&rcv->list); | ||
376 | spin_unlock(&acm->read_lock); | ||
377 | |||
378 | buf = list_entry(acm->spare_read_bufs.next, | ||
379 | struct acm_rb, list); | ||
380 | list_del(&buf->list); | ||
381 | |||
382 | rcv->buffer = buf; | ||
383 | |||
384 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
385 | acm->rx_endpoint, | ||
386 | buf->base, | ||
387 | acm->readsize, | ||
388 | acm_read_bulk, rcv); | ||
389 | rcv->urb->transfer_dma = buf->dma; | ||
390 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
391 | |||
392 | dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf); | ||
393 | |||
394 | /* This shouldn't kill the driver as unsuccessful URBs are returned to the | ||
395 | free-urbs-pool and resubmited ASAP */ | ||
396 | if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | ||
397 | list_add(&buf->list, &acm->spare_read_bufs); | ||
398 | spin_lock(&acm->read_lock); | ||
399 | list_add(&rcv->list, &acm->spare_read_urbs); | ||
400 | spin_unlock(&acm->read_lock); | ||
401 | return; | ||
402 | } | ||
403 | } | ||
339 | } | 404 | } |
340 | 405 | ||
341 | /* data interface wrote those outgoing bytes */ | 406 | /* data interface wrote those outgoing bytes */ |
@@ -369,6 +434,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
369 | { | 434 | { |
370 | struct acm *acm; | 435 | struct acm *acm; |
371 | int rv = -EINVAL; | 436 | int rv = -EINVAL; |
437 | int i; | ||
372 | dbg("Entering acm_tty_open.\n"); | 438 | dbg("Entering acm_tty_open.\n"); |
373 | 439 | ||
374 | down(&open_sem); | 440 | down(&open_sem); |
@@ -382,7 +448,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
382 | tty->driver_data = acm; | 448 | tty->driver_data = acm; |
383 | acm->tty = tty; | 449 | acm->tty = tty; |
384 | 450 | ||
385 | 451 | /* force low_latency on so that our tty_push actually forces the data through, | |
452 | otherwise it is scheduled, and with high data rates data can get lost. */ | ||
453 | tty->low_latency = 1; | ||
386 | 454 | ||
387 | if (acm->used++) { | 455 | if (acm->used++) { |
388 | goto done; | 456 | goto done; |
@@ -394,18 +462,20 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
394 | goto bail_out; | 462 | goto bail_out; |
395 | } | 463 | } |
396 | 464 | ||
397 | acm->readurb->dev = acm->dev; | ||
398 | if (usb_submit_urb(acm->readurb, GFP_KERNEL)) { | ||
399 | dbg("usb_submit_urb(read bulk) failed"); | ||
400 | goto bail_out_and_unlink; | ||
401 | } | ||
402 | |||
403 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) | 465 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) |
404 | goto full_bailout; | 466 | goto full_bailout; |
405 | 467 | ||
406 | /* force low_latency on so that our tty_push actually forces the data through, | 468 | INIT_LIST_HEAD(&acm->spare_read_urbs); |
407 | otherwise it is scheduled, and with high data rates data can get lost. */ | 469 | INIT_LIST_HEAD(&acm->spare_read_bufs); |
408 | tty->low_latency = 1; | 470 | INIT_LIST_HEAD(&acm->filled_read_bufs); |
471 | for (i = 0; i < ACM_NRU; i++) { | ||
472 | list_add(&(acm->ru[i].list), &acm->spare_read_urbs); | ||
473 | } | ||
474 | for (i = 0; i < ACM_NRB; i++) { | ||
475 | list_add(&(acm->rb[i].list), &acm->spare_read_bufs); | ||
476 | } | ||
477 | |||
478 | tasklet_schedule(&acm->urb_task); | ||
409 | 479 | ||
410 | done: | 480 | done: |
411 | err_out: | 481 | err_out: |
@@ -413,8 +483,6 @@ err_out: | |||
413 | return rv; | 483 | return rv; |
414 | 484 | ||
415 | full_bailout: | 485 | full_bailout: |
416 | usb_kill_urb(acm->readurb); | ||
417 | bail_out_and_unlink: | ||
418 | usb_kill_urb(acm->ctrlurb); | 486 | usb_kill_urb(acm->ctrlurb); |
419 | bail_out: | 487 | bail_out: |
420 | acm->used--; | 488 | acm->used--; |
@@ -424,18 +492,22 @@ bail_out: | |||
424 | 492 | ||
425 | static void acm_tty_unregister(struct acm *acm) | 493 | static void acm_tty_unregister(struct acm *acm) |
426 | { | 494 | { |
495 | int i; | ||
496 | |||
427 | tty_unregister_device(acm_tty_driver, acm->minor); | 497 | tty_unregister_device(acm_tty_driver, acm->minor); |
428 | usb_put_intf(acm->control); | 498 | usb_put_intf(acm->control); |
429 | acm_table[acm->minor] = NULL; | 499 | acm_table[acm->minor] = NULL; |
430 | usb_free_urb(acm->ctrlurb); | 500 | usb_free_urb(acm->ctrlurb); |
431 | usb_free_urb(acm->readurb); | ||
432 | usb_free_urb(acm->writeurb); | 501 | usb_free_urb(acm->writeurb); |
502 | for (i = 0; i < ACM_NRU; i++) | ||
503 | usb_free_urb(acm->ru[i].urb); | ||
433 | kfree(acm); | 504 | kfree(acm); |
434 | } | 505 | } |
435 | 506 | ||
436 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 507 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
437 | { | 508 | { |
438 | struct acm *acm = tty->driver_data; | 509 | struct acm *acm = tty->driver_data; |
510 | int i; | ||
439 | 511 | ||
440 | if (!acm || !acm->used) | 512 | if (!acm || !acm->used) |
441 | return; | 513 | return; |
@@ -446,7 +518,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
446 | acm_set_control(acm, acm->ctrlout = 0); | 518 | acm_set_control(acm, acm->ctrlout = 0); |
447 | usb_kill_urb(acm->ctrlurb); | 519 | usb_kill_urb(acm->ctrlurb); |
448 | usb_kill_urb(acm->writeurb); | 520 | usb_kill_urb(acm->writeurb); |
449 | usb_kill_urb(acm->readurb); | 521 | for (i = 0; i < ACM_NRU; i++) |
522 | usb_kill_urb(acm->ru[i].urb); | ||
450 | } else | 523 | } else |
451 | acm_tty_unregister(acm); | 524 | acm_tty_unregister(acm); |
452 | } | 525 | } |
@@ -528,10 +601,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty) | |||
528 | spin_lock_bh(&acm->throttle_lock); | 601 | spin_lock_bh(&acm->throttle_lock); |
529 | acm->throttle = 0; | 602 | acm->throttle = 0; |
530 | spin_unlock_bh(&acm->throttle_lock); | 603 | spin_unlock_bh(&acm->throttle_lock); |
531 | if (acm->resubmit_to_unthrottle) { | 604 | tasklet_schedule(&acm->urb_task); |
532 | acm->resubmit_to_unthrottle = 0; | ||
533 | acm_read_bulk(acm->readurb, NULL); | ||
534 | } | ||
535 | } | 605 | } |
536 | 606 | ||
537 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) | 607 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) |
@@ -588,7 +658,7 @@ static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int | |||
588 | return -ENOIOCTLCMD; | 658 | return -ENOIOCTLCMD; |
589 | } | 659 | } |
590 | 660 | ||
591 | static __u32 acm_tty_speed[] = { | 661 | static const __u32 acm_tty_speed[] = { |
592 | 0, 50, 75, 110, 134, 150, 200, 300, 600, | 662 | 0, 50, 75, 110, 134, 150, 200, 300, 600, |
593 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, | 663 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, |
594 | 57600, 115200, 230400, 460800, 500000, 576000, | 664 | 57600, 115200, 230400, 460800, 500000, 576000, |
@@ -596,7 +666,7 @@ static __u32 acm_tty_speed[] = { | |||
596 | 2500000, 3000000, 3500000, 4000000 | 666 | 2500000, 3000000, 3500000, 4000000 |
597 | }; | 667 | }; |
598 | 668 | ||
599 | static __u8 acm_tty_size[] = { | 669 | static const __u8 acm_tty_size[] = { |
600 | 5, 6, 7, 8 | 670 | 5, 6, 7, 8 |
601 | }; | 671 | }; |
602 | 672 | ||
@@ -694,6 +764,7 @@ static int acm_probe (struct usb_interface *intf, | |||
694 | int call_interface_num = -1; | 764 | int call_interface_num = -1; |
695 | int data_interface_num; | 765 | int data_interface_num; |
696 | unsigned long quirks; | 766 | unsigned long quirks; |
767 | int i; | ||
697 | 768 | ||
698 | /* handle quirks deadly to normal probing*/ | 769 | /* handle quirks deadly to normal probing*/ |
699 | quirks = (unsigned long)id->driver_info; | 770 | quirks = (unsigned long)id->driver_info; |
@@ -833,7 +904,7 @@ skip_normal_probe: | |||
833 | } | 904 | } |
834 | 905 | ||
835 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); | 906 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); |
836 | readsize = le16_to_cpu(epread->wMaxPacketSize); | 907 | readsize = le16_to_cpu(epread->wMaxPacketSize)*2; |
837 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); | 908 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); |
838 | acm->control = control_interface; | 909 | acm->control = control_interface; |
839 | acm->data = data_interface; | 910 | acm->data = data_interface; |
@@ -842,12 +913,14 @@ skip_normal_probe: | |||
842 | acm->ctrl_caps = ac_management_function; | 913 | acm->ctrl_caps = ac_management_function; |
843 | acm->ctrlsize = ctrlsize; | 914 | acm->ctrlsize = ctrlsize; |
844 | acm->readsize = readsize; | 915 | acm->readsize = readsize; |
845 | acm->bh.func = acm_rx_tasklet; | 916 | acm->urb_task.func = acm_rx_tasklet; |
846 | acm->bh.data = (unsigned long) acm; | 917 | acm->urb_task.data = (unsigned long) acm; |
847 | INIT_WORK(&acm->work, acm_softint, acm); | 918 | INIT_WORK(&acm->work, acm_softint, acm); |
848 | spin_lock_init(&acm->throttle_lock); | 919 | spin_lock_init(&acm->throttle_lock); |
849 | spin_lock_init(&acm->write_lock); | 920 | spin_lock_init(&acm->write_lock); |
921 | spin_lock_init(&acm->read_lock); | ||
850 | acm->write_ready = 1; | 922 | acm->write_ready = 1; |
923 | acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); | ||
851 | 924 | ||
852 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 925 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
853 | if (!buf) { | 926 | if (!buf) { |
@@ -856,13 +929,6 @@ skip_normal_probe: | |||
856 | } | 929 | } |
857 | acm->ctrl_buffer = buf; | 930 | acm->ctrl_buffer = buf; |
858 | 931 | ||
859 | buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma); | ||
860 | if (!buf) { | ||
861 | dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n"); | ||
862 | goto alloc_fail3; | ||
863 | } | ||
864 | acm->read_buffer = buf; | ||
865 | |||
866 | if (acm_write_buffers_alloc(acm) < 0) { | 932 | if (acm_write_buffers_alloc(acm) < 0) { |
867 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); | 933 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); |
868 | goto alloc_fail4; | 934 | goto alloc_fail4; |
@@ -873,10 +939,25 @@ skip_normal_probe: | |||
873 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | 939 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
874 | goto alloc_fail5; | 940 | goto alloc_fail5; |
875 | } | 941 | } |
876 | acm->readurb = usb_alloc_urb(0, GFP_KERNEL); | 942 | for (i = 0; i < ACM_NRU; i++) { |
877 | if (!acm->readurb) { | 943 | struct acm_ru *rcv = &(acm->ru[i]); |
878 | dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n"); | 944 | |
879 | goto alloc_fail6; | 945 | if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { |
946 | dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); | ||
947 | goto alloc_fail7; | ||
948 | } | ||
949 | |||
950 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
951 | rcv->instance = acm; | ||
952 | } | ||
953 | for (i = 0; i < ACM_NRB; i++) { | ||
954 | struct acm_rb *buf = &(acm->rb[i]); | ||
955 | |||
956 | // Using usb_buffer_alloc instead of kmalloc as Oliver suggested | ||
957 | if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { | ||
958 | dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); | ||
959 | goto alloc_fail7; | ||
960 | } | ||
880 | } | 961 | } |
881 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); | 962 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); |
882 | if (!acm->writeurb) { | 963 | if (!acm->writeurb) { |
@@ -889,15 +970,9 @@ skip_normal_probe: | |||
889 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 970 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
890 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; | 971 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; |
891 | 972 | ||
892 | usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), | ||
893 | acm->read_buffer, readsize, acm_read_bulk, acm); | ||
894 | acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | ||
895 | acm->readurb->transfer_dma = acm->read_dma; | ||
896 | |||
897 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 973 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
898 | NULL, acm->writesize, acm_write_bulk, acm); | 974 | NULL, acm->writesize, acm_write_bulk, acm); |
899 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | 975 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; |
900 | /* acm->writeurb->transfer_dma = 0; */ | ||
901 | 976 | ||
902 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); | 977 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); |
903 | 978 | ||
@@ -917,14 +992,14 @@ skip_normal_probe: | |||
917 | return 0; | 992 | return 0; |
918 | 993 | ||
919 | alloc_fail7: | 994 | alloc_fail7: |
920 | usb_free_urb(acm->readurb); | 995 | for (i = 0; i < ACM_NRB; i++) |
921 | alloc_fail6: | 996 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); |
997 | for (i = 0; i < ACM_NRU; i++) | ||
998 | usb_free_urb(acm->ru[i].urb); | ||
922 | usb_free_urb(acm->ctrlurb); | 999 | usb_free_urb(acm->ctrlurb); |
923 | alloc_fail5: | 1000 | alloc_fail5: |
924 | acm_write_buffers_free(acm); | 1001 | acm_write_buffers_free(acm); |
925 | alloc_fail4: | 1002 | alloc_fail4: |
926 | usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma); | ||
927 | alloc_fail3: | ||
928 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1003 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
929 | alloc_fail2: | 1004 | alloc_fail2: |
930 | kfree(acm); | 1005 | kfree(acm); |
@@ -936,6 +1011,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
936 | { | 1011 | { |
937 | struct acm *acm = usb_get_intfdata (intf); | 1012 | struct acm *acm = usb_get_intfdata (intf); |
938 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1013 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
1014 | int i; | ||
939 | 1015 | ||
940 | if (!acm || !acm->dev) { | 1016 | if (!acm || !acm->dev) { |
941 | dbg("disconnect on nonexisting interface"); | 1017 | dbg("disconnect on nonexisting interface"); |
@@ -946,15 +1022,24 @@ static void acm_disconnect(struct usb_interface *intf) | |||
946 | acm->dev = NULL; | 1022 | acm->dev = NULL; |
947 | usb_set_intfdata (intf, NULL); | 1023 | usb_set_intfdata (intf, NULL); |
948 | 1024 | ||
1025 | tasklet_disable(&acm->urb_task); | ||
1026 | |||
949 | usb_kill_urb(acm->ctrlurb); | 1027 | usb_kill_urb(acm->ctrlurb); |
950 | usb_kill_urb(acm->readurb); | ||
951 | usb_kill_urb(acm->writeurb); | 1028 | usb_kill_urb(acm->writeurb); |
1029 | for (i = 0; i < ACM_NRU; i++) | ||
1030 | usb_kill_urb(acm->ru[i].urb); | ||
1031 | |||
1032 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
1033 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
1034 | |||
1035 | tasklet_enable(&acm->urb_task); | ||
952 | 1036 | ||
953 | flush_scheduled_work(); /* wait for acm_softint */ | 1037 | flush_scheduled_work(); /* wait for acm_softint */ |
954 | 1038 | ||
955 | acm_write_buffers_free(acm); | 1039 | acm_write_buffers_free(acm); |
956 | usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma); | ||
957 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1040 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
1041 | for (i = 0; i < ACM_NRB; i++) | ||
1042 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
958 | 1043 | ||
959 | usb_driver_release_interface(&acm_driver, acm->data); | 1044 | usb_driver_release_interface(&acm_driver, acm->data); |
960 | 1045 | ||
@@ -1003,7 +1088,6 @@ static struct usb_device_id acm_ids[] = { | |||
1003 | MODULE_DEVICE_TABLE (usb, acm_ids); | 1088 | MODULE_DEVICE_TABLE (usb, acm_ids); |
1004 | 1089 | ||
1005 | static struct usb_driver acm_driver = { | 1090 | static struct usb_driver acm_driver = { |
1006 | .owner = THIS_MODULE, | ||
1007 | .name = "cdc_acm", | 1091 | .name = "cdc_acm", |
1008 | .probe = acm_probe, | 1092 | .probe = acm_probe, |
1009 | .disconnect = acm_disconnect, | 1093 | .disconnect = acm_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 963a5dfd2096..fd2aaccdcbac 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -59,6 +59,9 @@ | |||
59 | * when processing onlcr, so we only need 2 buffers. | 59 | * when processing onlcr, so we only need 2 buffers. |
60 | */ | 60 | */ |
61 | #define ACM_NWB 2 | 61 | #define ACM_NWB 2 |
62 | #define ACM_NRU 16 | ||
63 | #define ACM_NRB 16 | ||
64 | |||
62 | struct acm_wb { | 65 | struct acm_wb { |
63 | unsigned char *buf; | 66 | unsigned char *buf; |
64 | dma_addr_t dmah; | 67 | dma_addr_t dmah; |
@@ -66,22 +69,43 @@ struct acm_wb { | |||
66 | int use; | 69 | int use; |
67 | }; | 70 | }; |
68 | 71 | ||
72 | struct acm_rb { | ||
73 | struct list_head list; | ||
74 | int size; | ||
75 | unsigned char *base; | ||
76 | dma_addr_t dma; | ||
77 | }; | ||
78 | |||
79 | struct acm_ru { | ||
80 | struct list_head list; | ||
81 | struct acm_rb *buffer; | ||
82 | struct urb *urb; | ||
83 | struct acm *instance; | ||
84 | }; | ||
85 | |||
69 | struct acm { | 86 | struct acm { |
70 | struct usb_device *dev; /* the corresponding usb device */ | 87 | struct usb_device *dev; /* the corresponding usb device */ |
71 | struct usb_interface *control; /* control interface */ | 88 | struct usb_interface *control; /* control interface */ |
72 | struct usb_interface *data; /* data interface */ | 89 | struct usb_interface *data; /* data interface */ |
73 | struct tty_struct *tty; /* the corresponding tty */ | 90 | struct tty_struct *tty; /* the corresponding tty */ |
74 | struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ | 91 | struct urb *ctrlurb, *writeurb; /* urbs */ |
75 | u8 *ctrl_buffer, *read_buffer; /* buffers of urbs */ | 92 | u8 *ctrl_buffer; /* buffers of urbs */ |
76 | dma_addr_t ctrl_dma, read_dma; /* dma handles of buffers */ | 93 | dma_addr_t ctrl_dma; /* dma handles of buffers */ |
77 | struct acm_wb wb[ACM_NWB]; | 94 | struct acm_wb wb[ACM_NWB]; |
95 | struct acm_ru ru[ACM_NRU]; | ||
96 | struct acm_rb rb[ACM_NRB]; | ||
97 | int rx_endpoint; | ||
98 | spinlock_t read_lock; | ||
99 | struct list_head spare_read_urbs; | ||
100 | struct list_head spare_read_bufs; | ||
101 | struct list_head filled_read_bufs; | ||
78 | int write_current; /* current write buffer */ | 102 | int write_current; /* current write buffer */ |
79 | int write_used; /* number of non-empty write buffers */ | 103 | int write_used; /* number of non-empty write buffers */ |
80 | int write_ready; /* write urb is not running */ | 104 | int write_ready; /* write urb is not running */ |
81 | spinlock_t write_lock; | 105 | spinlock_t write_lock; |
82 | struct usb_cdc_line_coding line; /* bits, stop, parity */ | 106 | struct usb_cdc_line_coding line; /* bits, stop, parity */ |
83 | struct work_struct work; /* work queue entry for line discipline waking up */ | 107 | struct work_struct work; /* work queue entry for line discipline waking up */ |
84 | struct tasklet_struct bh; /* rx processing */ | 108 | struct tasklet_struct urb_task; /* rx processing */ |
85 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ | 109 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ |
86 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ | 110 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ |
87 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ | 111 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ |
@@ -91,7 +115,6 @@ struct acm { | |||
91 | unsigned int minor; /* acm minor number */ | 115 | unsigned int minor; /* acm minor number */ |
92 | unsigned char throttle; /* throttled by tty layer */ | 116 | unsigned char throttle; /* throttled by tty layer */ |
93 | unsigned char clocal; /* termios CLOCAL */ | 117 | unsigned char clocal; /* termios CLOCAL */ |
94 | unsigned char resubmit_to_unthrottle; /* throtteling has disabled the read urb */ | ||
95 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ | 118 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ |
96 | }; | 119 | }; |
97 | 120 | ||
diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 5f8af35e7633..f13f004d311f 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c | |||
@@ -2027,7 +2027,6 @@ static struct usb_device_id id_table[] = { | |||
2027 | }; | 2027 | }; |
2028 | 2028 | ||
2029 | static struct usb_driver usb_midi_driver = { | 2029 | static struct usb_driver usb_midi_driver = { |
2030 | .owner = THIS_MODULE, | ||
2031 | .name = "midi", | 2030 | .name = "midi", |
2032 | .probe = usb_midi_probe, | 2031 | .probe = usb_midi_probe, |
2033 | .disconnect = usb_midi_disconnect, | 2032 | .disconnect = usb_midi_disconnect, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 357e75335f17..dba4cc026077 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com> | 4 | * Copyright (c) 1999 Michael Gee <michael@linuxspecific.com> |
5 | * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> | 5 | * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> |
6 | * Copyright (c) 2000 Randy Dunlap <rddunlap@osdl.org> | 6 | * Copyright (c) 2000 Randy Dunlap <rdunlap@xenotime.net> |
7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> |
8 | # Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com> | 8 | # Copyright (c) 2001 Pete Zaitcev <zaitcev@redhat.com> |
9 | # Copyright (c) 2001 David Paschal <paschal@rcsis.com> | 9 | # Copyright (c) 2001 David Paschal <paschal@rcsis.com> |
@@ -199,7 +199,7 @@ struct quirk_printer_struct { | |||
199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ | 199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ |
200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ | 200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ |
201 | 201 | ||
202 | static struct quirk_printer_struct quirk_printers[] = { | 202 | static const struct quirk_printer_struct quirk_printers[] = { |
203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ | 203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ |
204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ | 204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ |
205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ | 205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ |
@@ -301,7 +301,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) | |||
301 | * Get and print printer errors. | 301 | * Get and print printer errors. |
302 | */ | 302 | */ |
303 | 303 | ||
304 | static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; | 304 | static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; |
305 | 305 | ||
306 | static int usblp_check_status(struct usblp *usblp, int err) | 306 | static int usblp_check_status(struct usblp *usblp, int err) |
307 | { | 307 | { |
@@ -438,7 +438,7 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait | |||
438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); |
439 | } | 439 | } |
440 | 440 | ||
441 | static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 441 | static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
442 | { | 442 | { |
443 | struct usblp *usblp = file->private_data; | 443 | struct usblp *usblp = file->private_data; |
444 | int length, err, i; | 444 | int length, err, i; |
@@ -838,7 +838,8 @@ static struct file_operations usblp_fops = { | |||
838 | .read = usblp_read, | 838 | .read = usblp_read, |
839 | .write = usblp_write, | 839 | .write = usblp_write, |
840 | .poll = usblp_poll, | 840 | .poll = usblp_poll, |
841 | .ioctl = usblp_ioctl, | 841 | .unlocked_ioctl = usblp_ioctl, |
842 | .compat_ioctl = usblp_ioctl, | ||
842 | .open = usblp_open, | 843 | .open = usblp_open, |
843 | .release = usblp_release, | 844 | .release = usblp_release, |
844 | }; | 845 | }; |
@@ -849,6 +850,20 @@ static struct usb_class_driver usblp_class = { | |||
849 | .minor_base = USBLP_MINOR_BASE, | 850 | .minor_base = USBLP_MINOR_BASE, |
850 | }; | 851 | }; |
851 | 852 | ||
853 | static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf) | ||
854 | { | ||
855 | struct usb_interface *intf = to_usb_interface(dev); | ||
856 | struct usblp *usblp = usb_get_intfdata (intf); | ||
857 | |||
858 | if (usblp->device_id_string[0] == 0 && | ||
859 | usblp->device_id_string[1] == 0) | ||
860 | return 0; | ||
861 | |||
862 | return sprintf(buf, "%s", usblp->device_id_string+2); | ||
863 | } | ||
864 | |||
865 | static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL); | ||
866 | |||
852 | static int usblp_probe(struct usb_interface *intf, | 867 | static int usblp_probe(struct usb_interface *intf, |
853 | const struct usb_device_id *id) | 868 | const struct usb_device_id *id) |
854 | { | 869 | { |
@@ -933,20 +948,12 @@ static int usblp_probe(struct usb_interface *intf, | |||
933 | 948 | ||
934 | /* Retrieve and store the device ID string. */ | 949 | /* Retrieve and store the device ID string. */ |
935 | usblp_cache_device_id_string(usblp); | 950 | usblp_cache_device_id_string(usblp); |
951 | device_create_file(&intf->dev, &dev_attr_ieee1284_id); | ||
936 | 952 | ||
937 | #ifdef DEBUG | 953 | #ifdef DEBUG |
938 | usblp_check_status(usblp, 0); | 954 | usblp_check_status(usblp, 0); |
939 | #endif | 955 | #endif |
940 | 956 | ||
941 | info("usblp%d: USB %sdirectional printer dev %d " | ||
942 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
943 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
944 | usblp->ifnum, | ||
945 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
946 | usblp->current_protocol, | ||
947 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
948 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
949 | |||
950 | usb_set_intfdata (intf, usblp); | 957 | usb_set_intfdata (intf, usblp); |
951 | 958 | ||
952 | usblp->present = 1; | 959 | usblp->present = 1; |
@@ -957,11 +964,20 @@ static int usblp_probe(struct usb_interface *intf, | |||
957 | goto abort_intfdata; | 964 | goto abort_intfdata; |
958 | } | 965 | } |
959 | usblp->minor = intf->minor; | 966 | usblp->minor = intf->minor; |
967 | info("usblp%d: USB %sdirectional printer dev %d " | ||
968 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
969 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
970 | usblp->ifnum, | ||
971 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
972 | usblp->current_protocol, | ||
973 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
974 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
960 | 975 | ||
961 | return 0; | 976 | return 0; |
962 | 977 | ||
963 | abort_intfdata: | 978 | abort_intfdata: |
964 | usb_set_intfdata (intf, NULL); | 979 | usb_set_intfdata (intf, NULL); |
980 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
965 | abort: | 981 | abort: |
966 | if (usblp) { | 982 | if (usblp) { |
967 | if (usblp->writebuf) | 983 | if (usblp->writebuf) |
@@ -1156,6 +1172,8 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1156 | BUG (); | 1172 | BUG (); |
1157 | } | 1173 | } |
1158 | 1174 | ||
1175 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
1176 | |||
1159 | down (&usblp_sem); | 1177 | down (&usblp_sem); |
1160 | down (&usblp->sem); | 1178 | down (&usblp->sem); |
1161 | usblp->present = 0; | 1179 | usblp->present = 0; |
@@ -1186,7 +1204,6 @@ static struct usb_device_id usblp_ids [] = { | |||
1186 | MODULE_DEVICE_TABLE (usb, usblp_ids); | 1204 | MODULE_DEVICE_TABLE (usb, usblp_ids); |
1187 | 1205 | ||
1188 | static struct usb_driver usblp_driver = { | 1206 | static struct usb_driver usblp_driver = { |
1189 | .owner = THIS_MODULE, | ||
1190 | .name = "usblp", | 1207 | .name = "usblp", |
1191 | .probe = usblp_probe, | 1208 | .probe = usblp_probe, |
1192 | .disconnect = usblp_disconnect, | 1209 | .disconnect = usblp_disconnect, |
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 86d5c380892d..28329ddf187c 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Core files and filesystem | 2 | # Makefile for USB Core files and filesystem |
3 | # | 3 | # |
4 | 4 | ||
5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ |
6 | config.o file.o buffer.o sysfs.o devio.o notify.o | 6 | config.o file.o buffer.o sysfs.o devio.o notify.o |
7 | 7 | ||
8 | ifeq ($(CONFIG_PCI),y) | 8 | ifeq ($(CONFIG_PCI),y) |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 419c9943a7cb..ad742cec94fa 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -55,6 +55,9 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
55 | char name [16]; | 55 | char name [16]; |
56 | int i, size; | 56 | int i, size; |
57 | 57 | ||
58 | if (!hcd->self.controller->dma_mask) | ||
59 | return 0; | ||
60 | |||
58 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 61 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
59 | if (!(size = pool_max [i])) | 62 | if (!(size = pool_max [i])) |
60 | continue; | 63 | continue; |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 83e815d3cd52..2684e15b813b 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -67,45 +67,45 @@ | |||
67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ | 67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ |
68 | #define ALLOW_SERIAL_NUMBER | 68 | #define ALLOW_SERIAL_NUMBER |
69 | 69 | ||
70 | static char *format_topo = | 70 | static const char *format_topo = |
71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ | 71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ |
72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; | 72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; |
73 | 73 | ||
74 | static char *format_string_manufacturer = | 74 | static const char *format_string_manufacturer = |
75 | /* S: Manufacturer=xxxx */ | 75 | /* S: Manufacturer=xxxx */ |
76 | "S: Manufacturer=%.100s\n"; | 76 | "S: Manufacturer=%.100s\n"; |
77 | 77 | ||
78 | static char *format_string_product = | 78 | static const char *format_string_product = |
79 | /* S: Product=xxxx */ | 79 | /* S: Product=xxxx */ |
80 | "S: Product=%.100s\n"; | 80 | "S: Product=%.100s\n"; |
81 | 81 | ||
82 | #ifdef ALLOW_SERIAL_NUMBER | 82 | #ifdef ALLOW_SERIAL_NUMBER |
83 | static char *format_string_serialnumber = | 83 | static const char *format_string_serialnumber = |
84 | /* S: SerialNumber=xxxx */ | 84 | /* S: SerialNumber=xxxx */ |
85 | "S: SerialNumber=%.100s\n"; | 85 | "S: SerialNumber=%.100s\n"; |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | static char *format_bandwidth = | 88 | static const char *format_bandwidth = |
89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ | 89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ |
90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; | 90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; |
91 | 91 | ||
92 | static char *format_device1 = | 92 | static const char *format_device1 = |
93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ | 93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ |
94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; | 94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; |
95 | 95 | ||
96 | static char *format_device2 = | 96 | static const char *format_device2 = |
97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ | 97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ |
98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; | 98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; |
99 | 99 | ||
100 | static char *format_config = | 100 | static const char *format_config = |
101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ | 101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ |
102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; | 102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; |
103 | 103 | ||
104 | static char *format_iface = | 104 | static const char *format_iface = |
105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
107 | 107 | ||
108 | static char *format_endpt = | 108 | static const char *format_endpt = |
109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; | 110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; |
111 | 111 | ||
@@ -545,10 +545,10 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
545 | struct usb_device *childdev = usbdev->children[chix]; | 545 | struct usb_device *childdev = usbdev->children[chix]; |
546 | 546 | ||
547 | if (childdev) { | 547 | if (childdev) { |
548 | down(&childdev->serialize); | 548 | usb_lock_device(childdev); |
549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, | 549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, |
550 | bus, level + 1, chix, ++cnt); | 550 | bus, level + 1, chix, ++cnt); |
551 | up(&childdev->serialize); | 551 | usb_unlock_device(childdev); |
552 | if (ret == -EFAULT) | 552 | if (ret == -EFAULT) |
553 | return total_written; | 553 | return total_written; |
554 | total_written += ret; | 554 | total_written += ret; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b1d6e9af732d..2b68998fe4b3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -402,7 +402,6 @@ static void driver_disconnect(struct usb_interface *intf) | |||
402 | } | 402 | } |
403 | 403 | ||
404 | struct usb_driver usbfs_driver = { | 404 | struct usb_driver usbfs_driver = { |
405 | .owner = THIS_MODULE, | ||
406 | .name = "usbfs", | 405 | .name = "usbfs", |
407 | .probe = driver_probe, | 406 | .probe = driver_probe, |
408 | .disconnect = driver_disconnect, | 407 | .disconnect = driver_disconnect, |
@@ -1350,9 +1349,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1350 | /* let kernel drivers try to (re)bind to the interface */ | 1349 | /* let kernel drivers try to (re)bind to the interface */ |
1351 | case USBDEVFS_CONNECT: | 1350 | case USBDEVFS_CONNECT: |
1352 | usb_unlock_device(ps->dev); | 1351 | usb_unlock_device(ps->dev); |
1353 | usb_lock_all_devices(); | ||
1354 | bus_rescan_devices(intf->dev.bus); | 1352 | bus_rescan_devices(intf->dev.bus); |
1355 | usb_unlock_all_devices(); | ||
1356 | usb_lock_device(ps->dev); | 1353 | usb_lock_device(ps->dev); |
1357 | break; | 1354 | break; |
1358 | 1355 | ||
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c new file mode 100644 index 000000000000..076462c8ba2a --- /dev/null +++ b/drivers/usb/core/driver.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * drivers/usb/driver.c - most of the driver model stuff for usb | ||
3 | * | ||
4 | * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * based on drivers/usb/usb.c which had the following copyrights: | ||
7 | * (C) Copyright Linus Torvalds 1999 | ||
8 | * (C) Copyright Johannes Erdfelt 1999-2001 | ||
9 | * (C) Copyright Andreas Gal 1999 | ||
10 | * (C) Copyright Gregory P. Smith 1999 | ||
11 | * (C) Copyright Deti Fliegl 1999 (new USB architecture) | ||
12 | * (C) Copyright Randy Dunlap 2000 | ||
13 | * (C) Copyright David Brownell 2000-2004 | ||
14 | * (C) Copyright Yggdrasil Computing, Inc. 2000 | ||
15 | * (usb_device_id matching changes by Adam J. Richter) | ||
16 | * (C) Copyright Greg Kroah-Hartman 2002-2003 | ||
17 | * | ||
18 | * NOTE! This is not actually a driver at all, rather this is | ||
19 | * just a collection of helper routines that implement the | ||
20 | * generic USB things that the real drivers can use.. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include "hcd.h" | ||
28 | #include "usb.h" | ||
29 | |||
30 | static int usb_match_one_id(struct usb_interface *interface, | ||
31 | const struct usb_device_id *id); | ||
32 | |||
33 | struct usb_dynid { | ||
34 | struct list_head node; | ||
35 | struct usb_device_id id; | ||
36 | }; | ||
37 | |||
38 | |||
39 | static int generic_probe(struct device *dev) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | static int generic_remove(struct device *dev) | ||
44 | { | ||
45 | struct usb_device *udev = to_usb_device(dev); | ||
46 | |||
47 | /* if this is only an unbind, not a physical disconnect, then | ||
48 | * unconfigure the device */ | ||
49 | if (udev->state == USB_STATE_CONFIGURED) | ||
50 | usb_set_configuration(udev, 0); | ||
51 | |||
52 | /* in case the call failed or the device was suspended */ | ||
53 | if (udev->state >= USB_STATE_CONFIGURED) | ||
54 | usb_disable_device(udev, 0); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | struct device_driver usb_generic_driver = { | ||
59 | .owner = THIS_MODULE, | ||
60 | .name = "usb", | ||
61 | .bus = &usb_bus_type, | ||
62 | .probe = generic_probe, | ||
63 | .remove = generic_remove, | ||
64 | }; | ||
65 | |||
66 | /* Fun hack to determine if the struct device is a | ||
67 | * usb device or a usb interface. */ | ||
68 | int usb_generic_driver_data; | ||
69 | |||
70 | #ifdef CONFIG_HOTPLUG | ||
71 | |||
72 | /* | ||
73 | * Adds a new dynamic USBdevice ID to this driver, | ||
74 | * and cause the driver to probe for all devices again. | ||
75 | */ | ||
76 | static ssize_t store_new_id(struct device_driver *driver, | ||
77 | const char *buf, size_t count) | ||
78 | { | ||
79 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
80 | struct usb_dynid *dynid; | ||
81 | u32 idVendor = 0; | ||
82 | u32 idProduct = 0; | ||
83 | int fields = 0; | ||
84 | |||
85 | fields = sscanf(buf, "%x %x", &idVendor, &idProduct); | ||
86 | if (fields < 2) | ||
87 | return -EINVAL; | ||
88 | |||
89 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | ||
90 | if (!dynid) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | INIT_LIST_HEAD(&dynid->node); | ||
94 | dynid->id.idVendor = idVendor; | ||
95 | dynid->id.idProduct = idProduct; | ||
96 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
97 | |||
98 | spin_lock(&usb_drv->dynids.lock); | ||
99 | list_add_tail(&usb_drv->dynids.list, &dynid->node); | ||
100 | spin_unlock(&usb_drv->dynids.lock); | ||
101 | |||
102 | if (get_driver(driver)) { | ||
103 | driver_attach(driver); | ||
104 | put_driver(driver); | ||
105 | } | ||
106 | |||
107 | return count; | ||
108 | } | ||
109 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | ||
110 | |||
111 | static int usb_create_newid_file(struct usb_driver *usb_drv) | ||
112 | { | ||
113 | int error = 0; | ||
114 | |||
115 | if (usb_drv->no_dynamic_id) | ||
116 | goto exit; | ||
117 | |||
118 | if (usb_drv->probe != NULL) | ||
119 | error = sysfs_create_file(&usb_drv->driver.kobj, | ||
120 | &driver_attr_new_id.attr); | ||
121 | exit: | ||
122 | return error; | ||
123 | } | ||
124 | |||
125 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
126 | { | ||
127 | if (usb_drv->no_dynamic_id) | ||
128 | return; | ||
129 | |||
130 | if (usb_drv->probe != NULL) | ||
131 | sysfs_remove_file(&usb_drv->driver.kobj, | ||
132 | &driver_attr_new_id.attr); | ||
133 | } | ||
134 | |||
135 | static void usb_free_dynids(struct usb_driver *usb_drv) | ||
136 | { | ||
137 | struct usb_dynid *dynid, *n; | ||
138 | |||
139 | spin_lock(&usb_drv->dynids.lock); | ||
140 | list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) { | ||
141 | list_del(&dynid->node); | ||
142 | kfree(dynid); | ||
143 | } | ||
144 | spin_unlock(&usb_drv->dynids.lock); | ||
145 | } | ||
146 | #else | ||
147 | static inline int usb_create_newid_file(struct usb_driver *usb_drv) | ||
148 | { | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | static inline void usb_free_dynids(struct usb_driver *usb_drv) | ||
157 | { | ||
158 | } | ||
159 | #endif | ||
160 | |||
161 | static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, | ||
162 | struct usb_driver *drv) | ||
163 | { | ||
164 | struct usb_dynid *dynid; | ||
165 | |||
166 | spin_lock(&drv->dynids.lock); | ||
167 | list_for_each_entry(dynid, &drv->dynids.list, node) { | ||
168 | if (usb_match_one_id(intf, &dynid->id)) { | ||
169 | spin_unlock(&drv->dynids.lock); | ||
170 | return &dynid->id; | ||
171 | } | ||
172 | } | ||
173 | spin_unlock(&drv->dynids.lock); | ||
174 | return NULL; | ||
175 | } | ||
176 | |||
177 | |||
178 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
179 | static int usb_probe_interface(struct device *dev) | ||
180 | { | ||
181 | struct usb_interface * intf = to_usb_interface(dev); | ||
182 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
183 | const struct usb_device_id *id; | ||
184 | int error = -ENODEV; | ||
185 | |||
186 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
187 | |||
188 | if (!driver->probe) | ||
189 | return error; | ||
190 | /* FIXME we'd much prefer to just resume it ... */ | ||
191 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
192 | return -EHOSTUNREACH; | ||
193 | |||
194 | id = usb_match_id(intf, driver->id_table); | ||
195 | if (!id) | ||
196 | id = usb_match_dynamic_id(intf, driver); | ||
197 | if (id) { | ||
198 | dev_dbg(dev, "%s - got id\n", __FUNCTION__); | ||
199 | |||
200 | /* Interface "power state" doesn't correspond to any hardware | ||
201 | * state whatsoever. We use it to record when it's bound to | ||
202 | * a driver that may start I/0: it's not frozen/quiesced. | ||
203 | */ | ||
204 | mark_active(intf); | ||
205 | intf->condition = USB_INTERFACE_BINDING; | ||
206 | error = driver->probe(intf, id); | ||
207 | if (error) { | ||
208 | mark_quiesced(intf); | ||
209 | intf->condition = USB_INTERFACE_UNBOUND; | ||
210 | } else | ||
211 | intf->condition = USB_INTERFACE_BOUND; | ||
212 | } | ||
213 | |||
214 | return error; | ||
215 | } | ||
216 | |||
217 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
218 | static int usb_unbind_interface(struct device *dev) | ||
219 | { | ||
220 | struct usb_interface *intf = to_usb_interface(dev); | ||
221 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
222 | |||
223 | intf->condition = USB_INTERFACE_UNBINDING; | ||
224 | |||
225 | /* release all urbs for this interface */ | ||
226 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
227 | |||
228 | if (driver && driver->disconnect) | ||
229 | driver->disconnect(intf); | ||
230 | |||
231 | /* reset other interface state */ | ||
232 | usb_set_interface(interface_to_usbdev(intf), | ||
233 | intf->altsetting[0].desc.bInterfaceNumber, | ||
234 | 0); | ||
235 | usb_set_intfdata(intf, NULL); | ||
236 | intf->condition = USB_INTERFACE_UNBOUND; | ||
237 | mark_quiesced(intf); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /* returns 0 if no match, 1 if match */ | ||
243 | static int usb_match_one_id(struct usb_interface *interface, | ||
244 | const struct usb_device_id *id) | ||
245 | { | ||
246 | struct usb_host_interface *intf; | ||
247 | struct usb_device *dev; | ||
248 | |||
249 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
250 | if (id == NULL) | ||
251 | return 0; | ||
252 | |||
253 | intf = interface->cur_altsetting; | ||
254 | dev = interface_to_usbdev(interface); | ||
255 | |||
256 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
257 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
258 | return 0; | ||
259 | |||
260 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
261 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
262 | return 0; | ||
263 | |||
264 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
265 | greater than any unsigned number. */ | ||
266 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
267 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
268 | return 0; | ||
269 | |||
270 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
271 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
272 | return 0; | ||
273 | |||
274 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
275 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
276 | return 0; | ||
277 | |||
278 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
279 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
280 | return 0; | ||
281 | |||
282 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
283 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
284 | return 0; | ||
285 | |||
286 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
287 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
288 | return 0; | ||
289 | |||
290 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
291 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
292 | return 0; | ||
293 | |||
294 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
295 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
296 | return 0; | ||
297 | |||
298 | return 1; | ||
299 | } | ||
300 | /** | ||
301 | * usb_match_id - find first usb_device_id matching device or interface | ||
302 | * @interface: the interface of interest | ||
303 | * @id: array of usb_device_id structures, terminated by zero entry | ||
304 | * | ||
305 | * usb_match_id searches an array of usb_device_id's and returns | ||
306 | * the first one matching the device or interface, or null. | ||
307 | * This is used when binding (or rebinding) a driver to an interface. | ||
308 | * Most USB device drivers will use this indirectly, through the usb core, | ||
309 | * but some layered driver frameworks use it directly. | ||
310 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
311 | * modutils, to support the driver loading functionality of USB hotplugging. | ||
312 | * | ||
313 | * What Matches: | ||
314 | * | ||
315 | * The "match_flags" element in a usb_device_id controls which | ||
316 | * members are used. If the corresponding bit is set, the | ||
317 | * value in the device_id must match its corresponding member | ||
318 | * in the device or interface descriptor, or else the device_id | ||
319 | * does not match. | ||
320 | * | ||
321 | * "driver_info" is normally used only by device drivers, | ||
322 | * but you can create a wildcard "matches anything" usb_device_id | ||
323 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
324 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
325 | * driver's probe() routine should use additional intelligence to | ||
326 | * decide whether to bind to the specified interface. | ||
327 | * | ||
328 | * What Makes Good usb_device_id Tables: | ||
329 | * | ||
330 | * The match algorithm is very simple, so that intelligence in | ||
331 | * driver selection must come from smart driver id records. | ||
332 | * Unless you have good reasons to use another selection policy, | ||
333 | * provide match elements only in related groups, and order match | ||
334 | * specifiers from specific to general. Use the macros provided | ||
335 | * for that purpose if you can. | ||
336 | * | ||
337 | * The most specific match specifiers use device descriptor | ||
338 | * data. These are commonly used with product-specific matches; | ||
339 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
340 | * and you can also match against ranges of product revisions. | ||
341 | * These are widely used for devices with application or vendor | ||
342 | * specific bDeviceClass values. | ||
343 | * | ||
344 | * Matches based on device class/subclass/protocol specifications | ||
345 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
346 | * its siblings. These are used with single-function devices | ||
347 | * where bDeviceClass doesn't specify that each interface has | ||
348 | * its own class. | ||
349 | * | ||
350 | * Matches based on interface class/subclass/protocol are the | ||
351 | * most general; they let drivers bind to any interface on a | ||
352 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
353 | * macro, or its siblings, to match class-per-interface style | ||
354 | * devices (as recorded in bDeviceClass). | ||
355 | * | ||
356 | * Within those groups, remember that not all combinations are | ||
357 | * meaningful. For example, don't give a product version range | ||
358 | * without vendor and product IDs; or specify a protocol without | ||
359 | * its associated class and subclass. | ||
360 | */ | ||
361 | const struct usb_device_id *usb_match_id(struct usb_interface *interface, | ||
362 | const struct usb_device_id *id) | ||
363 | { | ||
364 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
365 | if (id == NULL) | ||
366 | return NULL; | ||
367 | |||
368 | /* It is important to check that id->driver_info is nonzero, | ||
369 | since an entry that is all zeroes except for a nonzero | ||
370 | id->driver_info is the way to create an entry that | ||
371 | indicates that the driver want to examine every | ||
372 | device and interface. */ | ||
373 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
374 | id->driver_info; id++) { | ||
375 | if (usb_match_one_id(interface, id)) | ||
376 | return id; | ||
377 | } | ||
378 | |||
379 | return NULL; | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(usb_match_id); | ||
382 | |||
383 | int usb_device_match(struct device *dev, struct device_driver *drv) | ||
384 | { | ||
385 | struct usb_interface *intf; | ||
386 | struct usb_driver *usb_drv; | ||
387 | const struct usb_device_id *id; | ||
388 | |||
389 | /* check for generic driver, which we don't match any device with */ | ||
390 | if (drv == &usb_generic_driver) | ||
391 | return 0; | ||
392 | |||
393 | intf = to_usb_interface(dev); | ||
394 | usb_drv = to_usb_driver(drv); | ||
395 | |||
396 | id = usb_match_id(intf, usb_drv->id_table); | ||
397 | if (id) | ||
398 | return 1; | ||
399 | |||
400 | id = usb_match_dynamic_id(intf, usb_drv); | ||
401 | if (id) | ||
402 | return 1; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * usb_register_driver - register a USB driver | ||
408 | * @new_driver: USB operations for the driver | ||
409 | * @owner: module owner of this driver. | ||
410 | * | ||
411 | * Registers a USB driver with the USB core. The list of unattached | ||
412 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
413 | * the new driver to attach to any recognized devices. | ||
414 | * Returns a negative error code on failure and 0 on success. | ||
415 | * | ||
416 | * NOTE: if you want your driver to use the USB major number, you must call | ||
417 | * usb_register_dev() to enable that functionality. This function no longer | ||
418 | * takes care of that. | ||
419 | */ | ||
420 | int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | ||
421 | { | ||
422 | int retval = 0; | ||
423 | |||
424 | if (usb_disabled()) | ||
425 | return -ENODEV; | ||
426 | |||
427 | new_driver->driver.name = (char *)new_driver->name; | ||
428 | new_driver->driver.bus = &usb_bus_type; | ||
429 | new_driver->driver.probe = usb_probe_interface; | ||
430 | new_driver->driver.remove = usb_unbind_interface; | ||
431 | new_driver->driver.owner = owner; | ||
432 | spin_lock_init(&new_driver->dynids.lock); | ||
433 | INIT_LIST_HEAD(&new_driver->dynids.list); | ||
434 | |||
435 | retval = driver_register(&new_driver->driver); | ||
436 | |||
437 | if (!retval) { | ||
438 | pr_info("%s: registered new driver %s\n", | ||
439 | usbcore_name, new_driver->name); | ||
440 | usbfs_update_special(); | ||
441 | usb_create_newid_file(new_driver); | ||
442 | } else { | ||
443 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
444 | usbcore_name, retval, new_driver->name); | ||
445 | } | ||
446 | |||
447 | return retval; | ||
448 | } | ||
449 | EXPORT_SYMBOL_GPL(usb_register_driver); | ||
450 | |||
451 | /** | ||
452 | * usb_deregister - unregister a USB driver | ||
453 | * @driver: USB operations of the driver to unregister | ||
454 | * Context: must be able to sleep | ||
455 | * | ||
456 | * Unlinks the specified driver from the internal USB driver list. | ||
457 | * | ||
458 | * NOTE: If you called usb_register_dev(), you still need to call | ||
459 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
460 | * this * call will no longer do it for you. | ||
461 | */ | ||
462 | void usb_deregister(struct usb_driver *driver) | ||
463 | { | ||
464 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
465 | |||
466 | usb_remove_newid_file(driver); | ||
467 | usb_free_dynids(driver); | ||
468 | driver_unregister(&driver->driver); | ||
469 | |||
470 | usbfs_update_special(); | ||
471 | } | ||
472 | EXPORT_SYMBOL_GPL(usb_deregister); | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index da24c31ee00d..0018bbc4de34 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -857,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev, | |||
857 | return (retval < 0) ? retval : -EMSGSIZE; | 857 | return (retval < 0) ? retval : -EMSGSIZE; |
858 | } | 858 | } |
859 | 859 | ||
860 | usb_lock_device (usb_dev); | ||
861 | retval = usb_new_device (usb_dev); | 860 | retval = usb_new_device (usb_dev); |
862 | usb_unlock_device (usb_dev); | ||
863 | if (retval) { | 861 | if (retval) { |
864 | usb_dev->bus->root_hub = NULL; | 862 | usb_dev->bus->root_hub = NULL; |
865 | dev_err (parent_dev, "can't register root hub for %s, %d\n", | 863 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
@@ -1827,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1827 | retval = -ENOMEM; | 1825 | retval = -ENOMEM; |
1828 | goto err_allocate_root_hub; | 1826 | goto err_allocate_root_hub; |
1829 | } | 1827 | } |
1830 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1831 | USB_SPEED_FULL; | ||
1832 | 1828 | ||
1833 | /* Although in principle hcd->driver->start() might need to use rhdev, | 1829 | /* Although in principle hcd->driver->start() might need to use rhdev, |
1834 | * none of the current drivers do. | 1830 | * none of the current drivers do. |
@@ -1846,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1846 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); | 1842 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); |
1847 | hcd->remote_wakeup = hcd->can_wakeup; | 1843 | hcd->remote_wakeup = hcd->can_wakeup; |
1848 | 1844 | ||
1845 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1846 | USB_SPEED_FULL; | ||
1847 | rhdev->bus_mA = min(500u, hcd->power_budget); | ||
1849 | if ((retval = register_root_hub(rhdev, hcd)) != 0) | 1848 | if ((retval = register_root_hub(rhdev, hcd)) != 0) |
1850 | goto err_register_root_hub; | 1849 | goto err_register_root_hub; |
1851 | 1850 | ||
@@ -1891,7 +1890,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1891 | spin_lock_irq (&hcd_root_hub_lock); | 1890 | spin_lock_irq (&hcd_root_hub_lock); |
1892 | hcd->rh_registered = 0; | 1891 | hcd->rh_registered = 0; |
1893 | spin_unlock_irq (&hcd_root_hub_lock); | 1892 | spin_unlock_irq (&hcd_root_hub_lock); |
1893 | |||
1894 | down(&usb_bus_list_lock); | ||
1894 | usb_disconnect(&hcd->self.root_hub); | 1895 | usb_disconnect(&hcd->self.root_hub); |
1896 | up(&usb_bus_list_lock); | ||
1895 | 1897 | ||
1896 | hcd->poll_rh = 0; | 1898 | hcd->poll_rh = 0; |
1897 | del_timer_sync(&hcd->rh_timer); | 1899 | del_timer_sync(&hcd->rh_timer); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index c8a1b350e2cf..591b5aad1a18 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -380,6 +380,7 @@ extern int usb_find_interface_driver (struct usb_device *dev, | |||
380 | #ifdef CONFIG_PM | 380 | #ifdef CONFIG_PM |
381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); | 381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); |
382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | 382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); |
383 | extern void usb_root_hub_lost_power (struct usb_device *rhdev); | ||
383 | extern int hcd_bus_suspend (struct usb_bus *bus); | 384 | extern int hcd_bus_suspend (struct usb_bus *bus); |
384 | extern int hcd_bus_resume (struct usb_bus *bus); | 385 | extern int hcd_bus_resume (struct usb_bus *bus); |
385 | #else | 386 | #else |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f78bd124d290..650d5ee5871b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "hub.h" | 32 | #include "hub.h" |
33 | 33 | ||
34 | /* Protect struct usb_device->state and ->children members | 34 | /* Protect struct usb_device->state and ->children members |
35 | * Note: Both are also protected by ->serialize, except that ->state can | 35 | * Note: Both are also protected by ->dev.sem, except that ->state can |
36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ | 36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ |
37 | static DEFINE_SPINLOCK(device_state_lock); | 37 | static DEFINE_SPINLOCK(device_state_lock); |
38 | 38 | ||
@@ -515,6 +515,31 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | |||
515 | return ret; | 515 | return ret; |
516 | } | 516 | } |
517 | 517 | ||
518 | |||
519 | /* caller has locked the hub device */ | ||
520 | static void hub_pre_reset(struct usb_hub *hub, int disable_ports) | ||
521 | { | ||
522 | struct usb_device *hdev = hub->hdev; | ||
523 | int port1; | ||
524 | |||
525 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
526 | if (hdev->children[port1 - 1]) { | ||
527 | usb_disconnect(&hdev->children[port1 - 1]); | ||
528 | if (disable_ports) | ||
529 | hub_port_disable(hub, port1, 0); | ||
530 | } | ||
531 | } | ||
532 | hub_quiesce(hub); | ||
533 | } | ||
534 | |||
535 | /* caller has locked the hub device */ | ||
536 | static void hub_post_reset(struct usb_hub *hub) | ||
537 | { | ||
538 | hub_activate(hub); | ||
539 | hub_power_on(hub); | ||
540 | } | ||
541 | |||
542 | |||
518 | static int hub_configure(struct usb_hub *hub, | 543 | static int hub_configure(struct usb_hub *hub, |
519 | struct usb_endpoint_descriptor *endpoint) | 544 | struct usb_endpoint_descriptor *endpoint) |
520 | { | 545 | { |
@@ -677,26 +702,40 @@ static int hub_configure(struct usb_hub *hub, | |||
677 | * and battery-powered root hubs (may provide just 8 mA). | 702 | * and battery-powered root hubs (may provide just 8 mA). |
678 | */ | 703 | */ |
679 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); | 704 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); |
680 | if (ret < 0) { | 705 | if (ret < 2) { |
681 | message = "can't get hub status"; | 706 | message = "can't get hub status"; |
682 | goto fail; | 707 | goto fail; |
683 | } | 708 | } |
684 | le16_to_cpus(&hubstatus); | 709 | le16_to_cpus(&hubstatus); |
685 | if (hdev == hdev->bus->root_hub) { | 710 | if (hdev == hdev->bus->root_hub) { |
686 | struct usb_hcd *hcd = | 711 | if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) |
687 | container_of(hdev->bus, struct usb_hcd, self); | 712 | hub->mA_per_port = 500; |
688 | 713 | else { | |
689 | hub->power_budget = min(500u, hcd->power_budget) / 2; | 714 | hub->mA_per_port = hdev->bus_mA; |
715 | hub->limited_power = 1; | ||
716 | } | ||
690 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 717 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
691 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", | 718 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", |
692 | hub->descriptor->bHubContrCurrent); | 719 | hub->descriptor->bHubContrCurrent); |
693 | hub->power_budget = (501 - hub->descriptor->bHubContrCurrent) | 720 | hub->limited_power = 1; |
694 | / 2; | 721 | if (hdev->maxchild > 0) { |
722 | int remaining = hdev->bus_mA - | ||
723 | hub->descriptor->bHubContrCurrent; | ||
724 | |||
725 | if (remaining < hdev->maxchild * 100) | ||
726 | dev_warn(hub_dev, | ||
727 | "insufficient power available " | ||
728 | "to use all downstream ports\n"); | ||
729 | hub->mA_per_port = 100; /* 7.2.1.1 */ | ||
730 | } | ||
731 | } else { /* Self-powered external hub */ | ||
732 | /* FIXME: What about battery-powered external hubs that | ||
733 | * provide less current per port? */ | ||
734 | hub->mA_per_port = 500; | ||
695 | } | 735 | } |
696 | if (hub->power_budget) | 736 | if (hub->mA_per_port < 500) |
697 | dev_dbg(hub_dev, "%dmA bus power budget for children\n", | 737 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
698 | hub->power_budget * 2); | 738 | hub->mA_per_port); |
699 | |||
700 | 739 | ||
701 | ret = hub_hub_status(hub, &hubstatus, &hubchange); | 740 | ret = hub_hub_status(hub, &hubstatus, &hubchange); |
702 | if (ret < 0) { | 741 | if (ret < 0) { |
@@ -750,29 +789,10 @@ fail: | |||
750 | 789 | ||
751 | static unsigned highspeed_hubs; | 790 | static unsigned highspeed_hubs; |
752 | 791 | ||
753 | /* Called after the hub driver is unbound from a hub with children */ | ||
754 | static void hub_remove_children_work(void *__hub) | ||
755 | { | ||
756 | struct usb_hub *hub = __hub; | ||
757 | struct usb_device *hdev = hub->hdev; | ||
758 | int i; | ||
759 | |||
760 | kfree(hub); | ||
761 | |||
762 | usb_lock_device(hdev); | ||
763 | for (i = 0; i < hdev->maxchild; ++i) { | ||
764 | if (hdev->children[i]) | ||
765 | usb_disconnect(&hdev->children[i]); | ||
766 | } | ||
767 | usb_unlock_device(hdev); | ||
768 | usb_put_dev(hdev); | ||
769 | } | ||
770 | |||
771 | static void hub_disconnect(struct usb_interface *intf) | 792 | static void hub_disconnect(struct usb_interface *intf) |
772 | { | 793 | { |
773 | struct usb_hub *hub = usb_get_intfdata (intf); | 794 | struct usb_hub *hub = usb_get_intfdata (intf); |
774 | struct usb_device *hdev; | 795 | struct usb_device *hdev; |
775 | int n, port1; | ||
776 | 796 | ||
777 | usb_set_intfdata (intf, NULL); | 797 | usb_set_intfdata (intf, NULL); |
778 | hdev = hub->hdev; | 798 | hdev = hub->hdev; |
@@ -780,7 +800,9 @@ static void hub_disconnect(struct usb_interface *intf) | |||
780 | if (hdev->speed == USB_SPEED_HIGH) | 800 | if (hdev->speed == USB_SPEED_HIGH) |
781 | highspeed_hubs--; | 801 | highspeed_hubs--; |
782 | 802 | ||
783 | hub_quiesce(hub); | 803 | /* Disconnect all children and quiesce the hub */ |
804 | hub_pre_reset(hub, 1); | ||
805 | |||
784 | usb_free_urb(hub->urb); | 806 | usb_free_urb(hub->urb); |
785 | hub->urb = NULL; | 807 | hub->urb = NULL; |
786 | 808 | ||
@@ -800,27 +822,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
800 | hub->buffer = NULL; | 822 | hub->buffer = NULL; |
801 | } | 823 | } |
802 | 824 | ||
803 | /* If there are any children then this is an unbind only, not a | 825 | kfree(hub); |
804 | * physical disconnection. The active ports must be disabled | ||
805 | * and later on we must call usb_disconnect(). We can't call | ||
806 | * it now because we may not hold the hub's device lock. | ||
807 | */ | ||
808 | n = 0; | ||
809 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
810 | if (hdev->children[port1 - 1]) { | ||
811 | ++n; | ||
812 | hub_port_disable(hub, port1, 1); | ||
813 | } | ||
814 | } | ||
815 | |||
816 | if (n == 0) | ||
817 | kfree(hub); | ||
818 | else { | ||
819 | /* Reuse the hub->leds work_struct for our own purposes */ | ||
820 | INIT_WORK(&hub->leds, hub_remove_children_work, hub); | ||
821 | schedule_work(&hub->leds); | ||
822 | usb_get_dev(hdev); | ||
823 | } | ||
824 | } | 826 | } |
825 | 827 | ||
826 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | 828 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -917,26 +919,6 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | |||
917 | } | 919 | } |
918 | } | 920 | } |
919 | 921 | ||
920 | /* caller has locked the hub device */ | ||
921 | static void hub_pre_reset(struct usb_hub *hub) | ||
922 | { | ||
923 | struct usb_device *hdev = hub->hdev; | ||
924 | int i; | ||
925 | |||
926 | for (i = 0; i < hdev->maxchild; ++i) { | ||
927 | if (hdev->children[i]) | ||
928 | usb_disconnect(&hdev->children[i]); | ||
929 | } | ||
930 | hub_quiesce(hub); | ||
931 | } | ||
932 | |||
933 | /* caller has locked the hub device */ | ||
934 | static void hub_post_reset(struct usb_hub *hub) | ||
935 | { | ||
936 | hub_activate(hub); | ||
937 | hub_power_on(hub); | ||
938 | } | ||
939 | |||
940 | 922 | ||
941 | /* grab device/port lock, returning index of that port (zero based). | 923 | /* grab device/port lock, returning index of that port (zero based). |
942 | * protects the upstream link used by this device from concurrent | 924 | * protects the upstream link used by this device from concurrent |
@@ -964,24 +946,21 @@ static int locktree(struct usb_device *udev) | |||
964 | t = locktree(hdev); | 946 | t = locktree(hdev); |
965 | if (t < 0) | 947 | if (t < 0) |
966 | return t; | 948 | return t; |
967 | for (t = 0; t < hdev->maxchild; t++) { | ||
968 | if (hdev->children[t] == udev) { | ||
969 | /* everything is fail-fast once disconnect | ||
970 | * processing starts | ||
971 | */ | ||
972 | if (udev->state == USB_STATE_NOTATTACHED) | ||
973 | break; | ||
974 | 949 | ||
975 | /* when everyone grabs locks top->bottom, | 950 | /* everything is fail-fast once disconnect |
976 | * non-overlapping work may be concurrent | 951 | * processing starts |
977 | */ | 952 | */ |
978 | down(&udev->serialize); | 953 | if (udev->state == USB_STATE_NOTATTACHED) { |
979 | up(&hdev->serialize); | 954 | usb_unlock_device(hdev); |
980 | return t + 1; | 955 | return -ENODEV; |
981 | } | ||
982 | } | 956 | } |
957 | |||
958 | /* when everyone grabs locks top->bottom, | ||
959 | * non-overlapping work may be concurrent | ||
960 | */ | ||
961 | usb_lock_device(udev); | ||
983 | usb_unlock_device(hdev); | 962 | usb_unlock_device(hdev); |
984 | return -ENODEV; | 963 | return udev->portnum; |
985 | } | 964 | } |
986 | 965 | ||
987 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 966 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) |
@@ -1039,6 +1018,39 @@ void usb_set_device_state(struct usb_device *udev, | |||
1039 | EXPORT_SYMBOL(usb_set_device_state); | 1018 | EXPORT_SYMBOL(usb_set_device_state); |
1040 | 1019 | ||
1041 | 1020 | ||
1021 | #ifdef CONFIG_PM | ||
1022 | |||
1023 | /** | ||
1024 | * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power | ||
1025 | * @rhdev: struct usb_device for the root hub | ||
1026 | * | ||
1027 | * The USB host controller driver calls this function when its root hub | ||
1028 | * is resumed and Vbus power has been interrupted or the controller | ||
1029 | * has been reset. The routine marks all the children of the root hub | ||
1030 | * as NOTATTACHED and marks logical connect-change events on their ports. | ||
1031 | */ | ||
1032 | void usb_root_hub_lost_power(struct usb_device *rhdev) | ||
1033 | { | ||
1034 | struct usb_hub *hub; | ||
1035 | int port1; | ||
1036 | unsigned long flags; | ||
1037 | |||
1038 | dev_warn(&rhdev->dev, "root hub lost power or was reset\n"); | ||
1039 | spin_lock_irqsave(&device_state_lock, flags); | ||
1040 | hub = hdev_to_hub(rhdev); | ||
1041 | for (port1 = 1; port1 <= rhdev->maxchild; ++port1) { | ||
1042 | if (rhdev->children[port1 - 1]) { | ||
1043 | recursively_mark_NOTATTACHED( | ||
1044 | rhdev->children[port1 - 1]); | ||
1045 | set_bit(port1, hub->change_bits); | ||
1046 | } | ||
1047 | } | ||
1048 | spin_unlock_irqrestore(&device_state_lock, flags); | ||
1049 | } | ||
1050 | EXPORT_SYMBOL_GPL(usb_root_hub_lost_power); | ||
1051 | |||
1052 | #endif | ||
1053 | |||
1042 | static void choose_address(struct usb_device *udev) | 1054 | static void choose_address(struct usb_device *udev) |
1043 | { | 1055 | { |
1044 | int devnum; | 1056 | int devnum; |
@@ -1099,16 +1111,10 @@ void usb_disconnect(struct usb_device **pdev) | |||
1099 | * this quiesces everyting except pending urbs. | 1111 | * this quiesces everyting except pending urbs. |
1100 | */ | 1112 | */ |
1101 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1113 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1102 | |||
1103 | /* lock the bus list on behalf of HCDs unregistering their root hubs */ | ||
1104 | if (!udev->parent) { | ||
1105 | down(&usb_bus_list_lock); | ||
1106 | usb_lock_device(udev); | ||
1107 | } else | ||
1108 | down(&udev->serialize); | ||
1109 | |||
1110 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); | 1114 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); |
1111 | 1115 | ||
1116 | usb_lock_device(udev); | ||
1117 | |||
1112 | /* Free up all the children before we remove this device */ | 1118 | /* Free up all the children before we remove this device */ |
1113 | for (i = 0; i < USB_MAXCHILDREN; i++) { | 1119 | for (i = 0; i < USB_MAXCHILDREN; i++) { |
1114 | if (udev->children[i]) | 1120 | if (udev->children[i]) |
@@ -1136,54 +1142,112 @@ void usb_disconnect(struct usb_device **pdev) | |||
1136 | *pdev = NULL; | 1142 | *pdev = NULL; |
1137 | spin_unlock_irq(&device_state_lock); | 1143 | spin_unlock_irq(&device_state_lock); |
1138 | 1144 | ||
1139 | if (!udev->parent) { | 1145 | usb_unlock_device(udev); |
1140 | usb_unlock_device(udev); | ||
1141 | up(&usb_bus_list_lock); | ||
1142 | } else | ||
1143 | up(&udev->serialize); | ||
1144 | 1146 | ||
1145 | device_unregister(&udev->dev); | 1147 | device_unregister(&udev->dev); |
1146 | } | 1148 | } |
1147 | 1149 | ||
1150 | static inline const char *plural(int n) | ||
1151 | { | ||
1152 | return (n == 1 ? "" : "s"); | ||
1153 | } | ||
1154 | |||
1148 | static int choose_configuration(struct usb_device *udev) | 1155 | static int choose_configuration(struct usb_device *udev) |
1149 | { | 1156 | { |
1150 | int c, i; | 1157 | int i; |
1158 | u16 devstatus; | ||
1159 | int bus_powered; | ||
1160 | int num_configs; | ||
1161 | struct usb_host_config *c, *best; | ||
1162 | |||
1163 | /* If this fails, assume the device is bus-powered */ | ||
1164 | devstatus = 0; | ||
1165 | usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | ||
1166 | le16_to_cpus(&devstatus); | ||
1167 | bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); | ||
1168 | dev_dbg(&udev->dev, "device is %s-powered\n", | ||
1169 | bus_powered ? "bus" : "self"); | ||
1170 | |||
1171 | best = NULL; | ||
1172 | c = udev->config; | ||
1173 | num_configs = udev->descriptor.bNumConfigurations; | ||
1174 | for (i = 0; i < num_configs; (i++, c++)) { | ||
1175 | struct usb_interface_descriptor *desc = | ||
1176 | &c->intf_cache[0]->altsetting->desc; | ||
1177 | |||
1178 | /* | ||
1179 | * HP's USB bus-powered keyboard has only one configuration | ||
1180 | * and it claims to be self-powered; other devices may have | ||
1181 | * similar errors in their descriptors. If the next test | ||
1182 | * were allowed to execute, such configurations would always | ||
1183 | * be rejected and the devices would not work as expected. | ||
1184 | */ | ||
1185 | #if 0 | ||
1186 | /* Rule out self-powered configs for a bus-powered device */ | ||
1187 | if (bus_powered && (c->desc.bmAttributes & | ||
1188 | USB_CONFIG_ATT_SELFPOWER)) | ||
1189 | continue; | ||
1190 | #endif | ||
1151 | 1191 | ||
1152 | /* NOTE: this should interact with hub power budgeting */ | 1192 | /* |
1193 | * The next test may not be as effective as it should be. | ||
1194 | * Some hubs have errors in their descriptor, claiming | ||
1195 | * to be self-powered when they are really bus-powered. | ||
1196 | * We will overestimate the amount of current such hubs | ||
1197 | * make available for each port. | ||
1198 | * | ||
1199 | * This is a fairly benign sort of failure. It won't | ||
1200 | * cause us to reject configurations that we should have | ||
1201 | * accepted. | ||
1202 | */ | ||
1153 | 1203 | ||
1154 | c = udev->config[0].desc.bConfigurationValue; | 1204 | /* Rule out configs that draw too much bus current */ |
1155 | if (udev->descriptor.bNumConfigurations != 1) { | 1205 | if (c->desc.bMaxPower * 2 > udev->bus_mA) |
1156 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { | 1206 | continue; |
1157 | struct usb_interface_descriptor *desc; | ||
1158 | 1207 | ||
1159 | /* heuristic: Linux is more likely to have class | 1208 | /* If the first config's first interface is COMM/2/0xff |
1160 | * drivers, so avoid vendor-specific interfaces. | 1209 | * (MSFT RNDIS), rule it out unless Linux has host-side |
1161 | */ | 1210 | * RNDIS support. */ |
1162 | desc = &udev->config[i].intf_cache[0] | 1211 | if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM |
1163 | ->altsetting->desc; | 1212 | && desc->bInterfaceSubClass == 2 |
1164 | if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) | 1213 | && desc->bInterfaceProtocol == 0xff) { |
1165 | continue; | 1214 | #ifndef CONFIG_USB_NET_RNDIS |
1166 | /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS. | 1215 | continue; |
1167 | * MSFT needs this to be the first config; never use | 1216 | #else |
1168 | * it as the default unless Linux has host-side RNDIS. | 1217 | best = c; |
1169 | * A second config would ideally be CDC-Ethernet, but | 1218 | #endif |
1170 | * may instead be the "vendor specific" CDC subset | 1219 | } |
1171 | * long used by ARM Linux for sa1100 or pxa255. | 1220 | |
1172 | */ | 1221 | /* From the remaining configs, choose the first one whose |
1173 | if (desc->bInterfaceClass == USB_CLASS_COMM | 1222 | * first interface is for a non-vendor-specific class. |
1174 | && desc->bInterfaceSubClass == 2 | 1223 | * Reason: Linux is more likely to have a class driver |
1175 | && desc->bInterfaceProtocol == 0xff) { | 1224 | * than a vendor-specific driver. */ |
1176 | c = udev->config[1].desc.bConfigurationValue; | 1225 | else if (udev->descriptor.bDeviceClass != |
1177 | continue; | 1226 | USB_CLASS_VENDOR_SPEC && |
1178 | } | 1227 | desc->bInterfaceClass != |
1179 | c = udev->config[i].desc.bConfigurationValue; | 1228 | USB_CLASS_VENDOR_SPEC) { |
1229 | best = c; | ||
1180 | break; | 1230 | break; |
1181 | } | 1231 | } |
1232 | |||
1233 | /* If all the remaining configs are vendor-specific, | ||
1234 | * choose the first one. */ | ||
1235 | else if (!best) | ||
1236 | best = c; | ||
1237 | } | ||
1238 | |||
1239 | if (best) { | ||
1240 | i = best->desc.bConfigurationValue; | ||
1182 | dev_info(&udev->dev, | 1241 | dev_info(&udev->dev, |
1183 | "configuration #%d chosen from %d choices\n", | 1242 | "configuration #%d chosen from %d choice%s\n", |
1184 | c, udev->descriptor.bNumConfigurations); | 1243 | i, num_configs, plural(num_configs)); |
1244 | } else { | ||
1245 | i = -1; | ||
1246 | dev_warn(&udev->dev, | ||
1247 | "no configuration chosen from %d choice%s\n", | ||
1248 | num_configs, plural(num_configs)); | ||
1185 | } | 1249 | } |
1186 | return c; | 1250 | return i; |
1187 | } | 1251 | } |
1188 | 1252 | ||
1189 | #ifdef DEBUG | 1253 | #ifdef DEBUG |
@@ -1210,8 +1274,8 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1210 | * | 1274 | * |
1211 | * This is called with devices which have been enumerated, but not yet | 1275 | * This is called with devices which have been enumerated, but not yet |
1212 | * configured. The device descriptor is available, but not descriptors | 1276 | * configured. The device descriptor is available, but not descriptors |
1213 | * for any device configuration. The caller must have locked udev and | 1277 | * for any device configuration. The caller must have locked either |
1214 | * either the parent hub (if udev is a normal device) or else the | 1278 | * the parent hub (if udev is a normal device) or else the |
1215 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | 1279 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to |
1216 | * udev has already been installed, but udev is not yet visible through | 1280 | * udev has already been installed, but udev is not yet visible through |
1217 | * sysfs or other filesystem code. | 1281 | * sysfs or other filesystem code. |
@@ -1221,8 +1285,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1221 | * | 1285 | * |
1222 | * This call is synchronous, and may not be used in an interrupt context. | 1286 | * This call is synchronous, and may not be used in an interrupt context. |
1223 | * | 1287 | * |
1224 | * Only the hub driver should ever call this; root hub registration | 1288 | * Only the hub driver or root-hub registrar should ever call this. |
1225 | * uses it indirectly. | ||
1226 | */ | 1289 | */ |
1227 | int usb_new_device(struct usb_device *udev) | 1290 | int usb_new_device(struct usb_device *udev) |
1228 | { | 1291 | { |
@@ -1269,15 +1332,9 @@ int usb_new_device(struct usb_device *udev) | |||
1269 | le16_to_cpu(udev->config[0].desc.wTotalLength), | 1332 | le16_to_cpu(udev->config[0].desc.wTotalLength), |
1270 | USB_DT_OTG, (void **) &desc) == 0) { | 1333 | USB_DT_OTG, (void **) &desc) == 0) { |
1271 | if (desc->bmAttributes & USB_OTG_HNP) { | 1334 | if (desc->bmAttributes & USB_OTG_HNP) { |
1272 | unsigned port1; | 1335 | unsigned port1 = udev->portnum; |
1273 | struct usb_device *root = udev->parent; | 1336 | struct usb_device *root = udev->parent; |
1274 | 1337 | ||
1275 | for (port1 = 1; port1 <= root->maxchild; | ||
1276 | port1++) { | ||
1277 | if (root->children[port1-1] == udev) | ||
1278 | break; | ||
1279 | } | ||
1280 | |||
1281 | dev_info(&udev->dev, | 1338 | dev_info(&udev->dev, |
1282 | "Dual-Role OTG device on %sHNP port\n", | 1339 | "Dual-Role OTG device on %sHNP port\n", |
1283 | (port1 == bus->otg_port) | 1340 | (port1 == bus->otg_port) |
@@ -1331,27 +1388,27 @@ int usb_new_device(struct usb_device *udev) | |||
1331 | } | 1388 | } |
1332 | usb_create_sysfs_dev_files (udev); | 1389 | usb_create_sysfs_dev_files (udev); |
1333 | 1390 | ||
1391 | usb_lock_device(udev); | ||
1392 | |||
1334 | /* choose and set the configuration. that registers the interfaces | 1393 | /* choose and set the configuration. that registers the interfaces |
1335 | * with the driver core, and lets usb device drivers bind to them. | 1394 | * with the driver core, and lets usb device drivers bind to them. |
1336 | */ | 1395 | */ |
1337 | c = choose_configuration(udev); | 1396 | c = choose_configuration(udev); |
1338 | if (c < 0) | 1397 | if (c >= 0) { |
1339 | dev_warn(&udev->dev, | ||
1340 | "can't choose an initial configuration\n"); | ||
1341 | else { | ||
1342 | err = usb_set_configuration(udev, c); | 1398 | err = usb_set_configuration(udev, c); |
1343 | if (err) { | 1399 | if (err) { |
1344 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 1400 | dev_err(&udev->dev, "can't set config #%d, error %d\n", |
1345 | c, err); | 1401 | c, err); |
1346 | usb_remove_sysfs_dev_files(udev); | 1402 | /* This need not be fatal. The user can try to |
1347 | device_del(&udev->dev); | 1403 | * set other configurations. */ |
1348 | goto fail; | ||
1349 | } | 1404 | } |
1350 | } | 1405 | } |
1351 | 1406 | ||
1352 | /* USB device state == configured ... usable */ | 1407 | /* USB device state == configured ... usable */ |
1353 | usb_notify_add_device(udev); | 1408 | usb_notify_add_device(udev); |
1354 | 1409 | ||
1410 | usb_unlock_device(udev); | ||
1411 | |||
1355 | return 0; | 1412 | return 0; |
1356 | 1413 | ||
1357 | fail: | 1414 | fail: |
@@ -1654,15 +1711,9 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) | |||
1654 | int usb_suspend_device(struct usb_device *udev) | 1711 | int usb_suspend_device(struct usb_device *udev) |
1655 | { | 1712 | { |
1656 | #ifdef CONFIG_USB_SUSPEND | 1713 | #ifdef CONFIG_USB_SUSPEND |
1657 | int port1, status; | 1714 | if (udev->state == USB_STATE_NOTATTACHED) |
1658 | 1715 | return -ENODEV; | |
1659 | port1 = locktree(udev); | 1716 | return __usb_suspend_device(udev, udev->portnum); |
1660 | if (port1 < 0) | ||
1661 | return port1; | ||
1662 | |||
1663 | status = __usb_suspend_device(udev, port1); | ||
1664 | usb_unlock_device(udev); | ||
1665 | return status; | ||
1666 | #else | 1717 | #else |
1667 | /* NOTE: udev->state unchanged, it's not lying ... */ | 1718 | /* NOTE: udev->state unchanged, it's not lying ... */ |
1668 | udev->dev.power.power_state = PMSG_SUSPEND; | 1719 | udev->dev.power.power_state = PMSG_SUSPEND; |
@@ -1694,13 +1745,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
1694 | usb_set_device_state(udev, udev->actconfig | 1745 | usb_set_device_state(udev, udev->actconfig |
1695 | ? USB_STATE_CONFIGURED | 1746 | ? USB_STATE_CONFIGURED |
1696 | : USB_STATE_ADDRESS); | 1747 | : USB_STATE_ADDRESS); |
1748 | udev->dev.power.power_state = PMSG_ON; | ||
1697 | 1749 | ||
1698 | /* 10.5.4.5 says be sure devices in the tree are still there. | 1750 | /* 10.5.4.5 says be sure devices in the tree are still there. |
1699 | * For now let's assume the device didn't go crazy on resume, | 1751 | * For now let's assume the device didn't go crazy on resume, |
1700 | * and device drivers will know about any resume quirks. | 1752 | * and device drivers will know about any resume quirks. |
1701 | */ | 1753 | */ |
1702 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1754 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
1703 | if (status < 0) | 1755 | if (status < 2) |
1704 | dev_dbg(&udev->dev, | 1756 | dev_dbg(&udev->dev, |
1705 | "gone after usb resume? status %d\n", | 1757 | "gone after usb resume? status %d\n", |
1706 | status); | 1758 | status); |
@@ -1709,7 +1761,7 @@ static int finish_device_resume(struct usb_device *udev) | |||
1709 | int (*resume)(struct device *); | 1761 | int (*resume)(struct device *); |
1710 | 1762 | ||
1711 | le16_to_cpus(&devstatus); | 1763 | le16_to_cpus(&devstatus); |
1712 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) | 1764 | if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
1713 | && udev->parent) { | 1765 | && udev->parent) { |
1714 | status = usb_control_msg(udev, | 1766 | status = usb_control_msg(udev, |
1715 | usb_sndctrlpipe(udev, 0), | 1767 | usb_sndctrlpipe(udev, 0), |
@@ -1729,8 +1781,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
1729 | * may have a child resume event to deal with soon | 1781 | * may have a child resume event to deal with soon |
1730 | */ | 1782 | */ |
1731 | resume = udev->dev.bus->resume; | 1783 | resume = udev->dev.bus->resume; |
1732 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) | 1784 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1733 | (void) resume(&udev->actconfig->interface[i]->dev); | 1785 | struct device *dev = |
1786 | &udev->actconfig->interface[i]->dev; | ||
1787 | |||
1788 | down(&dev->sem); | ||
1789 | (void) resume(dev); | ||
1790 | up(&dev->sem); | ||
1791 | } | ||
1734 | status = 0; | 1792 | status = 0; |
1735 | 1793 | ||
1736 | } else if (udev->devnum <= 0) { | 1794 | } else if (udev->devnum <= 0) { |
@@ -1813,11 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
1813 | */ | 1871 | */ |
1814 | int usb_resume_device(struct usb_device *udev) | 1872 | int usb_resume_device(struct usb_device *udev) |
1815 | { | 1873 | { |
1816 | int port1, status; | 1874 | int status; |
1817 | 1875 | ||
1818 | port1 = locktree(udev); | 1876 | if (udev->state == USB_STATE_NOTATTACHED) |
1819 | if (port1 < 0) | 1877 | return -ENODEV; |
1820 | return port1; | ||
1821 | 1878 | ||
1822 | #ifdef CONFIG_USB_SUSPEND | 1879 | #ifdef CONFIG_USB_SUSPEND |
1823 | /* selective resume of one downstream hub-to-device port */ | 1880 | /* selective resume of one downstream hub-to-device port */ |
@@ -1826,7 +1883,7 @@ int usb_resume_device(struct usb_device *udev) | |||
1826 | // NOTE swsusp may bork us, device state being wrong... | 1883 | // NOTE swsusp may bork us, device state being wrong... |
1827 | // NOTE this fails if parent is also suspended... | 1884 | // NOTE this fails if parent is also suspended... |
1828 | status = hub_port_resume(hdev_to_hub(udev->parent), | 1885 | status = hub_port_resume(hdev_to_hub(udev->parent), |
1829 | port1, udev); | 1886 | udev->portnum, udev); |
1830 | } else | 1887 | } else |
1831 | status = 0; | 1888 | status = 0; |
1832 | } else | 1889 | } else |
@@ -1836,13 +1893,11 @@ int usb_resume_device(struct usb_device *udev) | |||
1836 | dev_dbg(&udev->dev, "can't resume, status %d\n", | 1893 | dev_dbg(&udev->dev, "can't resume, status %d\n", |
1837 | status); | 1894 | status); |
1838 | 1895 | ||
1839 | usb_unlock_device(udev); | ||
1840 | |||
1841 | /* rebind drivers that had no suspend() */ | 1896 | /* rebind drivers that had no suspend() */ |
1842 | if (status == 0) { | 1897 | if (status == 0) { |
1843 | usb_lock_all_devices(); | 1898 | usb_unlock_device(udev); |
1844 | bus_rescan_devices(&usb_bus_type); | 1899 | bus_rescan_devices(&usb_bus_type); |
1845 | usb_unlock_all_devices(); | 1900 | usb_lock_device(udev); |
1846 | } | 1901 | } |
1847 | return status; | 1902 | return status; |
1848 | } | 1903 | } |
@@ -1856,14 +1911,14 @@ static int remote_wakeup(struct usb_device *udev) | |||
1856 | /* don't repeat RESUME sequence if this device | 1911 | /* don't repeat RESUME sequence if this device |
1857 | * was already woken up by some other task | 1912 | * was already woken up by some other task |
1858 | */ | 1913 | */ |
1859 | down(&udev->serialize); | 1914 | usb_lock_device(udev); |
1860 | if (udev->state == USB_STATE_SUSPENDED) { | 1915 | if (udev->state == USB_STATE_SUSPENDED) { |
1861 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); | 1916 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); |
1862 | /* TRSMRCY = 10 msec */ | 1917 | /* TRSMRCY = 10 msec */ |
1863 | msleep(10); | 1918 | msleep(10); |
1864 | status = finish_device_resume(udev); | 1919 | status = finish_device_resume(udev); |
1865 | } | 1920 | } |
1866 | up(&udev->serialize); | 1921 | usb_unlock_device(udev); |
1867 | #endif | 1922 | #endif |
1868 | return status; | 1923 | return status; |
1869 | } | 1924 | } |
@@ -1964,7 +2019,7 @@ static int hub_resume(struct usb_interface *intf) | |||
1964 | 2019 | ||
1965 | if (!udev || status < 0) | 2020 | if (!udev || status < 0) |
1966 | continue; | 2021 | continue; |
1967 | down (&udev->serialize); | 2022 | usb_lock_device(udev); |
1968 | if (portstat & USB_PORT_STAT_SUSPEND) | 2023 | if (portstat & USB_PORT_STAT_SUSPEND) |
1969 | status = hub_port_resume(hub, port1, udev); | 2024 | status = hub_port_resume(hub, port1, udev); |
1970 | else { | 2025 | else { |
@@ -1975,7 +2030,7 @@ static int hub_resume(struct usb_interface *intf) | |||
1975 | hub_port_logical_disconnect(hub, port1); | 2030 | hub_port_logical_disconnect(hub, port1); |
1976 | } | 2031 | } |
1977 | } | 2032 | } |
1978 | up(&udev->serialize); | 2033 | usb_unlock_device(udev); |
1979 | } | 2034 | } |
1980 | } | 2035 | } |
1981 | #endif | 2036 | #endif |
@@ -2359,39 +2414,36 @@ hub_power_remaining (struct usb_hub *hub) | |||
2359 | { | 2414 | { |
2360 | struct usb_device *hdev = hub->hdev; | 2415 | struct usb_device *hdev = hub->hdev; |
2361 | int remaining; | 2416 | int remaining; |
2362 | unsigned i; | 2417 | int port1; |
2363 | 2418 | ||
2364 | remaining = hub->power_budget; | 2419 | if (!hub->limited_power) |
2365 | if (!remaining) /* self-powered */ | ||
2366 | return 0; | 2420 | return 0; |
2367 | 2421 | ||
2368 | for (i = 0; i < hdev->maxchild; i++) { | 2422 | remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; |
2369 | struct usb_device *udev = hdev->children[i]; | 2423 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
2370 | int delta, ceiling; | 2424 | struct usb_device *udev = hdev->children[port1 - 1]; |
2425 | int delta; | ||
2371 | 2426 | ||
2372 | if (!udev) | 2427 | if (!udev) |
2373 | continue; | 2428 | continue; |
2374 | 2429 | ||
2375 | /* 100mA per-port ceiling, or 8mA for OTG ports */ | 2430 | /* Unconfigured devices may not use more than 100mA, |
2376 | if (i != (udev->bus->otg_port - 1) || hdev->parent) | 2431 | * or 8mA for OTG ports */ |
2377 | ceiling = 50; | ||
2378 | else | ||
2379 | ceiling = 4; | ||
2380 | |||
2381 | if (udev->actconfig) | 2432 | if (udev->actconfig) |
2382 | delta = udev->actconfig->desc.bMaxPower; | 2433 | delta = udev->actconfig->desc.bMaxPower * 2; |
2434 | else if (port1 != udev->bus->otg_port || hdev->parent) | ||
2435 | delta = 100; | ||
2383 | else | 2436 | else |
2384 | delta = ceiling; | 2437 | delta = 8; |
2385 | // dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta); | 2438 | if (delta > hub->mA_per_port) |
2386 | if (delta > ceiling) | 2439 | dev_warn(&udev->dev, "%dmA is over %umA budget " |
2387 | dev_warn(&udev->dev, "%dmA over %dmA budget!\n", | 2440 | "for port %d!\n", |
2388 | 2 * (delta - ceiling), 2 * ceiling); | 2441 | delta, hub->mA_per_port, port1); |
2389 | remaining -= delta; | 2442 | remaining -= delta; |
2390 | } | 2443 | } |
2391 | if (remaining < 0) { | 2444 | if (remaining < 0) { |
2392 | dev_warn(hub->intfdev, | 2445 | dev_warn(hub->intfdev, "%dmA over power budget!\n", |
2393 | "%dmA over power budget!\n", | 2446 | - remaining); |
2394 | -2 * remaining); | ||
2395 | remaining = 0; | 2447 | remaining = 0; |
2396 | } | 2448 | } |
2397 | return remaining; | 2449 | return remaining; |
@@ -2486,7 +2538,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2486 | 2538 | ||
2487 | usb_set_device_state(udev, USB_STATE_POWERED); | 2539 | usb_set_device_state(udev, USB_STATE_POWERED); |
2488 | udev->speed = USB_SPEED_UNKNOWN; | 2540 | udev->speed = USB_SPEED_UNKNOWN; |
2489 | 2541 | udev->bus_mA = hub->mA_per_port; | |
2542 | |||
2490 | /* set the address */ | 2543 | /* set the address */ |
2491 | choose_address(udev); | 2544 | choose_address(udev); |
2492 | if (udev->devnum <= 0) { | 2545 | if (udev->devnum <= 0) { |
@@ -2506,16 +2559,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2506 | * on the parent. | 2559 | * on the parent. |
2507 | */ | 2560 | */ |
2508 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB | 2561 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB |
2509 | && hub->power_budget) { | 2562 | && udev->bus_mA <= 100) { |
2510 | u16 devstat; | 2563 | u16 devstat; |
2511 | 2564 | ||
2512 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, | 2565 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, |
2513 | &devstat); | 2566 | &devstat); |
2514 | if (status < 0) { | 2567 | if (status < 2) { |
2515 | dev_dbg(&udev->dev, "get status %d ?\n", status); | 2568 | dev_dbg(&udev->dev, "get status %d ?\n", status); |
2516 | goto loop_disable; | 2569 | goto loop_disable; |
2517 | } | 2570 | } |
2518 | cpu_to_le16s(&devstat); | 2571 | le16_to_cpus(&devstat); |
2519 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 2572 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
2520 | dev_err(&udev->dev, | 2573 | dev_err(&udev->dev, |
2521 | "can't connect bus-powered hub " | 2574 | "can't connect bus-powered hub " |
@@ -2540,7 +2593,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2540 | * udev becomes globally accessible, although presumably | 2593 | * udev becomes globally accessible, although presumably |
2541 | * no one will look at it until hdev is unlocked. | 2594 | * no one will look at it until hdev is unlocked. |
2542 | */ | 2595 | */ |
2543 | down (&udev->serialize); | ||
2544 | status = 0; | 2596 | status = 0; |
2545 | 2597 | ||
2546 | /* We mustn't add new devices if the parent hub has | 2598 | /* We mustn't add new devices if the parent hub has |
@@ -2564,15 +2616,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2564 | } | 2616 | } |
2565 | } | 2617 | } |
2566 | 2618 | ||
2567 | up (&udev->serialize); | ||
2568 | if (status) | 2619 | if (status) |
2569 | goto loop_disable; | 2620 | goto loop_disable; |
2570 | 2621 | ||
2571 | status = hub_power_remaining(hub); | 2622 | status = hub_power_remaining(hub); |
2572 | if (status) | 2623 | if (status) |
2573 | dev_dbg(hub_dev, | 2624 | dev_dbg(hub_dev, "%dmA power budget left\n", status); |
2574 | "%dmA power budget left\n", | ||
2575 | 2 * status); | ||
2576 | 2625 | ||
2577 | return; | 2626 | return; |
2578 | 2627 | ||
@@ -2648,6 +2697,8 @@ static void hub_events(void) | |||
2648 | if (i) { | 2697 | if (i) { |
2649 | dpm_runtime_resume(&hdev->dev); | 2698 | dpm_runtime_resume(&hdev->dev); |
2650 | dpm_runtime_resume(&intf->dev); | 2699 | dpm_runtime_resume(&intf->dev); |
2700 | usb_put_intf(intf); | ||
2701 | continue; | ||
2651 | } | 2702 | } |
2652 | 2703 | ||
2653 | /* Lock the device, then check to see if we were | 2704 | /* Lock the device, then check to see if we were |
@@ -2661,7 +2712,7 @@ static void hub_events(void) | |||
2661 | 2712 | ||
2662 | /* If the hub has died, clean up after it */ | 2713 | /* If the hub has died, clean up after it */ |
2663 | if (hdev->state == USB_STATE_NOTATTACHED) { | 2714 | if (hdev->state == USB_STATE_NOTATTACHED) { |
2664 | hub_pre_reset(hub); | 2715 | hub_pre_reset(hub, 0); |
2665 | goto loop; | 2716 | goto loop; |
2666 | } | 2717 | } |
2667 | 2718 | ||
@@ -2784,6 +2835,11 @@ static void hub_events(void) | |||
2784 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { | 2835 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { |
2785 | dev_dbg (hub_dev, "power change\n"); | 2836 | dev_dbg (hub_dev, "power change\n"); |
2786 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2837 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
2838 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | ||
2839 | /* FIXME: Is this always true? */ | ||
2840 | hub->limited_power = 0; | ||
2841 | else | ||
2842 | hub->limited_power = 1; | ||
2787 | } | 2843 | } |
2788 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2844 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
2789 | dev_dbg (hub_dev, "overcurrent change\n"); | 2845 | dev_dbg (hub_dev, "overcurrent change\n"); |
@@ -2832,7 +2888,6 @@ static struct usb_device_id hub_id_table [] = { | |||
2832 | MODULE_DEVICE_TABLE (usb, hub_id_table); | 2888 | MODULE_DEVICE_TABLE (usb, hub_id_table); |
2833 | 2889 | ||
2834 | static struct usb_driver hub_driver = { | 2890 | static struct usb_driver hub_driver = { |
2835 | .owner = THIS_MODULE, | ||
2836 | .name = "hub", | 2891 | .name = "hub", |
2837 | .probe = hub_probe, | 2892 | .probe = hub_probe, |
2838 | .disconnect = hub_disconnect, | 2893 | .disconnect = hub_disconnect, |
@@ -2944,7 +2999,8 @@ int usb_reset_device(struct usb_device *udev) | |||
2944 | struct usb_hub *parent_hub; | 2999 | struct usb_hub *parent_hub; |
2945 | struct usb_device_descriptor descriptor = udev->descriptor; | 3000 | struct usb_device_descriptor descriptor = udev->descriptor; |
2946 | struct usb_hub *hub = NULL; | 3001 | struct usb_hub *hub = NULL; |
2947 | int i, ret = 0, port1 = -1; | 3002 | int i, ret = 0; |
3003 | int port1 = udev->portnum; | ||
2948 | 3004 | ||
2949 | if (udev->state == USB_STATE_NOTATTACHED || | 3005 | if (udev->state == USB_STATE_NOTATTACHED || |
2950 | udev->state == USB_STATE_SUSPENDED) { | 3006 | udev->state == USB_STATE_SUSPENDED) { |
@@ -2958,18 +3014,6 @@ int usb_reset_device(struct usb_device *udev) | |||
2958 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); | 3014 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); |
2959 | return -EISDIR; | 3015 | return -EISDIR; |
2960 | } | 3016 | } |
2961 | |||
2962 | for (i = 0; i < parent_hdev->maxchild; i++) | ||
2963 | if (parent_hdev->children[i] == udev) { | ||
2964 | port1 = i + 1; | ||
2965 | break; | ||
2966 | } | ||
2967 | |||
2968 | if (port1 < 0) { | ||
2969 | /* If this ever happens, it's very bad */ | ||
2970 | dev_err(&udev->dev, "Can't locate device's port!\n"); | ||
2971 | return -ENOENT; | ||
2972 | } | ||
2973 | parent_hub = hdev_to_hub(parent_hdev); | 3017 | parent_hub = hdev_to_hub(parent_hdev); |
2974 | 3018 | ||
2975 | /* If we're resetting an active hub, take some special actions */ | 3019 | /* If we're resetting an active hub, take some special actions */ |
@@ -2977,7 +3021,7 @@ int usb_reset_device(struct usb_device *udev) | |||
2977 | udev->actconfig->interface[0]->dev.driver == | 3021 | udev->actconfig->interface[0]->dev.driver == |
2978 | &hub_driver.driver && | 3022 | &hub_driver.driver && |
2979 | (hub = hdev_to_hub(udev)) != NULL) { | 3023 | (hub = hdev_to_hub(udev)) != NULL) { |
2980 | hub_pre_reset(hub); | 3024 | hub_pre_reset(hub, 0); |
2981 | } | 3025 | } |
2982 | 3026 | ||
2983 | set_bit(port1, parent_hub->busy_bits); | 3027 | set_bit(port1, parent_hub->busy_bits); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index bf23f8978024..29d5f45a8456 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -220,8 +220,9 @@ struct usb_hub { | |||
220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | 220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ |
221 | struct usb_tt tt; /* Transaction Translator */ | 221 | struct usb_tt tt; /* Transaction Translator */ |
222 | 222 | ||
223 | u8 power_budget; /* in 2mA units; or zero */ | 223 | unsigned mA_per_port; /* current for each child */ |
224 | 224 | ||
225 | unsigned limited_power:1; | ||
225 | unsigned quiescing:1; | 226 | unsigned quiescing:1; |
226 | unsigned activating:1; | 227 | unsigned activating:1; |
227 | unsigned resume_root_hub:1; | 228 | unsigned resume_root_hub:1; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fe74f99ca5f4..319de03944e7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1387,6 +1387,12 @@ free_interfaces: | |||
1387 | if (dev->state != USB_STATE_ADDRESS) | 1387 | if (dev->state != USB_STATE_ADDRESS) |
1388 | usb_disable_device (dev, 1); // Skip ep0 | 1388 | usb_disable_device (dev, 1); // Skip ep0 |
1389 | 1389 | ||
1390 | i = dev->bus_mA - cp->desc.bMaxPower * 2; | ||
1391 | if (i < 0) | ||
1392 | dev_warn(&dev->dev, "new config #%d exceeds power " | ||
1393 | "limit by %dmA\n", | ||
1394 | configuration, -i); | ||
1395 | |||
1390 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1396 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1391 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1397 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1392 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) | 1398 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index e80ef9467825..13d1d367f7f1 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
35 | #include <linux/rwsem.h> | ||
36 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
37 | 36 | ||
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -47,165 +46,7 @@ | |||
47 | const char *usbcore_name = "usbcore"; | 46 | const char *usbcore_name = "usbcore"; |
48 | 47 | ||
49 | static int nousb; /* Disable USB when built into kernel image */ | 48 | static int nousb; /* Disable USB when built into kernel image */ |
50 | /* Not honored on modular build */ | ||
51 | 49 | ||
52 | static DECLARE_RWSEM(usb_all_devices_rwsem); | ||
53 | |||
54 | |||
55 | static int generic_probe (struct device *dev) | ||
56 | { | ||
57 | return 0; | ||
58 | } | ||
59 | static int generic_remove (struct device *dev) | ||
60 | { | ||
61 | struct usb_device *udev = to_usb_device(dev); | ||
62 | |||
63 | /* if this is only an unbind, not a physical disconnect, then | ||
64 | * unconfigure the device */ | ||
65 | if (udev->state == USB_STATE_CONFIGURED) | ||
66 | usb_set_configuration(udev, 0); | ||
67 | |||
68 | /* in case the call failed or the device was suspended */ | ||
69 | if (udev->state >= USB_STATE_CONFIGURED) | ||
70 | usb_disable_device(udev, 0); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static struct device_driver usb_generic_driver = { | ||
75 | .owner = THIS_MODULE, | ||
76 | .name = "usb", | ||
77 | .bus = &usb_bus_type, | ||
78 | .probe = generic_probe, | ||
79 | .remove = generic_remove, | ||
80 | }; | ||
81 | |||
82 | static int usb_generic_driver_data; | ||
83 | |||
84 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
85 | static int usb_probe_interface(struct device *dev) | ||
86 | { | ||
87 | struct usb_interface * intf = to_usb_interface(dev); | ||
88 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
89 | const struct usb_device_id *id; | ||
90 | int error = -ENODEV; | ||
91 | |||
92 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
93 | |||
94 | if (!driver->probe) | ||
95 | return error; | ||
96 | /* FIXME we'd much prefer to just resume it ... */ | ||
97 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
98 | return -EHOSTUNREACH; | ||
99 | |||
100 | id = usb_match_id (intf, driver->id_table); | ||
101 | if (id) { | ||
102 | dev_dbg (dev, "%s - got id\n", __FUNCTION__); | ||
103 | |||
104 | /* Interface "power state" doesn't correspond to any hardware | ||
105 | * state whatsoever. We use it to record when it's bound to | ||
106 | * a driver that may start I/0: it's not frozen/quiesced. | ||
107 | */ | ||
108 | mark_active(intf); | ||
109 | intf->condition = USB_INTERFACE_BINDING; | ||
110 | error = driver->probe (intf, id); | ||
111 | if (error) { | ||
112 | mark_quiesced(intf); | ||
113 | intf->condition = USB_INTERFACE_UNBOUND; | ||
114 | } else | ||
115 | intf->condition = USB_INTERFACE_BOUND; | ||
116 | } | ||
117 | |||
118 | return error; | ||
119 | } | ||
120 | |||
121 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
122 | static int usb_unbind_interface(struct device *dev) | ||
123 | { | ||
124 | struct usb_interface *intf = to_usb_interface(dev); | ||
125 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
126 | |||
127 | intf->condition = USB_INTERFACE_UNBINDING; | ||
128 | |||
129 | /* release all urbs for this interface */ | ||
130 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
131 | |||
132 | if (driver && driver->disconnect) | ||
133 | driver->disconnect(intf); | ||
134 | |||
135 | /* reset other interface state */ | ||
136 | usb_set_interface(interface_to_usbdev(intf), | ||
137 | intf->altsetting[0].desc.bInterfaceNumber, | ||
138 | 0); | ||
139 | usb_set_intfdata(intf, NULL); | ||
140 | intf->condition = USB_INTERFACE_UNBOUND; | ||
141 | mark_quiesced(intf); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * usb_register - register a USB driver | ||
148 | * @new_driver: USB operations for the driver | ||
149 | * | ||
150 | * Registers a USB driver with the USB core. The list of unattached | ||
151 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
152 | * the new driver to attach to any recognized devices. | ||
153 | * Returns a negative error code on failure and 0 on success. | ||
154 | * | ||
155 | * NOTE: if you want your driver to use the USB major number, you must call | ||
156 | * usb_register_dev() to enable that functionality. This function no longer | ||
157 | * takes care of that. | ||
158 | */ | ||
159 | int usb_register(struct usb_driver *new_driver) | ||
160 | { | ||
161 | int retval = 0; | ||
162 | |||
163 | if (nousb) | ||
164 | return -ENODEV; | ||
165 | |||
166 | new_driver->driver.name = (char *)new_driver->name; | ||
167 | new_driver->driver.bus = &usb_bus_type; | ||
168 | new_driver->driver.probe = usb_probe_interface; | ||
169 | new_driver->driver.remove = usb_unbind_interface; | ||
170 | new_driver->driver.owner = new_driver->owner; | ||
171 | |||
172 | usb_lock_all_devices(); | ||
173 | retval = driver_register(&new_driver->driver); | ||
174 | usb_unlock_all_devices(); | ||
175 | |||
176 | if (!retval) { | ||
177 | pr_info("%s: registered new driver %s\n", | ||
178 | usbcore_name, new_driver->name); | ||
179 | usbfs_update_special(); | ||
180 | } else { | ||
181 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
182 | usbcore_name, retval, new_driver->name); | ||
183 | } | ||
184 | |||
185 | return retval; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * usb_deregister - unregister a USB driver | ||
190 | * @driver: USB operations of the driver to unregister | ||
191 | * Context: must be able to sleep | ||
192 | * | ||
193 | * Unlinks the specified driver from the internal USB driver list. | ||
194 | * | ||
195 | * NOTE: If you called usb_register_dev(), you still need to call | ||
196 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
197 | * this * call will no longer do it for you. | ||
198 | */ | ||
199 | void usb_deregister(struct usb_driver *driver) | ||
200 | { | ||
201 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
202 | |||
203 | usb_lock_all_devices(); | ||
204 | driver_unregister (&driver->driver); | ||
205 | usb_unlock_all_devices(); | ||
206 | |||
207 | usbfs_update_special(); | ||
208 | } | ||
209 | 50 | ||
210 | /** | 51 | /** |
211 | * usb_ifnum_to_if - get the interface object with a given interface number | 52 | * usb_ifnum_to_if - get the interface object with a given interface number |
@@ -352,151 +193,23 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
352 | mark_quiesced(iface); | 193 | mark_quiesced(iface); |
353 | } | 194 | } |
354 | 195 | ||
355 | /** | 196 | struct find_interface_arg { |
356 | * usb_match_id - find first usb_device_id matching device or interface | 197 | int minor; |
357 | * @interface: the interface of interest | 198 | struct usb_interface *interface; |
358 | * @id: array of usb_device_id structures, terminated by zero entry | 199 | }; |
359 | * | ||
360 | * usb_match_id searches an array of usb_device_id's and returns | ||
361 | * the first one matching the device or interface, or null. | ||
362 | * This is used when binding (or rebinding) a driver to an interface. | ||
363 | * Most USB device drivers will use this indirectly, through the usb core, | ||
364 | * but some layered driver frameworks use it directly. | ||
365 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
366 | * modutils and "modules.usbmap", to support the driver loading | ||
367 | * functionality of USB hotplugging. | ||
368 | * | ||
369 | * What Matches: | ||
370 | * | ||
371 | * The "match_flags" element in a usb_device_id controls which | ||
372 | * members are used. If the corresponding bit is set, the | ||
373 | * value in the device_id must match its corresponding member | ||
374 | * in the device or interface descriptor, or else the device_id | ||
375 | * does not match. | ||
376 | * | ||
377 | * "driver_info" is normally used only by device drivers, | ||
378 | * but you can create a wildcard "matches anything" usb_device_id | ||
379 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
380 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
381 | * driver's probe() routine should use additional intelligence to | ||
382 | * decide whether to bind to the specified interface. | ||
383 | * | ||
384 | * What Makes Good usb_device_id Tables: | ||
385 | * | ||
386 | * The match algorithm is very simple, so that intelligence in | ||
387 | * driver selection must come from smart driver id records. | ||
388 | * Unless you have good reasons to use another selection policy, | ||
389 | * provide match elements only in related groups, and order match | ||
390 | * specifiers from specific to general. Use the macros provided | ||
391 | * for that purpose if you can. | ||
392 | * | ||
393 | * The most specific match specifiers use device descriptor | ||
394 | * data. These are commonly used with product-specific matches; | ||
395 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
396 | * and you can also match against ranges of product revisions. | ||
397 | * These are widely used for devices with application or vendor | ||
398 | * specific bDeviceClass values. | ||
399 | * | ||
400 | * Matches based on device class/subclass/protocol specifications | ||
401 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
402 | * its siblings. These are used with single-function devices | ||
403 | * where bDeviceClass doesn't specify that each interface has | ||
404 | * its own class. | ||
405 | * | ||
406 | * Matches based on interface class/subclass/protocol are the | ||
407 | * most general; they let drivers bind to any interface on a | ||
408 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
409 | * macro, or its siblings, to match class-per-interface style | ||
410 | * devices (as recorded in bDeviceClass). | ||
411 | * | ||
412 | * Within those groups, remember that not all combinations are | ||
413 | * meaningful. For example, don't give a product version range | ||
414 | * without vendor and product IDs; or specify a protocol without | ||
415 | * its associated class and subclass. | ||
416 | */ | ||
417 | const struct usb_device_id * | ||
418 | usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | ||
419 | { | ||
420 | struct usb_host_interface *intf; | ||
421 | struct usb_device *dev; | ||
422 | |||
423 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
424 | if (id == NULL) | ||
425 | return NULL; | ||
426 | |||
427 | intf = interface->cur_altsetting; | ||
428 | dev = interface_to_usbdev(interface); | ||
429 | |||
430 | /* It is important to check that id->driver_info is nonzero, | ||
431 | since an entry that is all zeroes except for a nonzero | ||
432 | id->driver_info is the way to create an entry that | ||
433 | indicates that the driver want to examine every | ||
434 | device and interface. */ | ||
435 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
436 | id->driver_info; id++) { | ||
437 | |||
438 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
439 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
440 | continue; | ||
441 | |||
442 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
443 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
444 | continue; | ||
445 | |||
446 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
447 | greater than any unsigned number. */ | ||
448 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
449 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
450 | continue; | ||
451 | |||
452 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
453 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
454 | continue; | ||
455 | |||
456 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
457 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
458 | continue; | ||
459 | |||
460 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
461 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
462 | continue; | ||
463 | |||
464 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
465 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
466 | continue; | ||
467 | |||
468 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
469 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
470 | continue; | ||
471 | |||
472 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
473 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
474 | continue; | ||
475 | |||
476 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
477 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
478 | continue; | ||
479 | |||
480 | return id; | ||
481 | } | ||
482 | |||
483 | return NULL; | ||
484 | } | ||
485 | |||
486 | 200 | ||
487 | static int __find_interface(struct device * dev, void * data) | 201 | static int __find_interface(struct device * dev, void * data) |
488 | { | 202 | { |
489 | struct usb_interface ** ret = (struct usb_interface **)data; | 203 | struct find_interface_arg *arg = data; |
490 | struct usb_interface * intf = *ret; | 204 | struct usb_interface *intf; |
491 | int *minor = (int *)data; | ||
492 | 205 | ||
493 | /* can't look at usb devices, only interfaces */ | 206 | /* can't look at usb devices, only interfaces */ |
494 | if (dev->driver == &usb_generic_driver) | 207 | if (dev->driver == &usb_generic_driver) |
495 | return 0; | 208 | return 0; |
496 | 209 | ||
497 | intf = to_usb_interface(dev); | 210 | intf = to_usb_interface(dev); |
498 | if (intf->minor != -1 && intf->minor == *minor) { | 211 | if (intf->minor != -1 && intf->minor == arg->minor) { |
499 | *ret = intf; | 212 | arg->interface = intf; |
500 | return 1; | 213 | return 1; |
501 | } | 214 | } |
502 | return 0; | 215 | return 0; |
@@ -513,42 +226,18 @@ static int __find_interface(struct device * dev, void * data) | |||
513 | */ | 226 | */ |
514 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 227 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
515 | { | 228 | { |
516 | struct usb_interface *intf = (struct usb_interface *)(long)minor; | 229 | struct find_interface_arg argb; |
517 | int ret; | ||
518 | |||
519 | ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface); | ||
520 | |||
521 | return ret ? intf : NULL; | ||
522 | } | ||
523 | |||
524 | static int usb_device_match (struct device *dev, struct device_driver *drv) | ||
525 | { | ||
526 | struct usb_interface *intf; | ||
527 | struct usb_driver *usb_drv; | ||
528 | const struct usb_device_id *id; | ||
529 | |||
530 | /* check for generic driver, which we don't match any device with */ | ||
531 | if (drv == &usb_generic_driver) | ||
532 | return 0; | ||
533 | |||
534 | intf = to_usb_interface(dev); | ||
535 | usb_drv = to_usb_driver(drv); | ||
536 | |||
537 | id = usb_match_id (intf, usb_drv->id_table); | ||
538 | if (id) | ||
539 | return 1; | ||
540 | 230 | ||
541 | return 0; | 231 | argb.minor = minor; |
232 | argb.interface = NULL; | ||
233 | driver_for_each_device(&drv->driver, NULL, &argb, __find_interface); | ||
234 | return argb.interface; | ||
542 | } | 235 | } |
543 | 236 | ||
544 | |||
545 | #ifdef CONFIG_HOTPLUG | 237 | #ifdef CONFIG_HOTPLUG |
546 | 238 | ||
547 | /* | 239 | /* |
548 | * USB hotplugging invokes what /proc/sys/kernel/hotplug says | 240 | * This sends an uevent to userspace, typically helping to load driver |
549 | * (normally /sbin/hotplug) when USB devices get added or removed. | ||
550 | * | ||
551 | * This invokes a user mode policy agent, typically helping to load driver | ||
552 | * or other modules, configure the device, and more. Drivers can provide | 241 | * or other modules, configure the device, and more. Drivers can provide |
553 | * a MODULE_DEVICE_TABLE to help with module loading subtasks. | 242 | * a MODULE_DEVICE_TABLE to help with module loading subtasks. |
554 | * | 243 | * |
@@ -557,8 +246,8 @@ static int usb_device_match (struct device *dev, struct device_driver *drv) | |||
557 | * delays in event delivery. Use sysfs (and DEVPATH) to make sure the | 246 | * delays in event delivery. Use sysfs (and DEVPATH) to make sure the |
558 | * device (and this configuration!) are still present. | 247 | * device (and this configuration!) are still present. |
559 | */ | 248 | */ |
560 | static int usb_hotplug (struct device *dev, char **envp, int num_envp, | 249 | static int usb_uevent(struct device *dev, char **envp, int num_envp, |
561 | char *buffer, int buffer_size) | 250 | char *buffer, int buffer_size) |
562 | { | 251 | { |
563 | struct usb_interface *intf; | 252 | struct usb_interface *intf; |
564 | struct usb_device *usb_dev; | 253 | struct usb_device *usb_dev; |
@@ -570,7 +259,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
570 | return -ENODEV; | 259 | return -ENODEV; |
571 | 260 | ||
572 | /* driver is often null here; dev_dbg() would oops */ | 261 | /* driver is often null here; dev_dbg() would oops */ |
573 | pr_debug ("usb %s: hotplug\n", dev->bus_id); | 262 | pr_debug ("usb %s: uevent\n", dev->bus_id); |
574 | 263 | ||
575 | /* Must check driver_data here, as on remove driver is always NULL */ | 264 | /* Must check driver_data here, as on remove driver is always NULL */ |
576 | if ((dev->driver == &usb_generic_driver) || | 265 | if ((dev->driver == &usb_generic_driver) || |
@@ -597,51 +286,51 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
597 | * | 286 | * |
598 | * FIXME reduce hardwired intelligence here | 287 | * FIXME reduce hardwired intelligence here |
599 | */ | 288 | */ |
600 | if (add_hotplug_env_var(envp, num_envp, &i, | 289 | if (add_uevent_var(envp, num_envp, &i, |
601 | buffer, buffer_size, &length, | 290 | buffer, buffer_size, &length, |
602 | "DEVICE=/proc/bus/usb/%03d/%03d", | 291 | "DEVICE=/proc/bus/usb/%03d/%03d", |
603 | usb_dev->bus->busnum, usb_dev->devnum)) | 292 | usb_dev->bus->busnum, usb_dev->devnum)) |
604 | return -ENOMEM; | 293 | return -ENOMEM; |
605 | #endif | 294 | #endif |
606 | 295 | ||
607 | /* per-device configurations are common */ | 296 | /* per-device configurations are common */ |
608 | if (add_hotplug_env_var(envp, num_envp, &i, | 297 | if (add_uevent_var(envp, num_envp, &i, |
609 | buffer, buffer_size, &length, | 298 | buffer, buffer_size, &length, |
610 | "PRODUCT=%x/%x/%x", | 299 | "PRODUCT=%x/%x/%x", |
611 | le16_to_cpu(usb_dev->descriptor.idVendor), | 300 | le16_to_cpu(usb_dev->descriptor.idVendor), |
612 | le16_to_cpu(usb_dev->descriptor.idProduct), | 301 | le16_to_cpu(usb_dev->descriptor.idProduct), |
613 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 302 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
614 | return -ENOMEM; | 303 | return -ENOMEM; |
615 | 304 | ||
616 | /* class-based driver binding models */ | 305 | /* class-based driver binding models */ |
617 | if (add_hotplug_env_var(envp, num_envp, &i, | 306 | if (add_uevent_var(envp, num_envp, &i, |
618 | buffer, buffer_size, &length, | 307 | buffer, buffer_size, &length, |
619 | "TYPE=%d/%d/%d", | 308 | "TYPE=%d/%d/%d", |
620 | usb_dev->descriptor.bDeviceClass, | 309 | usb_dev->descriptor.bDeviceClass, |
621 | usb_dev->descriptor.bDeviceSubClass, | 310 | usb_dev->descriptor.bDeviceSubClass, |
622 | usb_dev->descriptor.bDeviceProtocol)) | 311 | usb_dev->descriptor.bDeviceProtocol)) |
623 | return -ENOMEM; | 312 | return -ENOMEM; |
624 | 313 | ||
625 | if (add_hotplug_env_var(envp, num_envp, &i, | 314 | if (add_uevent_var(envp, num_envp, &i, |
626 | buffer, buffer_size, &length, | 315 | buffer, buffer_size, &length, |
627 | "INTERFACE=%d/%d/%d", | 316 | "INTERFACE=%d/%d/%d", |
628 | alt->desc.bInterfaceClass, | 317 | alt->desc.bInterfaceClass, |
629 | alt->desc.bInterfaceSubClass, | 318 | alt->desc.bInterfaceSubClass, |
630 | alt->desc.bInterfaceProtocol)) | 319 | alt->desc.bInterfaceProtocol)) |
631 | return -ENOMEM; | 320 | return -ENOMEM; |
632 | 321 | ||
633 | if (add_hotplug_env_var(envp, num_envp, &i, | 322 | if (add_uevent_var(envp, num_envp, &i, |
634 | buffer, buffer_size, &length, | 323 | buffer, buffer_size, &length, |
635 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 324 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", |
636 | le16_to_cpu(usb_dev->descriptor.idVendor), | 325 | le16_to_cpu(usb_dev->descriptor.idVendor), |
637 | le16_to_cpu(usb_dev->descriptor.idProduct), | 326 | le16_to_cpu(usb_dev->descriptor.idProduct), |
638 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | 327 | le16_to_cpu(usb_dev->descriptor.bcdDevice), |
639 | usb_dev->descriptor.bDeviceClass, | 328 | usb_dev->descriptor.bDeviceClass, |
640 | usb_dev->descriptor.bDeviceSubClass, | 329 | usb_dev->descriptor.bDeviceSubClass, |
641 | usb_dev->descriptor.bDeviceProtocol, | 330 | usb_dev->descriptor.bDeviceProtocol, |
642 | alt->desc.bInterfaceClass, | 331 | alt->desc.bInterfaceClass, |
643 | alt->desc.bInterfaceSubClass, | 332 | alt->desc.bInterfaceSubClass, |
644 | alt->desc.bInterfaceProtocol)) | 333 | alt->desc.bInterfaceProtocol)) |
645 | return -ENOMEM; | 334 | return -ENOMEM; |
646 | 335 | ||
647 | envp[i] = NULL; | 336 | envp[i] = NULL; |
@@ -651,7 +340,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
651 | 340 | ||
652 | #else | 341 | #else |
653 | 342 | ||
654 | static int usb_hotplug (struct device *dev, char **envp, | 343 | static int usb_uevent(struct device *dev, char **envp, |
655 | int num_envp, char *buffer, int buffer_size) | 344 | int num_envp, char *buffer, int buffer_size) |
656 | { | 345 | { |
657 | return -ENODEV; | 346 | return -ENODEV; |
@@ -750,12 +439,11 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
750 | /* hub driver sets up TT records */ | 439 | /* hub driver sets up TT records */ |
751 | } | 440 | } |
752 | 441 | ||
442 | dev->portnum = port1; | ||
753 | dev->bus = bus; | 443 | dev->bus = bus; |
754 | dev->parent = parent; | 444 | dev->parent = parent; |
755 | INIT_LIST_HEAD(&dev->filelist); | 445 | INIT_LIST_HEAD(&dev->filelist); |
756 | 446 | ||
757 | init_MUTEX(&dev->serialize); | ||
758 | |||
759 | return dev; | 447 | return dev; |
760 | } | 448 | } |
761 | 449 | ||
@@ -828,76 +516,21 @@ void usb_put_intf(struct usb_interface *intf) | |||
828 | 516 | ||
829 | /* USB device locking | 517 | /* USB device locking |
830 | * | 518 | * |
831 | * Although locking USB devices should be straightforward, it is | 519 | * USB devices and interfaces are locked using the semaphore in their |
832 | * complicated by the way the driver-model core works. When a new USB | 520 | * embedded struct device. The hub driver guarantees that whenever a |
833 | * driver is registered or unregistered, the core will automatically | 521 | * device is connected or disconnected, drivers are called with the |
834 | * probe or disconnect all matching interfaces on all USB devices while | 522 | * USB device locked as well as their particular interface. |
835 | * holding the USB subsystem writelock. There's no good way for us to | ||
836 | * tell which devices will be used or to lock them beforehand; our only | ||
837 | * option is to effectively lock all the USB devices. | ||
838 | * | ||
839 | * We do that by using a private rw-semaphore, usb_all_devices_rwsem. | ||
840 | * When locking an individual device you must first acquire the rwsem's | ||
841 | * readlock. When a driver is registered or unregistered the writelock | ||
842 | * must be held. These actions are encapsulated in the subroutines | ||
843 | * below, so all a driver needs to do is call usb_lock_device() and | ||
844 | * usb_unlock_device(). | ||
845 | * | 523 | * |
846 | * Complications arise when several devices are to be locked at the same | 524 | * Complications arise when several devices are to be locked at the same |
847 | * time. Only hub-aware drivers that are part of usbcore ever have to | 525 | * time. Only hub-aware drivers that are part of usbcore ever have to |
848 | * do this; nobody else needs to worry about it. The problem is that | 526 | * do this; nobody else needs to worry about it. The rule for locking |
849 | * usb_lock_device() must not be called to lock a second device since it | 527 | * is simple: |
850 | * would acquire the rwsem's readlock reentrantly, leading to deadlock if | ||
851 | * another thread was waiting for the writelock. The solution is simple: | ||
852 | * | ||
853 | * When locking more than one device, call usb_lock_device() | ||
854 | * to lock the first one. Lock the others by calling | ||
855 | * down(&udev->serialize) directly. | ||
856 | * | ||
857 | * When unlocking multiple devices, use up(&udev->serialize) | ||
858 | * to unlock all but the last one. Unlock the last one by | ||
859 | * calling usb_unlock_device(). | ||
860 | * | 528 | * |
861 | * When locking both a device and its parent, always lock the | 529 | * When locking both a device and its parent, always lock the |
862 | * the parent first. | 530 | * the parent first. |
863 | */ | 531 | */ |
864 | 532 | ||
865 | /** | 533 | /** |
866 | * usb_lock_device - acquire the lock for a usb device structure | ||
867 | * @udev: device that's being locked | ||
868 | * | ||
869 | * Use this routine when you don't hold any other device locks; | ||
870 | * to acquire nested inner locks call down(&udev->serialize) directly. | ||
871 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
872 | */ | ||
873 | void usb_lock_device(struct usb_device *udev) | ||
874 | { | ||
875 | down_read(&usb_all_devices_rwsem); | ||
876 | down(&udev->serialize); | ||
877 | } | ||
878 | |||
879 | /** | ||
880 | * usb_trylock_device - attempt to acquire the lock for a usb device structure | ||
881 | * @udev: device that's being locked | ||
882 | * | ||
883 | * Don't use this routine if you already hold a device lock; | ||
884 | * use down_trylock(&udev->serialize) instead. | ||
885 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
886 | * | ||
887 | * Returns 1 if successful, 0 if contention. | ||
888 | */ | ||
889 | int usb_trylock_device(struct usb_device *udev) | ||
890 | { | ||
891 | if (!down_read_trylock(&usb_all_devices_rwsem)) | ||
892 | return 0; | ||
893 | if (down_trylock(&udev->serialize)) { | ||
894 | up_read(&usb_all_devices_rwsem); | ||
895 | return 0; | ||
896 | } | ||
897 | return 1; | ||
898 | } | ||
899 | |||
900 | /** | ||
901 | * usb_lock_device_for_reset - cautiously acquire the lock for a | 534 | * usb_lock_device_for_reset - cautiously acquire the lock for a |
902 | * usb device structure | 535 | * usb device structure |
903 | * @udev: device that's being locked | 536 | * @udev: device that's being locked |
@@ -935,7 +568,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
935 | } | 568 | } |
936 | } | 569 | } |
937 | 570 | ||
938 | while (!usb_trylock_device(udev)) { | 571 | while (usb_trylock_device(udev) != 0) { |
939 | 572 | ||
940 | /* If we can't acquire the lock after waiting one second, | 573 | /* If we can't acquire the lock after waiting one second, |
941 | * we're probably deadlocked */ | 574 | * we're probably deadlocked */ |
@@ -953,39 +586,6 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
953 | return 1; | 586 | return 1; |
954 | } | 587 | } |
955 | 588 | ||
956 | /** | ||
957 | * usb_unlock_device - release the lock for a usb device structure | ||
958 | * @udev: device that's being unlocked | ||
959 | * | ||
960 | * Use this routine when releasing the only device lock you hold; | ||
961 | * to release inner nested locks call up(&udev->serialize) directly. | ||
962 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
963 | */ | ||
964 | void usb_unlock_device(struct usb_device *udev) | ||
965 | { | ||
966 | up(&udev->serialize); | ||
967 | up_read(&usb_all_devices_rwsem); | ||
968 | } | ||
969 | |||
970 | /** | ||
971 | * usb_lock_all_devices - acquire the lock for all usb device structures | ||
972 | * | ||
973 | * This is necessary when registering a new driver or probing a bus, | ||
974 | * since the driver-model core may try to use any usb_device. | ||
975 | */ | ||
976 | void usb_lock_all_devices(void) | ||
977 | { | ||
978 | down_write(&usb_all_devices_rwsem); | ||
979 | } | ||
980 | |||
981 | /** | ||
982 | * usb_unlock_all_devices - release the lock for all usb device structures | ||
983 | */ | ||
984 | void usb_unlock_all_devices(void) | ||
985 | { | ||
986 | up_write(&usb_all_devices_rwsem); | ||
987 | } | ||
988 | |||
989 | 589 | ||
990 | static struct usb_device *match_device(struct usb_device *dev, | 590 | static struct usb_device *match_device(struct usb_device *dev, |
991 | u16 vendor_id, u16 product_id) | 591 | u16 vendor_id, u16 product_id) |
@@ -1008,10 +608,10 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
1008 | /* look through all of the children of this device */ | 608 | /* look through all of the children of this device */ |
1009 | for (child = 0; child < dev->maxchild; ++child) { | 609 | for (child = 0; child < dev->maxchild; ++child) { |
1010 | if (dev->children[child]) { | 610 | if (dev->children[child]) { |
1011 | down(&dev->children[child]->serialize); | 611 | usb_lock_device(dev->children[child]); |
1012 | ret_dev = match_device(dev->children[child], | 612 | ret_dev = match_device(dev->children[child], |
1013 | vendor_id, product_id); | 613 | vendor_id, product_id); |
1014 | up(&dev->children[child]->serialize); | 614 | usb_unlock_device(dev->children[child]); |
1015 | if (ret_dev) | 615 | if (ret_dev) |
1016 | goto exit; | 616 | goto exit; |
1017 | } | 617 | } |
@@ -1491,23 +1091,13 @@ static int usb_generic_resume(struct device *dev) | |||
1491 | struct bus_type usb_bus_type = { | 1091 | struct bus_type usb_bus_type = { |
1492 | .name = "usb", | 1092 | .name = "usb", |
1493 | .match = usb_device_match, | 1093 | .match = usb_device_match, |
1494 | .hotplug = usb_hotplug, | 1094 | .uevent = usb_uevent, |
1495 | .suspend = usb_generic_suspend, | 1095 | .suspend = usb_generic_suspend, |
1496 | .resume = usb_generic_resume, | 1096 | .resume = usb_generic_resume, |
1497 | }; | 1097 | }; |
1498 | 1098 | ||
1499 | #ifndef MODULE | ||
1500 | |||
1501 | static int __init usb_setup_disable(char *str) | ||
1502 | { | ||
1503 | nousb = 1; | ||
1504 | return 1; | ||
1505 | } | ||
1506 | |||
1507 | /* format to disable USB on kernel command line is: nousb */ | 1099 | /* format to disable USB on kernel command line is: nousb */ |
1508 | __setup("nousb", usb_setup_disable); | 1100 | __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); |
1509 | |||
1510 | #endif | ||
1511 | 1101 | ||
1512 | /* | 1102 | /* |
1513 | * for external read access to <nousb> | 1103 | * for external read access to <nousb> |
@@ -1598,8 +1188,6 @@ module_exit(usb_exit); | |||
1598 | * driver modules to use. | 1188 | * driver modules to use. |
1599 | */ | 1189 | */ |
1600 | 1190 | ||
1601 | EXPORT_SYMBOL(usb_register); | ||
1602 | EXPORT_SYMBOL(usb_deregister); | ||
1603 | EXPORT_SYMBOL(usb_disabled); | 1191 | EXPORT_SYMBOL(usb_disabled); |
1604 | 1192 | ||
1605 | EXPORT_SYMBOL_GPL(usb_get_intf); | 1193 | EXPORT_SYMBOL_GPL(usb_get_intf); |
@@ -1610,14 +1198,10 @@ EXPORT_SYMBOL(usb_put_dev); | |||
1610 | EXPORT_SYMBOL(usb_get_dev); | 1198 | EXPORT_SYMBOL(usb_get_dev); |
1611 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | 1199 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); |
1612 | 1200 | ||
1613 | EXPORT_SYMBOL(usb_lock_device); | ||
1614 | EXPORT_SYMBOL(usb_trylock_device); | ||
1615 | EXPORT_SYMBOL(usb_lock_device_for_reset); | 1201 | EXPORT_SYMBOL(usb_lock_device_for_reset); |
1616 | EXPORT_SYMBOL(usb_unlock_device); | ||
1617 | 1202 | ||
1618 | EXPORT_SYMBOL(usb_driver_claim_interface); | 1203 | EXPORT_SYMBOL(usb_driver_claim_interface); |
1619 | EXPORT_SYMBOL(usb_driver_release_interface); | 1204 | EXPORT_SYMBOL(usb_driver_release_interface); |
1620 | EXPORT_SYMBOL(usb_match_id); | ||
1621 | EXPORT_SYMBOL(usb_find_interface); | 1205 | EXPORT_SYMBOL(usb_find_interface); |
1622 | EXPORT_SYMBOL(usb_ifnum_to_if); | 1206 | EXPORT_SYMBOL(usb_ifnum_to_if); |
1623 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 1207 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1c4a68499dce..4647e1ebc68d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -16,9 +16,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev, | |||
16 | extern char *usb_cache_string(struct usb_device *udev, int index); | 16 | extern char *usb_cache_string(struct usb_device *udev, int index); |
17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
18 | 18 | ||
19 | extern void usb_lock_all_devices(void); | ||
20 | extern void usb_unlock_all_devices(void); | ||
21 | |||
22 | extern void usb_kick_khubd(struct usb_device *dev); | 19 | extern void usb_kick_khubd(struct usb_device *dev); |
23 | extern void usb_suspend_root_hub(struct usb_device *hdev); | 20 | extern void usb_suspend_root_hub(struct usb_device *hdev); |
24 | extern void usb_resume_root_hub(struct usb_device *dev); | 21 | extern void usb_resume_root_hub(struct usb_device *dev); |
@@ -33,6 +30,9 @@ extern void usb_host_cleanup(void); | |||
33 | extern int usb_suspend_device(struct usb_device *dev); | 30 | extern int usb_suspend_device(struct usb_device *dev); |
34 | extern int usb_resume_device(struct usb_device *dev); | 31 | extern int usb_resume_device(struct usb_device *dev); |
35 | 32 | ||
33 | extern struct device_driver usb_generic_driver; | ||
34 | extern int usb_generic_driver_data; | ||
35 | extern int usb_device_match(struct device *dev, struct device_driver *drv); | ||
36 | 36 | ||
37 | /* Interfaces and their "power state" are owned by usbcore */ | 37 | /* Interfaces and their "power state" are owned by usbcore */ |
38 | 38 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c655d46c8aed..9734cb76dd6c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -138,7 +138,7 @@ static const char *const ep_name [] = { | |||
138 | /* or like sa1100: two fixed function endpoints */ | 138 | /* or like sa1100: two fixed function endpoints */ |
139 | "ep1out-bulk", "ep2in-bulk", | 139 | "ep1out-bulk", "ep2in-bulk", |
140 | }; | 140 | }; |
141 | #define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *)) | 141 | #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) |
142 | 142 | ||
143 | /*-------------------------------------------------------------------------*/ | 143 | /*-------------------------------------------------------------------------*/ |
144 | 144 | ||
@@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev) | |||
896 | #endif | 896 | #endif |
897 | } | 897 | } |
898 | 898 | ||
899 | static int dummy_udc_probe (struct platform_device *dev) | 899 | static int dummy_udc_probe (struct platform_device *pdev) |
900 | { | 900 | { |
901 | struct dummy *dum = the_controller; | 901 | struct dummy *dum = the_controller; |
902 | int rc; | 902 | int rc; |
@@ -909,7 +909,7 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); | 909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); |
910 | 910 | ||
911 | strcpy (dum->gadget.dev.bus_id, "gadget"); | 911 | strcpy (dum->gadget.dev.bus_id, "gadget"); |
912 | dum->gadget.dev.parent = &dev->dev; | 912 | dum->gadget.dev.parent = &pdev->dev; |
913 | dum->gadget.dev.release = dummy_gadget_release; | 913 | dum->gadget.dev.release = dummy_gadget_release; |
914 | rc = device_register (&dum->gadget.dev); | 914 | rc = device_register (&dum->gadget.dev); |
915 | if (rc < 0) | 915 | if (rc < 0) |
@@ -919,47 +919,47 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
919 | usb_bus_get (&dummy_to_hcd (dum)->self); | 919 | usb_bus_get (&dummy_to_hcd (dum)->self); |
920 | #endif | 920 | #endif |
921 | 921 | ||
922 | platform_set_drvdata (dev, dum); | 922 | platform_set_drvdata (pdev, dum); |
923 | device_create_file (&dum->gadget.dev, &dev_attr_function); | 923 | device_create_file (&dum->gadget.dev, &dev_attr_function); |
924 | return rc; | 924 | return rc; |
925 | } | 925 | } |
926 | 926 | ||
927 | static int dummy_udc_remove (struct platform_device *dev) | 927 | static int dummy_udc_remove (struct platform_device *pdev) |
928 | { | 928 | { |
929 | struct dummy *dum = platform_get_drvdata (dev); | 929 | struct dummy *dum = platform_get_drvdata (pdev); |
930 | 930 | ||
931 | platform_set_drvdata (dev, NULL); | 931 | platform_set_drvdata (pdev, NULL); |
932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); | 932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); |
933 | device_unregister (&dum->gadget.dev); | 933 | device_unregister (&dum->gadget.dev); |
934 | return 0; | 934 | return 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state) | 937 | static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) |
938 | { | 938 | { |
939 | struct dummy *dum = platform_get_drvdata(dev); | 939 | struct dummy *dum = platform_get_drvdata(pdev); |
940 | 940 | ||
941 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 941 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
942 | spin_lock_irq (&dum->lock); | 942 | spin_lock_irq (&dum->lock); |
943 | dum->udc_suspended = 1; | 943 | dum->udc_suspended = 1; |
944 | set_link_state (dum); | 944 | set_link_state (dum); |
945 | spin_unlock_irq (&dum->lock); | 945 | spin_unlock_irq (&dum->lock); |
946 | 946 | ||
947 | dev->dev.power.power_state = state; | 947 | pdev->dev.power.power_state = state; |
948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
951 | 951 | ||
952 | static int dummy_udc_resume (struct platform_device *dev) | 952 | static int dummy_udc_resume (struct platform_device *pdev) |
953 | { | 953 | { |
954 | struct dummy *dum = platform_get_drvdata(dev); | 954 | struct dummy *dum = platform_get_drvdata(pdev); |
955 | 955 | ||
956 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 956 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
957 | spin_lock_irq (&dum->lock); | 957 | spin_lock_irq (&dum->lock); |
958 | dum->udc_suspended = 0; | 958 | dum->udc_suspended = 0; |
959 | set_link_state (dum); | 959 | set_link_state (dum); |
960 | spin_unlock_irq (&dum->lock); | 960 | spin_unlock_irq (&dum->lock); |
961 | 961 | ||
962 | dev->dev.power.power_state = PMSG_ON; | 962 | pdev->dev.power.power_state = PMSG_ON; |
963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
964 | return 0; | 964 | return 0; |
965 | } | 965 | } |
@@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | |||
1576 | dum = hcd_to_dummy (hcd); | 1576 | dum = hcd_to_dummy (hcd); |
1577 | 1577 | ||
1578 | spin_lock_irqsave (&dum->lock, flags); | 1578 | spin_lock_irqsave (&dum->lock, flags); |
1579 | if (hcd->state != HC_STATE_RUNNING) | 1579 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1580 | goto done; | 1580 | goto done; |
1581 | 1581 | ||
1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { | 1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { |
@@ -1623,7 +1623,7 @@ static int dummy_hub_control ( | |||
1623 | int retval = 0; | 1623 | int retval = 0; |
1624 | unsigned long flags; | 1624 | unsigned long flags; |
1625 | 1625 | ||
1626 | if (hcd->state != HC_STATE_RUNNING) | 1626 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1627 | return -ETIMEDOUT; | 1627 | return -ETIMEDOUT; |
1628 | 1628 | ||
1629 | dum = hcd_to_dummy (hcd); | 1629 | dum = hcd_to_dummy (hcd); |
@@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1756 | { | 1756 | { |
1757 | struct dummy *dum = hcd_to_dummy (hcd); | 1757 | struct dummy *dum = hcd_to_dummy (hcd); |
1758 | 1758 | ||
1759 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1760 | |||
1759 | spin_lock_irq (&dum->lock); | 1761 | spin_lock_irq (&dum->lock); |
1760 | dum->rh_state = DUMMY_RH_SUSPENDED; | 1762 | dum->rh_state = DUMMY_RH_SUSPENDED; |
1761 | set_link_state (dum); | 1763 | set_link_state (dum); |
1764 | hcd->state = HC_STATE_SUSPENDED; | ||
1762 | spin_unlock_irq (&dum->lock); | 1765 | spin_unlock_irq (&dum->lock); |
1763 | return 0; | 1766 | return 0; |
1764 | } | 1767 | } |
@@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1766 | static int dummy_bus_resume (struct usb_hcd *hcd) | 1769 | static int dummy_bus_resume (struct usb_hcd *hcd) |
1767 | { | 1770 | { |
1768 | struct dummy *dum = hcd_to_dummy (hcd); | 1771 | struct dummy *dum = hcd_to_dummy (hcd); |
1772 | int rc = 0; | ||
1773 | |||
1774 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1769 | 1775 | ||
1770 | spin_lock_irq (&dum->lock); | 1776 | spin_lock_irq (&dum->lock); |
1771 | dum->rh_state = DUMMY_RH_RUNNING; | 1777 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
1772 | set_link_state (dum); | 1778 | dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); |
1773 | if (!list_empty(&dum->urbp_list)) | 1779 | rc = -ENODEV; |
1774 | mod_timer (&dum->timer, jiffies); | 1780 | } else { |
1781 | dum->rh_state = DUMMY_RH_RUNNING; | ||
1782 | set_link_state (dum); | ||
1783 | if (!list_empty(&dum->urbp_list)) | ||
1784 | mod_timer (&dum->timer, jiffies); | ||
1785 | hcd->state = HC_STATE_RUNNING; | ||
1786 | } | ||
1775 | spin_unlock_irq (&dum->lock); | 1787 | spin_unlock_irq (&dum->lock); |
1776 | return 0; | 1788 | return rc; |
1777 | } | 1789 | } |
1778 | 1790 | ||
1779 | /*-------------------------------------------------------------------------*/ | 1791 | /*-------------------------------------------------------------------------*/ |
@@ -1899,14 +1911,14 @@ static const struct hc_driver dummy_hcd = { | |||
1899 | .bus_resume = dummy_bus_resume, | 1911 | .bus_resume = dummy_bus_resume, |
1900 | }; | 1912 | }; |
1901 | 1913 | ||
1902 | static int dummy_hcd_probe (struct platform_device *dev) | 1914 | static int dummy_hcd_probe(struct platform_device *pdev) |
1903 | { | 1915 | { |
1904 | struct usb_hcd *hcd; | 1916 | struct usb_hcd *hcd; |
1905 | int retval; | 1917 | int retval; |
1906 | 1918 | ||
1907 | dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1919 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
1908 | 1920 | ||
1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); | 1921 | hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id); |
1910 | if (!hcd) | 1922 | if (!hcd) |
1911 | return -ENOMEM; | 1923 | return -ENOMEM; |
1912 | the_controller = hcd_to_dummy (hcd); | 1924 | the_controller = hcd_to_dummy (hcd); |
@@ -1919,36 +1931,43 @@ static int dummy_hcd_probe (struct platform_device *dev) | |||
1919 | return retval; | 1931 | return retval; |
1920 | } | 1932 | } |
1921 | 1933 | ||
1922 | static int dummy_hcd_remove (struct platform_device *dev) | 1934 | static int dummy_hcd_remove (struct platform_device *pdev) |
1923 | { | 1935 | { |
1924 | struct usb_hcd *hcd; | 1936 | struct usb_hcd *hcd; |
1925 | 1937 | ||
1926 | hcd = platform_get_drvdata (dev); | 1938 | hcd = platform_get_drvdata (pdev); |
1927 | usb_remove_hcd (hcd); | 1939 | usb_remove_hcd (hcd); |
1928 | usb_put_hcd (hcd); | 1940 | usb_put_hcd (hcd); |
1929 | the_controller = NULL; | 1941 | the_controller = NULL; |
1930 | return 0; | 1942 | return 0; |
1931 | } | 1943 | } |
1932 | 1944 | ||
1933 | static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state) | 1945 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) |
1934 | { | 1946 | { |
1935 | struct usb_hcd *hcd; | 1947 | struct usb_hcd *hcd; |
1948 | struct dummy *dum; | ||
1949 | int rc = 0; | ||
1936 | 1950 | ||
1937 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1951 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1938 | hcd = platform_get_drvdata (dev); | ||
1939 | 1952 | ||
1940 | hcd->state = HC_STATE_SUSPENDED; | 1953 | hcd = platform_get_drvdata (pdev); |
1941 | return 0; | 1954 | dum = hcd_to_dummy (hcd); |
1955 | if (dum->rh_state == DUMMY_RH_RUNNING) { | ||
1956 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | ||
1957 | rc = -EBUSY; | ||
1958 | } else | ||
1959 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1960 | return rc; | ||
1942 | } | 1961 | } |
1943 | 1962 | ||
1944 | static int dummy_hcd_resume (struct platform_device *dev) | 1963 | static int dummy_hcd_resume (struct platform_device *pdev) |
1945 | { | 1964 | { |
1946 | struct usb_hcd *hcd; | 1965 | struct usb_hcd *hcd; |
1947 | 1966 | ||
1948 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1967 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1949 | hcd = platform_get_drvdata (dev); | ||
1950 | hcd->state = HC_STATE_RUNNING; | ||
1951 | 1968 | ||
1969 | hcd = platform_get_drvdata (pdev); | ||
1970 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1952 | usb_hcd_poll_rh_status (hcd); | 1971 | usb_hcd_poll_rh_status (hcd); |
1953 | return 0; | 1972 | return 0; |
1954 | } | 1973 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ea09aaa3cab6..0cea9782d7d4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kref.h> | ||
227 | #include <linux/kthread.h> | 228 | #include <linux/kthread.h> |
228 | #include <linux/limits.h> | 229 | #include <linux/limits.h> |
229 | #include <linux/list.h> | 230 | #include <linux/list.h> |
@@ -238,7 +239,6 @@ | |||
238 | #include <linux/string.h> | 239 | #include <linux/string.h> |
239 | #include <linux/suspend.h> | 240 | #include <linux/suspend.h> |
240 | #include <linux/utsname.h> | 241 | #include <linux/utsname.h> |
241 | #include <linux/wait.h> | ||
242 | 242 | ||
243 | #include <linux/usb_ch9.h> | 243 | #include <linux/usb_ch9.h> |
244 | #include <linux/usb_gadget.h> | 244 | #include <linux/usb_gadget.h> |
@@ -250,7 +250,7 @@ | |||
250 | 250 | ||
251 | #define DRIVER_DESC "File-backed Storage Gadget" | 251 | #define DRIVER_DESC "File-backed Storage Gadget" |
252 | #define DRIVER_NAME "g_file_storage" | 252 | #define DRIVER_NAME "g_file_storage" |
253 | #define DRIVER_VERSION "20 October 2004" | 253 | #define DRIVER_VERSION "28 November 2005" |
254 | 254 | ||
255 | static const char longname[] = DRIVER_DESC; | 255 | static const char longname[] = DRIVER_DESC; |
256 | static const char shortname[] = DRIVER_NAME; | 256 | static const char shortname[] = DRIVER_NAME; |
@@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
335 | #define MAX_LUNS 8 | 335 | #define MAX_LUNS 8 |
336 | 336 | ||
337 | /* Arggh! There should be a module_param_array_named macro! */ | 337 | /* Arggh! There should be a module_param_array_named macro! */ |
338 | static char *file[MAX_LUNS] = {NULL, }; | 338 | static char *file[MAX_LUNS]; |
339 | static int ro[MAX_LUNS] = {0, }; | 339 | static int ro[MAX_LUNS]; |
340 | 340 | ||
341 | static struct { | 341 | static struct { |
342 | int num_filenames; | 342 | int num_filenames; |
@@ -587,7 +587,7 @@ enum fsg_buffer_state { | |||
587 | struct fsg_buffhd { | 587 | struct fsg_buffhd { |
588 | void *buf; | 588 | void *buf; |
589 | dma_addr_t dma; | 589 | dma_addr_t dma; |
590 | volatile enum fsg_buffer_state state; | 590 | enum fsg_buffer_state state; |
591 | struct fsg_buffhd *next; | 591 | struct fsg_buffhd *next; |
592 | 592 | ||
593 | /* The NetChip 2280 is faster, and handles some protocol faults | 593 | /* The NetChip 2280 is faster, and handles some protocol faults |
@@ -596,9 +596,9 @@ struct fsg_buffhd { | |||
596 | unsigned int bulk_out_intended_length; | 596 | unsigned int bulk_out_intended_length; |
597 | 597 | ||
598 | struct usb_request *inreq; | 598 | struct usb_request *inreq; |
599 | volatile int inreq_busy; | 599 | int inreq_busy; |
600 | struct usb_request *outreq; | 600 | struct usb_request *outreq; |
601 | volatile int outreq_busy; | 601 | int outreq_busy; |
602 | }; | 602 | }; |
603 | 603 | ||
604 | enum fsg_state { | 604 | enum fsg_state { |
@@ -631,13 +631,16 @@ struct fsg_dev { | |||
631 | /* filesem protects: backing files in use */ | 631 | /* filesem protects: backing files in use */ |
632 | struct rw_semaphore filesem; | 632 | struct rw_semaphore filesem; |
633 | 633 | ||
634 | /* reference counting: wait until all LUNs are released */ | ||
635 | struct kref ref; | ||
636 | |||
634 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 637 | struct usb_ep *ep0; // Handy copy of gadget->ep0 |
635 | struct usb_request *ep0req; // For control responses | 638 | struct usb_request *ep0req; // For control responses |
636 | volatile unsigned int ep0_req_tag; | 639 | unsigned int ep0_req_tag; |
637 | const char *ep0req_name; | 640 | const char *ep0req_name; |
638 | 641 | ||
639 | struct usb_request *intreq; // For interrupt responses | 642 | struct usb_request *intreq; // For interrupt responses |
640 | volatile int intreq_busy; | 643 | int intreq_busy; |
641 | struct fsg_buffhd *intr_buffhd; | 644 | struct fsg_buffhd *intr_buffhd; |
642 | 645 | ||
643 | unsigned int bulk_out_maxpacket; | 646 | unsigned int bulk_out_maxpacket; |
@@ -667,7 +670,6 @@ struct fsg_dev { | |||
667 | struct fsg_buffhd *next_buffhd_to_drain; | 670 | struct fsg_buffhd *next_buffhd_to_drain; |
668 | struct fsg_buffhd buffhds[NUM_BUFFERS]; | 671 | struct fsg_buffhd buffhds[NUM_BUFFERS]; |
669 | 672 | ||
670 | wait_queue_head_t thread_wqh; | ||
671 | int thread_wakeup_needed; | 673 | int thread_wakeup_needed; |
672 | struct completion thread_notifier; | 674 | struct completion thread_notifier; |
673 | struct task_struct *thread_task; | 675 | struct task_struct *thread_task; |
@@ -694,7 +696,6 @@ struct fsg_dev { | |||
694 | unsigned int nluns; | 696 | unsigned int nluns; |
695 | struct lun *luns; | 697 | struct lun *luns; |
696 | struct lun *curlun; | 698 | struct lun *curlun; |
697 | struct completion lun_released; | ||
698 | }; | 699 | }; |
699 | 700 | ||
700 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 701 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
@@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
1073 | 1074 | ||
1074 | /* These routines may be called in process context or in_irq */ | 1075 | /* These routines may be called in process context or in_irq */ |
1075 | 1076 | ||
1077 | /* Caller must hold fsg->lock */ | ||
1076 | static void wakeup_thread(struct fsg_dev *fsg) | 1078 | static void wakeup_thread(struct fsg_dev *fsg) |
1077 | { | 1079 | { |
1078 | /* Tell the main thread that something has happened */ | 1080 | /* Tell the main thread that something has happened */ |
1079 | fsg->thread_wakeup_needed = 1; | 1081 | fsg->thread_wakeup_needed = 1; |
1080 | wake_up_all(&fsg->thread_wqh); | 1082 | if (fsg->thread_task) |
1083 | wake_up_process(fsg->thread_task); | ||
1081 | } | 1084 | } |
1082 | 1085 | ||
1083 | 1086 | ||
@@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1164 | usb_ep_fifo_flush(ep); | 1167 | usb_ep_fifo_flush(ep); |
1165 | 1168 | ||
1166 | /* Hold the lock while we update the request and buffer states */ | 1169 | /* Hold the lock while we update the request and buffer states */ |
1170 | smp_wmb(); | ||
1167 | spin_lock(&fsg->lock); | 1171 | spin_lock(&fsg->lock); |
1168 | bh->inreq_busy = 0; | 1172 | bh->inreq_busy = 0; |
1169 | bh->state = BUF_STATE_EMPTY; | 1173 | bh->state = BUF_STATE_EMPTY; |
1170 | spin_unlock(&fsg->lock); | ||
1171 | wakeup_thread(fsg); | 1174 | wakeup_thread(fsg); |
1175 | spin_unlock(&fsg->lock); | ||
1172 | } | 1176 | } |
1173 | 1177 | ||
1174 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1178 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1185 | usb_ep_fifo_flush(ep); | 1189 | usb_ep_fifo_flush(ep); |
1186 | 1190 | ||
1187 | /* Hold the lock while we update the request and buffer states */ | 1191 | /* Hold the lock while we update the request and buffer states */ |
1192 | smp_wmb(); | ||
1188 | spin_lock(&fsg->lock); | 1193 | spin_lock(&fsg->lock); |
1189 | bh->outreq_busy = 0; | 1194 | bh->outreq_busy = 0; |
1190 | bh->state = BUF_STATE_FULL; | 1195 | bh->state = BUF_STATE_FULL; |
1191 | spin_unlock(&fsg->lock); | ||
1192 | wakeup_thread(fsg); | 1196 | wakeup_thread(fsg); |
1197 | spin_unlock(&fsg->lock); | ||
1193 | } | 1198 | } |
1194 | 1199 | ||
1195 | 1200 | ||
@@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1206 | usb_ep_fifo_flush(ep); | 1211 | usb_ep_fifo_flush(ep); |
1207 | 1212 | ||
1208 | /* Hold the lock while we update the request and buffer states */ | 1213 | /* Hold the lock while we update the request and buffer states */ |
1214 | smp_wmb(); | ||
1209 | spin_lock(&fsg->lock); | 1215 | spin_lock(&fsg->lock); |
1210 | fsg->intreq_busy = 0; | 1216 | fsg->intreq_busy = 0; |
1211 | bh->state = BUF_STATE_EMPTY; | 1217 | bh->state = BUF_STATE_EMPTY; |
1212 | spin_unlock(&fsg->lock); | ||
1213 | wakeup_thread(fsg); | 1218 | wakeup_thread(fsg); |
1219 | spin_unlock(&fsg->lock); | ||
1214 | } | 1220 | } |
1215 | 1221 | ||
1216 | #else | 1222 | #else |
@@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
1261 | fsg->cbbuf_cmnd_size = req->actual; | 1267 | fsg->cbbuf_cmnd_size = req->actual; |
1262 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | 1268 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); |
1263 | 1269 | ||
1264 | spin_unlock(&fsg->lock); | ||
1265 | wakeup_thread(fsg); | 1270 | wakeup_thread(fsg); |
1271 | spin_unlock(&fsg->lock); | ||
1266 | } | 1272 | } |
1267 | 1273 | ||
1268 | #else | 1274 | #else |
@@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1514 | 1520 | ||
1515 | /* Use this for bulk or interrupt transfers, not ep0 */ | 1521 | /* Use this for bulk or interrupt transfers, not ep0 */ |
1516 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 1522 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
1517 | struct usb_request *req, volatile int *pbusy, | 1523 | struct usb_request *req, int *pbusy, |
1518 | volatile enum fsg_buffer_state *state) | 1524 | enum fsg_buffer_state *state) |
1519 | { | 1525 | { |
1520 | int rc; | 1526 | int rc; |
1521 | 1527 | ||
@@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1523 | dump_msg(fsg, "bulk-in", req->buf, req->length); | 1529 | dump_msg(fsg, "bulk-in", req->buf, req->length); |
1524 | else if (ep == fsg->intr_in) | 1530 | else if (ep == fsg->intr_in) |
1525 | dump_msg(fsg, "intr-in", req->buf, req->length); | 1531 | dump_msg(fsg, "intr-in", req->buf, req->length); |
1532 | |||
1533 | spin_lock_irq(&fsg->lock); | ||
1526 | *pbusy = 1; | 1534 | *pbusy = 1; |
1527 | *state = BUF_STATE_BUSY; | 1535 | *state = BUF_STATE_BUSY; |
1536 | spin_unlock_irq(&fsg->lock); | ||
1528 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | 1537 | rc = usb_ep_queue(ep, req, GFP_KERNEL); |
1529 | if (rc != 0) { | 1538 | if (rc != 0) { |
1530 | *pbusy = 0; | 1539 | *pbusy = 0; |
@@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1544 | 1553 | ||
1545 | static int sleep_thread(struct fsg_dev *fsg) | 1554 | static int sleep_thread(struct fsg_dev *fsg) |
1546 | { | 1555 | { |
1547 | int rc; | 1556 | int rc = 0; |
1548 | 1557 | ||
1549 | /* Wait until a signal arrives or we are woken up */ | 1558 | /* Wait until a signal arrives or we are woken up */ |
1550 | rc = wait_event_interruptible(fsg->thread_wqh, | 1559 | for (;;) { |
1551 | fsg->thread_wakeup_needed); | 1560 | try_to_freeze(); |
1561 | set_current_state(TASK_INTERRUPTIBLE); | ||
1562 | if (signal_pending(current)) { | ||
1563 | rc = -EINTR; | ||
1564 | break; | ||
1565 | } | ||
1566 | if (fsg->thread_wakeup_needed) | ||
1567 | break; | ||
1568 | schedule(); | ||
1569 | } | ||
1570 | __set_current_state(TASK_RUNNING); | ||
1552 | fsg->thread_wakeup_needed = 0; | 1571 | fsg->thread_wakeup_needed = 0; |
1553 | try_to_freeze(); | 1572 | return rc; |
1554 | return (rc ? -EINTR : 0); | ||
1555 | } | 1573 | } |
1556 | 1574 | ||
1557 | 1575 | ||
@@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1788 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | 1806 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) |
1789 | break; // We stopped early | 1807 | break; // We stopped early |
1790 | if (bh->state == BUF_STATE_FULL) { | 1808 | if (bh->state == BUF_STATE_FULL) { |
1809 | smp_rmb(); | ||
1791 | fsg->next_buffhd_to_drain = bh->next; | 1810 | fsg->next_buffhd_to_drain = bh->next; |
1792 | bh->state = BUF_STATE_EMPTY; | 1811 | bh->state = BUF_STATE_EMPTY; |
1793 | 1812 | ||
@@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2356 | 2375 | ||
2357 | /* Throw away the data in a filled buffer */ | 2376 | /* Throw away the data in a filled buffer */ |
2358 | if (bh->state == BUF_STATE_FULL) { | 2377 | if (bh->state == BUF_STATE_FULL) { |
2378 | smp_rmb(); | ||
2359 | bh->state = BUF_STATE_EMPTY; | 2379 | bh->state = BUF_STATE_EMPTY; |
2360 | fsg->next_buffhd_to_drain = bh->next; | 2380 | fsg->next_buffhd_to_drain = bh->next; |
2361 | 2381 | ||
@@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3021 | if ((rc = sleep_thread(fsg)) != 0) | 3041 | if ((rc = sleep_thread(fsg)) != 0) |
3022 | return rc; | 3042 | return rc; |
3023 | } | 3043 | } |
3044 | smp_rmb(); | ||
3024 | rc = received_cbw(fsg, bh); | 3045 | rc = received_cbw(fsg, bh); |
3025 | bh->state = BUF_STATE_EMPTY; | 3046 | bh->state = BUF_STATE_EMPTY; |
3026 | 3047 | ||
@@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); | |||
3642 | 3663 | ||
3643 | /*-------------------------------------------------------------------------*/ | 3664 | /*-------------------------------------------------------------------------*/ |
3644 | 3665 | ||
3666 | static void fsg_release(struct kref *ref) | ||
3667 | { | ||
3668 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
3669 | |||
3670 | kfree(fsg->luns); | ||
3671 | kfree(fsg); | ||
3672 | } | ||
3673 | |||
3645 | static void lun_release(struct device *dev) | 3674 | static void lun_release(struct device *dev) |
3646 | { | 3675 | { |
3647 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3676 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
3648 | 3677 | ||
3649 | complete(&fsg->lun_released); | 3678 | kref_put(&fsg->ref, fsg_release); |
3650 | } | 3679 | } |
3651 | 3680 | ||
3652 | static void fsg_unbind(struct usb_gadget *gadget) | 3681 | static void fsg_unbind(struct usb_gadget *gadget) |
@@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget) | |||
3660 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3689 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
3661 | 3690 | ||
3662 | /* Unregister the sysfs attribute files and the LUNs */ | 3691 | /* Unregister the sysfs attribute files and the LUNs */ |
3663 | init_completion(&fsg->lun_released); | ||
3664 | for (i = 0; i < fsg->nluns; ++i) { | 3692 | for (i = 0; i < fsg->nluns; ++i) { |
3665 | curlun = &fsg->luns[i]; | 3693 | curlun = &fsg->luns[i]; |
3666 | if (curlun->registered) { | 3694 | if (curlun->registered) { |
3667 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3695 | device_remove_file(&curlun->dev, &dev_attr_ro); |
3668 | device_remove_file(&curlun->dev, &dev_attr_file); | 3696 | device_remove_file(&curlun->dev, &dev_attr_file); |
3669 | device_unregister(&curlun->dev); | 3697 | device_unregister(&curlun->dev); |
3670 | wait_for_completion(&fsg->lun_released); | ||
3671 | curlun->registered = 0; | 3698 | curlun->registered = 0; |
3672 | } | 3699 | } |
3673 | } | 3700 | } |
@@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3846 | curlun->dev.release = lun_release; | 3873 | curlun->dev.release = lun_release; |
3847 | device_create_file(&curlun->dev, &dev_attr_ro); | 3874 | device_create_file(&curlun->dev, &dev_attr_ro); |
3848 | device_create_file(&curlun->dev, &dev_attr_file); | 3875 | device_create_file(&curlun->dev, &dev_attr_file); |
3876 | kref_get(&fsg->ref); | ||
3849 | } | 3877 | } |
3850 | 3878 | ||
3851 | if (file[i] && *file[i]) { | 3879 | if (file[i] && *file[i]) { |
@@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void) | |||
4061 | return -ENOMEM; | 4089 | return -ENOMEM; |
4062 | spin_lock_init(&fsg->lock); | 4090 | spin_lock_init(&fsg->lock); |
4063 | init_rwsem(&fsg->filesem); | 4091 | init_rwsem(&fsg->filesem); |
4064 | init_waitqueue_head(&fsg->thread_wqh); | 4092 | kref_init(&fsg->ref); |
4065 | init_completion(&fsg->thread_notifier); | 4093 | init_completion(&fsg->thread_notifier); |
4066 | 4094 | ||
4067 | the_fsg = fsg; | 4095 | the_fsg = fsg; |
@@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void) | |||
4069 | } | 4097 | } |
4070 | 4098 | ||
4071 | 4099 | ||
4072 | static void fsg_free(struct fsg_dev *fsg) | ||
4073 | { | ||
4074 | kfree(fsg->luns); | ||
4075 | kfree(fsg); | ||
4076 | } | ||
4077 | |||
4078 | |||
4079 | static int __init fsg_init(void) | 4100 | static int __init fsg_init(void) |
4080 | { | 4101 | { |
4081 | int rc; | 4102 | int rc; |
@@ -4085,7 +4106,7 @@ static int __init fsg_init(void) | |||
4085 | return rc; | 4106 | return rc; |
4086 | fsg = the_fsg; | 4107 | fsg = the_fsg; |
4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) | 4108 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4088 | fsg_free(fsg); | 4109 | kref_put(&fsg->ref, fsg_release); |
4089 | return rc; | 4110 | return rc; |
4090 | } | 4111 | } |
4091 | module_init(fsg_init); | 4112 | module_init(fsg_init); |
@@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void) | |||
4103 | wait_for_completion(&fsg->thread_notifier); | 4124 | wait_for_completion(&fsg->thread_notifier); |
4104 | 4125 | ||
4105 | close_all_backing_files(fsg); | 4126 | close_all_backing_files(fsg); |
4106 | fsg_free(fsg); | 4127 | kref_put(&fsg->ref, fsg_release); |
4107 | } | 4128 | } |
4108 | module_exit(fsg_cleanup); | 4129 | module_exit(fsg_cleanup); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b35ac6d334f8..65e084a2c87e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -890,10 +890,12 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
890 | /* wait for write buffer to drain, or */ | 890 | /* wait for write buffer to drain, or */ |
891 | /* at most GS_CLOSE_TIMEOUT seconds */ | 891 | /* at most GS_CLOSE_TIMEOUT seconds */ |
892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
893 | spin_unlock_irqrestore(&port->port_lock, flags); | ||
893 | wait_cond_interruptible_timeout(port->port_write_wait, | 894 | wait_cond_interruptible_timeout(port->port_write_wait, |
894 | port->port_dev == NULL | 895 | port->port_dev == NULL |
895 | || gs_buf_data_avail(port->port_write_buf) == 0, | 896 | || gs_buf_data_avail(port->port_write_buf) == 0, |
896 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 897 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); |
898 | spin_lock_irqsave(&port->port_lock, flags); | ||
897 | } | 899 | } |
898 | 900 | ||
899 | /* free disconnected port on final close */ | 901 | /* free disconnected port on final close */ |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58321d3f314c..e3020f4b17be 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -2,6 +2,10 @@ | |||
2 | # Makefile for USB Host Controller Drivers | 2 | # Makefile for USB Host Controller Drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
5 | obj-$(CONFIG_PCI) += pci-quirks.o | 9 | obj-$(CONFIG_PCI) += pci-quirks.o |
6 | 10 | ||
7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 11 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 29f52a44b928..9dd3d14c64f3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -17,13 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
20 | |||
21 | #ifdef CONFIG_USB_DEBUG | ||
22 | #define DEBUG | ||
23 | #else | ||
24 | #undef DEBUG | ||
25 | #endif | ||
26 | |||
27 | #include <linux/module.h> | 20 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
29 | #include <linux/dmapool.h> | 22 | #include <linux/dmapool.h> |
@@ -624,7 +617,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | |||
624 | } | 617 | } |
625 | 618 | ||
626 | /* remote wakeup [4.3.1] */ | 619 | /* remote wakeup [4.3.1] */ |
627 | if ((status & STS_PCD) && hcd->remote_wakeup) { | 620 | if (status & STS_PCD) { |
628 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 621 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
629 | 622 | ||
630 | /* resume root hub? */ | 623 | /* resume root hub? */ |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 82caf336e9b6..69b0b9be7a64 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -59,7 +59,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
59 | 59 | ||
60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) | 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) |
61 | t2 |= PORT_SUSPEND; | 61 | t2 |= PORT_SUSPEND; |
62 | if (hcd->remote_wakeup) | 62 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; | 63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; |
64 | else | 64 | else |
65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); | 65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); |
@@ -517,7 +517,7 @@ static int ehci_hub_control ( | |||
517 | if ((temp & PORT_PE) == 0 | 517 | if ((temp & PORT_PE) == 0 |
518 | || (temp & PORT_RESET) != 0) | 518 | || (temp & PORT_RESET) != 0) |
519 | goto error; | 519 | goto error; |
520 | if (hcd->remote_wakeup) | 520 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
521 | temp |= PORT_WAKE_BITS; | 521 | temp |= PORT_WAKE_BITS; |
522 | writel (temp | PORT_SUSPEND, | 522 | writel (temp | PORT_SUSPEND, |
523 | &ehci->regs->port_status [wIndex]); | 523 | &ehci->regs->port_status [wIndex]); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 13f73a836e45..08ca0f849dab 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -210,7 +210,16 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
210 | /* Serial Bus Release Number is at PCI 0x60 offset */ | 210 | /* Serial Bus Release Number is at PCI 0x60 offset */ |
211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | 211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); |
212 | 212 | ||
213 | /* REVISIT: per-port wake capability (PCI 0x62) currently unused */ | 213 | /* Workaround current PCI init glitch: wakeup bits aren't |
214 | * being set from PCI PM capability. | ||
215 | */ | ||
216 | if (!device_can_wakeup(&pdev->dev)) { | ||
217 | u16 port_wake; | ||
218 | |||
219 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
220 | if (port_wake & 0x0001) | ||
221 | device_init_wakeup(&pdev->dev, 1); | ||
222 | } | ||
214 | 223 | ||
215 | retval = ehci_pci_reinit(ehci, pdev); | 224 | retval = ehci_pci_reinit(ehci, pdev); |
216 | done: | 225 | done: |
@@ -269,7 +278,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
269 | { | 278 | { |
270 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 279 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
271 | unsigned port; | 280 | unsigned port; |
272 | struct usb_device *root = hcd->self.root_hub; | ||
273 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 281 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
274 | int retval = -EINVAL; | 282 | int retval = -EINVAL; |
275 | 283 | ||
@@ -303,13 +311,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
303 | 311 | ||
304 | restart: | 312 | restart: |
305 | ehci_dbg(ehci, "lost power, restarting\n"); | 313 | ehci_dbg(ehci, "lost power, restarting\n"); |
306 | for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { | 314 | usb_root_hub_lost_power(hcd->self.root_hub); |
307 | port--; | ||
308 | if (!root->children [port]) | ||
309 | continue; | ||
310 | usb_set_device_state(root->children[port], | ||
311 | USB_STATE_NOTATTACHED); | ||
312 | } | ||
313 | 315 | ||
314 | /* Else reset, to cope with power loss or flush-to-storage | 316 | /* Else reset, to cope with power loss or flush-to-storage |
315 | * style "resume" having let BIOS kick in during reboot. | 317 | * style "resume" having let BIOS kick in during reboot. |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index bf03ec0d8ee2..9b13bf2fa98d 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -514,18 +514,18 @@ qh_urb_transaction ( | |||
514 | qtd->urb = urb; | 514 | qtd->urb = urb; |
515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); | 515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); |
516 | list_add_tail (&qtd->qtd_list, head); | 516 | list_add_tail (&qtd->qtd_list, head); |
517 | |||
518 | /* for zero length DATA stages, STATUS is always IN */ | ||
519 | if (len == 0) | ||
520 | token |= (1 /* "in" */ << 8); | ||
517 | } | 521 | } |
518 | 522 | ||
519 | /* | 523 | /* |
520 | * data transfer stage: buffer setup | 524 | * data transfer stage: buffer setup |
521 | */ | 525 | */ |
522 | if (likely (len > 0)) | 526 | buf = urb->transfer_dma; |
523 | buf = urb->transfer_dma; | ||
524 | else | ||
525 | buf = 0; | ||
526 | 527 | ||
527 | /* for zero length DATA stages, STATUS is always IN */ | 528 | if (is_input) |
528 | if (!buf || is_input) | ||
529 | token |= (1 /* "in" */ << 8); | 529 | token |= (1 /* "in" */ << 8); |
530 | /* else it's already initted to "out" pid (0 << 8) */ | 530 | /* else it's already initted to "out" pid (0 << 8) */ |
531 | 531 | ||
@@ -572,7 +572,7 @@ qh_urb_transaction ( | |||
572 | * control requests may need a terminating data "status" ack; | 572 | * control requests may need a terminating data "status" ack; |
573 | * bulk ones may need a terminating short packet (zero length). | 573 | * bulk ones may need a terminating short packet (zero length). |
574 | */ | 574 | */ |
575 | if (likely (buf != 0)) { | 575 | if (likely (urb->transfer_buffer_length != 0)) { |
576 | int one_more = 0; | 576 | int one_more = 0; |
577 | 577 | ||
578 | if (usb_pipecontrol (urb->pipe)) { | 578 | if (usb_pipecontrol (urb->pipe)) { |
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index 0eaabeb37ac3..641268d7e6f3 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c | |||
@@ -4397,7 +4397,7 @@ static int __init etrax_usb_hc_init(void) | |||
4397 | device_initialize(&fake_device); | 4397 | device_initialize(&fake_device); |
4398 | kobject_set_name(&fake_device.kobj, "etrax_usb"); | 4398 | kobject_set_name(&fake_device.kobj, "etrax_usb"); |
4399 | kobject_add(&fake_device.kobj); | 4399 | kobject_add(&fake_device.kobj); |
4400 | kobject_hotplug(&fake_device.kobj, KOBJ_ADD); | 4400 | kobject_uevent(&fake_device.kobj, KOBJ_ADD); |
4401 | hc->bus->controller = &fake_device; | 4401 | hc->bus->controller = &fake_device; |
4402 | usb_register_bus(hc->bus); | 4402 | usb_register_bus(hc->bus); |
4403 | 4403 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 82f64986bc22..584b8dc65119 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -55,19 +55,13 @@ | |||
55 | /* enqueuing/finishing log of urbs */ | 55 | /* enqueuing/finishing log of urbs */ |
56 | //#define URB_TRACE | 56 | //#define URB_TRACE |
57 | 57 | ||
58 | #include <linux/config.h> | ||
59 | #include <linux/module.h> | 58 | #include <linux/module.h> |
60 | #include <linux/moduleparam.h> | ||
61 | #include <linux/kernel.h> | ||
62 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
63 | #include <linux/ioport.h> | 60 | #include <linux/debugfs.h> |
64 | #include <linux/sched.h> | 61 | #include <linux/seq_file.h> |
65 | #include <linux/slab.h> | ||
66 | #include <linux/smp_lock.h> | ||
67 | #include <linux/errno.h> | 62 | #include <linux/errno.h> |
68 | #include <linux/init.h> | 63 | #include <linux/init.h> |
69 | #include <linux/list.h> | 64 | #include <linux/list.h> |
70 | #include <linux/interrupt.h> | ||
71 | #include <linux/usb.h> | 65 | #include <linux/usb.h> |
72 | #include <linux/usb_isp116x.h> | 66 | #include <linux/usb_isp116x.h> |
73 | #include <linux/platform_device.h> | 67 | #include <linux/platform_device.h> |
@@ -77,14 +71,10 @@ | |||
77 | #include <asm/system.h> | 71 | #include <asm/system.h> |
78 | #include <asm/byteorder.h> | 72 | #include <asm/byteorder.h> |
79 | 73 | ||
80 | #ifndef DEBUG | ||
81 | # define STUB_DEBUG_FILE | ||
82 | #endif | ||
83 | |||
84 | #include "../core/hcd.h" | 74 | #include "../core/hcd.h" |
85 | #include "isp116x.h" | 75 | #include "isp116x.h" |
86 | 76 | ||
87 | #define DRIVER_VERSION "05 Aug 2005" | 77 | #define DRIVER_VERSION "03 Nov 2005" |
88 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" | 78 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" |
89 | 79 | ||
90 | MODULE_DESCRIPTION(DRIVER_DESC); | 80 | MODULE_DESCRIPTION(DRIVER_DESC); |
@@ -164,13 +154,11 @@ static void pack_fifo(struct isp116x *isp116x) | |||
164 | struct ptd *ptd; | 154 | struct ptd *ptd; |
165 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN | 155 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN |
166 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; | 156 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; |
167 | int ptd_count = 0; | ||
168 | 157 | ||
169 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); | 158 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); |
170 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); | 159 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); |
171 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); | 160 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); |
172 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 161 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
173 | ++ptd_count; | ||
174 | ptd = &ep->ptd; | 162 | ptd = &ep->ptd; |
175 | dump_ptd(ptd); | 163 | dump_ptd(ptd); |
176 | dump_ptd_out_data(ptd, ep->data); | 164 | dump_ptd_out_data(ptd, ep->data); |
@@ -305,9 +293,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
305 | udev = urb->dev; | 293 | udev = urb->dev; |
306 | ptd = &ep->ptd; | 294 | ptd = &ep->ptd; |
307 | cc = PTD_GET_CC(ptd); | 295 | cc = PTD_GET_CC(ptd); |
308 | |||
309 | spin_lock(&urb->lock); | ||
310 | short_not_ok = 1; | 296 | short_not_ok = 1; |
297 | spin_lock(&urb->lock); | ||
311 | 298 | ||
312 | /* Data underrun is special. For allowed underrun | 299 | /* Data underrun is special. For allowed underrun |
313 | we clear the error and continue as normal. For | 300 | we clear the error and continue as normal. For |
@@ -420,7 +407,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
420 | ep->nextpid = 0; | 407 | ep->nextpid = 0; |
421 | break; | 408 | break; |
422 | default: | 409 | default: |
423 | BUG_ON(1); | 410 | BUG(); |
424 | } | 411 | } |
425 | spin_unlock(&urb->lock); | 412 | spin_unlock(&urb->lock); |
426 | } | 413 | } |
@@ -628,8 +615,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
628 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); | 615 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); |
629 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); | 616 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); |
630 | if (intstat & HCINT_UE) { | 617 | if (intstat & HCINT_UE) { |
631 | ERR("Unrecoverable error\n"); | 618 | ERR("Unrecoverable error, HC is dead!\n"); |
632 | /* What should we do here? Reset? */ | 619 | /* IRQ's are off, we do no DMA, |
620 | perfectly ready to die ... */ | ||
621 | hcd->state = HC_STATE_HALT; | ||
622 | ret = IRQ_HANDLED; | ||
623 | goto done; | ||
633 | } | 624 | } |
634 | if (intstat & HCINT_RHSC) | 625 | if (intstat & HCINT_RHSC) |
635 | /* When root hub or any of its ports is going | 626 | /* When root hub or any of its ports is going |
@@ -640,7 +631,6 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
640 | if (intstat & HCINT_RD) { | 631 | if (intstat & HCINT_RD) { |
641 | DBG("---- remote wakeup\n"); | 632 | DBG("---- remote wakeup\n"); |
642 | usb_hcd_resume_root_hub(hcd); | 633 | usb_hcd_resume_root_hub(hcd); |
643 | ret = IRQ_HANDLED; | ||
644 | } | 634 | } |
645 | irqstat &= ~HCuPINT_OPR; | 635 | irqstat &= ~HCuPINT_OPR; |
646 | ret = IRQ_HANDLED; | 636 | ret = IRQ_HANDLED; |
@@ -651,6 +641,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
651 | } | 641 | } |
652 | 642 | ||
653 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); | 643 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); |
644 | done: | ||
654 | spin_unlock(&isp116x->lock); | 645 | spin_unlock(&isp116x->lock); |
655 | return ret; | 646 | return ret; |
656 | } | 647 | } |
@@ -724,6 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
724 | 715 | ||
725 | spin_lock_irqsave(&isp116x->lock, flags); | 716 | spin_lock_irqsave(&isp116x->lock, flags); |
726 | if (!HC_IS_RUNNING(hcd->state)) { | 717 | if (!HC_IS_RUNNING(hcd->state)) { |
718 | kfree(ep); | ||
727 | ret = -ENODEV; | 719 | ret = -ENODEV; |
728 | goto fail; | 720 | goto fail; |
729 | } | 721 | } |
@@ -888,7 +880,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd, | |||
888 | struct usb_host_endpoint *hep) | 880 | struct usb_host_endpoint *hep) |
889 | { | 881 | { |
890 | int i; | 882 | int i; |
891 | struct isp116x_ep *ep = hep->hcpriv;; | 883 | struct isp116x_ep *ep = hep->hcpriv; |
892 | 884 | ||
893 | if (!ep) | 885 | if (!ep) |
894 | return; | 886 | return; |
@@ -916,8 +908,6 @@ static int isp116x_get_frame(struct usb_hcd *hcd) | |||
916 | return (int)fmnum; | 908 | return (int)fmnum; |
917 | } | 909 | } |
918 | 910 | ||
919 | /*----------------------------------------------------------------*/ | ||
920 | |||
921 | /* | 911 | /* |
922 | Adapted from ohci-hub.c. Currently we don't support autosuspend. | 912 | Adapted from ohci-hub.c. Currently we don't support autosuspend. |
923 | */ | 913 | */ |
@@ -968,11 +958,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, | |||
968 | desc->bHubContrCurrent = 0; | 958 | desc->bHubContrCurrent = 0; |
969 | desc->bNbrPorts = (u8) (reg & 0x3); | 959 | desc->bNbrPorts = (u8) (reg & 0x3); |
970 | /* Power switching, device type, overcurrent. */ | 960 | /* Power switching, device type, overcurrent. */ |
971 | desc->wHubCharacteristics = | 961 | desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); |
972 | (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f)); | ||
973 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); | 962 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); |
974 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ | 963 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ |
975 | desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; | 964 | desc->bitmap[0] = 0; |
976 | desc->bitmap[1] = ~0; | 965 | desc->bitmap[1] = ~0; |
977 | } | 966 | } |
978 | 967 | ||
@@ -1159,135 +1148,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1159 | return ret; | 1148 | return ret; |
1160 | } | 1149 | } |
1161 | 1150 | ||
1162 | #ifdef CONFIG_PM | ||
1163 | |||
1164 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
1165 | { | ||
1166 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1167 | unsigned long flags; | ||
1168 | u32 val; | ||
1169 | int ret = 0; | ||
1170 | |||
1171 | spin_lock_irqsave(&isp116x->lock, flags); | ||
1172 | |||
1173 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1174 | switch (val & HCCONTROL_HCFS) { | ||
1175 | case HCCONTROL_USB_OPER: | ||
1176 | hcd->state = HC_STATE_QUIESCING; | ||
1177 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
1178 | val |= HCCONTROL_USB_SUSPEND; | ||
1179 | if (hcd->remote_wakeup) | ||
1180 | val |= HCCONTROL_RWE; | ||
1181 | /* Wait for usb transfers to finish */ | ||
1182 | mdelay(2); | ||
1183 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1184 | hcd->state = HC_STATE_SUSPENDED; | ||
1185 | /* Wait for devices to suspend */ | ||
1186 | mdelay(5); | ||
1187 | case HCCONTROL_USB_SUSPEND: | ||
1188 | break; | ||
1189 | case HCCONTROL_USB_RESUME: | ||
1190 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1191 | (val & ~HCCONTROL_HCFS) | | ||
1192 | HCCONTROL_USB_RESET); | ||
1193 | case HCCONTROL_USB_RESET: | ||
1194 | ret = -EBUSY; | ||
1195 | break; | ||
1196 | default: | ||
1197 | ret = -EINVAL; | ||
1198 | } | ||
1199 | |||
1200 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
1201 | return ret; | ||
1202 | } | ||
1203 | |||
1204 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
1205 | { | ||
1206 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1207 | u32 val; | ||
1208 | int ret = -EINPROGRESS; | ||
1209 | |||
1210 | msleep(5); | ||
1211 | spin_lock_irq(&isp116x->lock); | ||
1212 | |||
1213 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1214 | switch (val & HCCONTROL_HCFS) { | ||
1215 | case HCCONTROL_USB_SUSPEND: | ||
1216 | val &= ~HCCONTROL_HCFS; | ||
1217 | val |= HCCONTROL_USB_RESUME; | ||
1218 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1219 | case HCCONTROL_USB_RESUME: | ||
1220 | break; | ||
1221 | case HCCONTROL_USB_OPER: | ||
1222 | /* Without setting power_state here the | ||
1223 | SUSPENDED state won't be removed from | ||
1224 | sysfs/usbN/power.state as a response to remote | ||
1225 | wakeup. Maybe in the future. */ | ||
1226 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1227 | ret = 0; | ||
1228 | break; | ||
1229 | default: | ||
1230 | ret = -EBUSY; | ||
1231 | } | ||
1232 | |||
1233 | if (ret != -EINPROGRESS) { | ||
1234 | spin_unlock_irq(&isp116x->lock); | ||
1235 | return ret; | ||
1236 | } | ||
1237 | |||
1238 | val = isp116x->rhdesca & RH_A_NDP; | ||
1239 | while (val--) { | ||
1240 | u32 stat = | ||
1241 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
1242 | /* force global, not selective, resume */ | ||
1243 | if (!(stat & RH_PS_PSS)) | ||
1244 | continue; | ||
1245 | DBG("%s: Resuming port %d\n", __func__, val); | ||
1246 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
1247 | ? HCRHPORT2 : HCRHPORT1); | ||
1248 | } | ||
1249 | spin_unlock_irq(&isp116x->lock); | ||
1250 | |||
1251 | hcd->state = HC_STATE_RESUMING; | ||
1252 | mdelay(20); | ||
1253 | |||
1254 | /* Go operational */ | ||
1255 | spin_lock_irq(&isp116x->lock); | ||
1256 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1257 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1258 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
1259 | spin_unlock_irq(&isp116x->lock); | ||
1260 | /* see analogous comment above */ | ||
1261 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1262 | hcd->state = HC_STATE_RUNNING; | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | |||
1268 | #else | ||
1269 | |||
1270 | #define isp116x_bus_suspend NULL | ||
1271 | #define isp116x_bus_resume NULL | ||
1272 | |||
1273 | #endif | ||
1274 | |||
1275 | /*-----------------------------------------------------------------*/ | 1151 | /*-----------------------------------------------------------------*/ |
1276 | 1152 | ||
1277 | #ifdef STUB_DEBUG_FILE | 1153 | #ifdef CONFIG_DEBUG_FS |
1278 | |||
1279 | static inline void create_debug_file(struct isp116x *isp116x) | ||
1280 | { | ||
1281 | } | ||
1282 | |||
1283 | static inline void remove_debug_file(struct isp116x *isp116x) | ||
1284 | { | ||
1285 | } | ||
1286 | |||
1287 | #else | ||
1288 | |||
1289 | #include <linux/proc_fs.h> | ||
1290 | #include <linux/seq_file.h> | ||
1291 | 1154 | ||
1292 | static void dump_irq(struct seq_file *s, char *label, u16 mask) | 1155 | static void dump_irq(struct seq_file *s, char *label, u16 mask) |
1293 | { | 1156 | { |
@@ -1311,13 +1174,9 @@ static void dump_int(struct seq_file *s, char *label, u32 mask) | |||
1311 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); | 1174 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); |
1312 | } | 1175 | } |
1313 | 1176 | ||
1314 | static int proc_isp116x_show(struct seq_file *s, void *unused) | 1177 | static int isp116x_show_dbg(struct seq_file *s, void *unused) |
1315 | { | 1178 | { |
1316 | struct isp116x *isp116x = s->private; | 1179 | struct isp116x *isp116x = s->private; |
1317 | struct isp116x_ep *ep; | ||
1318 | struct urb *urb; | ||
1319 | unsigned i; | ||
1320 | char *str; | ||
1321 | 1180 | ||
1322 | seq_printf(s, "%s\n%s version %s\n", | 1181 | seq_printf(s, "%s\n%s version %s\n", |
1323 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, | 1182 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, |
@@ -1333,105 +1192,50 @@ static int proc_isp116x_show(struct seq_file *s, void *unused) | |||
1333 | } | 1192 | } |
1334 | 1193 | ||
1335 | spin_lock_irq(&isp116x->lock); | 1194 | spin_lock_irq(&isp116x->lock); |
1336 | |||
1337 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); | 1195 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); |
1338 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); | 1196 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); |
1339 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); | 1197 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); |
1340 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); | 1198 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); |
1341 | 1199 | isp116x_show_regs_seq(isp116x, s); | |
1342 | list_for_each_entry(ep, &isp116x->async, schedule) { | ||
1343 | |||
1344 | switch (ep->nextpid) { | ||
1345 | case USB_PID_IN: | ||
1346 | str = "in"; | ||
1347 | break; | ||
1348 | case USB_PID_OUT: | ||
1349 | str = "out"; | ||
1350 | break; | ||
1351 | case USB_PID_SETUP: | ||
1352 | str = "setup"; | ||
1353 | break; | ||
1354 | case USB_PID_ACK: | ||
1355 | str = "status"; | ||
1356 | break; | ||
1357 | default: | ||
1358 | str = "?"; | ||
1359 | break; | ||
1360 | }; | ||
1361 | seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, | ||
1362 | ep->epnum, str, ep->maxpacket); | ||
1363 | list_for_each_entry(urb, &ep->hep->urb_list, urb_list) { | ||
1364 | seq_printf(s, " urb%p, %d/%d\n", urb, | ||
1365 | urb->actual_length, | ||
1366 | urb->transfer_buffer_length); | ||
1367 | } | ||
1368 | } | ||
1369 | if (!list_empty(&isp116x->async)) | ||
1370 | seq_printf(s, "\n"); | ||
1371 | |||
1372 | seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE); | ||
1373 | |||
1374 | for (i = 0; i < PERIODIC_SIZE; i++) { | ||
1375 | ep = isp116x->periodic[i]; | ||
1376 | if (!ep) | ||
1377 | continue; | ||
1378 | seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]); | ||
1379 | |||
1380 | /* DUMB: prints shared entries multiple times */ | ||
1381 | do { | ||
1382 | seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", | ||
1383 | ep->period, ep, | ||
1384 | (ep->udev->speed == | ||
1385 | USB_SPEED_FULL) ? "" : "ls ", | ||
1386 | ep->udev->devnum, ep->epnum, | ||
1387 | (ep->epnum == | ||
1388 | 0) ? "" : ((ep->nextpid == | ||
1389 | USB_PID_IN) ? "in" : "out"), | ||
1390 | ep->maxpacket); | ||
1391 | ep = ep->next; | ||
1392 | } while (ep); | ||
1393 | } | ||
1394 | spin_unlock_irq(&isp116x->lock); | 1200 | spin_unlock_irq(&isp116x->lock); |
1395 | seq_printf(s, "\n"); | 1201 | seq_printf(s, "\n"); |
1396 | 1202 | ||
1397 | return 0; | 1203 | return 0; |
1398 | } | 1204 | } |
1399 | 1205 | ||
1400 | static int proc_isp116x_open(struct inode *inode, struct file *file) | 1206 | static int isp116x_open_seq(struct inode *inode, struct file *file) |
1401 | { | 1207 | { |
1402 | return single_open(file, proc_isp116x_show, PDE(inode)->data); | 1208 | return single_open(file, isp116x_show_dbg, inode->u.generic_ip); |
1403 | } | 1209 | } |
1404 | 1210 | ||
1405 | static struct file_operations proc_ops = { | 1211 | static struct file_operations isp116x_debug_fops = { |
1406 | .open = proc_isp116x_open, | 1212 | .open = isp116x_open_seq, |
1407 | .read = seq_read, | 1213 | .read = seq_read, |
1408 | .llseek = seq_lseek, | 1214 | .llseek = seq_lseek, |
1409 | .release = single_release, | 1215 | .release = single_release, |
1410 | }; | 1216 | }; |
1411 | 1217 | ||
1412 | /* expect just one isp116x per system */ | 1218 | static int create_debug_file(struct isp116x *isp116x) |
1413 | static const char proc_filename[] = "driver/isp116x"; | ||
1414 | |||
1415 | static void create_debug_file(struct isp116x *isp116x) | ||
1416 | { | 1219 | { |
1417 | struct proc_dir_entry *pde; | 1220 | isp116x->dentry = debugfs_create_file(hcd_name, |
1418 | 1221 | S_IRUGO, NULL, isp116x, | |
1419 | pde = create_proc_entry(proc_filename, 0, NULL); | 1222 | &isp116x_debug_fops); |
1420 | if (pde == NULL) | 1223 | if (!isp116x->dentry) |
1421 | return; | 1224 | return -ENOMEM; |
1422 | 1225 | return 0; | |
1423 | pde->proc_fops = &proc_ops; | ||
1424 | pde->data = isp116x; | ||
1425 | isp116x->pde = pde; | ||
1426 | } | 1226 | } |
1427 | 1227 | ||
1428 | static void remove_debug_file(struct isp116x *isp116x) | 1228 | static void remove_debug_file(struct isp116x *isp116x) |
1429 | { | 1229 | { |
1430 | if (isp116x->pde) | 1230 | debugfs_remove(isp116x->dentry); |
1431 | remove_proc_entry(proc_filename, NULL); | ||
1432 | } | 1231 | } |
1433 | 1232 | ||
1434 | #endif | 1233 | #else |
1234 | |||
1235 | #define create_debug_file(d) 0 | ||
1236 | #define remove_debug_file(d) do{}while(0) | ||
1237 | |||
1238 | #endif /* CONFIG_DEBUG_FS */ | ||
1435 | 1239 | ||
1436 | /*-----------------------------------------------------------------*/ | 1240 | /*-----------------------------------------------------------------*/ |
1437 | 1241 | ||
@@ -1466,7 +1270,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
1466 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1270 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1467 | unsigned long t; | 1271 | unsigned long t; |
1468 | u16 clkrdy = 0; | 1272 | u16 clkrdy = 0; |
1469 | int ret = 0, timeout = 15 /* ms */ ; | 1273 | int ret, timeout = 15 /* ms */ ; |
1470 | 1274 | ||
1471 | ret = isp116x_sw_reset(isp116x); | 1275 | ret = isp116x_sw_reset(isp116x); |
1472 | if (ret) | 1276 | if (ret) |
@@ -1482,7 +1286,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
1482 | break; | 1286 | break; |
1483 | } | 1287 | } |
1484 | if (!clkrdy) { | 1288 | if (!clkrdy) { |
1485 | ERR("Clock not ready after 20ms\n"); | 1289 | ERR("Clock not ready after %dms\n", timeout); |
1486 | /* After sw_reset the clock won't report to be ready, if | 1290 | /* After sw_reset the clock won't report to be ready, if |
1487 | H_WAKEUP pin is high. */ | 1291 | H_WAKEUP pin is high. */ |
1488 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); | 1292 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); |
@@ -1572,7 +1376,8 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
1572 | 1376 | ||
1573 | val = 0; | 1377 | val = 0; |
1574 | if (board->remote_wakeup_enable) { | 1378 | if (board->remote_wakeup_enable) { |
1575 | hcd->can_wakeup = 1; | 1379 | if (!device_can_wakeup(hcd->self.controller)) |
1380 | device_init_wakeup(hcd->self.controller, 1); | ||
1576 | val |= RH_HS_DRWE; | 1381 | val |= RH_HS_DRWE; |
1577 | } | 1382 | } |
1578 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); | 1383 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); |
@@ -1600,12 +1405,126 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
1600 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); | 1405 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); |
1601 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); | 1406 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); |
1602 | 1407 | ||
1603 | isp116x_show_regs(isp116x); | 1408 | isp116x_show_regs_log(isp116x); |
1604 | spin_unlock_irqrestore(&isp116x->lock, flags); | 1409 | spin_unlock_irqrestore(&isp116x->lock, flags); |
1605 | return 0; | 1410 | return 0; |
1606 | } | 1411 | } |
1607 | 1412 | ||
1608 | /*-----------------------------------------------------------------*/ | 1413 | #ifdef CONFIG_PM |
1414 | |||
1415 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
1416 | { | ||
1417 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1418 | unsigned long flags; | ||
1419 | u32 val; | ||
1420 | int ret = 0; | ||
1421 | |||
1422 | spin_lock_irqsave(&isp116x->lock, flags); | ||
1423 | |||
1424 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1425 | switch (val & HCCONTROL_HCFS) { | ||
1426 | case HCCONTROL_USB_OPER: | ||
1427 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
1428 | val |= HCCONTROL_USB_SUSPEND; | ||
1429 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | ||
1430 | val |= HCCONTROL_RWE; | ||
1431 | /* Wait for usb transfers to finish */ | ||
1432 | mdelay(2); | ||
1433 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1434 | /* Wait for devices to suspend */ | ||
1435 | mdelay(5); | ||
1436 | case HCCONTROL_USB_SUSPEND: | ||
1437 | break; | ||
1438 | case HCCONTROL_USB_RESUME: | ||
1439 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1440 | (val & ~HCCONTROL_HCFS) | | ||
1441 | HCCONTROL_USB_RESET); | ||
1442 | case HCCONTROL_USB_RESET: | ||
1443 | ret = -EBUSY; | ||
1444 | break; | ||
1445 | default: | ||
1446 | ret = -EINVAL; | ||
1447 | } | ||
1448 | |||
1449 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
1450 | return ret; | ||
1451 | } | ||
1452 | |||
1453 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
1454 | { | ||
1455 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1456 | u32 val; | ||
1457 | |||
1458 | msleep(5); | ||
1459 | spin_lock_irq(&isp116x->lock); | ||
1460 | |||
1461 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1462 | switch (val & HCCONTROL_HCFS) { | ||
1463 | case HCCONTROL_USB_SUSPEND: | ||
1464 | val &= ~HCCONTROL_HCFS; | ||
1465 | val |= HCCONTROL_USB_RESUME; | ||
1466 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1467 | case HCCONTROL_USB_RESUME: | ||
1468 | break; | ||
1469 | case HCCONTROL_USB_OPER: | ||
1470 | spin_unlock_irq(&isp116x->lock); | ||
1471 | /* Without setting power_state here the | ||
1472 | SUSPENDED state won't be removed from | ||
1473 | sysfs/usbN/power.state as a response to remote | ||
1474 | wakeup. Maybe in the future. */ | ||
1475 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1476 | return 0; | ||
1477 | default: | ||
1478 | /* HCCONTROL_USB_RESET: this may happen, when during | ||
1479 | suspension the HC lost power. Reinitialize completely */ | ||
1480 | spin_unlock_irq(&isp116x->lock); | ||
1481 | DBG("Chip has been reset while suspended. Reinit from scratch.\n"); | ||
1482 | isp116x_reset(hcd); | ||
1483 | isp116x_start(hcd); | ||
1484 | isp116x_hub_control(hcd, SetPortFeature, | ||
1485 | USB_PORT_FEAT_POWER, 1, NULL, 0); | ||
1486 | if ((isp116x->rhdesca & RH_A_NDP) == 2) | ||
1487 | isp116x_hub_control(hcd, SetPortFeature, | ||
1488 | USB_PORT_FEAT_POWER, 2, NULL, 0); | ||
1489 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1493 | val = isp116x->rhdesca & RH_A_NDP; | ||
1494 | while (val--) { | ||
1495 | u32 stat = | ||
1496 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
1497 | /* force global, not selective, resume */ | ||
1498 | if (!(stat & RH_PS_PSS)) | ||
1499 | continue; | ||
1500 | DBG("%s: Resuming port %d\n", __func__, val); | ||
1501 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
1502 | ? HCRHPORT2 : HCRHPORT1); | ||
1503 | } | ||
1504 | spin_unlock_irq(&isp116x->lock); | ||
1505 | |||
1506 | hcd->state = HC_STATE_RESUMING; | ||
1507 | msleep(20); | ||
1508 | |||
1509 | /* Go operational */ | ||
1510 | spin_lock_irq(&isp116x->lock); | ||
1511 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1512 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1513 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
1514 | spin_unlock_irq(&isp116x->lock); | ||
1515 | /* see analogous comment above */ | ||
1516 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1517 | hcd->state = HC_STATE_RUNNING; | ||
1518 | |||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | #else | ||
1523 | |||
1524 | #define isp116x_bus_suspend NULL | ||
1525 | #define isp116x_bus_resume NULL | ||
1526 | |||
1527 | #endif | ||
1609 | 1528 | ||
1610 | static struct hc_driver isp116x_hc_driver = { | 1529 | static struct hc_driver isp116x_hc_driver = { |
1611 | .description = hcd_name, | 1530 | .description = hcd_name, |
@@ -1735,12 +1654,19 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
1735 | } | 1654 | } |
1736 | 1655 | ||
1737 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1656 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); |
1738 | if (ret != 0) | 1657 | if (ret) |
1739 | goto err6; | 1658 | goto err6; |
1740 | 1659 | ||
1741 | create_debug_file(isp116x); | 1660 | ret = create_debug_file(isp116x); |
1661 | if (ret) { | ||
1662 | ERR("Couldn't create debugfs entry\n"); | ||
1663 | goto err7; | ||
1664 | } | ||
1665 | |||
1742 | return 0; | 1666 | return 0; |
1743 | 1667 | ||
1668 | err7: | ||
1669 | usb_remove_hcd(hcd); | ||
1744 | err6: | 1670 | err6: |
1745 | usb_put_hcd(hcd); | 1671 | usb_put_hcd(hcd); |
1746 | err5: | 1672 | err5: |
@@ -1762,13 +1688,9 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
1762 | */ | 1688 | */ |
1763 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | 1689 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) |
1764 | { | 1690 | { |
1765 | int ret = 0; | 1691 | VDBG("%s: state %x\n", __func__, state.event); |
1766 | |||
1767 | VDBG("%s: state %x\n", __func__, state); | ||
1768 | |||
1769 | dev->dev.power.power_state = state; | 1692 | dev->dev.power.power_state = state; |
1770 | 1693 | return 0; | |
1771 | return ret; | ||
1772 | } | 1694 | } |
1773 | 1695 | ||
1774 | /* | 1696 | /* |
@@ -1776,13 +1698,9 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | |||
1776 | */ | 1698 | */ |
1777 | static int isp116x_resume(struct platform_device *dev) | 1699 | static int isp116x_resume(struct platform_device *dev) |
1778 | { | 1700 | { |
1779 | int ret = 0; | 1701 | VDBG("%s: state %x\n", __func__, dev->power.power_state.event); |
1780 | |||
1781 | VDBG("%s: state %x\n", __func__, dev->dev.power.power_state); | ||
1782 | |||
1783 | dev->dev.power.power_state = PMSG_ON; | 1702 | dev->dev.power.power_state = PMSG_ON; |
1784 | 1703 | return 0; | |
1785 | return ret; | ||
1786 | } | 1704 | } |
1787 | 1705 | ||
1788 | #else | 1706 | #else |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index c6fec96785fe..a1b7c3813d3a 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -259,7 +259,7 @@ struct isp116x { | |||
259 | 259 | ||
260 | struct isp116x_platform_data *board; | 260 | struct isp116x_platform_data *board; |
261 | 261 | ||
262 | struct proc_dir_entry *pde; | 262 | struct dentry *dentry; |
263 | unsigned long stat1, stat2, stat4, stat8, stat16; | 263 | unsigned long stat1, stat2, stat4, stat8, stat16; |
264 | 264 | ||
265 | /* HC registers */ | 265 | /* HC registers */ |
@@ -450,7 +450,7 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
450 | isp116x_write_data32(isp116x, (u32) val); | 450 | isp116x_write_data32(isp116x, (u32) val); |
451 | } | 451 | } |
452 | 452 | ||
453 | #define isp116x_show_reg(d,r) { \ | 453 | #define isp116x_show_reg_log(d,r,s) { \ |
454 | if ((r) < 0x20) { \ | 454 | if ((r) < 0x20) { \ |
455 | DBG("%-12s[%02x]: %08x\n", #r, \ | 455 | DBG("%-12s[%02x]: %08x\n", #r, \ |
456 | r, isp116x_read_reg32(d, r)); \ | 456 | r, isp116x_read_reg32(d, r)); \ |
@@ -459,35 +459,60 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
459 | r, isp116x_read_reg16(d, r)); \ | 459 | r, isp116x_read_reg16(d, r)); \ |
460 | } \ | 460 | } \ |
461 | } | 461 | } |
462 | #define isp116x_show_reg_seq(d,r,s) { \ | ||
463 | if ((r) < 0x20) { \ | ||
464 | seq_printf(s, "%-12s[%02x]: %08x\n", #r, \ | ||
465 | r, isp116x_read_reg32(d, r)); \ | ||
466 | } else { \ | ||
467 | seq_printf(s, "%-12s[%02x]: %04x\n", #r, \ | ||
468 | r, isp116x_read_reg16(d, r)); \ | ||
469 | } \ | ||
470 | } | ||
462 | 471 | ||
463 | static inline void isp116x_show_regs(struct isp116x *isp116x) | 472 | #define isp116x_show_regs(d,type,s) { \ |
473 | isp116x_show_reg_##type(d, HCREVISION, s); \ | ||
474 | isp116x_show_reg_##type(d, HCCONTROL, s); \ | ||
475 | isp116x_show_reg_##type(d, HCCMDSTAT, s); \ | ||
476 | isp116x_show_reg_##type(d, HCINTSTAT, s); \ | ||
477 | isp116x_show_reg_##type(d, HCINTENB, s); \ | ||
478 | isp116x_show_reg_##type(d, HCFMINTVL, s); \ | ||
479 | isp116x_show_reg_##type(d, HCFMREM, s); \ | ||
480 | isp116x_show_reg_##type(d, HCFMNUM, s); \ | ||
481 | isp116x_show_reg_##type(d, HCLSTHRESH, s); \ | ||
482 | isp116x_show_reg_##type(d, HCRHDESCA, s); \ | ||
483 | isp116x_show_reg_##type(d, HCRHDESCB, s); \ | ||
484 | isp116x_show_reg_##type(d, HCRHSTATUS, s); \ | ||
485 | isp116x_show_reg_##type(d, HCRHPORT1, s); \ | ||
486 | isp116x_show_reg_##type(d, HCRHPORT2, s); \ | ||
487 | isp116x_show_reg_##type(d, HCHWCFG, s); \ | ||
488 | isp116x_show_reg_##type(d, HCDMACFG, s); \ | ||
489 | isp116x_show_reg_##type(d, HCXFERCTR, s); \ | ||
490 | isp116x_show_reg_##type(d, HCuPINT, s); \ | ||
491 | isp116x_show_reg_##type(d, HCuPINTENB, s); \ | ||
492 | isp116x_show_reg_##type(d, HCCHIPID, s); \ | ||
493 | isp116x_show_reg_##type(d, HCSCRATCH, s); \ | ||
494 | isp116x_show_reg_##type(d, HCITLBUFLEN, s); \ | ||
495 | isp116x_show_reg_##type(d, HCATLBUFLEN, s); \ | ||
496 | isp116x_show_reg_##type(d, HCBUFSTAT, s); \ | ||
497 | isp116x_show_reg_##type(d, HCRDITL0LEN, s); \ | ||
498 | isp116x_show_reg_##type(d, HCRDITL1LEN, s); \ | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | Dump registers for debugfs. | ||
503 | */ | ||
504 | static inline void isp116x_show_regs_seq(struct isp116x *isp116x, | ||
505 | struct seq_file *s) | ||
506 | { | ||
507 | isp116x_show_regs(isp116x, seq, s); | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | Dump registers to syslog. | ||
512 | */ | ||
513 | static inline void isp116x_show_regs_log(struct isp116x *isp116x) | ||
464 | { | 514 | { |
465 | isp116x_show_reg(isp116x, HCREVISION); | 515 | isp116x_show_regs(isp116x, log, NULL); |
466 | isp116x_show_reg(isp116x, HCCONTROL); | ||
467 | isp116x_show_reg(isp116x, HCCMDSTAT); | ||
468 | isp116x_show_reg(isp116x, HCINTSTAT); | ||
469 | isp116x_show_reg(isp116x, HCINTENB); | ||
470 | isp116x_show_reg(isp116x, HCFMINTVL); | ||
471 | isp116x_show_reg(isp116x, HCFMREM); | ||
472 | isp116x_show_reg(isp116x, HCFMNUM); | ||
473 | isp116x_show_reg(isp116x, HCLSTHRESH); | ||
474 | isp116x_show_reg(isp116x, HCRHDESCA); | ||
475 | isp116x_show_reg(isp116x, HCRHDESCB); | ||
476 | isp116x_show_reg(isp116x, HCRHSTATUS); | ||
477 | isp116x_show_reg(isp116x, HCRHPORT1); | ||
478 | isp116x_show_reg(isp116x, HCRHPORT2); | ||
479 | isp116x_show_reg(isp116x, HCHWCFG); | ||
480 | isp116x_show_reg(isp116x, HCDMACFG); | ||
481 | isp116x_show_reg(isp116x, HCXFERCTR); | ||
482 | isp116x_show_reg(isp116x, HCuPINT); | ||
483 | isp116x_show_reg(isp116x, HCuPINTENB); | ||
484 | isp116x_show_reg(isp116x, HCCHIPID); | ||
485 | isp116x_show_reg(isp116x, HCSCRATCH); | ||
486 | isp116x_show_reg(isp116x, HCITLBUFLEN); | ||
487 | isp116x_show_reg(isp116x, HCATLBUFLEN); | ||
488 | isp116x_show_reg(isp116x, HCBUFSTAT); | ||
489 | isp116x_show_reg(isp116x, HCRDITL0LEN); | ||
490 | isp116x_show_reg(isp116x, HCRDITL1LEN); | ||
491 | } | 516 | } |
492 | 517 | ||
493 | #if defined(URB_TRACE) | 518 | #if defined(URB_TRACE) |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index bf1d9abc07ac..a4b12404ae08 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -75,13 +75,6 @@ | |||
75 | */ | 75 | */ |
76 | 76 | ||
77 | #include <linux/config.h> | 77 | #include <linux/config.h> |
78 | |||
79 | #ifdef CONFIG_USB_DEBUG | ||
80 | # define DEBUG | ||
81 | #else | ||
82 | # undef DEBUG | ||
83 | #endif | ||
84 | |||
85 | #include <linux/module.h> | 78 | #include <linux/module.h> |
86 | #include <linux/moduleparam.h> | 79 | #include <linux/moduleparam.h> |
87 | #include <linux/pci.h> | 80 | #include <linux/pci.h> |
@@ -802,7 +795,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
802 | int temp; | 795 | int temp; |
803 | int i; | 796 | int i; |
804 | struct urb_priv *priv; | 797 | struct urb_priv *priv; |
805 | struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub; | ||
806 | 798 | ||
807 | /* mark any devices gone, so they do nothing till khubd disconnects. | 799 | /* mark any devices gone, so they do nothing till khubd disconnects. |
808 | * recycle any "live" eds/tds (and urbs) right away. | 800 | * recycle any "live" eds/tds (and urbs) right away. |
@@ -811,11 +803,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
811 | */ | 803 | */ |
812 | spin_lock_irq(&ohci->lock); | 804 | spin_lock_irq(&ohci->lock); |
813 | disable (ohci); | 805 | disable (ohci); |
814 | for (i = 0; i < root->maxchild; i++) { | 806 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); |
815 | if (root->children [i]) | ||
816 | usb_set_device_state (root->children[i], | ||
817 | USB_STATE_NOTATTACHED); | ||
818 | } | ||
819 | if (!list_empty (&ohci->pending)) | 807 | if (!list_empty (&ohci->pending)) |
820 | ohci_dbg(ohci, "abort schedule...\n"); | 808 | ohci_dbg(ohci, "abort schedule...\n"); |
821 | list_for_each_entry (priv, &ohci->pending, pending) { | 809 | list_for_each_entry (priv, &ohci->pending, pending) { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 72e3b12a1926..4b2226d77b34 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -372,7 +372,7 @@ done: | |||
372 | & ohci->hc_control) | 372 | & ohci->hc_control) |
373 | == OHCI_USB_OPER | 373 | == OHCI_USB_OPER |
374 | && time_after (jiffies, ohci->next_statechange) | 374 | && time_after (jiffies, ohci->next_statechange) |
375 | && usb_trylock_device (hcd->self.root_hub) | 375 | && usb_trylock_device (hcd->self.root_hub) == 0 |
376 | ) { | 376 | ) { |
377 | ohci_vdbg (ohci, "autosuspend\n"); | 377 | ohci_vdbg (ohci, "autosuspend\n"); |
378 | (void) ohci_bus_suspend (hcd); | 378 | (void) ohci_bus_suspend (hcd); |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 9d65ec307990..acde8868da21 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -26,18 +26,12 @@ | |||
26 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
27 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
28 | #include <asm/arch/pxa-regs.h> | 28 | #include <asm/arch/pxa-regs.h> |
29 | 29 | #include <asm/arch/ohci.h> | |
30 | |||
31 | #define PMM_NPS_MODE 1 | ||
32 | #define PMM_GLOBAL_MODE 2 | ||
33 | #define PMM_PERPORT_MODE 3 | ||
34 | 30 | ||
35 | #define PXA_UHC_MAX_PORTNUM 3 | 31 | #define PXA_UHC_MAX_PORTNUM 3 |
36 | 32 | ||
37 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) | 33 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) |
38 | 34 | ||
39 | static int pxa27x_ohci_pmm_state; | ||
40 | |||
41 | /* | 35 | /* |
42 | PMM_NPS_MODE -- PMM Non-power switching mode | 36 | PMM_NPS_MODE -- PMM Non-power switching mode |
43 | Ports are powered continuously. | 37 | Ports are powered continuously. |
@@ -50,8 +44,6 @@ static int pxa27x_ohci_pmm_state; | |||
50 | */ | 44 | */ |
51 | static int pxa27x_ohci_select_pmm( int mode ) | 45 | static int pxa27x_ohci_select_pmm( int mode ) |
52 | { | 46 | { |
53 | pxa27x_ohci_pmm_state = mode; | ||
54 | |||
55 | switch ( mode ) { | 47 | switch ( mode ) { |
56 | case PMM_NPS_MODE: | 48 | case PMM_NPS_MODE: |
57 | UHCRHDA |= RH_A_NPS; | 49 | UHCRHDA |= RH_A_NPS; |
@@ -71,7 +63,6 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
71 | "Invalid mode %d, set to non-power switch mode.\n", | 63 | "Invalid mode %d, set to non-power switch mode.\n", |
72 | mode ); | 64 | mode ); |
73 | 65 | ||
74 | pxa27x_ohci_pmm_state = PMM_NPS_MODE; | ||
75 | UHCRHDA |= RH_A_NPS; | 66 | UHCRHDA |= RH_A_NPS; |
76 | } | 67 | } |
77 | 68 | ||
@@ -82,8 +73,13 @@ extern int usb_disabled(void); | |||
82 | 73 | ||
83 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
84 | 75 | ||
85 | static void pxa27x_start_hc(struct platform_device *dev) | 76 | static int pxa27x_start_hc(struct device *dev) |
86 | { | 77 | { |
78 | int retval = 0; | ||
79 | struct pxaohci_platform_data *inf; | ||
80 | |||
81 | inf = dev->platform_data; | ||
82 | |||
87 | pxa_set_cken(CKEN10_USBHOST, 1); | 83 | pxa_set_cken(CKEN10_USBHOST, 1); |
88 | 84 | ||
89 | UHCHR |= UHCHR_FHR; | 85 | UHCHR |= UHCHR_FHR; |
@@ -94,21 +90,11 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
94 | while (UHCHR & UHCHR_FSBIR) | 90 | while (UHCHR & UHCHR_FSBIR) |
95 | cpu_relax(); | 91 | cpu_relax(); |
96 | 92 | ||
97 | /* This could be properly abstracted away through the | 93 | if (inf->init) |
98 | device data the day more machines are supported and | 94 | retval = inf->init(dev); |
99 | their differences can be figured out correctly. */ | ||
100 | if (machine_is_mainstone()) { | ||
101 | /* setup Port1 GPIO pin. */ | ||
102 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
103 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
104 | |||
105 | /* Set the Power Control Polarity Low and Power Sense | ||
106 | Polarity Low to active low. Supply power to USB ports. */ | ||
107 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
108 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
109 | 95 | ||
110 | pxa27x_ohci_pmm_state = PMM_PERPORT_MODE; | 96 | if (retval < 0) |
111 | } | 97 | return retval; |
112 | 98 | ||
113 | UHCHR &= ~UHCHR_SSE; | 99 | UHCHR &= ~UHCHR_SSE; |
114 | 100 | ||
@@ -117,10 +103,19 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
117 | /* Clear any OTG Pin Hold */ | 103 | /* Clear any OTG Pin Hold */ |
118 | if (PSSR & PSSR_OTGPH) | 104 | if (PSSR & PSSR_OTGPH) |
119 | PSSR |= PSSR_OTGPH; | 105 | PSSR |= PSSR_OTGPH; |
106 | |||
107 | return 0; | ||
120 | } | 108 | } |
121 | 109 | ||
122 | static void pxa27x_stop_hc(struct platform_device *dev) | 110 | static void pxa27x_stop_hc(struct device *dev) |
123 | { | 111 | { |
112 | struct pxaohci_platform_data *inf; | ||
113 | |||
114 | inf = dev->platform_data; | ||
115 | |||
116 | if (inf->exit) | ||
117 | inf->exit(dev); | ||
118 | |||
124 | UHCHR |= UHCHR_FHR; | 119 | UHCHR |= UHCHR_FHR; |
125 | udelay(11); | 120 | udelay(11); |
126 | UHCHR &= ~UHCHR_FHR; | 121 | UHCHR &= ~UHCHR_FHR; |
@@ -147,22 +142,27 @@ static void pxa27x_stop_hc(struct platform_device *dev) | |||
147 | * through the hotplug entry's driver_data. | 142 | * through the hotplug entry's driver_data. |
148 | * | 143 | * |
149 | */ | 144 | */ |
150 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | 145 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev) |
151 | struct platform_device *dev) | ||
152 | { | 146 | { |
153 | int retval; | 147 | int retval; |
154 | struct usb_hcd *hcd; | 148 | struct usb_hcd *hcd; |
149 | struct pxaohci_platform_data *inf; | ||
155 | 150 | ||
156 | if (dev->resource[1].flags != IORESOURCE_IRQ) { | 151 | inf = pdev->dev.platform_data; |
152 | |||
153 | if (!inf) | ||
154 | return -ENODEV; | ||
155 | |||
156 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); | 157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); |
158 | return -ENOMEM; | 158 | return -ENOMEM; |
159 | } | 159 | } |
160 | 160 | ||
161 | hcd = usb_create_hcd (driver, &dev->dev, "pxa27x"); | 161 | hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); |
162 | if (!hcd) | 162 | if (!hcd) |
163 | return -ENOMEM; | 163 | return -ENOMEM; |
164 | hcd->rsrc_start = dev->resource[0].start; | 164 | hcd->rsrc_start = pdev->resource[0].start; |
165 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | 165 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; |
166 | 166 | ||
167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
168 | pr_debug("request_mem_region failed"); | 168 | pr_debug("request_mem_region failed"); |
@@ -177,18 +177,22 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
177 | goto err2; | 177 | goto err2; |
178 | } | 178 | } |
179 | 179 | ||
180 | pxa27x_start_hc(dev); | 180 | if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) { |
181 | pr_debug("pxa27x_start_hc failed"); | ||
182 | goto err3; | ||
183 | } | ||
181 | 184 | ||
182 | /* Select Power Management Mode */ | 185 | /* Select Power Management Mode */ |
183 | pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state); | 186 | pxa27x_ohci_select_pmm(inf->port_mode); |
184 | 187 | ||
185 | ohci_hcd_init(hcd_to_ohci(hcd)); | 188 | ohci_hcd_init(hcd_to_ohci(hcd)); |
186 | 189 | ||
187 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | 190 | retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); |
188 | if (retval == 0) | 191 | if (retval == 0) |
189 | return retval; | 192 | return retval; |
190 | 193 | ||
191 | pxa27x_stop_hc(dev); | 194 | pxa27x_stop_hc(&pdev->dev); |
195 | err3: | ||
192 | iounmap(hcd->regs); | 196 | iounmap(hcd->regs); |
193 | err2: | 197 | err2: |
194 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 198 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
@@ -211,10 +215,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
211 | * context, normally "rmmod", "apmd", or something similar. | 215 | * context, normally "rmmod", "apmd", or something similar. |
212 | * | 216 | * |
213 | */ | 217 | */ |
214 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev) | 218 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev) |
215 | { | 219 | { |
216 | usb_remove_hcd(hcd); | 220 | usb_remove_hcd(hcd); |
217 | pxa27x_stop_hc(dev); | 221 | pxa27x_stop_hc(&pdev->dev); |
218 | iounmap(hcd->regs); | 222 | iounmap(hcd->regs); |
219 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 223 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
220 | usb_put_hcd(hcd); | 224 | usb_put_hcd(hcd); |
@@ -292,15 +296,12 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
292 | 296 | ||
293 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) | 297 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) |
294 | { | 298 | { |
295 | int ret; | ||
296 | |||
297 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); | 299 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); |
298 | 300 | ||
299 | if (usb_disabled()) | 301 | if (usb_disabled()) |
300 | return -ENODEV; | 302 | return -ENODEV; |
301 | 303 | ||
302 | ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); | 304 | return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); |
303 | return ret; | ||
304 | } | 305 | } |
305 | 306 | ||
306 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | 307 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) |
@@ -308,31 +309,55 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | |||
308 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 309 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
309 | 310 | ||
310 | usb_hcd_pxa27x_remove(hcd, pdev); | 311 | usb_hcd_pxa27x_remove(hcd, pdev); |
312 | platform_set_drvdata(pdev, NULL); | ||
311 | return 0; | 313 | return 0; |
312 | } | 314 | } |
313 | 315 | ||
314 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state) | 316 | #ifdef CONFIG_PM |
317 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state) | ||
315 | { | 318 | { |
316 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 319 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
317 | printk("%s: not implemented yet\n", __FUNCTION__); | 320 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
321 | |||
322 | if (time_before(jiffies, ohci->next_statechange)) | ||
323 | msleep(5); | ||
324 | ohci->next_statechange = jiffies; | ||
325 | |||
326 | pxa27x_stop_hc(&pdev->dev); | ||
327 | hcd->state = HC_STATE_SUSPENDED; | ||
328 | pdev->dev.power.power_state = PMSG_SUSPEND; | ||
318 | 329 | ||
319 | return 0; | 330 | return 0; |
320 | } | 331 | } |
321 | 332 | ||
322 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev) | 333 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) |
323 | { | 334 | { |
324 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 335 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
325 | printk("%s: not implemented yet\n", __FUNCTION__); | 336 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
337 | int status; | ||
338 | |||
339 | if (time_before(jiffies, ohci->next_statechange)) | ||
340 | msleep(5); | ||
341 | ohci->next_statechange = jiffies; | ||
342 | |||
343 | if ((status = pxa27x_start_hc(&pdev->dev)) < 0) | ||
344 | return status; | ||
345 | |||
346 | pdev->dev.power.power_state = PMSG_ON; | ||
347 | usb_hcd_resume_root_hub(hcd); | ||
326 | 348 | ||
327 | return 0; | 349 | return 0; |
328 | } | 350 | } |
351 | #endif | ||
329 | 352 | ||
330 | 353 | ||
331 | static struct platform_driver ohci_hcd_pxa27x_driver = { | 354 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
332 | .probe = ohci_hcd_pxa27x_drv_probe, | 355 | .probe = ohci_hcd_pxa27x_drv_probe, |
333 | .remove = ohci_hcd_pxa27x_drv_remove, | 356 | .remove = ohci_hcd_pxa27x_drv_remove, |
357 | #ifdef CONFIG_PM | ||
334 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 358 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
335 | .resume = ohci_hcd_pxa27x_drv_resume, | 359 | .resume = ohci_hcd_pxa27x_drv_resume, |
360 | #endif | ||
336 | .driver = { | 361 | .driver = { |
337 | .name = "pxa27x-ohci", | 362 | .name = "pxa27x-ohci", |
338 | }, | 363 | }, |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e46528c825bf..3ef2c0cdf1db 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -9,12 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | |||
18 | #include <linux/types.h> | 12 | #include <linux/types.h> |
19 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
20 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a7722a6a5a5b..517360b77d8e 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -32,13 +32,6 @@ | |||
32 | #undef PACKET_TRACE | 32 | #undef PACKET_TRACE |
33 | 33 | ||
34 | #include <linux/config.h> | 34 | #include <linux/config.h> |
35 | |||
36 | #ifdef CONFIG_USB_DEBUG | ||
37 | # define DEBUG | ||
38 | #else | ||
39 | # undef DEBUG | ||
40 | #endif | ||
41 | |||
42 | #include <linux/module.h> | 35 | #include <linux/module.h> |
43 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
44 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -1581,7 +1574,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
1581 | hcd->state = HC_STATE_RUNNING; | 1574 | hcd->state = HC_STATE_RUNNING; |
1582 | 1575 | ||
1583 | if (sl811->board) { | 1576 | if (sl811->board) { |
1584 | hcd->can_wakeup = sl811->board->can_wakeup; | 1577 | if (!device_can_wakeup(hcd->self.controller)) |
1578 | device_init_wakeup(hcd->self.controller, | ||
1579 | sl811->board->can_wakeup); | ||
1585 | hcd->power_budget = sl811->board->power * 2; | 1580 | hcd->power_budget = sl811->board->power * 2; |
1586 | } | 1581 | } |
1587 | 1582 | ||
@@ -1805,9 +1800,10 @@ sl811h_resume(struct platform_device *dev) | |||
1805 | * let's assume it'd only be powered to enable remote wakeup. | 1800 | * let's assume it'd only be powered to enable remote wakeup. |
1806 | */ | 1801 | */ |
1807 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND | 1802 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND |
1808 | || !hcd->can_wakeup) { | 1803 | || !device_can_wakeup(&hcd->self.root_hub->dev)) { |
1809 | sl811->port1 = 0; | 1804 | sl811->port1 = 0; |
1810 | port_power(sl811, 1); | 1805 | port_power(sl811, 1); |
1806 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
1811 | return 0; | 1807 | return 0; |
1812 | } | 1808 | } |
1813 | 1809 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index e73faf831b24..466384d7c79f 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL"); | |||
38 | /* MACROS */ | 38 | /* MACROS */ |
39 | /*====================================================================*/ | 39 | /*====================================================================*/ |
40 | 40 | ||
41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | 41 | #if defined(DEBUG) || defined(PCMCIA_DEBUG) |
42 | 42 | ||
43 | static int pc_debug = 0; | 43 | static int pc_debug = 0; |
44 | module_param(pc_debug, int, 0644); | 44 | module_param(pc_debug, int, 0644); |
@@ -66,13 +66,13 @@ module_param(pc_debug, int, 0644); | |||
66 | 66 | ||
67 | static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; | 67 | static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; |
68 | 68 | ||
69 | static dev_link_t *dev_list = NULL; | ||
70 | |||
71 | typedef struct local_info_t { | 69 | typedef struct local_info_t { |
72 | dev_link_t link; | 70 | dev_link_t link; |
73 | dev_node_t node; | 71 | dev_node_t node; |
74 | } local_info_t; | 72 | } local_info_t; |
75 | 73 | ||
74 | static void sl811_cs_release(dev_link_t * link); | ||
75 | |||
76 | /*====================================================================*/ | 76 | /*====================================================================*/ |
77 | 77 | ||
78 | static void release_platform_dev(struct device * dev) | 78 | static void release_platform_dev(struct device * dev) |
@@ -129,7 +129,8 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
129 | resources[2].end = base_addr + 1; | 129 | resources[2].end = base_addr + 1; |
130 | 130 | ||
131 | /* The driver core will probe for us. We know sl811-hcd has been | 131 | /* The driver core will probe for us. We know sl811-hcd has been |
132 | * initialized already because of the link order dependency. | 132 | * initialized already because of the link order dependency created |
133 | * by referencing "sl811h_driver". | ||
133 | */ | 134 | */ |
134 | platform_dev.name = sl811h_driver.name; | 135 | platform_dev.name = sl811h_driver.name; |
135 | return platform_device_register(&platform_dev); | 136 | return platform_device_register(&platform_dev); |
@@ -137,26 +138,16 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
137 | 138 | ||
138 | /*====================================================================*/ | 139 | /*====================================================================*/ |
139 | 140 | ||
140 | static void sl811_cs_detach(dev_link_t *link) | 141 | static void sl811_cs_detach(struct pcmcia_device *p_dev) |
141 | { | 142 | { |
142 | dev_link_t **linkp; | 143 | dev_link_t *link = dev_to_instance(p_dev); |
143 | 144 | ||
144 | DBG(0, "sl811_cs_detach(0x%p)\n", link); | 145 | DBG(0, "sl811_cs_detach(0x%p)\n", link); |
145 | 146 | ||
146 | /* Locate device structure */ | 147 | link->state &= ~DEV_PRESENT; |
147 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { | 148 | if (link->state & DEV_CONFIG) |
148 | if (*linkp == link) | 149 | sl811_cs_release(link); |
149 | break; | ||
150 | } | ||
151 | if (*linkp == NULL) | ||
152 | return; | ||
153 | |||
154 | /* Break the link with Card Services */ | ||
155 | if (link->handle) | ||
156 | pcmcia_deregister_client(link->handle); | ||
157 | 150 | ||
158 | /* Unlink device structure, and free it */ | ||
159 | *linkp = link->next; | ||
160 | /* This points to the parent local_info_t struct */ | 151 | /* This points to the parent local_info_t struct */ |
161 | kfree(link->priv); | 152 | kfree(link->priv); |
162 | } | 153 | } |
@@ -166,13 +157,6 @@ static void sl811_cs_release(dev_link_t * link) | |||
166 | 157 | ||
167 | DBG(0, "sl811_cs_release(0x%p)\n", link); | 158 | DBG(0, "sl811_cs_release(0x%p)\n", link); |
168 | 159 | ||
169 | if (link->open) { | ||
170 | DBG(1, "sl811_cs: release postponed, '%s' still open\n", | ||
171 | link->dev->dev_name); | ||
172 | link->state |= DEV_STALE_CONFIG; | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | /* Unlink the device chain */ | 160 | /* Unlink the device chain */ |
177 | link->dev = NULL; | 161 | link->dev = NULL; |
178 | 162 | ||
@@ -183,9 +167,6 @@ static void sl811_cs_release(dev_link_t * link) | |||
183 | if (link->irq.AssignedIRQ) | 167 | if (link->irq.AssignedIRQ) |
184 | pcmcia_release_irq(link->handle, &link->irq); | 168 | pcmcia_release_irq(link->handle, &link->irq); |
185 | link->state &= ~DEV_CONFIG; | 169 | link->state &= ~DEV_CONFIG; |
186 | |||
187 | if (link->state & DEV_STALE_LINK) | ||
188 | sl811_cs_detach(link); | ||
189 | } | 170 | } |
190 | 171 | ||
191 | static void sl811_cs_config(dev_link_t *link) | 172 | static void sl811_cs_config(dev_link_t *link) |
@@ -322,55 +303,36 @@ cs_failed: | |||
322 | } | 303 | } |
323 | } | 304 | } |
324 | 305 | ||
325 | static int | 306 | static int sl811_suspend(struct pcmcia_device *dev) |
326 | sl811_cs_event(event_t event, int priority, event_callback_args_t *args) | ||
327 | { | 307 | { |
328 | dev_link_t *link = args->client_data; | 308 | dev_link_t *link = dev_to_instance(dev); |
329 | 309 | ||
330 | DBG(1, "sl811_cs_event(0x%06x)\n", event); | 310 | link->state |= DEV_SUSPEND; |
311 | if (link->state & DEV_CONFIG) | ||
312 | pcmcia_release_configuration(link->handle); | ||
331 | 313 | ||
332 | switch (event) { | 314 | return 0; |
333 | case CS_EVENT_CARD_REMOVAL: | 315 | } |
334 | link->state &= ~DEV_PRESENT; | ||
335 | if (link->state & DEV_CONFIG) | ||
336 | sl811_cs_release(link); | ||
337 | break; | ||
338 | 316 | ||
339 | case CS_EVENT_CARD_INSERTION: | 317 | static int sl811_resume(struct pcmcia_device *dev) |
340 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 318 | { |
341 | sl811_cs_config(link); | 319 | dev_link_t *link = dev_to_instance(dev); |
342 | break; | ||
343 | 320 | ||
344 | case CS_EVENT_PM_SUSPEND: | 321 | link->state &= ~DEV_SUSPEND; |
345 | link->state |= DEV_SUSPEND; | 322 | if (link->state & DEV_CONFIG) |
346 | /* Fall through... */ | 323 | pcmcia_request_configuration(link->handle, &link->conf); |
347 | case CS_EVENT_RESET_PHYSICAL: | ||
348 | if (link->state & DEV_CONFIG) | ||
349 | pcmcia_release_configuration(link->handle); | ||
350 | break; | ||
351 | 324 | ||
352 | case CS_EVENT_PM_RESUME: | ||
353 | link->state &= ~DEV_SUSPEND; | ||
354 | /* Fall through... */ | ||
355 | case CS_EVENT_CARD_RESET: | ||
356 | if (link->state & DEV_CONFIG) | ||
357 | pcmcia_request_configuration(link->handle, &link->conf); | ||
358 | DBG(0, "reset sl811-hcd here?\n"); | ||
359 | break; | ||
360 | } | ||
361 | return 0; | 325 | return 0; |
362 | } | 326 | } |
363 | 327 | ||
364 | static dev_link_t *sl811_cs_attach(void) | 328 | static int sl811_cs_attach(struct pcmcia_device *p_dev) |
365 | { | 329 | { |
366 | local_info_t *local; | 330 | local_info_t *local; |
367 | dev_link_t *link; | 331 | dev_link_t *link; |
368 | client_reg_t client_reg; | ||
369 | int ret; | ||
370 | 332 | ||
371 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); | 333 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); |
372 | if (!local) | 334 | if (!local) |
373 | return NULL; | 335 | return -ENOMEM; |
374 | memset(local, 0, sizeof(local_info_t)); | 336 | memset(local, 0, sizeof(local_info_t)); |
375 | link = &local->link; | 337 | link = &local->link; |
376 | link->priv = local; | 338 | link->priv = local; |
@@ -384,21 +346,13 @@ static dev_link_t *sl811_cs_attach(void) | |||
384 | link->conf.Vcc = 33; | 346 | link->conf.Vcc = 33; |
385 | link->conf.IntType = INT_MEMORY_AND_IO; | 347 | link->conf.IntType = INT_MEMORY_AND_IO; |
386 | 348 | ||
387 | /* Register with Card Services */ | 349 | link->handle = p_dev; |
388 | link->next = dev_list; | 350 | p_dev->instance = link; |
389 | dev_list = link; | ||
390 | client_reg.dev_info = (dev_info_t *) &driver_name; | ||
391 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | ||
392 | client_reg.Version = 0x0210; | ||
393 | client_reg.event_callback_args.client_data = link; | ||
394 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
395 | if (ret != CS_SUCCESS) { | ||
396 | cs_error(link->handle, RegisterClient, ret); | ||
397 | sl811_cs_detach(link); | ||
398 | return NULL; | ||
399 | } | ||
400 | 351 | ||
401 | return link; | 352 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
353 | sl811_cs_config(link); | ||
354 | |||
355 | return 0; | ||
402 | } | 356 | } |
403 | 357 | ||
404 | static struct pcmcia_device_id sl811_ids[] = { | 358 | static struct pcmcia_device_id sl811_ids[] = { |
@@ -412,10 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = { | |||
412 | .drv = { | 366 | .drv = { |
413 | .name = (char *)driver_name, | 367 | .name = (char *)driver_name, |
414 | }, | 368 | }, |
415 | .attach = sl811_cs_attach, | 369 | .probe = sl811_cs_attach, |
416 | .event = sl811_cs_event, | 370 | .remove = sl811_cs_detach, |
417 | .detach = sl811_cs_detach, | ||
418 | .id_table = sl811_ids, | 371 | .id_table = sl811_ids, |
372 | .suspend = sl811_suspend, | ||
373 | .resume = sl811_resume, | ||
419 | }; | 374 | }; |
420 | 375 | ||
421 | /*====================================================================*/ | 376 | /*====================================================================*/ |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 151154df37fa..5832953086f8 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * UHCI-specific debugging code. Invaluable when something | 2 | * UHCI-specific debugging code. Invaluable when something |
3 | * goes wrong, but don't get in my face. | 3 | * goes wrong, but don't get in my face. |
4 | * | 4 | * |
5 | * Kernel visible pointers are surrounded in []'s and bus | 5 | * Kernel visible pointers are surrounded in []s and bus |
6 | * visible pointers are surrounded in ()'s | 6 | * visible pointers are surrounded in ()s |
7 | * | 7 | * |
8 | * (C) Copyright 1999 Linus Torvalds | 8 | * (C) Copyright 1999 Linus Torvalds |
9 | * (C) Copyright 1999-2001 Johannes Erdfelt | 9 | * (C) Copyright 1999-2001 Johannes Erdfelt |
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | static struct dentry *uhci_debugfs_root = NULL; | 20 | static struct dentry *uhci_debugfs_root = NULL; |
21 | 21 | ||
22 | /* Handle REALLY large printk's so we don't overflow buffers */ | 22 | /* Handle REALLY large printks so we don't overflow buffers */ |
23 | static inline void lprintk(char *buf) | 23 | static inline void lprintk(char *buf) |
24 | { | 24 | { |
25 | char *p; | 25 | char *p; |
@@ -160,7 +160,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | if (active && ni > i) { | 162 | if (active && ni > i) { |
163 | out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i); | 163 | out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i); |
164 | tmp = ntmp; | 164 | tmp = ntmp; |
165 | td = ntd; | 165 | td = ntd; |
166 | i = ni; | 166 | i = ni; |
@@ -173,7 +173,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
173 | if (list_empty(&urbp->queue_list) || urbp->queued) | 173 | if (list_empty(&urbp->queue_list) || urbp->queued) |
174 | goto out; | 174 | goto out; |
175 | 175 | ||
176 | out += sprintf(out, "%*sQueued QH's:\n", -space, "--"); | 176 | out += sprintf(out, "%*sQueued QHs:\n", -space, "--"); |
177 | 177 | ||
178 | head = &urbp->queue_list; | 178 | head = &urbp->queue_list; |
179 | tmp = head->next; | 179 | tmp = head->next; |
@@ -197,7 +197,7 @@ out: | |||
197 | } | 197 | } |
198 | 198 | ||
199 | #ifdef CONFIG_PROC_FS | 199 | #ifdef CONFIG_PROC_FS |
200 | static const char *qh_names[] = { | 200 | static const char * const qh_names[] = { |
201 | "skel_int128_qh", "skel_int64_qh", | 201 | "skel_int128_qh", "skel_int64_qh", |
202 | "skel_int32_qh", "skel_int16_qh", | 202 | "skel_int32_qh", "skel_int16_qh", |
203 | "skel_int8_qh", "skel_int4_qh", | 203 | "skel_int8_qh", "skel_int4_qh", |
@@ -464,7 +464,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
464 | } while (tmp != head); | 464 | } while (tmp != head); |
465 | } | 465 | } |
466 | 466 | ||
467 | out += sprintf(out, "Skeleton QH's\n"); | 467 | out += sprintf(out, "Skeleton QHs\n"); |
468 | 468 | ||
469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { | 469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { |
470 | int shown = 0; | 470 | int shown = 0; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 79efaf7d86a3..dfe121d35887 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -23,11 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #ifdef CONFIG_USB_DEBUG | ||
27 | #define DEBUG | ||
28 | #else | ||
29 | #undef DEBUG | ||
30 | #endif | ||
31 | #include <linux/module.h> | 26 | #include <linux/module.h> |
32 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
33 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -67,10 +62,10 @@ Alan Stern" | |||
67 | 62 | ||
68 | /* | 63 | /* |
69 | * debug = 0, no debugging messages | 64 | * debug = 0, no debugging messages |
70 | * debug = 1, dump failed URB's except for stalls | 65 | * debug = 1, dump failed URBs except for stalls |
71 | * debug = 2, dump all failed URB's (including stalls) | 66 | * debug = 2, dump all failed URBs (including stalls) |
72 | * show all queues in /debug/uhci/[pci_addr] | 67 | * show all queues in /debug/uhci/[pci_addr] |
73 | * debug = 3, show all TD's in URB's when dumping | 68 | * debug = 3, show all TDs in URBs when dumping |
74 | */ | 69 | */ |
75 | #ifdef DEBUG | 70 | #ifdef DEBUG |
76 | static int debug = 1; | 71 | static int debug = 1; |
@@ -93,7 +88,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
93 | #define FSBR_DELAY msecs_to_jiffies(50) | 88 | #define FSBR_DELAY msecs_to_jiffies(50) |
94 | 89 | ||
95 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ | 90 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ |
96 | /* depth first traversal. We'll do it in groups of this number of TD's */ | 91 | /* depth first traversal. We'll do it in groups of this number of TDs */ |
97 | /* to make sure it doesn't hog all of the bandwidth */ | 92 | /* to make sure it doesn't hog all of the bandwidth */ |
98 | #define DEPTH_INTERVAL 5 | 93 | #define DEPTH_INTERVAL 5 |
99 | 94 | ||
@@ -478,8 +473,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
478 | struct dentry *dentry; | 473 | struct dentry *dentry; |
479 | 474 | ||
480 | hcd->uses_new_polling = 1; | 475 | hcd->uses_new_polling = 1; |
481 | if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) | ||
482 | hcd->can_wakeup = 1; /* Assume it supports PME# */ | ||
483 | 476 | ||
484 | dentry = debugfs_create_file(hcd->self.bus_name, | 477 | dentry = debugfs_create_file(hcd->self.bus_name, |
485 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, | 478 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, |
@@ -573,7 +566,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
573 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; | 566 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; |
574 | 567 | ||
575 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 568 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
576 | uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) | | 569 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | |
577 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); | 570 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); |
578 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); | 571 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); |
579 | 572 | ||
@@ -735,8 +728,9 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
735 | 728 | ||
736 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); | 729 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); |
737 | 730 | ||
738 | /* We aren't in D3 state anymore, we do that even if dead as I | 731 | /* Since we aren't in D3 any more, it's safe to set this flag |
739 | * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0 | 732 | * even if the controller was dead. It might not even be dead |
733 | * any more, if the firmware or quirks code has reset it. | ||
740 | */ | 734 | */ |
741 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 735 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
742 | mb(); | 736 | mb(); |
@@ -755,8 +749,12 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
755 | check_and_reset_hc(uhci); | 749 | check_and_reset_hc(uhci); |
756 | configure_hc(uhci); | 750 | configure_hc(uhci); |
757 | 751 | ||
758 | if (uhci->rh_state == UHCI_RH_RESET) | 752 | if (uhci->rh_state == UHCI_RH_RESET) { |
753 | |||
754 | /* The controller had to be reset */ | ||
755 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
759 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 756 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
757 | } | ||
760 | 758 | ||
761 | spin_unlock_irq(&uhci->lock); | 759 | spin_unlock_irq(&uhci->lock); |
762 | 760 | ||
@@ -882,7 +880,7 @@ static int __init uhci_hcd_init(void) | |||
882 | 880 | ||
883 | init_failed: | 881 | init_failed: |
884 | if (kmem_cache_destroy(uhci_up_cachep)) | 882 | if (kmem_cache_destroy(uhci_up_cachep)) |
885 | warn("not all urb_priv's were freed!"); | 883 | warn("not all urb_privs were freed!"); |
886 | 884 | ||
887 | up_failed: | 885 | up_failed: |
888 | debugfs_remove(uhci_debugfs_root); | 886 | debugfs_remove(uhci_debugfs_root); |
@@ -900,7 +898,7 @@ static void __exit uhci_hcd_cleanup(void) | |||
900 | pci_unregister_driver(&uhci_pci_driver); | 898 | pci_unregister_driver(&uhci_pci_driver); |
901 | 899 | ||
902 | if (kmem_cache_destroy(uhci_up_cachep)) | 900 | if (kmem_cache_destroy(uhci_up_cachep)) |
903 | warn("not all urb_priv's were freed!"); | 901 | warn("not all urb_privs were freed!"); |
904 | 902 | ||
905 | debugfs_remove(uhci_debugfs_root); | 903 | debugfs_remove(uhci_debugfs_root); |
906 | kfree(errbuf); | 904 | kfree(errbuf); |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index e576db57a926..8b4b887a7d41 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -71,8 +71,6 @@ | |||
71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | 71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ |
72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | 72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ |
73 | 73 | ||
74 | #define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */ | ||
75 | |||
76 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) | 74 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) |
77 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) | 75 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) |
78 | #define UHCI_PTR_QH cpu_to_le32(0x0002) | 76 | #define UHCI_PTR_QH cpu_to_le32(0x0002) |
@@ -168,9 +166,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
168 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ | 166 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ |
169 | #define TD_TOKEN_PID_MASK 0xFF | 167 | #define TD_TOKEN_PID_MASK 0xFF |
170 | 168 | ||
171 | #define uhci_explen(len) ((len) << TD_TOKEN_EXPLEN_SHIFT) | 169 | #define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \ |
170 | TD_TOKEN_EXPLEN_SHIFT) | ||
172 | 171 | ||
173 | #define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) | 172 | #define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \ |
173 | 1) & TD_TOKEN_EXPLEN_MASK) | ||
174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) | 174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) |
175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) | 175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) |
176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) | 176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) |
@@ -223,10 +223,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
223 | */ | 223 | */ |
224 | 224 | ||
225 | /* | 225 | /* |
226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QHs both |
227 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TDs for one transfer, and also to facilitate queuing |
228 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URBs. To make it easy to insert entries into the schedule, we have |
229 | * a skeleton of QH's for each predefined Interrupt latency, low-speed | 229 | * a skeleton of QHs for each predefined Interrupt latency, low-speed |
230 | * control, full-speed control and terminating QH (see explanation for | 230 | * control, full-speed control and terminating QH (see explanation for |
231 | * the terminating QH below). | 231 | * the terminating QH below). |
232 | * | 232 | * |
@@ -257,8 +257,8 @@ static u32 inline td_status(struct uhci_td *td) { | |||
257 | * reclamation. | 257 | * reclamation. |
258 | * | 258 | * |
259 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QHs. While the UHCI spec doesn't forbid the |
261 | * use of QH's for Isochronous, it doesn't use them either. And the spec | 261 | * use of QHs for Isochronous, it doesn't use them either. And the spec |
262 | * says that queues never advance on an error completion status, which | 262 | * says that queues never advance on an error completion status, which |
263 | * makes them totally unsuitable for Isochronous transfers. | 263 | * makes them totally unsuitable for Isochronous transfers. |
264 | */ | 264 | */ |
@@ -359,7 +359,7 @@ struct uhci_hcd { | |||
359 | struct dma_pool *td_pool; | 359 | struct dma_pool *td_pool; |
360 | 360 | ||
361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ | 361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ |
362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */ |
363 | 363 | ||
364 | spinlock_t lock; | 364 | spinlock_t lock; |
365 | 365 | ||
@@ -389,22 +389,22 @@ struct uhci_hcd { | |||
389 | unsigned long resuming_ports; | 389 | unsigned long resuming_ports; |
390 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
391 | 391 | ||
392 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URBs currently controlled by this HC */ |
393 | struct list_head urb_list; | 393 | struct list_head urb_list; |
394 | 394 | ||
395 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QHs that are done, but waiting to be unlinked (race) */ |
396 | struct list_head qh_remove_list; | 396 | struct list_head qh_remove_list; |
397 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
398 | 398 | ||
399 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TDs that are done, but waiting to be freed (race) */ |
400 | struct list_head td_remove_list; | 400 | struct list_head td_remove_list; |
401 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
402 | 402 | ||
403 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URBs */ |
404 | struct list_head urb_remove_list; | 404 | struct list_head urb_remove_list; |
405 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
406 | 406 | ||
407 | /* List of URB's awaiting completion callback */ | 407 | /* List of URBs awaiting completion callback */ |
408 | struct list_head complete_list; | 408 | struct list_head complete_list; |
409 | 409 | ||
410 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 7e46887d9e12..b6076004a437 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -80,7 +80,7 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status, | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * We insert Isochronous URB's directly into the frame list at the beginning | 83 | * We insert Isochronous URBs directly into the frame list at the beginning |
84 | */ | 84 | */ |
85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) | 85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) |
86 | { | 86 | { |
@@ -369,7 +369,7 @@ static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, stru | |||
369 | uhci_fixup_toggle(urb, | 369 | uhci_fixup_toggle(urb, |
370 | uhci_toggle(td_token(lltd)) ^ 1)); | 370 | uhci_toggle(td_token(lltd)) ^ 1)); |
371 | 371 | ||
372 | /* All qh's in the queue need to link to the next queue */ | 372 | /* All qhs in the queue need to link to the next queue */ |
373 | urbp->qh->link = eurbp->qh->link; | 373 | urbp->qh->link = eurbp->qh->link; |
374 | 374 | ||
375 | wmb(); /* Make sure we flush everything */ | 375 | wmb(); /* Make sure we flush everything */ |
@@ -502,7 +502,7 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
502 | } | 502 | } |
503 | 503 | ||
504 | /* Check to see if the remove list is empty. Set the IOC bit */ | 504 | /* Check to see if the remove list is empty. Set the IOC bit */ |
505 | /* to force an interrupt so we can remove the TD's*/ | 505 | /* to force an interrupt so we can remove the TDs*/ |
506 | if (list_empty(&uhci->td_remove_list)) | 506 | if (list_empty(&uhci->td_remove_list)) |
507 | uhci_set_next_interrupt(uhci); | 507 | uhci_set_next_interrupt(uhci); |
508 | 508 | ||
@@ -596,7 +596,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
596 | return -ENOMEM; | 596 | return -ENOMEM; |
597 | 597 | ||
598 | uhci_add_td_to_urb(urb, td); | 598 | uhci_add_td_to_urb(urb, td); |
599 | uhci_fill_td(td, status, destination | uhci_explen(7), | 599 | uhci_fill_td(td, status, destination | uhci_explen(8), |
600 | urb->setup_dma); | 600 | urb->setup_dma); |
601 | 601 | ||
602 | /* | 602 | /* |
@@ -612,7 +612,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
612 | } | 612 | } |
613 | 613 | ||
614 | /* | 614 | /* |
615 | * Build the DATA TD's | 615 | * Build the DATA TDs |
616 | */ | 616 | */ |
617 | while (len > 0) { | 617 | while (len > 0) { |
618 | int pktsze = len; | 618 | int pktsze = len; |
@@ -628,7 +628,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
628 | destination ^= TD_TOKEN_TOGGLE; | 628 | destination ^= TD_TOKEN_TOGGLE; |
629 | 629 | ||
630 | uhci_add_td_to_urb(urb, td); | 630 | uhci_add_td_to_urb(urb, td); |
631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1), | 631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), |
632 | data); | 632 | data); |
633 | 633 | ||
634 | data += pktsze; | 634 | data += pktsze; |
@@ -658,7 +658,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
658 | 658 | ||
659 | uhci_add_td_to_urb(urb, td); | 659 | uhci_add_td_to_urb(urb, td); |
660 | uhci_fill_td(td, status | TD_CTRL_IOC, | 660 | uhci_fill_td(td, status | TD_CTRL_IOC, |
661 | destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0); | 661 | destination | uhci_explen(0), 0); |
662 | 662 | ||
663 | qh = uhci_alloc_qh(uhci); | 663 | qh = uhci_alloc_qh(uhci); |
664 | if (!qh) | 664 | if (!qh) |
@@ -744,7 +744,7 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) | |||
744 | 744 | ||
745 | urb->actual_length = 0; | 745 | urb->actual_length = 0; |
746 | 746 | ||
747 | /* The rest of the TD's (but the last) are data */ | 747 | /* The rest of the TDs (but the last) are data */ |
748 | tmp = tmp->next; | 748 | tmp = tmp->next; |
749 | while (tmp != head && tmp->next != head) { | 749 | while (tmp != head && tmp->next != head) { |
750 | unsigned int ctrlstat; | 750 | unsigned int ctrlstat; |
@@ -848,7 +848,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
848 | status |= TD_CTRL_SPD; | 848 | status |= TD_CTRL_SPD; |
849 | 849 | ||
850 | /* | 850 | /* |
851 | * Build the DATA TD's | 851 | * Build the DATA TDs |
852 | */ | 852 | */ |
853 | do { /* Allow zero length packets */ | 853 | do { /* Allow zero length packets */ |
854 | int pktsze = maxsze; | 854 | int pktsze = maxsze; |
@@ -864,7 +864,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
864 | return -ENOMEM; | 864 | return -ENOMEM; |
865 | 865 | ||
866 | uhci_add_td_to_urb(urb, td); | 866 | uhci_add_td_to_urb(urb, td); |
867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) | | 867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze) | |
868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
870 | data); | 870 | data); |
@@ -890,7 +890,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
890 | return -ENOMEM; | 890 | return -ENOMEM; |
891 | 891 | ||
892 | uhci_add_td_to_urb(urb, td); | 892 | uhci_add_td_to_urb(urb, td); |
893 | uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) | | 893 | uhci_fill_td(td, status, destination | uhci_explen(0) | |
894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
896 | data); | 896 | data); |
@@ -1025,7 +1025,7 @@ static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsig | |||
1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { | 1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { |
1026 | struct urb *u = up->urb; | 1026 | struct urb *u = up->urb; |
1027 | 1027 | ||
1028 | /* look for pending URB's with identical pipe handle */ | 1028 | /* look for pending URBs with identical pipe handle */ |
1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && | 1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && |
1030 | (u->status == -EINPROGRESS) && (u != urb)) { | 1030 | (u->status == -EINPROGRESS) && (u != urb)) { |
1031 | if (!last_urb) | 1031 | if (!last_urb) |
@@ -1092,7 +1092,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1092 | return -ENOMEM; | 1092 | return -ENOMEM; |
1093 | 1093 | ||
1094 | uhci_add_td_to_urb(urb, td); | 1094 | uhci_add_td_to_urb(urb, td); |
1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1), | 1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length), |
1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); | 1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); |
1097 | 1097 | ||
1098 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
@@ -1355,7 +1355,7 @@ static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb) | |||
1355 | 1355 | ||
1356 | uhci_delete_queued_urb(uhci, urb); | 1356 | uhci_delete_queued_urb(uhci, urb); |
1357 | 1357 | ||
1358 | /* The interrupt loop will reclaim the QH's */ | 1358 | /* The interrupt loop will reclaim the QHs */ |
1359 | uhci_remove_qh(uhci, urbp->qh); | 1359 | uhci_remove_qh(uhci, urbp->qh); |
1360 | urbp->qh = NULL; | 1360 | urbp->qh = NULL; |
1361 | } | 1361 | } |
@@ -1413,7 +1413,7 @@ static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb) | |||
1413 | list_for_each_entry(td, head, list) { | 1413 | list_for_each_entry(td, head, list) { |
1414 | /* | 1414 | /* |
1415 | * Make sure we don't do the last one (since it'll have the | 1415 | * Make sure we don't do the last one (since it'll have the |
1416 | * TERM bit set) as well as we skip every so many TD's to | 1416 | * TERM bit set) as well as we skip every so many TDs to |
1417 | * make sure it doesn't hog the bandwidth | 1417 | * make sure it doesn't hog the bandwidth |
1418 | */ | 1418 | */ |
1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == | 1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 1d973bcf56aa..049871145d63 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -962,7 +962,6 @@ MODULE_DEVICE_TABLE (usb, mdc800_table); | |||
962 | */ | 962 | */ |
963 | static struct usb_driver mdc800_usb_driver = | 963 | static struct usb_driver mdc800_usb_driver = |
964 | { | 964 | { |
965 | .owner = THIS_MODULE, | ||
966 | .name = "mdc800", | 965 | .name = "mdc800", |
967 | .probe = mdc800_usb_probe, | 966 | .probe = mdc800_usb_probe, |
968 | .disconnect = mdc800_usb_disconnect, | 967 | .disconnect = mdc800_usb_disconnect, |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 950543aa5ac7..458f2acdeb0a 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -160,7 +160,6 @@ static void mts_usb_disconnect(struct usb_interface *intf); | |||
160 | static struct usb_device_id mts_usb_ids []; | 160 | static struct usb_device_id mts_usb_ids []; |
161 | 161 | ||
162 | static struct usb_driver mts_usb_driver = { | 162 | static struct usb_driver mts_usb_driver = { |
163 | .owner = THIS_MODULE, | ||
164 | .name = "microtekX6", | 163 | .name = "microtekX6", |
165 | .probe = mts_usb_probe, | 164 | .probe = mts_usb_probe, |
166 | .disconnect = mts_usb_disconnect, | 165 | .disconnect = mts_usb_disconnect, |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 1e53934907c0..509dd0a04c54 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -273,6 +273,20 @@ config USB_ATI_REMOTE | |||
273 | To compile this driver as a module, choose M here: the module will be | 273 | To compile this driver as a module, choose M here: the module will be |
274 | called ati_remote. | 274 | called ati_remote. |
275 | 275 | ||
276 | config USB_ATI_REMOTE2 | ||
277 | tristate "ATI / Philips USB RF remote control" | ||
278 | depends on USB && INPUT | ||
279 | ---help--- | ||
280 | Say Y here if you want to use an ATI or Philips USB RF remote control. | ||
281 | These are RF remotes with USB receivers. | ||
282 | ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards | ||
283 | and is also available as a separate product. | ||
284 | This driver provides mouse pointer, left and right mouse buttons, | ||
285 | and maps all the other remote buttons to keypress events. | ||
286 | |||
287 | To compile this driver as a module, choose M here: the module will be | ||
288 | called ati_remote2. | ||
289 | |||
276 | config USB_KEYSPAN_REMOTE | 290 | config USB_KEYSPAN_REMOTE |
277 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" | 291 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" |
278 | depends on USB && INPUT && EXPERIMENTAL | 292 | depends on USB && INPUT && EXPERIMENTAL |
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 07cb17db42fc..d512d9f488fe 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -28,6 +28,7 @@ endif | |||
28 | 28 | ||
29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o | 29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o |
30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o | 30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o |
31 | obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o | ||
31 | obj-$(CONFIG_USB_HID) += usbhid.o | 32 | obj-$(CONFIG_USB_HID) += usbhid.o |
32 | obj-$(CONFIG_USB_KBD) += usbkbd.o | 33 | obj-$(CONFIG_USB_KBD) += usbkbd.o |
33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o | 34 | obj-$(CONFIG_USB_KBTAB) += kbtab.o |
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index a32558b4048e..df29b8078b54 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c | |||
@@ -261,7 +261,6 @@ static struct usb_device_id usb_acecad_id_table [] = { | |||
261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); | 261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); |
262 | 262 | ||
263 | static struct usb_driver usb_acecad_driver = { | 263 | static struct usb_driver usb_acecad_driver = { |
264 | .owner = THIS_MODULE, | ||
265 | .name = "usb_acecad", | 264 | .name = "usb_acecad", |
266 | .probe = usb_acecad_probe, | 265 | .probe = usb_acecad_probe, |
267 | .disconnect = usb_acecad_disconnect, | 266 | .disconnect = usb_acecad_disconnect, |
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 0e2505c073db..a6693b0d1c4c 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -338,7 +338,7 @@ struct aiptek { | |||
338 | * the bitmap which comes from the tablet. This hides the | 338 | * the bitmap which comes from the tablet. This hides the |
339 | * issue that the F_keys are not sequentially numbered. | 339 | * issue that the F_keys are not sequentially numbered. |
340 | */ | 340 | */ |
341 | static int macroKeyEvents[] = { | 341 | static const int macroKeyEvents[] = { |
342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, | 342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, |
343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, | 343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, |
344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, | 344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, |
@@ -2093,7 +2093,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2093 | /* Programming the tablet macro keys needs to be done with a for loop | 2093 | /* Programming the tablet macro keys needs to be done with a for loop |
2094 | * as the keycodes are discontiguous. | 2094 | * as the keycodes are discontiguous. |
2095 | */ | 2095 | */ |
2096 | for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i) | 2096 | for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) |
2097 | set_bit(macroKeyEvents[i], inputdev->keybit); | 2097 | set_bit(macroKeyEvents[i], inputdev->keybit); |
2098 | 2098 | ||
2099 | /* | 2099 | /* |
@@ -2135,7 +2135,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2135 | * not an error :-) | 2135 | * not an error :-) |
2136 | */ | 2136 | */ |
2137 | 2137 | ||
2138 | for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) { | 2138 | for (i = 0; i < ARRAY_SIZE(speeds); ++i) { |
2139 | aiptek->curSetting.programmableDelay = speeds[i]; | 2139 | aiptek->curSetting.programmableDelay = speeds[i]; |
2140 | (void)aiptek_program_tablet(aiptek); | 2140 | (void)aiptek_program_tablet(aiptek); |
2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { | 2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { |
@@ -2190,7 +2190,6 @@ fail1: input_free_device(inputdev); | |||
2190 | static void aiptek_disconnect(struct usb_interface *intf); | 2190 | static void aiptek_disconnect(struct usb_interface *intf); |
2191 | 2191 | ||
2192 | static struct usb_driver aiptek_driver = { | 2192 | static struct usb_driver aiptek_driver = { |
2193 | .owner = THIS_MODULE, | ||
2194 | .name = "aiptek", | 2193 | .name = "aiptek", |
2195 | .probe = aiptek_probe, | 2194 | .probe = aiptek_probe, |
2196 | .disconnect = aiptek_disconnect, | 2195 | .disconnect = aiptek_disconnect, |
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 15840db092a5..1949b54f41f2 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c | |||
@@ -452,7 +452,6 @@ static int atp_resume(struct usb_interface *iface) | |||
452 | } | 452 | } |
453 | 453 | ||
454 | static struct usb_driver atp_driver = { | 454 | static struct usb_driver atp_driver = { |
455 | .owner = THIS_MODULE, | ||
456 | .name = "appletouch", | 455 | .name = "appletouch", |
457 | .probe = atp_probe, | 456 | .probe = atp_probe, |
458 | .disconnect = atp_disconnect, | 457 | .disconnect = atp_disconnect, |
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 9a2a47db9494..f7bdc506e613 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -96,6 +96,7 @@ | |||
96 | #include <linux/usb.h> | 96 | #include <linux/usb.h> |
97 | #include <linux/usb_input.h> | 97 | #include <linux/usb_input.h> |
98 | #include <linux/wait.h> | 98 | #include <linux/wait.h> |
99 | #include <linux/jiffies.h> | ||
99 | 100 | ||
100 | /* | 101 | /* |
101 | * Module and Version Information, Module Parameters | 102 | * Module and Version Information, Module Parameters |
@@ -146,7 +147,7 @@ static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | |||
146 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | 147 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; |
147 | 148 | ||
148 | /* Acceleration curve for directional control pad */ | 149 | /* Acceleration curve for directional control pad */ |
149 | static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | 150 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; |
150 | 151 | ||
151 | /* Duplicate event filtering time. | 152 | /* Duplicate event filtering time. |
152 | * Sequential, identical KIND_FILTERED inputs with less than | 153 | * Sequential, identical KIND_FILTERED inputs with less than |
@@ -197,7 +198,7 @@ struct ati_remote { | |||
197 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ | 198 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ |
198 | 199 | ||
199 | /* Translation table from hardware messages to input events. */ | 200 | /* Translation table from hardware messages to input events. */ |
200 | static struct { | 201 | static const struct { |
201 | short kind; | 202 | short kind; |
202 | unsigned char data1, data2; | 203 | unsigned char data1, data2; |
203 | int type; | 204 | int type; |
@@ -295,7 +296,6 @@ static void ati_remote_disconnect (struct usb_interface *interface); | |||
295 | 296 | ||
296 | /* usb specific object to register with the usb subsystem */ | 297 | /* usb specific object to register with the usb subsystem */ |
297 | static struct usb_driver ati_remote_driver = { | 298 | static struct usb_driver ati_remote_driver = { |
298 | .owner = THIS_MODULE, | ||
299 | .name = "ati_remote", | 299 | .name = "ati_remote", |
300 | .probe = ati_remote_probe, | 300 | .probe = ati_remote_probe, |
301 | .disconnect = ati_remote_disconnect, | 301 | .disconnect = ati_remote_disconnect, |
@@ -472,7 +472,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
472 | /* Filter duplicate events which happen "too close" together. */ | 472 | /* Filter duplicate events which happen "too close" together. */ |
473 | if ((ati_remote->old_data[0] == data[1]) && | 473 | if ((ati_remote->old_data[0] == data[1]) && |
474 | (ati_remote->old_data[1] == data[2]) && | 474 | (ati_remote->old_data[1] == data[2]) && |
475 | ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { | 475 | time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { |
476 | ati_remote->repeat_count++; | 476 | ati_remote->repeat_count++; |
477 | } else { | 477 | } else { |
478 | ati_remote->repeat_count = 0; | 478 | ati_remote->repeat_count = 0; |
@@ -507,16 +507,16 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
507 | * pad down, so we increase acceleration, ramping up over two seconds to | 507 | * pad down, so we increase acceleration, ramping up over two seconds to |
508 | * a maximum speed. The acceleration curve is #defined above. | 508 | * a maximum speed. The acceleration curve is #defined above. |
509 | */ | 509 | */ |
510 | if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) { | 510 | if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { |
511 | acc = 1; | 511 | acc = 1; |
512 | ati_remote->acc_jiffies = jiffies; | 512 | ati_remote->acc_jiffies = jiffies; |
513 | } | 513 | } |
514 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3)) acc = accel[0]; | 514 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; |
515 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2)) acc = accel[1]; | 515 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; |
516 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1)) acc = accel[2]; | 516 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; |
517 | else if ((jiffies - ati_remote->acc_jiffies) < HZ ) acc = accel[3]; | 517 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; |
518 | else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4]; | 518 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; |
519 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1)) acc = accel[5]; | 519 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; |
520 | else acc = accel[6]; | 520 | else acc = accel[6]; |
521 | 521 | ||
522 | input_regs(dev, regs); | 522 | input_regs(dev, regs); |
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c new file mode 100644 index 000000000000..ab1a1ae24be9 --- /dev/null +++ b/drivers/usb/input/ati_remote2.c | |||
@@ -0,0 +1,477 @@ | |||
1 | /* | ||
2 | * ati_remote2 - ATI/Philips USB RF remote driver | ||
3 | * | ||
4 | * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> | ||
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 | ||
8 | * as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/usb_input.h> | ||
12 | |||
13 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" | ||
14 | #define DRIVER_VERSION "0.1" | ||
15 | |||
16 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
17 | MODULE_VERSION(DRIVER_VERSION); | ||
18 | MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | static unsigned int mode_mask = 0x1F; | ||
22 | module_param(mode_mask, uint, 0644); | ||
23 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | ||
24 | |||
25 | static struct usb_device_id ati_remote2_id_table[] = { | ||
26 | { USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */ | ||
27 | { } | ||
28 | }; | ||
29 | MODULE_DEVICE_TABLE(usb, ati_remote2_id_table); | ||
30 | |||
31 | static struct { | ||
32 | int hw_code; | ||
33 | int key_code; | ||
34 | } ati_remote2_key_table[] = { | ||
35 | { 0x00, KEY_0 }, | ||
36 | { 0x01, KEY_1 }, | ||
37 | { 0x02, KEY_2 }, | ||
38 | { 0x03, KEY_3 }, | ||
39 | { 0x04, KEY_4 }, | ||
40 | { 0x05, KEY_5 }, | ||
41 | { 0x06, KEY_6 }, | ||
42 | { 0x07, KEY_7 }, | ||
43 | { 0x08, KEY_8 }, | ||
44 | { 0x09, KEY_9 }, | ||
45 | { 0x0c, KEY_POWER }, | ||
46 | { 0x0d, KEY_MUTE }, | ||
47 | { 0x10, KEY_VOLUMEUP }, | ||
48 | { 0x11, KEY_VOLUMEDOWN }, | ||
49 | { 0x20, KEY_CHANNELUP }, | ||
50 | { 0x21, KEY_CHANNELDOWN }, | ||
51 | { 0x28, KEY_FORWARD }, | ||
52 | { 0x29, KEY_REWIND }, | ||
53 | { 0x2c, KEY_PLAY }, | ||
54 | { 0x30, KEY_PAUSE }, | ||
55 | { 0x31, KEY_STOP }, | ||
56 | { 0x37, KEY_RECORD }, | ||
57 | { 0x38, KEY_DVD }, | ||
58 | { 0x39, KEY_TV }, | ||
59 | { 0x54, KEY_MENU }, | ||
60 | { 0x58, KEY_UP }, | ||
61 | { 0x59, KEY_DOWN }, | ||
62 | { 0x5a, KEY_LEFT }, | ||
63 | { 0x5b, KEY_RIGHT }, | ||
64 | { 0x5c, KEY_OK }, | ||
65 | { 0x78, KEY_A }, | ||
66 | { 0x79, KEY_B }, | ||
67 | { 0x7a, KEY_C }, | ||
68 | { 0x7b, KEY_D }, | ||
69 | { 0x7c, KEY_E }, | ||
70 | { 0x7d, KEY_F }, | ||
71 | { 0x82, KEY_ENTER }, | ||
72 | { 0x8e, KEY_VENDOR }, | ||
73 | { 0x96, KEY_COFFEE }, | ||
74 | { 0xa9, BTN_LEFT }, | ||
75 | { 0xaa, BTN_RIGHT }, | ||
76 | { 0xbe, KEY_QUESTION }, | ||
77 | { 0xd5, KEY_FRONT }, | ||
78 | { 0xd0, KEY_EDIT }, | ||
79 | { 0xf9, KEY_INFO }, | ||
80 | { (0x00 << 8) | 0x3f, KEY_PROG1 }, | ||
81 | { (0x01 << 8) | 0x3f, KEY_PROG2 }, | ||
82 | { (0x02 << 8) | 0x3f, KEY_PROG3 }, | ||
83 | { (0x03 << 8) | 0x3f, KEY_PROG4 }, | ||
84 | { (0x04 << 8) | 0x3f, KEY_PC }, | ||
85 | { 0, KEY_RESERVED } | ||
86 | }; | ||
87 | |||
88 | struct ati_remote2 { | ||
89 | struct input_dev *idev; | ||
90 | struct usb_device *udev; | ||
91 | |||
92 | struct usb_interface *intf[2]; | ||
93 | struct usb_endpoint_descriptor *ep[2]; | ||
94 | struct urb *urb[2]; | ||
95 | void *buf[2]; | ||
96 | dma_addr_t buf_dma[2]; | ||
97 | |||
98 | unsigned long jiffies; | ||
99 | int mode; | ||
100 | |||
101 | char name[64]; | ||
102 | char phys[64]; | ||
103 | }; | ||
104 | |||
105 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); | ||
106 | static void ati_remote2_disconnect(struct usb_interface *interface); | ||
107 | |||
108 | static struct usb_driver ati_remote2_driver = { | ||
109 | .name = "ati_remote2", | ||
110 | .probe = ati_remote2_probe, | ||
111 | .disconnect = ati_remote2_disconnect, | ||
112 | .id_table = ati_remote2_id_table, | ||
113 | }; | ||
114 | |||
115 | static int ati_remote2_open(struct input_dev *idev) | ||
116 | { | ||
117 | struct ati_remote2 *ar2 = idev->private; | ||
118 | int r; | ||
119 | |||
120 | r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); | ||
121 | if (r) { | ||
122 | dev_err(&ar2->intf[0]->dev, | ||
123 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
124 | return r; | ||
125 | } | ||
126 | r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); | ||
127 | if (r) { | ||
128 | usb_kill_urb(ar2->urb[0]); | ||
129 | dev_err(&ar2->intf[1]->dev, | ||
130 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
131 | return r; | ||
132 | } | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static void ati_remote2_close(struct input_dev *idev) | ||
138 | { | ||
139 | struct ati_remote2 *ar2 = idev->private; | ||
140 | |||
141 | usb_kill_urb(ar2->urb[0]); | ||
142 | usb_kill_urb(ar2->urb[1]); | ||
143 | } | ||
144 | |||
145 | static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
146 | { | ||
147 | struct input_dev *idev = ar2->idev; | ||
148 | u8 *data = ar2->buf[0]; | ||
149 | |||
150 | if (data[0] > 4) { | ||
151 | dev_err(&ar2->intf[0]->dev, | ||
152 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
153 | data[3], data[2], data[1], data[0]); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | if (!((1 << data[0]) & mode_mask)) | ||
158 | return; | ||
159 | |||
160 | input_regs(idev, regs); | ||
161 | input_event(idev, EV_REL, REL_X, (s8) data[1]); | ||
162 | input_event(idev, EV_REL, REL_Y, (s8) data[2]); | ||
163 | input_sync(idev); | ||
164 | } | ||
165 | |||
166 | static int ati_remote2_lookup(unsigned int hw_code) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
171 | if (ati_remote2_key_table[i].hw_code == hw_code) | ||
172 | return i; | ||
173 | |||
174 | return -1; | ||
175 | } | ||
176 | |||
177 | static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
178 | { | ||
179 | struct input_dev *idev = ar2->idev; | ||
180 | u8 *data = ar2->buf[1]; | ||
181 | int hw_code, index; | ||
182 | |||
183 | if (data[0] > 4) { | ||
184 | dev_err(&ar2->intf[1]->dev, | ||
185 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
186 | data[3], data[2], data[1], data[0]); | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | hw_code = data[2]; | ||
191 | /* | ||
192 | * Mode keys (AUX1-AUX4, PC) all generate the same code byte. | ||
193 | * Use the mode byte to figure out which one was pressed. | ||
194 | */ | ||
195 | if (hw_code == 0x3f) { | ||
196 | /* | ||
197 | * For some incomprehensible reason the mouse pad generates | ||
198 | * events which look identical to the events from the last | ||
199 | * pressed mode key. Naturally we don't want to generate key | ||
200 | * events for the mouse pad so we filter out any subsequent | ||
201 | * events from the same mode key. | ||
202 | */ | ||
203 | if (ar2->mode == data[0]) | ||
204 | return; | ||
205 | |||
206 | if (data[1] == 0) | ||
207 | ar2->mode = data[0]; | ||
208 | |||
209 | hw_code |= data[0] << 8; | ||
210 | } | ||
211 | |||
212 | if (!((1 << data[0]) & mode_mask)) | ||
213 | return; | ||
214 | |||
215 | index = ati_remote2_lookup(hw_code); | ||
216 | if (index < 0) { | ||
217 | dev_err(&ar2->intf[1]->dev, | ||
218 | "Unknown code byte (%02x %02x %02x %02x)\n", | ||
219 | data[3], data[2], data[1], data[0]); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | switch (data[1]) { | ||
224 | case 0: /* release */ | ||
225 | break; | ||
226 | case 1: /* press */ | ||
227 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]); | ||
228 | break; | ||
229 | case 2: /* repeat */ | ||
230 | |||
231 | /* No repeat for mouse buttons. */ | ||
232 | if (ati_remote2_key_table[index].key_code == BTN_LEFT || | ||
233 | ati_remote2_key_table[index].key_code == BTN_RIGHT) | ||
234 | return; | ||
235 | |||
236 | if (!time_after_eq(jiffies, ar2->jiffies)) | ||
237 | return; | ||
238 | |||
239 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]); | ||
240 | break; | ||
241 | default: | ||
242 | dev_err(&ar2->intf[1]->dev, | ||
243 | "Unknown state byte (%02x %02x %02x %02x)\n", | ||
244 | data[3], data[2], data[1], data[0]); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | input_regs(idev, regs); | ||
249 | input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); | ||
250 | input_sync(idev); | ||
251 | } | ||
252 | |||
253 | static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs) | ||
254 | { | ||
255 | struct ati_remote2 *ar2 = urb->context; | ||
256 | int r; | ||
257 | |||
258 | switch (urb->status) { | ||
259 | case 0: | ||
260 | ati_remote2_input_mouse(ar2, regs); | ||
261 | break; | ||
262 | case -ENOENT: | ||
263 | case -EILSEQ: | ||
264 | case -ECONNRESET: | ||
265 | case -ESHUTDOWN: | ||
266 | dev_dbg(&ar2->intf[0]->dev, | ||
267 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
268 | return; | ||
269 | default: | ||
270 | dev_err(&ar2->intf[0]->dev, | ||
271 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
272 | } | ||
273 | |||
274 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
275 | if (r) | ||
276 | dev_err(&ar2->intf[0]->dev, | ||
277 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
278 | } | ||
279 | |||
280 | static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs) | ||
281 | { | ||
282 | struct ati_remote2 *ar2 = urb->context; | ||
283 | int r; | ||
284 | |||
285 | switch (urb->status) { | ||
286 | case 0: | ||
287 | ati_remote2_input_key(ar2, regs); | ||
288 | break; | ||
289 | case -ENOENT: | ||
290 | case -EILSEQ: | ||
291 | case -ECONNRESET: | ||
292 | case -ESHUTDOWN: | ||
293 | dev_dbg(&ar2->intf[1]->dev, | ||
294 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
295 | return; | ||
296 | default: | ||
297 | dev_err(&ar2->intf[1]->dev, | ||
298 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
299 | } | ||
300 | |||
301 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
302 | if (r) | ||
303 | dev_err(&ar2->intf[1]->dev, | ||
304 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
305 | } | ||
306 | |||
307 | static int ati_remote2_input_init(struct ati_remote2 *ar2) | ||
308 | { | ||
309 | struct input_dev *idev; | ||
310 | int i; | ||
311 | |||
312 | idev = input_allocate_device(); | ||
313 | if (!idev) | ||
314 | return -ENOMEM; | ||
315 | |||
316 | ar2->idev = idev; | ||
317 | idev->private = ar2; | ||
318 | |||
319 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); | ||
320 | idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | ||
321 | idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
322 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
323 | set_bit(ati_remote2_key_table[i].key_code, idev->keybit); | ||
324 | |||
325 | idev->rep[REP_DELAY] = 250; | ||
326 | idev->rep[REP_PERIOD] = 33; | ||
327 | |||
328 | idev->open = ati_remote2_open; | ||
329 | idev->close = ati_remote2_close; | ||
330 | |||
331 | idev->name = ar2->name; | ||
332 | idev->phys = ar2->phys; | ||
333 | |||
334 | usb_to_input_id(ar2->udev, &idev->id); | ||
335 | idev->cdev.dev = &ar2->udev->dev; | ||
336 | |||
337 | i = input_register_device(idev); | ||
338 | if (i) | ||
339 | input_free_device(idev); | ||
340 | |||
341 | return i; | ||
342 | } | ||
343 | |||
344 | static int ati_remote2_urb_init(struct ati_remote2 *ar2) | ||
345 | { | ||
346 | struct usb_device *udev = ar2->udev; | ||
347 | int i, pipe, maxp; | ||
348 | |||
349 | for (i = 0; i < 2; i++) { | ||
350 | ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]); | ||
351 | if (!ar2->buf[i]) | ||
352 | return -ENOMEM; | ||
353 | |||
354 | ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
355 | if (!ar2->urb[i]) | ||
356 | return -ENOMEM; | ||
357 | |||
358 | pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress); | ||
359 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
360 | maxp = maxp > 4 ? 4 : maxp; | ||
361 | |||
362 | usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp, | ||
363 | i ? ati_remote2_complete_key : ati_remote2_complete_mouse, | ||
364 | ar2, ar2->ep[i]->bInterval); | ||
365 | ar2->urb[i]->transfer_dma = ar2->buf_dma[i]; | ||
366 | ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
367 | } | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) | ||
373 | { | ||
374 | int i; | ||
375 | |||
376 | for (i = 0; i < 2; i++) { | ||
377 | if (ar2->urb[i]) | ||
378 | usb_free_urb(ar2->urb[i]); | ||
379 | |||
380 | if (ar2->buf[i]) | ||
381 | usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
386 | { | ||
387 | struct usb_device *udev = interface_to_usbdev(interface); | ||
388 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
389 | struct ati_remote2 *ar2; | ||
390 | int r; | ||
391 | |||
392 | if (alt->desc.bInterfaceNumber) | ||
393 | return -ENODEV; | ||
394 | |||
395 | ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL); | ||
396 | if (!ar2) | ||
397 | return -ENOMEM; | ||
398 | |||
399 | ar2->udev = udev; | ||
400 | |||
401 | ar2->intf[0] = interface; | ||
402 | ar2->ep[0] = &alt->endpoint[0].desc; | ||
403 | |||
404 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); | ||
405 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); | ||
406 | if (r) | ||
407 | goto fail1; | ||
408 | alt = ar2->intf[1]->cur_altsetting; | ||
409 | ar2->ep[1] = &alt->endpoint[0].desc; | ||
410 | |||
411 | r = ati_remote2_urb_init(ar2); | ||
412 | if (r) | ||
413 | goto fail2; | ||
414 | |||
415 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); | ||
416 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); | ||
417 | |||
418 | strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); | ||
419 | |||
420 | r = ati_remote2_input_init(ar2); | ||
421 | if (r) | ||
422 | goto fail2; | ||
423 | |||
424 | usb_set_intfdata(interface, ar2); | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | fail2: | ||
429 | ati_remote2_urb_cleanup(ar2); | ||
430 | |||
431 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
432 | fail1: | ||
433 | kfree(ar2); | ||
434 | |||
435 | return r; | ||
436 | } | ||
437 | |||
438 | static void ati_remote2_disconnect(struct usb_interface *interface) | ||
439 | { | ||
440 | struct ati_remote2 *ar2; | ||
441 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
442 | |||
443 | if (alt->desc.bInterfaceNumber) | ||
444 | return; | ||
445 | |||
446 | ar2 = usb_get_intfdata(interface); | ||
447 | usb_set_intfdata(interface, NULL); | ||
448 | |||
449 | input_unregister_device(ar2->idev); | ||
450 | |||
451 | ati_remote2_urb_cleanup(ar2); | ||
452 | |||
453 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
454 | |||
455 | kfree(ar2); | ||
456 | } | ||
457 | |||
458 | static int __init ati_remote2_init(void) | ||
459 | { | ||
460 | int r; | ||
461 | |||
462 | r = usb_register(&ati_remote2_driver); | ||
463 | if (r) | ||
464 | printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r); | ||
465 | else | ||
466 | printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n"); | ||
467 | |||
468 | return r; | ||
469 | } | ||
470 | |||
471 | static void __exit ati_remote2_exit(void) | ||
472 | { | ||
473 | usb_deregister(&ati_remote2_driver); | ||
474 | } | ||
475 | |||
476 | module_init(ati_remote2_init); | ||
477 | module_exit(ati_remote2_exit); | ||
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h index 26ca5b890a61..b44d398de071 100644 --- a/drivers/usb/input/fixp-arith.h +++ b/drivers/usb/input/fixp-arith.h | |||
@@ -38,7 +38,7 @@ typedef s16 fixp_t; | |||
38 | #define FRAC_MASK ((1<<FRAC_N)-1) | 38 | #define FRAC_MASK ((1<<FRAC_N)-1) |
39 | 39 | ||
40 | // Not to be used directly. Use fixp_{cos,sin} | 40 | // Not to be used directly. Use fixp_{cos,sin} |
41 | static fixp_t cos_table[45] = { | 41 | static const fixp_t cos_table[45] = { |
42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, | 42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, |
43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, | 43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, |
44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, | 44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a3e44ef1df43..5f52979af1c7 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1454,7 +1454,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1454 | * Alphabetically sorted blacklist by quirk type. | 1454 | * Alphabetically sorted blacklist by quirk type. |
1455 | */ | 1455 | */ |
1456 | 1456 | ||
1457 | static struct hid_blacklist { | 1457 | static const struct hid_blacklist { |
1458 | __u16 idVendor; | 1458 | __u16 idVendor; |
1459 | __u16 idProduct; | 1459 | __u16 idProduct; |
1460 | unsigned quirks; | 1460 | unsigned quirks; |
@@ -1930,7 +1930,6 @@ static struct usb_device_id hid_usb_ids [] = { | |||
1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); | 1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); |
1931 | 1931 | ||
1932 | static struct usb_driver hid_driver = { | 1932 | static struct usb_driver hid_driver = { |
1933 | .owner = THIS_MODULE, | ||
1934 | .name = "usbhid", | 1933 | .name = "usbhid", |
1935 | .probe = hid_probe, | 1934 | .probe = hid_probe, |
1936 | .disconnect = hid_disconnect, | 1935 | .disconnect = hid_disconnect, |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 1220a5004a5c..192a03b28971 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define unk KEY_UNKNOWN | 40 | #define unk KEY_UNKNOWN |
41 | 41 | ||
42 | static unsigned char hid_keyboard[256] = { | 42 | static const unsigned char hid_keyboard[256] = { |
43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | 43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, |
44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | 44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, |
45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | 45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, |
@@ -58,7 +58,7 @@ static unsigned char hid_keyboard[256] = { | |||
58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | 58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct { | 61 | static const struct { |
62 | __s32 x; | 62 | __s32 x; |
63 | __s32 y; | 63 | __s32 y; |
64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; | 64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 440377c7a0da..4dff8473553d 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -826,7 +826,6 @@ static int hiddev_usbd_probe(struct usb_interface *intf, | |||
826 | 826 | ||
827 | 827 | ||
828 | static /* const */ struct usb_driver hiddev_driver = { | 828 | static /* const */ struct usb_driver hiddev_driver = { |
829 | .owner = THIS_MODULE, | ||
830 | .name = "hiddev", | 829 | .name = "hiddev", |
831 | .probe = hiddev_usbd_probe, | 830 | .probe = hiddev_usbd_probe, |
832 | }; | 831 | }; |
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 4a50acb39d29..7618ae5c104f 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c | |||
@@ -250,7 +250,6 @@ static void itmtouch_disconnect(struct usb_interface *intf) | |||
250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); | 250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); |
251 | 251 | ||
252 | static struct usb_driver itmtouch_driver = { | 252 | static struct usb_driver itmtouch_driver = { |
253 | .owner = THIS_MODULE, | ||
254 | .name = "itmtouch", | 253 | .name = "itmtouch", |
255 | .probe = itmtouch_probe, | 254 | .probe = itmtouch_probe, |
256 | .disconnect = itmtouch_disconnect, | 255 | .disconnect = itmtouch_disconnect, |
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index fd48e74e78ed..f6d5cead542b 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c | |||
@@ -197,7 +197,6 @@ static void kbtab_disconnect(struct usb_interface *intf) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | static struct usb_driver kbtab_driver = { | 199 | static struct usb_driver kbtab_driver = { |
200 | .owner = THIS_MODULE, | ||
201 | .name = "kbtab", | 200 | .name = "kbtab", |
202 | .probe = kbtab_probe, | 201 | .probe = kbtab_probe, |
203 | .disconnect = kbtab_disconnect, | 202 | .disconnect = kbtab_disconnect, |
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index a32cfe51b77d..b4a051b549d1 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c | |||
@@ -95,7 +95,7 @@ struct usb_keyspan { | |||
95 | * Currently there are 15 and 17 button models so RESERVED codes | 95 | * Currently there are 15 and 17 button models so RESERVED codes |
96 | * are blank areas in the mapping. | 96 | * are blank areas in the mapping. |
97 | */ | 97 | */ |
98 | static int keyspan_key_table[] = { | 98 | static const int keyspan_key_table[] = { |
99 | KEY_RESERVED, /* 0 is just a place holder. */ | 99 | KEY_RESERVED, /* 0 is just a place holder. */ |
100 | KEY_RESERVED, | 100 | KEY_RESERVED, |
101 | KEY_STOP, | 101 | KEY_STOP, |
@@ -559,7 +559,6 @@ static void keyspan_disconnect(struct usb_interface *interface) | |||
559 | */ | 559 | */ |
560 | static struct usb_driver keyspan_driver = | 560 | static struct usb_driver keyspan_driver = |
561 | { | 561 | { |
562 | .owner = THIS_MODULE, | ||
563 | .name = "keyspan_remote", | 562 | .name = "keyspan_remote", |
564 | .probe = keyspan_probe, | 563 | .probe = keyspan_probe, |
565 | .disconnect = keyspan_disconnect, | 564 | .disconnect = keyspan_disconnect, |
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 52cc18cd247d..f018953a5485 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
@@ -310,7 +310,6 @@ static void mtouchusb_disconnect(struct usb_interface *intf) | |||
310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); | 310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); |
311 | 311 | ||
312 | static struct usb_driver mtouchusb_driver = { | 312 | static struct usb_driver mtouchusb_driver = { |
313 | .owner = THIS_MODULE, | ||
314 | .name = "mtouchusb", | 313 | .name = "mtouchusb", |
315 | .probe = mtouchusb_probe, | 314 | .probe = mtouchusb_probe, |
316 | .disconnect = mtouchusb_disconnect, | 315 | .disconnect = mtouchusb_disconnect, |
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index b7476233ef5d..fdf0f788062c 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c | |||
@@ -441,7 +441,6 @@ static struct usb_device_id powermate_devices [] = { | |||
441 | MODULE_DEVICE_TABLE (usb, powermate_devices); | 441 | MODULE_DEVICE_TABLE (usb, powermate_devices); |
442 | 442 | ||
443 | static struct usb_driver powermate_driver = { | 443 | static struct usb_driver powermate_driver = { |
444 | .owner = THIS_MODULE, | ||
445 | .name = "powermate", | 444 | .name = "powermate", |
446 | .probe = powermate_probe, | 445 | .probe = powermate_probe, |
447 | .disconnect = powermate_disconnect, | 446 | .disconnect = powermate_disconnect, |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 7420c6b84284..3b3c7b4120a2 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens | 2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens |
3 | * | 3 | * |
4 | * Copyright (C) 2004 by Daniel Ritz | 4 | * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch> |
5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
@@ -41,15 +41,13 @@ | |||
41 | #define TOUCHKIT_MAX_YC 0x07ff | 41 | #define TOUCHKIT_MAX_YC 0x07ff |
42 | #define TOUCHKIT_YC_FUZZ 0x0 | 42 | #define TOUCHKIT_YC_FUZZ 0x0 |
43 | #define TOUCHKIT_YC_FLAT 0x0 | 43 | #define TOUCHKIT_YC_FLAT 0x0 |
44 | #define TOUCHKIT_REPORT_DATA_SIZE 8 | 44 | #define TOUCHKIT_REPORT_DATA_SIZE 16 |
45 | 45 | ||
46 | #define TOUCHKIT_DOWN 0x01 | 46 | #define TOUCHKIT_DOWN 0x01 |
47 | #define TOUCHKIT_POINT_TOUCH 0x81 | ||
48 | #define TOUCHKIT_POINT_NOTOUCH 0x80 | ||
49 | 47 | ||
50 | #define TOUCHKIT_GET_TOUCHED(dat) ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0) | 48 | #define TOUCHKIT_PKT_TYPE_MASK 0xFE |
51 | #define TOUCHKIT_GET_X(dat) (((dat)[3] << 7) | (dat)[4]) | 49 | #define TOUCHKIT_PKT_TYPE_REPT 0x80 |
52 | #define TOUCHKIT_GET_Y(dat) (((dat)[1] << 7) | (dat)[2]) | 50 | #define TOUCHKIT_PKT_TYPE_DIAG 0x0A |
53 | 51 | ||
54 | #define DRIVER_VERSION "v0.1" | 52 | #define DRIVER_VERSION "v0.1" |
55 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" | 53 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" |
@@ -62,6 +60,8 @@ MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); | |||
62 | struct touchkit_usb { | 60 | struct touchkit_usb { |
63 | unsigned char *data; | 61 | unsigned char *data; |
64 | dma_addr_t data_dma; | 62 | dma_addr_t data_dma; |
63 | char buffer[TOUCHKIT_REPORT_DATA_SIZE]; | ||
64 | int buf_len; | ||
65 | struct urb *irq; | 65 | struct urb *irq; |
66 | struct usb_device *udev; | 66 | struct usb_device *udev; |
67 | struct input_dev *input; | 67 | struct input_dev *input; |
@@ -77,11 +77,128 @@ static struct usb_device_id touchkit_devices[] = { | |||
77 | {} | 77 | {} |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /* helpers to read the data */ | ||
81 | static inline int touchkit_get_touched(char *data) | ||
82 | { | ||
83 | return (data[0] & TOUCHKIT_DOWN) ? 1 : 0; | ||
84 | } | ||
85 | |||
86 | static inline int touchkit_get_x(char *data) | ||
87 | { | ||
88 | return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F); | ||
89 | } | ||
90 | |||
91 | static inline int touchkit_get_y(char *data) | ||
92 | { | ||
93 | return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F); | ||
94 | } | ||
95 | |||
96 | |||
97 | /* processes one input packet. */ | ||
98 | static void touchkit_process_pkt(struct touchkit_usb *touchkit, | ||
99 | struct pt_regs *regs, char *pkt) | ||
100 | { | ||
101 | int x, y; | ||
102 | |||
103 | /* only process report packets */ | ||
104 | if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT) | ||
105 | return; | ||
106 | |||
107 | if (swap_xy) { | ||
108 | y = touchkit_get_x(pkt); | ||
109 | x = touchkit_get_y(pkt); | ||
110 | } else { | ||
111 | x = touchkit_get_x(pkt); | ||
112 | y = touchkit_get_y(pkt); | ||
113 | } | ||
114 | |||
115 | input_regs(touchkit->input, regs); | ||
116 | input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); | ||
117 | input_report_abs(touchkit->input, ABS_X, x); | ||
118 | input_report_abs(touchkit->input, ABS_Y, y); | ||
119 | input_sync(touchkit->input); | ||
120 | } | ||
121 | |||
122 | |||
123 | static int touchkit_get_pkt_len(char *buf) | ||
124 | { | ||
125 | switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) { | ||
126 | case TOUCHKIT_PKT_TYPE_REPT: | ||
127 | return 5; | ||
128 | |||
129 | case TOUCHKIT_PKT_TYPE_DIAG: | ||
130 | return buf[1] + 2; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void touchkit_process(struct touchkit_usb *touchkit, int len, | ||
137 | struct pt_regs *regs) | ||
138 | { | ||
139 | char *buffer; | ||
140 | int pkt_len, buf_len, pos; | ||
141 | |||
142 | /* if the buffer contains data, append */ | ||
143 | if (unlikely(touchkit->buf_len)) { | ||
144 | int tmp; | ||
145 | |||
146 | /* if only 1 byte in buffer, add another one to get length */ | ||
147 | if (touchkit->buf_len == 1) | ||
148 | touchkit->buffer[1] = touchkit->data[0]; | ||
149 | |||
150 | pkt_len = touchkit_get_pkt_len(touchkit->buffer); | ||
151 | |||
152 | /* unknown packet: drop everything */ | ||
153 | if (!pkt_len) | ||
154 | return; | ||
155 | |||
156 | /* append, process */ | ||
157 | tmp = pkt_len - touchkit->buf_len; | ||
158 | memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); | ||
159 | touchkit_process_pkt(touchkit, regs, touchkit->buffer); | ||
160 | |||
161 | buffer = touchkit->data + tmp; | ||
162 | buf_len = len - tmp; | ||
163 | } else { | ||
164 | buffer = touchkit->data; | ||
165 | buf_len = len; | ||
166 | } | ||
167 | |||
168 | /* only one byte left in buffer */ | ||
169 | if (unlikely(buf_len == 1)) { | ||
170 | touchkit->buffer[0] = buffer[0]; | ||
171 | touchkit->buf_len = 1; | ||
172 | return; | ||
173 | } | ||
174 | |||
175 | /* loop over the buffer */ | ||
176 | pos = 0; | ||
177 | while (pos < buf_len) { | ||
178 | /* get packet len */ | ||
179 | pkt_len = touchkit_get_pkt_len(buffer + pos); | ||
180 | |||
181 | /* unknown packet: drop everything */ | ||
182 | if (unlikely(!pkt_len)) | ||
183 | return; | ||
184 | |||
185 | /* full packet: process */ | ||
186 | if (likely(pkt_len <= buf_len)) { | ||
187 | touchkit_process_pkt(touchkit, regs, buffer + pos); | ||
188 | } else { | ||
189 | /* incomplete packet: save in buffer */ | ||
190 | memcpy(touchkit->buffer, buffer + pos, buf_len - pos); | ||
191 | touchkit->buf_len = buf_len - pos; | ||
192 | } | ||
193 | pos += pkt_len; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
80 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | 198 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) |
81 | { | 199 | { |
82 | struct touchkit_usb *touchkit = urb->context; | 200 | struct touchkit_usb *touchkit = urb->context; |
83 | int retval; | 201 | int retval; |
84 | int x, y; | ||
85 | 202 | ||
86 | switch (urb->status) { | 203 | switch (urb->status) { |
87 | case 0: | 204 | case 0: |
@@ -105,20 +222,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | |||
105 | goto exit; | 222 | goto exit; |
106 | } | 223 | } |
107 | 224 | ||
108 | if (swap_xy) { | 225 | touchkit_process(touchkit, urb->actual_length, regs); |
109 | y = TOUCHKIT_GET_X(touchkit->data); | ||
110 | x = TOUCHKIT_GET_Y(touchkit->data); | ||
111 | } else { | ||
112 | x = TOUCHKIT_GET_X(touchkit->data); | ||
113 | y = TOUCHKIT_GET_Y(touchkit->data); | ||
114 | } | ||
115 | |||
116 | input_regs(touchkit->input, regs); | ||
117 | input_report_key(touchkit->input, BTN_TOUCH, | ||
118 | TOUCHKIT_GET_TOUCHED(touchkit->data)); | ||
119 | input_report_abs(touchkit->input, ABS_X, x); | ||
120 | input_report_abs(touchkit->input, ABS_Y, y); | ||
121 | input_sync(touchkit->input); | ||
122 | 226 | ||
123 | exit: | 227 | exit: |
124 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 228 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -267,7 +371,6 @@ static void touchkit_disconnect(struct usb_interface *intf) | |||
267 | MODULE_DEVICE_TABLE(usb, touchkit_devices); | 371 | MODULE_DEVICE_TABLE(usb, touchkit_devices); |
268 | 372 | ||
269 | static struct usb_driver touchkit_driver = { | 373 | static struct usb_driver touchkit_driver = { |
270 | .owner = THIS_MODULE, | ||
271 | .name = "touchkitusb", | 374 | .name = "touchkitusb", |
272 | .probe = touchkit_probe, | 375 | .probe = touchkit_probe, |
273 | .disconnect = touchkit_disconnect, | 376 | .disconnect = touchkit_disconnect, |
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 226b6f90a907..2f3edc26cb50 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
@@ -345,7 +345,6 @@ static struct usb_device_id usb_kbd_id_table [] = { | |||
345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); | 345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); |
346 | 346 | ||
347 | static struct usb_driver usb_kbd_driver = { | 347 | static struct usb_driver usb_kbd_driver = { |
348 | .owner = THIS_MODULE, | ||
349 | .name = "usbkbd", | 348 | .name = "usbkbd", |
350 | .probe = usb_kbd_probe, | 349 | .probe = usb_kbd_probe, |
351 | .disconnect = usb_kbd_disconnect, | 350 | .disconnect = usb_kbd_disconnect, |
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 230f6b1b314a..af526135d210 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c | |||
@@ -226,7 +226,6 @@ static struct usb_device_id usb_mouse_id_table [] = { | |||
226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); | 226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); |
227 | 227 | ||
228 | static struct usb_driver usb_mouse_driver = { | 228 | static struct usb_driver usb_mouse_driver = { |
229 | .owner = THIS_MODULE, | ||
230 | .name = "usbmouse", | 229 | .name = "usbmouse", |
231 | .probe = usb_mouse_probe, | 230 | .probe = usb_mouse_probe, |
232 | .disconnect = usb_mouse_disconnect, | 231 | .disconnect = usb_mouse_disconnect, |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index dc099bbe12bf..48df4cfd5a42 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -945,7 +945,6 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
945 | } | 945 | } |
946 | 946 | ||
947 | static struct usb_driver wacom_driver = { | 947 | static struct usb_driver wacom_driver = { |
948 | .owner = THIS_MODULE, | ||
949 | .name = "wacom", | 948 | .name = "wacom", |
950 | .probe = wacom_probe, | 949 | .probe = wacom_probe, |
951 | .disconnect = wacom_disconnect, | 950 | .disconnect = wacom_disconnect, |
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 43112f040b6d..e278489a80c6 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -70,7 +70,7 @@ | |||
70 | 70 | ||
71 | #define XPAD_PKT_LEN 32 | 71 | #define XPAD_PKT_LEN 32 |
72 | 72 | ||
73 | static struct xpad_device { | 73 | static const struct xpad_device { |
74 | u16 idVendor; | 74 | u16 idVendor; |
75 | u16 idProduct; | 75 | u16 idProduct; |
76 | char *name; | 76 | char *name; |
@@ -81,13 +81,13 @@ static struct xpad_device { | |||
81 | { 0x0000, 0x0000, "X-Box pad" } | 81 | { 0x0000, 0x0000, "X-Box pad" } |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static signed short xpad_btn[] = { | 84 | static const signed short xpad_btn[] = { |
85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ | 85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ |
86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ | 86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ |
87 | -1 /* terminating entry */ | 87 | -1 /* terminating entry */ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static signed short xpad_abs[] = { | 90 | static const signed short xpad_abs[] = { |
91 | ABS_X, ABS_Y, /* left stick */ | 91 | ABS_X, ABS_Y, /* left stick */ |
92 | ABS_RX, ABS_RY, /* right stick */ | 92 | ABS_RX, ABS_RY, /* right stick */ |
93 | ABS_Z, ABS_RZ, /* triggers left/right */ | 93 | ABS_Z, ABS_RZ, /* triggers left/right */ |
@@ -316,7 +316,6 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | static struct usb_driver xpad_driver = { | 318 | static struct usb_driver xpad_driver = { |
319 | .owner = THIS_MODULE, | ||
320 | .name = "xpad", | 319 | .name = "xpad", |
321 | .probe = xpad_probe, | 320 | .probe = xpad_probe, |
322 | .disconnect = xpad_disconnect, | 321 | .disconnect = xpad_disconnect, |
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index f526aebea502..1bfc105ad4d6 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c | |||
@@ -987,7 +987,6 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
987 | } | 987 | } |
988 | 988 | ||
989 | static struct usb_driver yealink_driver = { | 989 | static struct usb_driver yealink_driver = { |
990 | .owner = THIS_MODULE, | ||
991 | .name = "yealink", | 990 | .name = "yealink", |
992 | .probe = usb_probe, | 991 | .probe = usb_probe, |
993 | .disconnect = usb_disconnect, | 992 | .disconnect = usb_disconnect, |
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 27b23c55bbc7..18d8eaf408d5 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c | |||
@@ -812,7 +812,6 @@ static struct usb_device_id dabusb_ids [] = { | |||
812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); | 812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); |
813 | 813 | ||
814 | static struct usb_driver dabusb_driver = { | 814 | static struct usb_driver dabusb_driver = { |
815 | .owner = THIS_MODULE, | ||
816 | .name = "dabusb", | 815 | .name = "dabusb", |
817 | .probe = dabusb_probe, | 816 | .probe = dabusb_probe, |
818 | .disconnect = dabusb_disconnect, | 817 | .disconnect = dabusb_disconnect, |
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index 7503f5b96f59..6a5700e9d428 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c | |||
@@ -150,7 +150,6 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table); | |||
150 | 150 | ||
151 | /* USB subsystem interface */ | 151 | /* USB subsystem interface */ |
152 | static struct usb_driver usb_dsbr100_driver = { | 152 | static struct usb_driver usb_dsbr100_driver = { |
153 | .owner = THIS_MODULE, | ||
154 | .name = "dsbr100", | 153 | .name = "dsbr100", |
155 | .probe = usb_dsbr100_probe, | 154 | .probe = usb_dsbr100_probe, |
156 | .disconnect = usb_dsbr100_disconnect, | 155 | .disconnect = usb_dsbr100_disconnect, |
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index ba41fc7b95c2..a42c22294124 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c | |||
@@ -3457,7 +3457,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) | |||
3457 | if(init_model3_input) { | 3457 | if(init_model3_input) { |
3458 | if (debug > 0) | 3458 | if (debug > 0) |
3459 | info("Setting input to RCA."); | 3459 | info("Setting input to RCA."); |
3460 | for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) { | 3460 | for (i=0; i < ARRAY_SIZE(initData); i++) { |
3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); | 3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); |
3462 | } | 3462 | } |
3463 | } | 3463 | } |
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 9fe2c2710d13..e2ede583518f 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c | |||
@@ -77,14 +77,14 @@ static int saturation = MAX_SATURATION/2; | |||
77 | static int sharpness = MAX_SHARPNESS/2; | 77 | static int sharpness = MAX_SHARPNESS/2; |
78 | static int whitebal = 3*(MAX_WHITEBAL/4); | 78 | static int whitebal = 3*(MAX_WHITEBAL/4); |
79 | 79 | ||
80 | static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; | 80 | static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; |
81 | 81 | ||
82 | /* These FPS speeds are from the windows config box. They are | 82 | /* These FPS speeds are from the windows config box. They are |
83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the | 83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the |
84 | * real fps. | 84 | * real fps. |
85 | */ | 85 | */ |
86 | 86 | ||
87 | static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, | 87 | static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, |
88 | { 24, 40, 48, 60, 72, 80, 100 }, | 88 | { 24, 40, 48, 60, 72, 80, 100 }, |
89 | { 18, 30, 36, 45, 54, 60, 75 }, | 89 | { 18, 30, 36, 45, 54, 60, 75 }, |
90 | { 6, 10, 12, 15, 18, 21, 25 } }; | 90 | { 6, 10, 12, 15, 18, 21, 25 } }; |
@@ -95,7 +95,7 @@ struct cam_size { | |||
95 | u8 cmd; | 95 | u8 cmd; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, | 98 | static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, |
99 | { 160, 136, 0xa }, | 99 | { 160, 136, 0xa }, |
100 | { 176, 144, 0x4 }, | 100 | { 176, 144, 0x4 }, |
101 | { 320, 240, 0x5 } }; | 101 | { 320, 240, 0x5 } }; |
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 036c485d1d1e..3a0e8ce67ebe 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c | |||
@@ -211,7 +211,7 @@ static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; | |||
211 | 211 | ||
212 | /* Number of times to retry a failed I2C transaction. Increase this if you | 212 | /* Number of times to retry a failed I2C transaction. Increase this if you |
213 | * are getting "Failed to read sensor ID..." */ | 213 | * are getting "Failed to read sensor ID..." */ |
214 | static int i2c_detect_tries = 5; | 214 | static const int i2c_detect_tries = 5; |
215 | 215 | ||
216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ | 216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ |
217 | #if defined(__i386__) || defined(__x86_64__) | 217 | #if defined(__i386__) || defined(__x86_64__) |
@@ -6008,7 +6008,6 @@ ov51x_disconnect(struct usb_interface *intf) | |||
6008 | } | 6008 | } |
6009 | 6009 | ||
6010 | static struct usb_driver ov511_driver = { | 6010 | static struct usb_driver ov511_driver = { |
6011 | .owner = THIS_MODULE, | ||
6012 | .name = "ov511", | 6011 | .name = "ov511", |
6013 | .id_table = device_table, | 6012 | .id_table = device_table, |
6014 | .probe = ov51x_probe, | 6013 | .probe = ov51x_probe, |
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 53099190952c..359c4b2df735 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
@@ -109,7 +109,7 @@ | |||
109 | #define PT_RESET_CONTROL_FORMATTER 0x02 | 109 | #define PT_RESET_CONTROL_FORMATTER 0x02 |
110 | #define PT_STATUS_FORMATTER 0x03 | 110 | #define PT_STATUS_FORMATTER 0x03 |
111 | 111 | ||
112 | static char *size2name[PSZ_MAX] = | 112 | static const char *size2name[PSZ_MAX] = |
113 | { | 113 | { |
114 | "subQCIF", | 114 | "subQCIF", |
115 | "QSIF", | 115 | "QSIF", |
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5524fd70210b..09ca6128ac20 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c | |||
@@ -111,7 +111,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
111 | static void usb_pwc_disconnect(struct usb_interface *intf); | 111 | static void usb_pwc_disconnect(struct usb_interface *intf); |
112 | 112 | ||
113 | static struct usb_driver pwc_driver = { | 113 | static struct usb_driver pwc_driver = { |
114 | .owner = THIS_MODULE, | ||
115 | .name = "Philips webcam", /* name */ | 114 | .name = "Philips webcam", /* name */ |
116 | .id_table = pwc_device_table, | 115 | .id_table = pwc_device_table, |
117 | .probe = usb_pwc_probe, /* probe() */ | 116 | .probe = usb_pwc_probe, /* probe() */ |
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index f69e443cd1bc..b2ae29af5940 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c | |||
@@ -1401,7 +1401,6 @@ static void se401_disconnect(struct usb_interface *intf) | |||
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | static struct usb_driver se401_driver = { | 1403 | static struct usb_driver se401_driver = { |
1404 | .owner = THIS_MODULE, | ||
1405 | .name = "se401", | 1404 | .name = "se401", |
1406 | .id_table = device_table, | 1405 | .id_table = device_table, |
1407 | .probe = se401_probe, | 1406 | .probe = se401_probe, |
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index b2e66e3b90aa..8d1a1c357d5a 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c | |||
@@ -1316,7 +1316,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1316 | struct v4l2_control ctrl; | 1316 | struct v4l2_control ctrl; |
1317 | struct v4l2_queryctrl *qctrl; | 1317 | struct v4l2_queryctrl *qctrl; |
1318 | struct v4l2_rect* rect; | 1318 | struct v4l2_rect* rect; |
1319 | u8 i = 0, n = 0; | 1319 | u8 i = 0; |
1320 | int err = 0; | 1320 | int err = 0; |
1321 | 1321 | ||
1322 | if (!(cam->state & DEV_INITIALIZED)) { | 1322 | if (!(cam->state & DEV_INITIALIZED)) { |
@@ -1352,7 +1352,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1352 | return err; | 1352 | return err; |
1353 | 1353 | ||
1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) | 1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) |
1355 | DBG(3, "Compressed video format is active, quality %d", | 1355 | DBG(3, "Compressed video format is active, quality %d", |
1356 | cam->compression.quality) | 1356 | cam->compression.quality) |
1357 | else | 1357 | else |
1358 | DBG(3, "Uncompressed video format is active") | 1358 | DBG(3, "Uncompressed video format is active") |
@@ -1364,9 +1364,8 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | if (s->set_ctrl) { | 1366 | if (s->set_ctrl) { |
1367 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1367 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1368 | for (i = 0; i < n; i++) | 1368 | if (s->qctrl[i].id != 0 && |
1369 | if (s->qctrl[i].id != 0 && | ||
1370 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { | 1369 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { |
1371 | ctrl.id = s->qctrl[i].id; | 1370 | ctrl.id = s->qctrl[i].id; |
1372 | ctrl.value = qctrl[i].default_value; | 1371 | ctrl.value = qctrl[i].default_value; |
@@ -1388,7 +1387,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1388 | init_waitqueue_head(&cam->wait_stream); | 1387 | init_waitqueue_head(&cam->wait_stream); |
1389 | cam->nreadbuffers = 2; | 1388 | cam->nreadbuffers = 2; |
1390 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); | 1389 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); |
1391 | memcpy(&(s->_rect), &(s->cropcap.defrect), | 1390 | memcpy(&(s->_rect), &(s->cropcap.defrect), |
1392 | sizeof(struct v4l2_rect)); | 1391 | sizeof(struct v4l2_rect)); |
1393 | cam->state |= DEV_INITIALIZED; | 1392 | cam->state |= DEV_INITIALIZED; |
1394 | } | 1393 | } |
@@ -1810,13 +1809,12 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1810 | { | 1809 | { |
1811 | struct sn9c102_sensor* s = cam->sensor; | 1810 | struct sn9c102_sensor* s = cam->sensor; |
1812 | struct v4l2_queryctrl qc; | 1811 | struct v4l2_queryctrl qc; |
1813 | u8 i, n; | 1812 | u8 i; |
1814 | 1813 | ||
1815 | if (copy_from_user(&qc, arg, sizeof(qc))) | 1814 | if (copy_from_user(&qc, arg, sizeof(qc))) |
1816 | return -EFAULT; | 1815 | return -EFAULT; |
1817 | 1816 | ||
1818 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1817 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1819 | for (i = 0; i < n; i++) | ||
1820 | if (qc.id && qc.id == s->qctrl[i].id) { | 1818 | if (qc.id && qc.id == s->qctrl[i].id) { |
1821 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); | 1819 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); |
1822 | if (copy_to_user(arg, &qc, sizeof(qc))) | 1820 | if (copy_to_user(arg, &qc, sizeof(qc))) |
@@ -1852,7 +1850,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1852 | { | 1850 | { |
1853 | struct sn9c102_sensor* s = cam->sensor; | 1851 | struct sn9c102_sensor* s = cam->sensor; |
1854 | struct v4l2_control ctrl; | 1852 | struct v4l2_control ctrl; |
1855 | u8 i, n; | 1853 | u8 i; |
1856 | int err = 0; | 1854 | int err = 0; |
1857 | 1855 | ||
1858 | if (!s->set_ctrl) | 1856 | if (!s->set_ctrl) |
@@ -1861,8 +1859,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1861 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 1859 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
1862 | return -EFAULT; | 1860 | return -EFAULT; |
1863 | 1861 | ||
1864 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1862 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1865 | for (i = 0; i < n; i++) | ||
1866 | if (ctrl.id == s->qctrl[i].id) { | 1863 | if (ctrl.id == s->qctrl[i].id) { |
1867 | if (ctrl.value < s->qctrl[i].minimum || | 1864 | if (ctrl.value < s->qctrl[i].minimum || |
1868 | ctrl.value > s->qctrl[i].maximum) | 1865 | ctrl.value > s->qctrl[i].maximum) |
@@ -2544,7 +2541,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2544 | unsigned int i, n; | 2541 | unsigned int i, n; |
2545 | int err = 0, r; | 2542 | int err = 0, r; |
2546 | 2543 | ||
2547 | n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]); | 2544 | n = ARRAY_SIZE(sn9c102_id_table); |
2548 | for (i = 0; i < n-1; i++) | 2545 | for (i = 0; i < n-1; i++) |
2549 | if (le16_to_cpu(udev->descriptor.idVendor) == | 2546 | if (le16_to_cpu(udev->descriptor.idVendor) == |
2550 | sn9c102_id_table[i].idVendor && | 2547 | sn9c102_id_table[i].idVendor && |
@@ -2711,7 +2708,6 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) | |||
2711 | 2708 | ||
2712 | 2709 | ||
2713 | static struct usb_driver sn9c102_usb_driver = { | 2710 | static struct usb_driver sn9c102_usb_driver = { |
2714 | .owner = THIS_MODULE, | ||
2715 | .name = "sn9c102", | 2711 | .name = "sn9c102", |
2716 | .id_table = sn9c102_id_table, | 2712 | .id_table = sn9c102_id_table, |
2717 | .probe = sn9c102_usb_probe, | 2713 | .probe = sn9c102_usb_probe, |
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 0fd0fa9fec21..774038b352cd 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c | |||
@@ -1477,7 +1477,6 @@ static void stv680_disconnect (struct usb_interface *intf) | |||
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | static struct usb_driver stv680_driver = { | 1479 | static struct usb_driver stv680_driver = { |
1480 | .owner = THIS_MODULE, | ||
1481 | .name = "stv680", | 1480 | .name = "stv680", |
1482 | .probe = stv680_probe, | 1481 | .probe = stv680_probe, |
1483 | .disconnect = stv680_disconnect, | 1482 | .disconnect = stv680_disconnect, |
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h index 445940612603..b0551cdb280b 100644 --- a/drivers/usb/media/stv680.h +++ b/drivers/usb/media/stv680.h | |||
@@ -151,7 +151,7 @@ struct usb_stv { | |||
151 | }; | 151 | }; |
152 | 152 | ||
153 | 153 | ||
154 | static unsigned char red[256] = { | 154 | static const unsigned char red[256] = { |
155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | 155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, |
156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, | 156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, |
157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, | 157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, |
@@ -176,7 +176,7 @@ static unsigned char red[256] = { | |||
176 | 220, 220, 221, 221 | 176 | 220, 220, 221, 221 |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static unsigned char green[256] = { | 179 | static const unsigned char green[256] = { |
180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, | 180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, |
181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, | 181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, |
182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, | 182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, |
@@ -201,7 +201,7 @@ static unsigned char green[256] = { | |||
201 | 245, 245, 246, 246 | 201 | 245, 245, 246, 246 |
202 | }; | 202 | }; |
203 | 203 | ||
204 | static unsigned char blue[256] = { | 204 | static const unsigned char blue[256] = { |
205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, | 205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, |
206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, | 206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, |
207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, | 207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, |
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 24efb21969c6..4bd113325ef9 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c | |||
@@ -725,7 +725,7 @@ int usbvideo_register( | |||
725 | /* Allocate user_data separately because of kmalloc's limits */ | 725 | /* Allocate user_data separately because of kmalloc's limits */ |
726 | if (num_extra > 0) { | 726 | if (num_extra > 0) { |
727 | up->user_size = num_cams * num_extra; | 727 | up->user_size = num_cams * num_extra; |
728 | up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL); | 728 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); |
729 | if (up->user_data == NULL) { | 729 | if (up->user_data == NULL) { |
730 | err("%s: Failed to allocate user_data (%d. bytes)", | 730 | err("%s: Failed to allocate user_data (%d. bytes)", |
731 | __FUNCTION__, up->user_size); | 731 | __FUNCTION__, up->user_size); |
@@ -955,7 +955,7 @@ static struct file_operations usbvideo_fops = { | |||
955 | .ioctl = usbvideo_v4l_ioctl, | 955 | .ioctl = usbvideo_v4l_ioctl, |
956 | .llseek = no_llseek, | 956 | .llseek = no_llseek, |
957 | }; | 957 | }; |
958 | static struct video_device usbvideo_template = { | 958 | static const struct video_device usbvideo_template = { |
959 | .owner = THIS_MODULE, | 959 | .owner = THIS_MODULE, |
960 | .type = VID_TYPE_CAPTURE, | 960 | .type = VID_TYPE_CAPTURE, |
961 | .hardware = VID_HARDWARE_CPIA, | 961 | .hardware = VID_HARDWARE_CPIA, |
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 0bc0b1247a6b..1c73155c8d77 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c | |||
@@ -1257,7 +1257,6 @@ static struct usb_device_id vicam_table[] = { | |||
1257 | MODULE_DEVICE_TABLE(usb, vicam_table); | 1257 | MODULE_DEVICE_TABLE(usb, vicam_table); |
1258 | 1258 | ||
1259 | static struct usb_driver vicam_driver = { | 1259 | static struct usb_driver vicam_driver = { |
1260 | .owner = THIS_MODULE, | ||
1261 | .name = "vicam", | 1260 | .name = "vicam", |
1262 | .probe = vicam_probe, | 1261 | .probe = vicam_probe, |
1263 | .disconnect = vicam_disconnect, | 1262 | .disconnect = vicam_disconnect, |
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 67612c81cb9f..3605a6f3067b 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c | |||
@@ -1533,12 +1533,12 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client) | |||
1533 | } | 1533 | } |
1534 | } else { | 1534 | } else { |
1535 | DBG(4, "Rejected client [%s] with driver [%s]", | 1535 | DBG(4, "Rejected client [%s] with driver [%s]", |
1536 | client->name, client->driver->name) | 1536 | client->name, client->driver->driver.name) |
1537 | return -EINVAL; | 1537 | return -EINVAL; |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | DBG(5, "I2C attach client [%s] with driver [%s]", | 1540 | DBG(5, "I2C attach client [%s] with driver [%s]", |
1541 | client->name, client->driver->name) | 1541 | client->name, client->driver->driver.name) |
1542 | 1542 | ||
1543 | return 0; | 1543 | return 0; |
1544 | } | 1544 | } |
@@ -2958,7 +2958,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, | |||
2958 | }; | 2958 | }; |
2959 | 2959 | ||
2960 | #define V4L1_IOCTL(cmd) \ | 2960 | #define V4L1_IOCTL(cmd) \ |
2961 | ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \ | 2961 | ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \ |
2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") | 2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") |
2963 | 2963 | ||
2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); | 2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); |
@@ -3554,7 +3554,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3554 | 3554 | ||
3555 | 3555 | ||
3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ | 3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ |
3557 | if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) { | 3557 | if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) { |
3558 | DBG(1,"Couldn't allocate memory for camera control transfers") | 3558 | DBG(1,"Couldn't allocate memory for camera control transfers") |
3559 | err = -ENOMEM; | 3559 | err = -ENOMEM; |
3560 | goto fail; | 3560 | goto fail; |
@@ -3562,7 +3562,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3562 | memset(cam->control_buffer, 0, 2); | 3562 | memset(cam->control_buffer, 0, 2); |
3563 | 3563 | ||
3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ | 3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ |
3565 | if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) { | 3565 | if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) { |
3566 | DBG(1, "Couldn't allocate memory for data " | 3566 | DBG(1, "Couldn't allocate memory for data " |
3567 | "transfers to the FSB") | 3567 | "transfers to the FSB") |
3568 | err = -ENOMEM; | 3568 | err = -ENOMEM; |
@@ -3668,7 +3668,6 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) | |||
3668 | 3668 | ||
3669 | 3669 | ||
3670 | static struct usb_driver w9968cf_usb_driver = { | 3670 | static struct usb_driver w9968cf_usb_driver = { |
3671 | .owner = THIS_MODULE, | ||
3672 | .name = "w9968cf", | 3671 | .name = "w9968cf", |
3673 | .id_table = winbond_id_table, | 3672 | .id_table = winbond_id_table, |
3674 | .probe = w9968cf_usb_probe, | 3673 | .probe = w9968cf_usb_probe, |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index b293db3c28c3..449b2501acf3 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -767,7 +767,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned | |||
767 | memset (bep, 0, sizeof (auerbuf_t)); | 767 | memset (bep, 0, sizeof (auerbuf_t)); |
768 | bep->list = bcp; | 768 | bep->list = bcp; |
769 | INIT_LIST_HEAD (&bep->buff_list); | 769 | INIT_LIST_HEAD (&bep->buff_list); |
770 | bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL); | 770 | bep->bufp = kmalloc (bufsize, GFP_KERNEL); |
771 | if (!bep->bufp) | 771 | if (!bep->bufp) |
772 | goto bl_fail; | 772 | goto bl_fail; |
773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); | 773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); |
@@ -1123,7 +1123,7 @@ static int auerswald_int_open (pauerswald_t cp) | |||
1123 | } | 1123 | } |
1124 | } | 1124 | } |
1125 | if (!cp->intbufp) { | 1125 | if (!cp->intbufp) { |
1126 | cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL); | 1126 | cp->intbufp = kmalloc (irqsize, GFP_KERNEL); |
1127 | if (!cp->intbufp) { | 1127 | if (!cp->intbufp) { |
1128 | ret = -ENOMEM; | 1128 | ret = -ENOMEM; |
1129 | goto intoend; | 1129 | goto intoend; |
@@ -2103,7 +2103,6 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids); | |||
2103 | 2103 | ||
2104 | /* Standard usb driver struct */ | 2104 | /* Standard usb driver struct */ |
2105 | static struct usb_driver auerswald_driver = { | 2105 | static struct usb_driver auerswald_driver = { |
2106 | .owner = THIS_MODULE, | ||
2107 | .name = "auerswald", | 2106 | .name = "auerswald", |
2108 | .probe = auerswald_probe, | 2107 | .probe = auerswald_probe, |
2109 | .disconnect = auerswald_disconnect, | 2108 | .disconnect = auerswald_disconnect, |
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index b33044d56a1e..6671317b495f 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
@@ -50,7 +50,6 @@ static void cytherm_disconnect(struct usb_interface *interface); | |||
50 | 50 | ||
51 | /* usb specific object needed to register this driver with the usb subsystem */ | 51 | /* usb specific object needed to register this driver with the usb subsystem */ |
52 | static struct usb_driver cytherm_driver = { | 52 | static struct usb_driver cytherm_driver = { |
53 | .owner = THIS_MODULE, | ||
54 | .name = "cytherm", | 53 | .name = "cytherm", |
55 | .probe = cytherm_probe, | 54 | .probe = cytherm_probe, |
56 | .disconnect = cytherm_disconnect, | 55 | .disconnect = cytherm_disconnect, |
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index c8155209bf4b..3824df33094e 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c | |||
@@ -227,7 +227,6 @@ static void emi26_disconnect(struct usb_interface *intf) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | static struct usb_driver emi26_driver = { | 229 | static struct usb_driver emi26_driver = { |
230 | .owner = THIS_MODULE, | ||
231 | .name = "emi26 - firmware loader", | 230 | .name = "emi26 - firmware loader", |
232 | .probe = emi26_probe, | 231 | .probe = emi26_probe, |
233 | .disconnect = emi26_disconnect, | 232 | .disconnect = emi26_disconnect, |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 189986af2ac7..52fea2e08db8 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -266,7 +266,6 @@ static void emi62_disconnect(struct usb_interface *intf) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | static struct usb_driver emi62_driver = { | 268 | static struct usb_driver emi62_driver = { |
269 | .owner = THIS_MODULE, | ||
270 | .name = "emi62 - firmware loader", | 269 | .name = "emi62 - firmware loader", |
271 | .probe = emi62_probe, | 270 | .probe = emi62_probe, |
272 | .disconnect = emi62_disconnect, | 271 | .disconnect = emi62_disconnect, |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 1dc3e0f73014..d8cde1017985 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -114,7 +114,6 @@ static struct usb_class_driver idmouse_class = { | |||
114 | 114 | ||
115 | /* usb specific object needed to register this driver with the usb subsystem */ | 115 | /* usb specific object needed to register this driver with the usb subsystem */ |
116 | static struct usb_driver idmouse_driver = { | 116 | static struct usb_driver idmouse_driver = { |
117 | .owner = THIS_MODULE, | ||
118 | .name = DRIVER_SHORT, | 117 | .name = DRIVER_SHORT, |
119 | .probe = idmouse_probe, | 118 | .probe = idmouse_probe, |
120 | .disconnect = idmouse_disconnect, | 119 | .disconnect = idmouse_disconnect, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7e93ac96490f..981d8a5fbfd9 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -763,7 +763,6 @@ static void ld_usb_disconnect(struct usb_interface *intf) | |||
763 | 763 | ||
764 | /* usb specific object needed to register this driver with the usb subsystem */ | 764 | /* usb specific object needed to register this driver with the usb subsystem */ |
765 | static struct usb_driver ld_usb_driver = { | 765 | static struct usb_driver ld_usb_driver = { |
766 | .owner = THIS_MODULE, | ||
767 | .name = "ldusb", | 766 | .name = "ldusb", |
768 | .probe = ld_usb_probe, | 767 | .probe = ld_usb_probe, |
769 | .disconnect = ld_usb_disconnect, | 768 | .disconnect = ld_usb_disconnect, |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 2703e205bc8f..1336745b8f55 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -282,7 +282,6 @@ static struct usb_class_driver tower_class = { | |||
282 | 282 | ||
283 | /* usb specific object needed to register this driver with the usb subsystem */ | 283 | /* usb specific object needed to register this driver with the usb subsystem */ |
284 | static struct usb_driver tower_driver = { | 284 | static struct usb_driver tower_driver = { |
285 | .owner = THIS_MODULE, | ||
286 | .name = "legousbtower", | 285 | .name = "legousbtower", |
287 | .probe = tower_probe, | 286 | .probe = tower_probe, |
288 | .disconnect = tower_disconnect, | 287 | .disconnect = tower_disconnect, |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 067a81486921..605a3c87e05c 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -555,7 +555,6 @@ static void interfacekit_disconnect(struct usb_interface *interface) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | static struct usb_driver interfacekit_driver = { | 557 | static struct usb_driver interfacekit_driver = { |
558 | .owner = THIS_MODULE, | ||
559 | .name = "phidgetkit", | 558 | .name = "phidgetkit", |
560 | .probe = interfacekit_probe, | 559 | .probe = interfacekit_probe, |
561 | .disconnect = interfacekit_disconnect, | 560 | .disconnect = interfacekit_disconnect, |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index a30d4a6ee824..b3418d2bcc69 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -306,7 +306,6 @@ servo_disconnect(struct usb_interface *interface) | |||
306 | } | 306 | } |
307 | 307 | ||
308 | static struct usb_driver servo_driver = { | 308 | static struct usb_driver servo_driver = { |
309 | .owner = THIS_MODULE, | ||
310 | .name = "phidgetservo", | 309 | .name = "phidgetservo", |
311 | .probe = servo_probe, | 310 | .probe = servo_probe, |
312 | .disconnect = servo_disconnect, | 311 | .disconnect = servo_disconnect, |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 9590dbac5d9a..384fa3769805 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -465,14 +465,14 @@ static int probe_rio(struct usb_interface *intf, | |||
465 | 465 | ||
466 | rio->rio_dev = dev; | 466 | rio->rio_dev = dev; |
467 | 467 | ||
468 | if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { | 468 | if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { |
469 | err("probe_rio: Not enough memory for the output buffer"); | 469 | err("probe_rio: Not enough memory for the output buffer"); |
470 | usb_deregister_dev(intf, &usb_rio_class); | 470 | usb_deregister_dev(intf, &usb_rio_class); |
471 | return -ENOMEM; | 471 | return -ENOMEM; |
472 | } | 472 | } |
473 | dbg("probe_rio: obuf address:%p", rio->obuf); | 473 | dbg("probe_rio: obuf address:%p", rio->obuf); |
474 | 474 | ||
475 | if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { | 475 | if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { |
476 | err("probe_rio: Not enough memory for the input buffer"); | 476 | err("probe_rio: Not enough memory for the input buffer"); |
477 | usb_deregister_dev(intf, &usb_rio_class); | 477 | usb_deregister_dev(intf, &usb_rio_class); |
478 | kfree(rio->obuf); | 478 | kfree(rio->obuf); |
@@ -522,7 +522,6 @@ static struct usb_device_id rio_table [] = { | |||
522 | MODULE_DEVICE_TABLE (usb, rio_table); | 522 | MODULE_DEVICE_TABLE (usb, rio_table); |
523 | 523 | ||
524 | static struct usb_driver rio_driver = { | 524 | static struct usb_driver rio_driver = { |
525 | .owner = THIS_MODULE, | ||
526 | .name = "rio500", | 525 | .name = "rio500", |
527 | .probe = probe_rio, | 526 | .probe = probe_rio, |
528 | .disconnect = disconnect_rio, | 527 | .disconnect = disconnect_rio, |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 41ef2b606751..3260d595441f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -863,9 +863,6 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
863 | 863 | ||
864 | switch (length) { | 864 | switch (length) { |
865 | 865 | ||
866 | case 0: | ||
867 | return ret; | ||
868 | |||
869 | case 1: | 866 | case 1: |
870 | if (userbuffer) { | 867 | if (userbuffer) { |
871 | if (get_user(swap8, (u8 __user *)userbuffer)) | 868 | if (get_user(swap8, (u8 __user *)userbuffer)) |
@@ -1221,9 +1218,6 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1221 | 1218 | ||
1222 | switch (length) { | 1219 | switch (length) { |
1223 | 1220 | ||
1224 | case 0: | ||
1225 | return ret; | ||
1226 | |||
1227 | case 1: | 1221 | case 1: |
1228 | 1222 | ||
1229 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, | 1223 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, |
@@ -2443,8 +2437,8 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2443 | u8 *tempbuf; | 2437 | u8 *tempbuf; |
2444 | u16 *tempbufb; | 2438 | u16 *tempbufb; |
2445 | size_t written; | 2439 | size_t written; |
2446 | static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; | 2440 | static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; |
2447 | static char bootlogo[] = "(o_ //\\ V_/_"; | 2441 | static const char bootlogo[] = "(o_ //\\ V_/_"; |
2448 | 2442 | ||
2449 | /* sisusb->lock is down */ | 2443 | /* sisusb->lock is down */ |
2450 | 2444 | ||
@@ -3489,7 +3483,6 @@ static struct usb_device_id sisusb_table [] = { | |||
3489 | MODULE_DEVICE_TABLE (usb, sisusb_table); | 3483 | MODULE_DEVICE_TABLE (usb, sisusb_table); |
3490 | 3484 | ||
3491 | static struct usb_driver sisusb_driver = { | 3485 | static struct usb_driver sisusb_driver = { |
3492 | .owner = THIS_MODULE, | ||
3493 | .name = "sisusb", | 3486 | .name = "sisusb", |
3494 | .probe = sisusb_probe, | 3487 | .probe = sisusb_probe, |
3495 | .disconnect = sisusb_disconnect, | 3488 | .disconnect = sisusb_disconnect, |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 85f3725334b0..cc3dae3f34e0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -371,7 +371,6 @@ static void lcd_disconnect(struct usb_interface *interface) | |||
371 | } | 371 | } |
372 | 372 | ||
373 | static struct usb_driver lcd_driver = { | 373 | static struct usb_driver lcd_driver = { |
374 | .owner = THIS_MODULE, | ||
375 | .name = "usblcd", | 374 | .name = "usblcd", |
376 | .probe = lcd_probe, | 375 | .probe = lcd_probe, |
377 | .disconnect = lcd_disconnect, | 376 | .disconnect = lcd_disconnect, |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 3c93921cb6b3..877b081a3a6e 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -148,7 +148,6 @@ static void led_disconnect(struct usb_interface *interface) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | static struct usb_driver led_driver = { | 150 | static struct usb_driver led_driver = { |
151 | .owner = THIS_MODULE, | ||
152 | .name = "usbled", | 151 | .name = "usbled", |
153 | .probe = led_probe, | 152 | .probe = led_probe, |
154 | .disconnect = led_disconnect, | 153 | .disconnect = led_disconnect, |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 605a2afe34ed..84fa1728f052 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -2134,7 +2134,6 @@ static struct usb_device_id id_table [] = { | |||
2134 | MODULE_DEVICE_TABLE (usb, id_table); | 2134 | MODULE_DEVICE_TABLE (usb, id_table); |
2135 | 2135 | ||
2136 | static struct usb_driver usbtest_driver = { | 2136 | static struct usb_driver usbtest_driver = { |
2137 | .owner = THIS_MODULE, | ||
2138 | .name = "usbtest", | 2137 | .name = "usbtest", |
2139 | .id_table = id_table, | 2138 | .id_table = id_table, |
2140 | .probe = usbtest_probe, | 2139 | .probe = usbtest_probe, |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 1cabe7ed91f5..4081990b7d1a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -780,7 +780,6 @@ MODULE_DEVICE_TABLE (usb, uss720_table); | |||
780 | 780 | ||
781 | 781 | ||
782 | static struct usb_driver uss720_driver = { | 782 | static struct usb_driver uss720_driver = { |
783 | .owner = THIS_MODULE, | ||
784 | .name = "uss720", | 783 | .name = "uss720", |
785 | .probe = uss720_probe, | 784 | .probe = uss720_probe, |
786 | .disconnect = uss720_disconnect, | 785 | .disconnect = uss720_disconnect, |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 17d0190ef64e..611612146ae9 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -97,19 +97,12 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
97 | if (len >= DATA_MAX) | 97 | if (len >= DATA_MAX) |
98 | len = DATA_MAX; | 98 | len = DATA_MAX; |
99 | 99 | ||
100 | /* | 100 | if (usb_pipein(pipe)) { |
101 | * Bulk is easy to shortcut reliably. | 101 | if (ev_type == 'S') |
102 | * XXX Other pipe types need consideration. Currently, we overdo it | 102 | return '<'; |
103 | * and collect garbage for them: better more than less. | 103 | } else { |
104 | */ | 104 | if (ev_type == 'C') |
105 | if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) { | 105 | return '>'; |
106 | if (usb_pipein(pipe)) { | ||
107 | if (ev_type == 'S') | ||
108 | return '<'; | ||
109 | } else { | ||
110 | if (ev_type == 'C') | ||
111 | return '>'; | ||
112 | } | ||
113 | } | 106 | } |
114 | 107 | ||
115 | /* | 108 | /* |
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 542120ef1fd2..541181695040 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -912,13 +912,16 @@ static const struct usb_device_id products [] = { | |||
912 | // ASIX AX88772 10/100 | 912 | // ASIX AX88772 10/100 |
913 | USB_DEVICE (0x0b95, 0x7720), | 913 | USB_DEVICE (0x0b95, 0x7720), |
914 | .driver_info = (unsigned long) &ax88772_info, | 914 | .driver_info = (unsigned long) &ax88772_info, |
915 | }, { | ||
916 | // Linksys USB200M Rev 2 | ||
917 | USB_DEVICE (0x13b1, 0x0018), | ||
918 | .driver_info = (unsigned long) &ax88772_info, | ||
915 | }, | 919 | }, |
916 | { }, // END | 920 | { }, // END |
917 | }; | 921 | }; |
918 | MODULE_DEVICE_TABLE(usb, products); | 922 | MODULE_DEVICE_TABLE(usb, products); |
919 | 923 | ||
920 | static struct usb_driver asix_driver = { | 924 | static struct usb_driver asix_driver = { |
921 | .owner = THIS_MODULE, | ||
922 | .name = "asix", | 925 | .name = "asix", |
923 | .id_table = products, | 926 | .id_table = products, |
924 | .probe = usbnet_probe, | 927 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 37ef365a2472..be5f5e142dd0 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c | |||
@@ -934,7 +934,6 @@ static struct usb_device_id catc_id_table [] = { | |||
934 | MODULE_DEVICE_TABLE(usb, catc_id_table); | 934 | MODULE_DEVICE_TABLE(usb, catc_id_table); |
935 | 935 | ||
936 | static struct usb_driver catc_driver = { | 936 | static struct usb_driver catc_driver = { |
937 | .owner = THIS_MODULE, | ||
938 | .name = driver_name, | 937 | .name = driver_name, |
939 | .probe = catc_probe, | 938 | .probe = catc_probe, |
940 | .disconnect = catc_disconnect, | 939 | .disconnect = catc_disconnect, |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index c008c981862b..63f1f3ba8e0b 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -476,7 +476,6 @@ static const struct usb_device_id products [] = { | |||
476 | MODULE_DEVICE_TABLE(usb, products); | 476 | MODULE_DEVICE_TABLE(usb, products); |
477 | 477 | ||
478 | static struct usb_driver cdc_driver = { | 478 | static struct usb_driver cdc_driver = { |
479 | .owner = THIS_MODULE, | ||
480 | .name = "cdc_ether", | 479 | .name = "cdc_ether", |
481 | .id_table = products, | 480 | .id_table = products, |
482 | .probe = usbnet_probe, | 481 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c index f05cfb83c82d..ec801e8bb1bb 100644 --- a/drivers/usb/net/cdc_subset.c +++ b/drivers/usb/net/cdc_subset.c | |||
@@ -306,7 +306,6 @@ MODULE_DEVICE_TABLE(usb, products); | |||
306 | /*-------------------------------------------------------------------------*/ | 306 | /*-------------------------------------------------------------------------*/ |
307 | 307 | ||
308 | static struct usb_driver cdc_subset_driver = { | 308 | static struct usb_driver cdc_subset_driver = { |
309 | .owner = THIS_MODULE, | ||
310 | .name = "cdc_subset", | 309 | .name = "cdc_subset", |
311 | .probe = usbnet_probe, | 310 | .probe = usbnet_probe, |
312 | .suspend = usbnet_suspend, | 311 | .suspend = usbnet_suspend, |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index 2455e9a85674..faf1e86be687 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
@@ -377,7 +377,6 @@ static const struct usb_device_id products [] = { | |||
377 | MODULE_DEVICE_TABLE(usb, products); | 377 | MODULE_DEVICE_TABLE(usb, products); |
378 | 378 | ||
379 | static struct usb_driver gl620a_driver = { | 379 | static struct usb_driver gl620a_driver = { |
380 | .owner = THIS_MODULE, | ||
381 | .name = "gl620a", | 380 | .name = "gl620a", |
382 | .id_table = products, | 381 | .id_table = products, |
383 | .probe = usbnet_probe, | 382 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index b5776518020f..def3bb8e2290 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -175,7 +175,6 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table); | |||
175 | * kaweth_driver | 175 | * kaweth_driver |
176 | ****************************************************************/ | 176 | ****************************************************************/ |
177 | static struct usb_driver kaweth_driver = { | 177 | static struct usb_driver kaweth_driver = { |
178 | .owner = THIS_MODULE, | ||
179 | .name = driver_name, | 178 | .name = driver_name, |
180 | .probe = kaweth_probe, | 179 | .probe = kaweth_probe, |
181 | .disconnect = kaweth_disconnect, | 180 | .disconnect = kaweth_disconnect, |
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c index b3799b1a2b0d..78e6a43b1087 100644 --- a/drivers/usb/net/net1080.c +++ b/drivers/usb/net/net1080.c | |||
@@ -593,7 +593,6 @@ static const struct usb_device_id products [] = { | |||
593 | MODULE_DEVICE_TABLE(usb, products); | 593 | MODULE_DEVICE_TABLE(usb, products); |
594 | 594 | ||
595 | static struct usb_driver net1080_driver = { | 595 | static struct usb_driver net1080_driver = { |
596 | .owner = THIS_MODULE, | ||
597 | .name = "net1080", | 596 | .name = "net1080", |
598 | .id_table = products, | 597 | .id_table = products, |
599 | .probe = usbnet_probe, | 598 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 683e3df5d607..156a2f1cb39a 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -45,7 +45,7 @@ | |||
45 | /* | 45 | /* |
46 | * Version Information | 46 | * Version Information |
47 | */ | 47 | */ |
48 | #define DRIVER_VERSION "v0.6.12 (2005/01/13)" | 48 | #define DRIVER_VERSION "v0.6.13 (2005/11/13)" |
49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" | 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" |
50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" | 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" |
51 | 51 | ||
@@ -57,12 +57,14 @@ static const char driver_name[] = "pegasus"; | |||
57 | 57 | ||
58 | static int loopback = 0; | 58 | static int loopback = 0; |
59 | static int mii_mode = 0; | 59 | static int mii_mode = 0; |
60 | static char *devid=NULL; | ||
60 | 61 | ||
61 | static struct usb_eth_dev usb_dev_id[] = { | 62 | static struct usb_eth_dev usb_dev_id[] = { |
62 | #define PEGASUS_DEV(pn, vid, pid, flags) \ | 63 | #define PEGASUS_DEV(pn, vid, pid, flags) \ |
63 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, | 64 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, |
64 | #include "pegasus.h" | 65 | #include "pegasus.h" |
65 | #undef PEGASUS_DEV | 66 | #undef PEGASUS_DEV |
67 | {NULL, 0, 0, 0}, | ||
66 | {NULL, 0, 0, 0} | 68 | {NULL, 0, 0, 0} |
67 | }; | 69 | }; |
68 | 70 | ||
@@ -71,6 +73,7 @@ static struct usb_device_id pegasus_ids[] = { | |||
71 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, | 73 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, |
72 | #include "pegasus.h" | 74 | #include "pegasus.h" |
73 | #undef PEGASUS_DEV | 75 | #undef PEGASUS_DEV |
76 | {}, | ||
74 | {} | 77 | {} |
75 | }; | 78 | }; |
76 | 79 | ||
@@ -79,8 +82,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
79 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
80 | module_param(loopback, bool, 0); | 83 | module_param(loopback, bool, 0); |
81 | module_param(mii_mode, bool, 0); | 84 | module_param(mii_mode, bool, 0); |
85 | module_param(devid, charp, 0); | ||
82 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); | 86 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); |
83 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); | 87 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); |
88 | MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'"); | ||
84 | 89 | ||
85 | /* use ethtool to change the level for any given device */ | 90 | /* use ethtool to change the level for any given device */ |
86 | static int msg_level = -1; | 91 | static int msg_level = -1; |
@@ -113,7 +118,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
113 | break; | 118 | break; |
114 | default: | 119 | default: |
115 | if (netif_msg_drv(pegasus)) | 120 | if (netif_msg_drv(pegasus)) |
116 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 121 | dev_dbg(&pegasus->intf->dev, "%s, status %d\n", |
117 | __FUNCTION__, urb->status); | 122 | __FUNCTION__, urb->status); |
118 | } | 123 | } |
119 | pegasus->flags &= ~ETH_REGS_CHANGED; | 124 | pegasus->flags &= ~ETH_REGS_CHANGED; |
@@ -308,9 +313,9 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
308 | __le16 regdi; | 313 | __le16 regdi; |
309 | int ret; | 314 | int ret; |
310 | 315 | ||
311 | ret = set_register(pegasus, PhyCtrl, 0); | 316 | set_register(pegasus, PhyCtrl, 0); |
312 | ret = set_registers(pegasus, PhyAddr, sizeof (data), data); | 317 | set_registers(pegasus, PhyAddr, sizeof (data), data); |
313 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ)); | 318 | set_register(pegasus, PhyCtrl, (indx | PHY_READ)); |
314 | for (i = 0; i < REG_TIMEOUT; i++) { | 319 | for (i = 0; i < REG_TIMEOUT; i++) { |
315 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 320 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
316 | if (data[0] & PHY_DONE) | 321 | if (data[0] & PHY_DONE) |
@@ -319,12 +324,12 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
319 | if (i < REG_TIMEOUT) { | 324 | if (i < REG_TIMEOUT) { |
320 | ret = get_registers(pegasus, PhyData, 2, ®di); | 325 | ret = get_registers(pegasus, PhyData, 2, ®di); |
321 | *regd = le16_to_cpu(regdi); | 326 | *regd = le16_to_cpu(regdi); |
322 | return 1; | 327 | return ret; |
323 | } | 328 | } |
324 | if (netif_msg_drv(pegasus)) | 329 | if (netif_msg_drv(pegasus)) |
325 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 330 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
326 | 331 | ||
327 | return 0; | 332 | return ret; |
328 | } | 333 | } |
329 | 334 | ||
330 | static int mdio_read(struct net_device *dev, int phy_id, int loc) | 335 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
@@ -344,20 +349,20 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) | |||
344 | 349 | ||
345 | data[1] = (u8) regd; | 350 | data[1] = (u8) regd; |
346 | data[2] = (u8) (regd >> 8); | 351 | data[2] = (u8) (regd >> 8); |
347 | ret = set_register(pegasus, PhyCtrl, 0); | 352 | set_register(pegasus, PhyCtrl, 0); |
348 | ret = set_registers(pegasus, PhyAddr, sizeof(data), data); | 353 | set_registers(pegasus, PhyAddr, sizeof(data), data); |
349 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); | 354 | set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); |
350 | for (i = 0; i < REG_TIMEOUT; i++) { | 355 | for (i = 0; i < REG_TIMEOUT; i++) { |
351 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 356 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
352 | if (data[0] & PHY_DONE) | 357 | if (data[0] & PHY_DONE) |
353 | break; | 358 | break; |
354 | } | 359 | } |
355 | if (i < REG_TIMEOUT) | 360 | if (i < REG_TIMEOUT) |
356 | return 0; | 361 | return ret; |
357 | 362 | ||
358 | if (netif_msg_drv(pegasus)) | 363 | if (netif_msg_drv(pegasus)) |
359 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 364 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
360 | return 1; | 365 | return -ETIMEDOUT; |
361 | } | 366 | } |
362 | 367 | ||
363 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) | 368 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) |
@@ -374,9 +379,9 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
374 | __le16 retdatai; | 379 | __le16 retdatai; |
375 | int ret; | 380 | int ret; |
376 | 381 | ||
377 | ret = set_register(pegasus, EpromCtrl, 0); | 382 | set_register(pegasus, EpromCtrl, 0); |
378 | ret = set_register(pegasus, EpromOffset, index); | 383 | set_register(pegasus, EpromOffset, index); |
379 | ret = set_register(pegasus, EpromCtrl, EPROM_READ); | 384 | set_register(pegasus, EpromCtrl, EPROM_READ); |
380 | 385 | ||
381 | for (i = 0; i < REG_TIMEOUT; i++) { | 386 | for (i = 0; i < REG_TIMEOUT; i++) { |
382 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 387 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
@@ -386,12 +391,12 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
386 | if (i < REG_TIMEOUT) { | 391 | if (i < REG_TIMEOUT) { |
387 | ret = get_registers(pegasus, EpromData, 2, &retdatai); | 392 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
388 | *retdata = le16_to_cpu(retdatai); | 393 | *retdata = le16_to_cpu(retdatai); |
389 | return 0; | 394 | return ret; |
390 | } | 395 | } |
391 | 396 | ||
392 | if (netif_msg_drv(pegasus)) | 397 | if (netif_msg_drv(pegasus)) |
393 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 398 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
394 | return -1; | 399 | return -ETIMEDOUT; |
395 | } | 400 | } |
396 | 401 | ||
397 | #ifdef PEGASUS_WRITE_EEPROM | 402 | #ifdef PEGASUS_WRITE_EEPROM |
@@ -400,8 +405,8 @@ static inline void enable_eprom_write(pegasus_t * pegasus) | |||
400 | __u8 tmp; | 405 | __u8 tmp; |
401 | int ret; | 406 | int ret; |
402 | 407 | ||
403 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 408 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
404 | ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); | 409 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); |
405 | } | 410 | } |
406 | 411 | ||
407 | static inline void disable_eprom_write(pegasus_t * pegasus) | 412 | static inline void disable_eprom_write(pegasus_t * pegasus) |
@@ -409,9 +414,9 @@ static inline void disable_eprom_write(pegasus_t * pegasus) | |||
409 | __u8 tmp; | 414 | __u8 tmp; |
410 | int ret; | 415 | int ret; |
411 | 416 | ||
412 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 417 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
413 | ret = set_register(pegasus, EpromCtrl, 0); | 418 | set_register(pegasus, EpromCtrl, 0); |
414 | ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); | 419 | set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); |
415 | } | 420 | } |
416 | 421 | ||
417 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | 422 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) |
@@ -420,11 +425,11 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
420 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; | 425 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; |
421 | int ret; | 426 | int ret; |
422 | 427 | ||
423 | ret = set_registers(pegasus, EpromOffset, 4, d); | 428 | set_registers(pegasus, EpromOffset, 4, d); |
424 | enable_eprom_write(pegasus); | 429 | enable_eprom_write(pegasus); |
425 | ret = set_register(pegasus, EpromOffset, index); | 430 | set_register(pegasus, EpromOffset, index); |
426 | ret = set_registers(pegasus, EpromData, 2, &data); | 431 | set_registers(pegasus, EpromData, 2, &data); |
427 | ret = set_register(pegasus, EpromCtrl, EPROM_WRITE); | 432 | set_register(pegasus, EpromCtrl, EPROM_WRITE); |
428 | 433 | ||
429 | for (i = 0; i < REG_TIMEOUT; i++) { | 434 | for (i = 0; i < REG_TIMEOUT; i++) { |
430 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 435 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
@@ -433,10 +438,10 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
433 | } | 438 | } |
434 | disable_eprom_write(pegasus); | 439 | disable_eprom_write(pegasus); |
435 | if (i < REG_TIMEOUT) | 440 | if (i < REG_TIMEOUT) |
436 | return 0; | 441 | return ret; |
437 | if (netif_msg_drv(pegasus)) | 442 | if (netif_msg_drv(pegasus)) |
438 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 443 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
439 | return -1; | 444 | return -ETIMEDOUT; |
440 | } | 445 | } |
441 | #endif /* PEGASUS_WRITE_EEPROM */ | 446 | #endif /* PEGASUS_WRITE_EEPROM */ |
442 | 447 | ||
@@ -454,10 +459,9 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id) | |||
454 | static void set_ethernet_addr(pegasus_t * pegasus) | 459 | static void set_ethernet_addr(pegasus_t * pegasus) |
455 | { | 460 | { |
456 | __u8 node_id[6]; | 461 | __u8 node_id[6]; |
457 | int ret; | ||
458 | 462 | ||
459 | get_node_id(pegasus, node_id); | 463 | get_node_id(pegasus, node_id); |
460 | ret = set_registers(pegasus, EthID, sizeof (node_id), node_id); | 464 | set_registers(pegasus, EthID, sizeof (node_id), node_id); |
461 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); | 465 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); |
462 | } | 466 | } |
463 | 467 | ||
@@ -465,30 +469,29 @@ static inline int reset_mac(pegasus_t * pegasus) | |||
465 | { | 469 | { |
466 | __u8 data = 0x8; | 470 | __u8 data = 0x8; |
467 | int i; | 471 | int i; |
468 | int ret; | ||
469 | 472 | ||
470 | ret = set_register(pegasus, EthCtrl1, data); | 473 | set_register(pegasus, EthCtrl1, data); |
471 | for (i = 0; i < REG_TIMEOUT; i++) { | 474 | for (i = 0; i < REG_TIMEOUT; i++) { |
472 | ret = get_registers(pegasus, EthCtrl1, 1, &data); | 475 | get_registers(pegasus, EthCtrl1, 1, &data); |
473 | if (~data & 0x08) { | 476 | if (~data & 0x08) { |
474 | if (loopback & 1) | 477 | if (loopback & 1) |
475 | break; | 478 | break; |
476 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) | 479 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) |
477 | ret = set_register(pegasus, Gpio1, 0x34); | 480 | set_register(pegasus, Gpio1, 0x34); |
478 | else | 481 | else |
479 | ret = set_register(pegasus, Gpio1, 0x26); | 482 | set_register(pegasus, Gpio1, 0x26); |
480 | ret = set_register(pegasus, Gpio0, pegasus->features); | 483 | set_register(pegasus, Gpio0, pegasus->features); |
481 | ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); | 484 | set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); |
482 | break; | 485 | break; |
483 | } | 486 | } |
484 | } | 487 | } |
485 | if (i == REG_TIMEOUT) | 488 | if (i == REG_TIMEOUT) |
486 | return 1; | 489 | return -ETIMEDOUT; |
487 | 490 | ||
488 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || | 491 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || |
489 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { | 492 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
490 | ret = set_register(pegasus, Gpio0, 0x24); | 493 | set_register(pegasus, Gpio0, 0x24); |
491 | ret = set_register(pegasus, Gpio0, 0x26); | 494 | set_register(pegasus, Gpio0, 0x26); |
492 | } | 495 | } |
493 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { | 496 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
494 | __u16 auxmode; | 497 | __u16 auxmode; |
@@ -527,7 +530,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
527 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); | 530 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); |
528 | } | 531 | } |
529 | 532 | ||
530 | return 0; | 533 | return ret; |
531 | } | 534 | } |
532 | 535 | ||
533 | static void fill_skb_pool(pegasus_t * pegasus) | 536 | static void fill_skb_pool(pegasus_t * pegasus) |
@@ -881,9 +884,8 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev) | |||
881 | static inline void disable_net_traffic(pegasus_t * pegasus) | 884 | static inline void disable_net_traffic(pegasus_t * pegasus) |
882 | { | 885 | { |
883 | int tmp = 0; | 886 | int tmp = 0; |
884 | int ret; | ||
885 | 887 | ||
886 | ret = set_registers(pegasus, EthCtrl0, 2, &tmp); | 888 | set_registers(pegasus, EthCtrl0, 2, &tmp); |
887 | } | 889 | } |
888 | 890 | ||
889 | static inline void get_interrupt_interval(pegasus_t * pegasus) | 891 | static inline void get_interrupt_interval(pegasus_t * pegasus) |
@@ -1206,18 +1208,17 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) | |||
1206 | static inline void setup_pegasus_II(pegasus_t * pegasus) | 1208 | static inline void setup_pegasus_II(pegasus_t * pegasus) |
1207 | { | 1209 | { |
1208 | __u8 data = 0xa5; | 1210 | __u8 data = 0xa5; |
1209 | int ret; | ||
1210 | 1211 | ||
1211 | ret = set_register(pegasus, Reg1d, 0); | 1212 | set_register(pegasus, Reg1d, 0); |
1212 | ret = set_register(pegasus, Reg7b, 1); | 1213 | set_register(pegasus, Reg7b, 1); |
1213 | mdelay(100); | 1214 | mdelay(100); |
1214 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) | 1215 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) |
1215 | ret = set_register(pegasus, Reg7b, 0); | 1216 | set_register(pegasus, Reg7b, 0); |
1216 | else | 1217 | else |
1217 | ret = set_register(pegasus, Reg7b, 2); | 1218 | set_register(pegasus, Reg7b, 2); |
1218 | 1219 | ||
1219 | ret = set_register(pegasus, 0x83, data); | 1220 | set_register(pegasus, 0x83, data); |
1220 | ret = get_registers(pegasus, 0x83, 1, &data); | 1221 | get_registers(pegasus, 0x83, 1, &data); |
1221 | 1222 | ||
1222 | if (data == 0xa5) { | 1223 | if (data == 0xa5) { |
1223 | pegasus->chip = 0x8513; | 1224 | pegasus->chip = 0x8513; |
@@ -1225,14 +1226,14 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) | |||
1225 | pegasus->chip = 0; | 1226 | pegasus->chip = 0; |
1226 | } | 1227 | } |
1227 | 1228 | ||
1228 | ret = set_register(pegasus, 0x80, 0xc0); | 1229 | set_register(pegasus, 0x80, 0xc0); |
1229 | ret = set_register(pegasus, 0x83, 0xff); | 1230 | set_register(pegasus, 0x83, 0xff); |
1230 | ret = set_register(pegasus, 0x84, 0x01); | 1231 | set_register(pegasus, 0x84, 0x01); |
1231 | 1232 | ||
1232 | if (pegasus->features & HAS_HOME_PNA && mii_mode) | 1233 | if (pegasus->features & HAS_HOME_PNA && mii_mode) |
1233 | ret = set_register(pegasus, Reg81, 6); | 1234 | set_register(pegasus, Reg81, 6); |
1234 | else | 1235 | else |
1235 | ret = set_register(pegasus, Reg81, 2); | 1236 | set_register(pegasus, Reg81, 2); |
1236 | } | 1237 | } |
1237 | 1238 | ||
1238 | 1239 | ||
@@ -1414,9 +1415,42 @@ static struct usb_driver pegasus_driver = { | |||
1414 | .resume = pegasus_resume, | 1415 | .resume = pegasus_resume, |
1415 | }; | 1416 | }; |
1416 | 1417 | ||
1418 | static void parse_id(char *id) | ||
1419 | { | ||
1420 | unsigned int vendor_id=0, device_id=0, flags=0, i=0; | ||
1421 | char *token, *name=NULL; | ||
1422 | |||
1423 | if ((token = strsep(&id, ":")) != NULL) | ||
1424 | name = token; | ||
1425 | /* name now points to a null terminated string*/ | ||
1426 | if ((token = strsep(&id, ":")) != NULL) | ||
1427 | vendor_id = simple_strtoul(token, NULL, 16); | ||
1428 | if ((token = strsep(&id, ":")) != NULL) | ||
1429 | device_id = simple_strtoul(token, NULL, 16); | ||
1430 | flags = simple_strtoul(id, NULL, 16); | ||
1431 | pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n", | ||
1432 | driver_name, name, vendor_id, device_id, flags); | ||
1433 | |||
1434 | if (vendor_id > 0x10000 || vendor_id == 0) | ||
1435 | return; | ||
1436 | if (device_id > 0x10000 || device_id == 0) | ||
1437 | return; | ||
1438 | |||
1439 | for (i=0; usb_dev_id[i].name; i++); | ||
1440 | usb_dev_id[i].name = name; | ||
1441 | usb_dev_id[i].vendor = vendor_id; | ||
1442 | usb_dev_id[i].device = device_id; | ||
1443 | usb_dev_id[i].private = flags; | ||
1444 | pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
1445 | pegasus_ids[i].idVendor = vendor_id; | ||
1446 | pegasus_ids[i].idProduct = device_id; | ||
1447 | } | ||
1448 | |||
1417 | static int __init pegasus_init(void) | 1449 | static int __init pegasus_init(void) |
1418 | { | 1450 | { |
1419 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); | 1451 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); |
1452 | if (devid) | ||
1453 | parse_id(devid); | ||
1420 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); | 1454 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); |
1421 | if (!pegasus_workqueue) | 1455 | if (!pegasus_workqueue) |
1422 | return -ENOMEM; | 1456 | return -ENOMEM; |
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c index 89856aa0e3b8..4fe863389cb7 100644 --- a/drivers/usb/net/plusb.c +++ b/drivers/usb/net/plusb.c | |||
@@ -127,7 +127,6 @@ static const struct usb_device_id products [] = { | |||
127 | MODULE_DEVICE_TABLE(usb, products); | 127 | MODULE_DEVICE_TABLE(usb, products); |
128 | 128 | ||
129 | static struct usb_driver plusb_driver = { | 129 | static struct usb_driver plusb_driver = { |
130 | .owner = THIS_MODULE, | ||
131 | .name = "plusb", | 130 | .name = "plusb", |
132 | .id_table = products, | 131 | .id_table = products, |
133 | .probe = usbnet_probe, | 132 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index c0ecbab6f6ba..49991ac1bf3b 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -586,7 +586,6 @@ static const struct usb_device_id products [] = { | |||
586 | MODULE_DEVICE_TABLE(usb, products); | 586 | MODULE_DEVICE_TABLE(usb, products); |
587 | 587 | ||
588 | static struct usb_driver rndis_driver = { | 588 | static struct usb_driver rndis_driver = { |
589 | .owner = THIS_MODULE, | ||
590 | .name = "rndis_host", | 589 | .name = "rndis_host", |
591 | .id_table = products, | 590 | .id_table = products, |
592 | .probe = usbnet_probe, | 591 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 787dd3591d6a..8ca52be23976 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -177,7 +177,6 @@ static int rtl8150_probe(struct usb_interface *intf, | |||
177 | static const char driver_name [] = "rtl8150"; | 177 | static const char driver_name [] = "rtl8150"; |
178 | 178 | ||
179 | static struct usb_driver rtl8150_driver = { | 179 | static struct usb_driver rtl8150_driver = { |
180 | .owner = THIS_MODULE, | ||
181 | .name = driver_name, | 180 | .name = driver_name, |
182 | .probe = rtl8150_probe, | 181 | .probe = rtl8150_probe, |
183 | .disconnect = rtl8150_disconnect, | 182 | .disconnect = rtl8150_disconnect, |
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index 680d13957af4..9c5ab251370c 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c | |||
@@ -357,7 +357,6 @@ static const struct usb_device_id products [] = { | |||
357 | MODULE_DEVICE_TABLE(usb, products); | 357 | MODULE_DEVICE_TABLE(usb, products); |
358 | 358 | ||
359 | static struct usb_driver zaurus_driver = { | 359 | static struct usb_driver zaurus_driver = { |
360 | .owner = THIS_MODULE, | ||
361 | .name = "zaurus", | 360 | .name = "zaurus", |
362 | .id_table = products, | 361 | .id_table = products, |
363 | .probe = usbnet_probe, | 362 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 2f52261c7cc1..f3a8e2807c3b 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c | |||
@@ -1722,7 +1722,7 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, | 1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, |
1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, | 1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, |
1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, | 1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, |
1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, | 1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, |
1726 | IW_PRIV_TYPE_NONE, "authstation" }, | 1726 | IW_PRIV_TYPE_NONE, "authstation" }, |
1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, | 1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, |
@@ -1731,9 +1731,9 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
1731 | }; | 1731 | }; |
1732 | 1732 | ||
1733 | static const struct iw_handler_def zd1201_iw_handlers = { | 1733 | static const struct iw_handler_def zd1201_iw_handlers = { |
1734 | .num_standard = sizeof(zd1201_iw_handler)/sizeof(iw_handler), | 1734 | .num_standard = ARRAY_SIZE(zd1201_iw_handler), |
1735 | .num_private = sizeof(zd1201_private_handler)/sizeof(iw_handler), | 1735 | .num_private = ARRAY_SIZE(zd1201_private_handler), |
1736 | .num_private_args = sizeof(zd1201_private_args)/sizeof(struct iw_priv_args), | 1736 | .num_private_args = ARRAY_SIZE(zd1201_private_args), |
1737 | .standard = (iw_handler *)zd1201_iw_handler, | 1737 | .standard = (iw_handler *)zd1201_iw_handler, |
1738 | .private = (iw_handler *)zd1201_private_handler, | 1738 | .private = (iw_handler *)zd1201_private_handler, |
1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, | 1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, |
@@ -1829,6 +1829,8 @@ static int zd1201_probe(struct usb_interface *interface, | |||
1829 | if (err) | 1829 | if (err) |
1830 | goto err_net; | 1830 | goto err_net; |
1831 | 1831 | ||
1832 | SET_NETDEV_DEV(zd->dev, &usb->dev); | ||
1833 | |||
1832 | err = register_netdev(zd->dev); | 1834 | err = register_netdev(zd->dev); |
1833 | if (err) | 1835 | if (err) |
1834 | goto err_net; | 1836 | goto err_net; |
@@ -1923,7 +1925,6 @@ static int zd1201_resume(struct usb_interface *interface) | |||
1923 | #endif | 1925 | #endif |
1924 | 1926 | ||
1925 | static struct usb_driver zd1201_usb = { | 1927 | static struct usb_driver zd1201_usb = { |
1926 | .owner = THIS_MODULE, | ||
1927 | .name = "zd1201", | 1928 | .name = "zd1201", |
1928 | .probe = zd1201_probe, | 1929 | .probe = zd1201_probe, |
1929 | .disconnect = zd1201_disconnect, | 1930 | .disconnect = zd1201_disconnect, |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 1f29d8837327..dbf1f063098c 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -23,11 +23,11 @@ static struct usb_device_id id_table [] = { | |||
23 | MODULE_DEVICE_TABLE(usb, id_table); | 23 | MODULE_DEVICE_TABLE(usb, id_table); |
24 | 24 | ||
25 | static struct usb_driver airprime_driver = { | 25 | static struct usb_driver airprime_driver = { |
26 | .owner = THIS_MODULE, | ||
27 | .name = "airprime", | 26 | .name = "airprime", |
28 | .probe = usb_serial_probe, | 27 | .probe = usb_serial_probe, |
29 | .disconnect = usb_serial_disconnect, | 28 | .disconnect = usb_serial_disconnect, |
30 | .id_table = id_table, | 29 | .id_table = id_table, |
30 | .no_dynamic_id = 1, | ||
31 | }; | 31 | }; |
32 | 32 | ||
33 | static struct usb_serial_driver airprime_device = { | 33 | static struct usb_serial_driver airprime_device = { |
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c index 18022a74a3dc..343f6f228220 100644 --- a/drivers/usb/serial/anydata.c +++ b/drivers/usb/serial/anydata.c | |||
@@ -27,11 +27,11 @@ static int buffer_size; | |||
27 | static int debug; | 27 | static int debug; |
28 | 28 | ||
29 | static struct usb_driver anydata_driver = { | 29 | static struct usb_driver anydata_driver = { |
30 | .owner = THIS_MODULE, | ||
31 | .name = "anydata", | 30 | .name = "anydata", |
32 | .probe = usb_serial_probe, | 31 | .probe = usb_serial_probe, |
33 | .disconnect = usb_serial_disconnect, | 32 | .disconnect = usb_serial_disconnect, |
34 | .id_table = id_table, | 33 | .id_table = id_table, |
34 | .no_dynamic_id = 1, | ||
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) | 37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 84bc0ee4f061..4144777ea18b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -113,11 +113,11 @@ static struct usb_device_id id_table_combined [] = { | |||
113 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 113 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
114 | 114 | ||
115 | static struct usb_driver belkin_driver = { | 115 | static struct usb_driver belkin_driver = { |
116 | .owner = THIS_MODULE, | ||
117 | .name = "belkin", | 116 | .name = "belkin", |
118 | .probe = usb_serial_probe, | 117 | .probe = usb_serial_probe, |
119 | .disconnect = usb_serial_disconnect, | 118 | .disconnect = usb_serial_disconnect, |
120 | .id_table = id_table_combined, | 119 | .id_table = id_table_combined, |
120 | .no_dynamic_id = 1, | ||
121 | }; | 121 | }; |
122 | 122 | ||
123 | /* All of the device info needed for the serial converters */ | 123 | /* All of the device info needed for the serial converters */ |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index c9787001cf2a..da46b351e188 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -67,11 +67,11 @@ static struct usb_device_id id_table [] = { | |||
67 | MODULE_DEVICE_TABLE (usb, id_table); | 67 | MODULE_DEVICE_TABLE (usb, id_table); |
68 | 68 | ||
69 | static struct usb_driver cp2101_driver = { | 69 | static struct usb_driver cp2101_driver = { |
70 | .owner = THIS_MODULE, | ||
71 | .name = "cp2101", | 70 | .name = "cp2101", |
72 | .probe = usb_serial_probe, | 71 | .probe = usb_serial_probe, |
73 | .disconnect = usb_serial_disconnect, | 72 | .disconnect = usb_serial_disconnect, |
74 | .id_table = id_table, | 73 | .id_table = id_table, |
74 | .no_dynamic_id = 1, | ||
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct usb_serial_driver cp2101_device = { | 77 | static struct usb_serial_driver cp2101_device = { |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index e581e4ae8483..6d18d4eaba35 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -76,11 +76,11 @@ static struct usb_device_id id_table [] = { | |||
76 | MODULE_DEVICE_TABLE (usb, id_table); | 76 | MODULE_DEVICE_TABLE (usb, id_table); |
77 | 77 | ||
78 | static struct usb_driver cyberjack_driver = { | 78 | static struct usb_driver cyberjack_driver = { |
79 | .owner = THIS_MODULE, | ||
80 | .name = "cyberjack", | 79 | .name = "cyberjack", |
81 | .probe = usb_serial_probe, | 80 | .probe = usb_serial_probe, |
82 | .disconnect = usb_serial_disconnect, | 81 | .disconnect = usb_serial_disconnect, |
83 | .id_table = id_table, | 82 | .id_table = id_table, |
83 | .no_dynamic_id = 1, | ||
84 | }; | 84 | }; |
85 | 85 | ||
86 | static struct usb_serial_driver cyberjack_device = { | 86 | static struct usb_serial_driver cyberjack_device = { |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index af9290ed257b..af18355e94cc 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -112,6 +112,7 @@ static struct usb_driver cypress_driver = { | |||
112 | .probe = usb_serial_probe, | 112 | .probe = usb_serial_probe, |
113 | .disconnect = usb_serial_disconnect, | 113 | .disconnect = usb_serial_disconnect, |
114 | .id_table = id_table_combined, | 114 | .id_table = id_table_combined, |
115 | .no_dynamic_id = 1, | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | struct cypress_private { | 118 | struct cypress_private { |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index dc74644a603d..8fc414bd5b24 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -493,11 +493,11 @@ static struct usb_device_id id_table_4 [] = { | |||
493 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 493 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
494 | 494 | ||
495 | static struct usb_driver digi_driver = { | 495 | static struct usb_driver digi_driver = { |
496 | .owner = THIS_MODULE, | ||
497 | .name = "digi_acceleport", | 496 | .name = "digi_acceleport", |
498 | .probe = usb_serial_probe, | 497 | .probe = usb_serial_probe, |
499 | .disconnect = usb_serial_disconnect, | 498 | .disconnect = usb_serial_disconnect, |
500 | .id_table = id_table_combined, | 499 | .id_table = id_table_combined, |
500 | .no_dynamic_id = 1, | ||
501 | }; | 501 | }; |
502 | 502 | ||
503 | 503 | ||
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 0b0546dcc7b9..79a766e9ca23 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -105,11 +105,11 @@ static struct usb_device_id id_table [] = { | |||
105 | MODULE_DEVICE_TABLE (usb, id_table); | 105 | MODULE_DEVICE_TABLE (usb, id_table); |
106 | 106 | ||
107 | static struct usb_driver empeg_driver = { | 107 | static struct usb_driver empeg_driver = { |
108 | .owner = THIS_MODULE, | ||
109 | .name = "empeg", | 108 | .name = "empeg", |
110 | .probe = usb_serial_probe, | 109 | .probe = usb_serial_probe, |
111 | .disconnect = usb_serial_disconnect, | 110 | .disconnect = usb_serial_disconnect, |
112 | .id_table = id_table, | 111 | .id_table = id_table, |
112 | .no_dynamic_id = 1, | ||
113 | }; | 113 | }; |
114 | 114 | ||
115 | static struct usb_serial_driver empeg_device = { | 115 | static struct usb_serial_driver empeg_device = { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06e04b442ff1..eb863b3f2d79 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -471,12 +471,15 @@ static struct usb_device_id id_table_combined [] = { | |||
471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | 472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, |
473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | 473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, |
474 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | ||
475 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | ||
474 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 476 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
475 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 477 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
476 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 478 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
477 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, | 479 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, |
478 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, | 480 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, |
479 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, | 481 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, |
482 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, | ||
480 | { }, /* Optional parameter entry */ | 483 | { }, /* Optional parameter entry */ |
481 | { } /* Terminating entry */ | 484 | { } /* Terminating entry */ |
482 | }; | 485 | }; |
@@ -488,9 +491,10 @@ static struct usb_driver ftdi_driver = { | |||
488 | .probe = usb_serial_probe, | 491 | .probe = usb_serial_probe, |
489 | .disconnect = usb_serial_disconnect, | 492 | .disconnect = usb_serial_disconnect, |
490 | .id_table = id_table_combined, | 493 | .id_table = id_table_combined, |
494 | .no_dynamic_id = 1, | ||
491 | }; | 495 | }; |
492 | 496 | ||
493 | static char *ftdi_chip_name[] = { | 497 | static const char *ftdi_chip_name[] = { |
494 | [SIO] = "SIO", /* the serial part of FT8U100AX */ | 498 | [SIO] = "SIO", /* the serial part of FT8U100AX */ |
495 | [FT8U232AM] = "FT8U232AM", | 499 | [FT8U232AM] = "FT8U232AM", |
496 | [FT232BM] = "FT232BM", | 500 | [FT232BM] = "FT232BM", |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 773ea3eca086..00d45f8600de 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -343,6 +343,13 @@ | |||
343 | #define XSENS_CONVERTER_7_PID 0xD38F | 343 | #define XSENS_CONVERTER_7_PID 0xD38F |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * Teratronik product ids. | ||
347 | * Submitted by O. Wölfelschneider. | ||
348 | */ | ||
349 | #define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ | ||
350 | #define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ | ||
351 | |||
352 | /* | ||
346 | * Evolution Robotics products (http://www.evolution.com/). | 353 | * Evolution Robotics products (http://www.evolution.com/). |
347 | * Submitted by Shawn M. Lavelle. | 354 | * Submitted by Shawn M. Lavelle. |
348 | */ | 355 | */ |
@@ -352,6 +359,12 @@ | |||
352 | /* Pyramid Computer GmbH */ | 359 | /* Pyramid Computer GmbH */ |
353 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 360 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
354 | 361 | ||
362 | /* | ||
363 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | ||
364 | */ | ||
365 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | ||
366 | #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ | ||
367 | |||
355 | /* Commands */ | 368 | /* Commands */ |
356 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 369 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
357 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 370 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
@@ -714,7 +727,7 @@ typedef enum { | |||
714 | */ | 727 | */ |
715 | 728 | ||
716 | /* FTDI_SIO_GET_MODEM_STATUS */ | 729 | /* FTDI_SIO_GET_MODEM_STATUS */ |
717 | /* Retreive the current value of the modem status register */ | 730 | /* Retrieve the current value of the modem status register */ |
718 | 731 | ||
719 | #define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0 | 732 | #define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0 |
720 | #define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS | 733 | #define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 35820bda7ae1..452efce72714 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -222,11 +222,11 @@ static struct usb_device_id id_table [] = { | |||
222 | MODULE_DEVICE_TABLE (usb, id_table); | 222 | MODULE_DEVICE_TABLE (usb, id_table); |
223 | 223 | ||
224 | static struct usb_driver garmin_driver = { | 224 | static struct usb_driver garmin_driver = { |
225 | .owner = THIS_MODULE, | ||
226 | .name = "garmin_gps", | 225 | .name = "garmin_gps", |
227 | .probe = usb_serial_probe, | 226 | .probe = usb_serial_probe, |
228 | .disconnect = usb_serial_disconnect, | 227 | .disconnect = usb_serial_disconnect, |
229 | .id_table = id_table, | 228 | .id_table = id_table, |
229 | .no_dynamic_id = 1, | ||
230 | }; | 230 | }; |
231 | 231 | ||
232 | 232 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 53a47c31cd0e..4ddac620fc0c 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -68,11 +68,11 @@ static int generic_probe(struct usb_interface *interface, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | static struct usb_driver generic_driver = { | 70 | static struct usb_driver generic_driver = { |
71 | .owner = THIS_MODULE, | ||
72 | .name = "usbserial_generic", | 71 | .name = "usbserial_generic", |
73 | .probe = generic_probe, | 72 | .probe = generic_probe, |
74 | .disconnect = usb_serial_disconnect, | 73 | .disconnect = usb_serial_disconnect, |
75 | .id_table = generic_serial_ids, | 74 | .id_table = generic_serial_ids, |
75 | .no_dynamic_id = 1, | ||
76 | }; | 76 | }; |
77 | #endif | 77 | #endif |
78 | 78 | ||
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 8eadfb705601..e9719da2aca1 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -37,11 +37,11 @@ static struct usb_device_id id_table [] = { | |||
37 | MODULE_DEVICE_TABLE(usb, id_table); | 37 | MODULE_DEVICE_TABLE(usb, id_table); |
38 | 38 | ||
39 | static struct usb_driver hp49gp_driver = { | 39 | static struct usb_driver hp49gp_driver = { |
40 | .owner = THIS_MODULE, | ||
41 | .name = "hp4X", | 40 | .name = "hp4X", |
42 | .probe = usb_serial_probe, | 41 | .probe = usb_serial_probe, |
43 | .disconnect = usb_serial_disconnect, | 42 | .disconnect = usb_serial_disconnect, |
44 | .id_table = id_table, | 43 | .id_table = id_table, |
44 | .no_dynamic_id = 1, | ||
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct usb_serial_driver hp49gp_device = { | 47 | static struct usb_serial_driver hp49gp_device = { |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dc4c498bd1ed..faedbeb6ba49 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -184,7 +184,7 @@ struct divisor_table_entry { | |||
184 | // These assume a 3.6864MHz crystal, the standard /16, and | 184 | // These assume a 3.6864MHz crystal, the standard /16, and |
185 | // MCR.7 = 0. | 185 | // MCR.7 = 0. |
186 | // | 186 | // |
187 | static struct divisor_table_entry divisor_table[] = { | 187 | static const struct divisor_table_entry divisor_table[] = { |
188 | { 50, 4608}, | 188 | { 50, 4608}, |
189 | { 75, 3072}, | 189 | { 75, 3072}, |
190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ | 190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ |
@@ -242,11 +242,11 @@ static void edge_shutdown (struct usb_serial *serial); | |||
242 | #include "io_tables.h" /* all of the devices that this driver supports */ | 242 | #include "io_tables.h" /* all of the devices that this driver supports */ |
243 | 243 | ||
244 | static struct usb_driver io_driver = { | 244 | static struct usb_driver io_driver = { |
245 | .owner = THIS_MODULE, | ||
246 | .name = "io_edgeport", | 245 | .name = "io_edgeport", |
247 | .probe = usb_serial_probe, | 246 | .probe = usb_serial_probe, |
248 | .disconnect = usb_serial_disconnect, | 247 | .disconnect = usb_serial_disconnect, |
249 | .id_table = id_table_combined, | 248 | .id_table = id_table_combined, |
249 | .no_dynamic_id = 1, | ||
250 | }; | 250 | }; |
251 | 251 | ||
252 | /* function prototypes for all of our local functions */ | 252 | /* function prototypes for all of our local functions */ |
@@ -2353,7 +2353,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
2353 | 2353 | ||
2354 | dbg("%s - %d", __FUNCTION__, baudrate); | 2354 | dbg("%s - %d", __FUNCTION__, baudrate); |
2355 | 2355 | ||
2356 | for (i = 0; i < NUM_ENTRIES(divisor_table); i++) { | 2356 | for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { |
2357 | if ( divisor_table[i].BaudRate == baudrate ) { | 2357 | if ( divisor_table[i].BaudRate == baudrate ) { |
2358 | *divisor = divisor_table[i].Divisor; | 2358 | *divisor = divisor_table[i].Divisor; |
2359 | return 0; | 2359 | return 0; |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 5112d7aac055..123fa8a904e6 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
@@ -31,9 +31,6 @@ | |||
31 | #ifndef HIGH8 | 31 | #ifndef HIGH8 |
32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) | 32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) |
33 | #endif | 33 | #endif |
34 | #ifndef NUM_ENTRIES | ||
35 | #define NUM_ENTRIES(x) (sizeof(x)/sizeof((x)[0])) | ||
36 | #endif | ||
37 | 34 | ||
38 | #ifndef __KERNEL__ | 35 | #ifndef __KERNEL__ |
39 | #define __KERNEL__ | 36 | #define __KERNEL__ |
diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h index c7c3a3c305fe..e3463de99de4 100644 --- a/drivers/usb/serial/io_fw_boot2.h +++ b/drivers/usb/serial/io_fw_boot2.h | |||
@@ -537,7 +537,7 @@ static unsigned char IMAGE_ARRAY_NAME[] = { | |||
537 | 537 | ||
538 | }; | 538 | }; |
539 | 539 | ||
540 | static struct edge_firmware_version_info IMAGE_VERSION_NAME = { | 540 | static const struct edge_firmware_version_info IMAGE_VERSION_NAME = { |
541 | 2, 0, 3 }; // Major, Minor, Build | 541 | 2, 0, 3 }; // Major, Minor, Build |
542 | 542 | ||
543 | #undef IMAGE_VERSION_NAME | 543 | #undef IMAGE_VERSION_NAME |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 832b6d6734c0..2edf9cabad20 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -216,11 +216,11 @@ static struct usb_device_id id_table_combined [] = { | |||
216 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 216 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
217 | 217 | ||
218 | static struct usb_driver io_driver = { | 218 | static struct usb_driver io_driver = { |
219 | .owner = THIS_MODULE, | ||
220 | .name = "io_ti", | 219 | .name = "io_ti", |
221 | .probe = usb_serial_probe, | 220 | .probe = usb_serial_probe, |
222 | .disconnect = usb_serial_disconnect, | 221 | .disconnect = usb_serial_disconnect, |
223 | .id_table = id_table_combined, | 222 | .id_table = id_table_combined, |
223 | .no_dynamic_id = 1, | ||
224 | }; | 224 | }; |
225 | 225 | ||
226 | 226 | ||
@@ -2843,7 +2843,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size) | |||
2843 | * Free the buffer and all associated memory. | 2843 | * Free the buffer and all associated memory. |
2844 | */ | 2844 | */ |
2845 | 2845 | ||
2846 | void edge_buf_free(struct edge_buf *eb) | 2846 | static void edge_buf_free(struct edge_buf *eb) |
2847 | { | 2847 | { |
2848 | if (eb) { | 2848 | if (eb) { |
2849 | kfree(eb->buf_buf); | 2849 | kfree(eb->buf_buf); |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d5d066488100..06d07cea0b70 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -542,11 +542,11 @@ static struct usb_device_id ipaq_id_table [] = { | |||
542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); | 542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); |
543 | 543 | ||
544 | static struct usb_driver ipaq_driver = { | 544 | static struct usb_driver ipaq_driver = { |
545 | .owner = THIS_MODULE, | ||
546 | .name = "ipaq", | 545 | .name = "ipaq", |
547 | .probe = usb_serial_probe, | 546 | .probe = usb_serial_probe, |
548 | .disconnect = usb_serial_disconnect, | 547 | .disconnect = usb_serial_disconnect, |
549 | .id_table = ipaq_id_table, | 548 | .id_table = ipaq_id_table, |
549 | .no_dynamic_id = 1, | ||
550 | }; | 550 | }; |
551 | 551 | ||
552 | 552 | ||
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 7744b8148bc5..2dd191f5fe76 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -152,11 +152,11 @@ static struct usb_device_id usb_ipw_ids[] = { | |||
152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); | 152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); |
153 | 153 | ||
154 | static struct usb_driver usb_ipw_driver = { | 154 | static struct usb_driver usb_ipw_driver = { |
155 | .owner = THIS_MODULE, | ||
156 | .name = "ipwtty", | 155 | .name = "ipwtty", |
157 | .probe = usb_serial_probe, | 156 | .probe = usb_serial_probe, |
158 | .disconnect = usb_serial_disconnect, | 157 | .disconnect = usb_serial_disconnect, |
159 | .id_table = usb_ipw_ids, | 158 | .id_table = usb_ipw_ids, |
159 | .no_dynamic_id = 1, | ||
160 | }; | 160 | }; |
161 | 161 | ||
162 | static int debug; | 162 | static int debug; |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 19f329e9bdcf..a59010421444 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -125,11 +125,11 @@ static struct usb_device_id id_table [] = { | |||
125 | MODULE_DEVICE_TABLE (usb, id_table); | 125 | MODULE_DEVICE_TABLE (usb, id_table); |
126 | 126 | ||
127 | static struct usb_driver ir_driver = { | 127 | static struct usb_driver ir_driver = { |
128 | .owner = THIS_MODULE, | ||
129 | .name = "ir-usb", | 128 | .name = "ir-usb", |
130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
132 | .id_table = id_table, | 131 | .id_table = id_table, |
132 | .no_dynamic_id = 1, | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | 135 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 5cfc13b5e56f..7472ed6bf626 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -520,11 +520,11 @@ static struct usb_device_id keyspan_ids_combined[] = { | |||
520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); | 520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); |
521 | 521 | ||
522 | static struct usb_driver keyspan_driver = { | 522 | static struct usb_driver keyspan_driver = { |
523 | .owner = THIS_MODULE, | ||
524 | .name = "keyspan", | 523 | .name = "keyspan", |
525 | .probe = usb_serial_probe, | 524 | .probe = usb_serial_probe, |
526 | .disconnect = usb_serial_disconnect, | 525 | .disconnect = usb_serial_disconnect, |
527 | .id_table = keyspan_ids_combined, | 526 | .id_table = keyspan_ids_combined, |
527 | .no_dynamic_id = 1, | ||
528 | }; | 528 | }; |
529 | 529 | ||
530 | /* usb_device_id table for the pre-firmware download keyspan devices */ | 530 | /* usb_device_id table for the pre-firmware download keyspan devices */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index cd4f48bd83b6..b0441c35f98f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -150,11 +150,11 @@ static struct usb_device_id id_table_combined [] = { | |||
150 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 150 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
151 | 151 | ||
152 | static struct usb_driver keyspan_pda_driver = { | 152 | static struct usb_driver keyspan_pda_driver = { |
153 | .owner = THIS_MODULE, | ||
154 | .name = "keyspan_pda", | 153 | .name = "keyspan_pda", |
155 | .probe = usb_serial_probe, | 154 | .probe = usb_serial_probe, |
156 | .disconnect = usb_serial_disconnect, | 155 | .disconnect = usb_serial_disconnect, |
157 | .id_table = id_table_combined, | 156 | .id_table = id_table_combined, |
157 | .no_dynamic_id = 1, | ||
158 | }; | 158 | }; |
159 | 159 | ||
160 | static struct usb_device_id id_table_std [] = { | 160 | static struct usb_device_id id_table_std [] = { |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a8951c0fd020..4e2f7dfb58b2 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -116,11 +116,11 @@ static struct usb_device_id id_table [] = { | |||
116 | MODULE_DEVICE_TABLE (usb, id_table); | 116 | MODULE_DEVICE_TABLE (usb, id_table); |
117 | 117 | ||
118 | static struct usb_driver kl5kusb105d_driver = { | 118 | static struct usb_driver kl5kusb105d_driver = { |
119 | .owner = THIS_MODULE, | ||
120 | .name = "kl5kusb105d", | 119 | .name = "kl5kusb105d", |
121 | .probe = usb_serial_probe, | 120 | .probe = usb_serial_probe, |
122 | .disconnect = usb_serial_disconnect, | 121 | .disconnect = usb_serial_disconnect, |
123 | .id_table = id_table, | 122 | .id_table = id_table, |
123 | .no_dynamic_id = 1, | ||
124 | }; | 124 | }; |
125 | 125 | ||
126 | static struct usb_serial_driver kl5kusb105d_device = { | 126 | static struct usb_serial_driver kl5kusb105d_device = { |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 9456dd9dd136..d9c21e275130 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -97,11 +97,11 @@ static struct usb_device_id id_table [] = { | |||
97 | MODULE_DEVICE_TABLE (usb, id_table); | 97 | MODULE_DEVICE_TABLE (usb, id_table); |
98 | 98 | ||
99 | static struct usb_driver kobil_driver = { | 99 | static struct usb_driver kobil_driver = { |
100 | .owner = THIS_MODULE, | ||
101 | .name = "kobil", | 100 | .name = "kobil", |
102 | .probe = usb_serial_probe, | 101 | .probe = usb_serial_probe, |
103 | .disconnect = usb_serial_disconnect, | 102 | .disconnect = usb_serial_disconnect, |
104 | .id_table = id_table, | 103 | .id_table = id_table, |
104 | .no_dynamic_id = 1, | ||
105 | }; | 105 | }; |
106 | 106 | ||
107 | 107 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index ca5dbadb9b7e..b6d6cab9c859 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -125,11 +125,11 @@ static struct usb_device_id id_table_combined [] = { | |||
125 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 125 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
126 | 126 | ||
127 | static struct usb_driver mct_u232_driver = { | 127 | static struct usb_driver mct_u232_driver = { |
128 | .owner = THIS_MODULE, | ||
129 | .name = "mct_u232", | 128 | .name = "mct_u232", |
130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
132 | .id_table = id_table_combined, | 131 | .id_table = id_table_combined, |
132 | .no_dynamic_id = 1, | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct usb_serial_driver mct_u232_device = { | 135 | static struct usb_serial_driver mct_u232_device = { |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 3caf97072ac0..762d8ff9a1e4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -80,11 +80,11 @@ static struct usb_device_id id_table [] = { | |||
80 | MODULE_DEVICE_TABLE (usb, id_table); | 80 | MODULE_DEVICE_TABLE (usb, id_table); |
81 | 81 | ||
82 | static struct usb_driver omninet_driver = { | 82 | static struct usb_driver omninet_driver = { |
83 | .owner = THIS_MODULE, | ||
84 | .name = "omninet", | 83 | .name = "omninet", |
85 | .probe = usb_serial_probe, | 84 | .probe = usb_serial_probe, |
86 | .disconnect = usb_serial_disconnect, | 85 | .disconnect = usb_serial_disconnect, |
87 | .id_table = id_table, | 86 | .id_table = id_table, |
87 | .no_dynamic_id = 1, | ||
88 | }; | 88 | }; |
89 | 89 | ||
90 | 90 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7716000045b7..3fd2405304fd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -95,11 +95,11 @@ static struct usb_device_id option_ids[] = { | |||
95 | MODULE_DEVICE_TABLE(usb, option_ids); | 95 | MODULE_DEVICE_TABLE(usb, option_ids); |
96 | 96 | ||
97 | static struct usb_driver option_driver = { | 97 | static struct usb_driver option_driver = { |
98 | .owner = THIS_MODULE, | ||
99 | .name = "option", | 98 | .name = "option", |
100 | .probe = usb_serial_probe, | 99 | .probe = usb_serial_probe, |
101 | .disconnect = usb_serial_disconnect, | 100 | .disconnect = usb_serial_disconnect, |
102 | .id_table = option_ids, | 101 | .id_table = option_ids, |
102 | .no_dynamic_id = 1, | ||
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* The card has three separate interfaces, wich the serial driver | 105 | /* The card has three separate interfaces, wich the serial driver |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 41a45a5025b2..f03721056190 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -82,11 +82,11 @@ static struct usb_device_id id_table [] = { | |||
82 | MODULE_DEVICE_TABLE (usb, id_table); | 82 | MODULE_DEVICE_TABLE (usb, id_table); |
83 | 83 | ||
84 | static struct usb_driver pl2303_driver = { | 84 | static struct usb_driver pl2303_driver = { |
85 | .owner = THIS_MODULE, | ||
86 | .name = "pl2303", | 85 | .name = "pl2303", |
87 | .probe = usb_serial_probe, | 86 | .probe = usb_serial_probe, |
88 | .disconnect = usb_serial_disconnect, | 87 | .disconnect = usb_serial_disconnect, |
89 | .id_table = id_table, | 88 | .id_table = id_table, |
89 | .no_dynamic_id = 1, | ||
90 | }; | 90 | }; |
91 | 91 | ||
92 | #define SET_LINE_REQUEST_TYPE 0x21 | 92 | #define SET_LINE_REQUEST_TYPE 0x21 |
@@ -810,7 +810,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, | |||
810 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 810 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
811 | unsigned long flags; | 811 | unsigned long flags; |
812 | u8 status_idx = UART_STATE; | 812 | u8 status_idx = UART_STATE; |
813 | u8 length = UART_STATE; | 813 | u8 length = UART_STATE + 1; |
814 | 814 | ||
815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && | 815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && |
816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || | 816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index c22bdc0c4dfd..f0215f850d2d 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -160,14 +160,14 @@ static struct usb_device_id id_table[] = { | |||
160 | MODULE_DEVICE_TABLE (usb, id_table); | 160 | MODULE_DEVICE_TABLE (usb, id_table); |
161 | 161 | ||
162 | static struct usb_driver safe_driver = { | 162 | static struct usb_driver safe_driver = { |
163 | .owner = THIS_MODULE, | ||
164 | .name = "safe_serial", | 163 | .name = "safe_serial", |
165 | .probe = usb_serial_probe, | 164 | .probe = usb_serial_probe, |
166 | .disconnect = usb_serial_disconnect, | 165 | .disconnect = usb_serial_disconnect, |
167 | .id_table = id_table, | 166 | .id_table = id_table, |
167 | .no_dynamic_id = 1, | ||
168 | }; | 168 | }; |
169 | 169 | ||
170 | static __u16 crc10_table[256] = { | 170 | static const __u16 crc10_table[256] = { |
171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, | 171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, |
172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, | 172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, |
173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, | 173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, |
@@ -425,7 +425,7 @@ static int __init safe_init (void) | |||
425 | if (vendor || product) { | 425 | if (vendor || product) { |
426 | info ("vendor: %x product: %x\n", vendor, product); | 426 | info ("vendor: %x product: %x\n", vendor, product); |
427 | 427 | ||
428 | for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) { | 428 | for (i = 0; i < ARRAY_SIZE(id_table); i++) { |
429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { | 429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { |
430 | id_table[i].idVendor = vendor; | 430 | id_table[i].idVendor = vendor; |
431 | id_table[i].idProduct = product; | 431 | id_table[i].idProduct = product; |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 205dbf7201da..abb830cb77bd 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -248,11 +248,11 @@ static struct usb_device_id ti_id_table_combined[] = { | |||
248 | }; | 248 | }; |
249 | 249 | ||
250 | static struct usb_driver ti_usb_driver = { | 250 | static struct usb_driver ti_usb_driver = { |
251 | .owner = THIS_MODULE, | ||
252 | .name = "ti_usb_3410_5052", | 251 | .name = "ti_usb_3410_5052", |
253 | .probe = usb_serial_probe, | 252 | .probe = usb_serial_probe, |
254 | .disconnect = usb_serial_disconnect, | 253 | .disconnect = usb_serial_disconnect, |
255 | .id_table = ti_id_table_combined, | 254 | .id_table = ti_id_table_combined, |
255 | .no_dynamic_id = 1, | ||
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct usb_serial_driver ti_1port_device = { | 258 | static struct usb_serial_driver ti_1port_device = { |
@@ -351,17 +351,14 @@ static int __init ti_init(void) | |||
351 | int i,j; | 351 | int i,j; |
352 | int ret; | 352 | int ret; |
353 | 353 | ||
354 | |||
355 | /* insert extra vendor and product ids */ | 354 | /* insert extra vendor and product ids */ |
356 | j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id) | 355 | j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; |
357 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
358 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { | 356 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { |
359 | ti_id_table_3410[j].idVendor = vendor_3410[i]; | 357 | ti_id_table_3410[j].idVendor = vendor_3410[i]; |
360 | ti_id_table_3410[j].idProduct = product_3410[i]; | 358 | ti_id_table_3410[j].idProduct = product_3410[i]; |
361 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 359 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
362 | } | 360 | } |
363 | j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id) | 361 | j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; |
364 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
365 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { | 362 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { |
366 | ti_id_table_5052[j].idVendor = vendor_5052[i]; | 363 | ti_id_table_5052[j].idVendor = vendor_5052[i]; |
367 | ti_id_table_5052[j].idProduct = product_5052[i]; | 364 | ti_id_table_5052[j].idProduct = product_5052[i]; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0c4881d18cd5..8bc8337c99c4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | #include <asm/semaphore.h> | ||
33 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
34 | #include "usb-serial.h" | 35 | #include "usb-serial.h" |
35 | #include "pl2303.h" | 36 | #include "pl2303.h" |
@@ -42,10 +43,10 @@ | |||
42 | 43 | ||
43 | /* Driver structure we register with the USB core */ | 44 | /* Driver structure we register with the USB core */ |
44 | static struct usb_driver usb_serial_driver = { | 45 | static struct usb_driver usb_serial_driver = { |
45 | .owner = THIS_MODULE, | ||
46 | .name = "usbserial", | 46 | .name = "usbserial", |
47 | .probe = usb_serial_probe, | 47 | .probe = usb_serial_probe, |
48 | .disconnect = usb_serial_disconnect, | 48 | .disconnect = usb_serial_disconnect, |
49 | .no_dynamic_id = 1, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead | 52 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead |
@@ -188,6 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
188 | 189 | ||
189 | portNumber = tty->index - serial->minor; | 190 | portNumber = tty->index - serial->minor; |
190 | port = serial->port[portNumber]; | 191 | port = serial->port[portNumber]; |
192 | if (!port) | ||
193 | return -ENODEV; | ||
194 | |||
195 | if (down_interruptible(&port->sem)) | ||
196 | return -ERESTARTSYS; | ||
191 | 197 | ||
192 | ++port->open_count; | 198 | ++port->open_count; |
193 | 199 | ||
@@ -213,6 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
213 | goto bailout_module_put; | 219 | goto bailout_module_put; |
214 | } | 220 | } |
215 | 221 | ||
222 | up(&port->sem); | ||
216 | return 0; | 223 | return 0; |
217 | 224 | ||
218 | bailout_module_put: | 225 | bailout_module_put: |
@@ -220,6 +227,7 @@ bailout_module_put: | |||
220 | bailout_kref_put: | 227 | bailout_kref_put: |
221 | kref_put(&serial->kref, destroy_serial); | 228 | kref_put(&serial->kref, destroy_serial); |
222 | port->open_count = 0; | 229 | port->open_count = 0; |
230 | up(&port->sem); | ||
223 | return retval; | 231 | return retval; |
224 | } | 232 | } |
225 | 233 | ||
@@ -232,8 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
232 | 240 | ||
233 | dbg("%s - port %d", __FUNCTION__, port->number); | 241 | dbg("%s - port %d", __FUNCTION__, port->number); |
234 | 242 | ||
243 | down(&port->sem); | ||
244 | |||
235 | if (port->open_count == 0) | 245 | if (port->open_count == 0) |
236 | return; | 246 | goto out; |
237 | 247 | ||
238 | --port->open_count; | 248 | --port->open_count; |
239 | if (port->open_count == 0) { | 249 | if (port->open_count == 0) { |
@@ -251,6 +261,9 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
251 | } | 261 | } |
252 | 262 | ||
253 | kref_put(&port->serial->kref, destroy_serial); | 263 | kref_put(&port->serial->kref, destroy_serial); |
264 | |||
265 | out: | ||
266 | up(&port->sem); | ||
254 | } | 267 | } |
255 | 268 | ||
256 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 269 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
@@ -258,6 +271,9 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int | |||
258 | struct usb_serial_port *port = tty->driver_data; | 271 | struct usb_serial_port *port = tty->driver_data; |
259 | int retval = -EINVAL; | 272 | int retval = -EINVAL; |
260 | 273 | ||
274 | if (!port) | ||
275 | goto exit; | ||
276 | |||
261 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); | 277 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
262 | 278 | ||
263 | if (!port->open_count) { | 279 | if (!port->open_count) { |
@@ -277,6 +293,9 @@ static int serial_write_room (struct tty_struct *tty) | |||
277 | struct usb_serial_port *port = tty->driver_data; | 293 | struct usb_serial_port *port = tty->driver_data; |
278 | int retval = -EINVAL; | 294 | int retval = -EINVAL; |
279 | 295 | ||
296 | if (!port) | ||
297 | goto exit; | ||
298 | |||
280 | dbg("%s - port %d", __FUNCTION__, port->number); | 299 | dbg("%s - port %d", __FUNCTION__, port->number); |
281 | 300 | ||
282 | if (!port->open_count) { | 301 | if (!port->open_count) { |
@@ -296,6 +315,9 @@ static int serial_chars_in_buffer (struct tty_struct *tty) | |||
296 | struct usb_serial_port *port = tty->driver_data; | 315 | struct usb_serial_port *port = tty->driver_data; |
297 | int retval = -EINVAL; | 316 | int retval = -EINVAL; |
298 | 317 | ||
318 | if (!port) | ||
319 | goto exit; | ||
320 | |||
299 | dbg("%s = port %d", __FUNCTION__, port->number); | 321 | dbg("%s = port %d", __FUNCTION__, port->number); |
300 | 322 | ||
301 | if (!port->open_count) { | 323 | if (!port->open_count) { |
@@ -314,6 +336,9 @@ static void serial_throttle (struct tty_struct * tty) | |||
314 | { | 336 | { |
315 | struct usb_serial_port *port = tty->driver_data; | 337 | struct usb_serial_port *port = tty->driver_data; |
316 | 338 | ||
339 | if (!port) | ||
340 | return; | ||
341 | |||
317 | dbg("%s - port %d", __FUNCTION__, port->number); | 342 | dbg("%s - port %d", __FUNCTION__, port->number); |
318 | 343 | ||
319 | if (!port->open_count) { | 344 | if (!port->open_count) { |
@@ -330,6 +355,9 @@ static void serial_unthrottle (struct tty_struct * tty) | |||
330 | { | 355 | { |
331 | struct usb_serial_port *port = tty->driver_data; | 356 | struct usb_serial_port *port = tty->driver_data; |
332 | 357 | ||
358 | if (!port) | ||
359 | return; | ||
360 | |||
333 | dbg("%s - port %d", __FUNCTION__, port->number); | 361 | dbg("%s - port %d", __FUNCTION__, port->number); |
334 | 362 | ||
335 | if (!port->open_count) { | 363 | if (!port->open_count) { |
@@ -347,6 +375,9 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in | |||
347 | struct usb_serial_port *port = tty->driver_data; | 375 | struct usb_serial_port *port = tty->driver_data; |
348 | int retval = -ENODEV; | 376 | int retval = -ENODEV; |
349 | 377 | ||
378 | if (!port) | ||
379 | goto exit; | ||
380 | |||
350 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); | 381 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); |
351 | 382 | ||
352 | if (!port->open_count) { | 383 | if (!port->open_count) { |
@@ -368,6 +399,9 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old) | |||
368 | { | 399 | { |
369 | struct usb_serial_port *port = tty->driver_data; | 400 | struct usb_serial_port *port = tty->driver_data; |
370 | 401 | ||
402 | if (!port) | ||
403 | return; | ||
404 | |||
371 | dbg("%s - port %d", __FUNCTION__, port->number); | 405 | dbg("%s - port %d", __FUNCTION__, port->number); |
372 | 406 | ||
373 | if (!port->open_count) { | 407 | if (!port->open_count) { |
@@ -384,6 +418,9 @@ static void serial_break (struct tty_struct *tty, int break_state) | |||
384 | { | 418 | { |
385 | struct usb_serial_port *port = tty->driver_data; | 419 | struct usb_serial_port *port = tty->driver_data; |
386 | 420 | ||
421 | if (!port) | ||
422 | return; | ||
423 | |||
387 | dbg("%s - port %d", __FUNCTION__, port->number); | 424 | dbg("%s - port %d", __FUNCTION__, port->number); |
388 | 425 | ||
389 | if (!port->open_count) { | 426 | if (!port->open_count) { |
@@ -445,6 +482,9 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file) | |||
445 | { | 482 | { |
446 | struct usb_serial_port *port = tty->driver_data; | 483 | struct usb_serial_port *port = tty->driver_data; |
447 | 484 | ||
485 | if (!port) | ||
486 | goto exit; | ||
487 | |||
448 | dbg("%s - port %d", __FUNCTION__, port->number); | 488 | dbg("%s - port %d", __FUNCTION__, port->number); |
449 | 489 | ||
450 | if (!port->open_count) { | 490 | if (!port->open_count) { |
@@ -464,6 +504,9 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file, | |||
464 | { | 504 | { |
465 | struct usb_serial_port *port = tty->driver_data; | 505 | struct usb_serial_port *port = tty->driver_data; |
466 | 506 | ||
507 | if (!port) | ||
508 | goto exit; | ||
509 | |||
467 | dbg("%s - port %d", __FUNCTION__, port->number); | 510 | dbg("%s - port %d", __FUNCTION__, port->number); |
468 | 511 | ||
469 | if (!port->open_count) { | 512 | if (!port->open_count) { |
@@ -742,6 +785,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
742 | port->number = i + serial->minor; | 785 | port->number = i + serial->minor; |
743 | port->serial = serial; | 786 | port->serial = serial; |
744 | spin_lock_init(&port->lock); | 787 | spin_lock_init(&port->lock); |
788 | sema_init(&port->sem, 1); | ||
745 | INIT_WORK(&port->work, usb_serial_port_softint, port); | 789 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
746 | serial->port[i] = port; | 790 | serial->port[i] = port; |
747 | } | 791 | } |
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 238a5a871ed6..d7d27c3385b3 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
18 | #include <linux/kref.h> | 18 | #include <linux/kref.h> |
19 | #include <asm/semaphore.h> | ||
19 | 20 | ||
20 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ | 21 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ |
21 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ | 22 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ |
@@ -30,6 +31,8 @@ | |||
30 | * @serial: pointer back to the struct usb_serial owner of this port. | 31 | * @serial: pointer back to the struct usb_serial owner of this port. |
31 | * @tty: pointer to the corresponding tty for this port. | 32 | * @tty: pointer to the corresponding tty for this port. |
32 | * @lock: spinlock to grab when updating portions of this structure. | 33 | * @lock: spinlock to grab when updating portions of this structure. |
34 | * @sem: semaphore used to synchronize serial_open() and serial_close() | ||
35 | * access for this port. | ||
33 | * @number: the number of the port (the minor number). | 36 | * @number: the number of the port (the minor number). |
34 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. | 37 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. |
35 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. | 38 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. |
@@ -60,6 +63,7 @@ struct usb_serial_port { | |||
60 | struct usb_serial * serial; | 63 | struct usb_serial * serial; |
61 | struct tty_struct * tty; | 64 | struct tty_struct * tty; |
62 | spinlock_t lock; | 65 | spinlock_t lock; |
66 | struct semaphore sem; | ||
63 | unsigned char number; | 67 | unsigned char number; |
64 | 68 | ||
65 | unsigned char * interrupt_in_buffer; | 69 | unsigned char * interrupt_in_buffer; |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index a473c1c34559..49b1fbe61f25 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -173,11 +173,11 @@ static struct usb_device_id id_table_combined [] = { | |||
173 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 173 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
174 | 174 | ||
175 | static struct usb_driver visor_driver = { | 175 | static struct usb_driver visor_driver = { |
176 | .owner = THIS_MODULE, | ||
177 | .name = "visor", | 176 | .name = "visor", |
178 | .probe = usb_serial_probe, | 177 | .probe = usb_serial_probe, |
179 | .disconnect = usb_serial_disconnect, | 178 | .disconnect = usb_serial_disconnect, |
180 | .id_table = id_table_combined, | 179 | .id_table = id_table_combined, |
180 | .no_dynamic_id = 1, | ||
181 | }; | 181 | }; |
182 | 182 | ||
183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ | 183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 18c3183be769..a7c3c4734d83 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -127,11 +127,11 @@ static struct usb_device_id id_table_combined [] = { | |||
127 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 127 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
128 | 128 | ||
129 | static struct usb_driver whiteheat_driver = { | 129 | static struct usb_driver whiteheat_driver = { |
130 | .owner = THIS_MODULE, | ||
131 | .name = "whiteheat", | 130 | .name = "whiteheat", |
132 | .probe = usb_serial_probe, | 131 | .probe = usb_serial_probe, |
133 | .disconnect = usb_serial_disconnect, | 132 | .disconnect = usb_serial_disconnect, |
134 | .id_table = id_table_combined, | 133 | .id_table = id_table_combined, |
134 | .no_dynamic_id = 1, | ||
135 | }; | 135 | }; |
136 | 136 | ||
137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ | 137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c41d64dbb0f0..92be101feba7 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -112,6 +112,15 @@ config USB_STORAGE_JUMPSHOT | |||
112 | Say Y here to include additional code to support the Lexar Jumpshot | 112 | Say Y here to include additional code to support the Lexar Jumpshot |
113 | USB CompactFlash reader. | 113 | USB CompactFlash reader. |
114 | 114 | ||
115 | config USB_STORAGE_ALAUDA | ||
116 | bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)" | ||
117 | depends on USB_STORAGE && EXPERIMENTAL | ||
118 | help | ||
119 | Say Y here to include additional code to support the Olympus MAUSB-10 | ||
120 | and Fujifilm DPC-R1 USB Card reader/writer devices. | ||
121 | |||
122 | These devices are based on the Alauda chip and support support both | ||
123 | XD and SmartMedia cards. | ||
115 | 124 | ||
116 | config USB_STORAGE_ONETOUCH | 125 | config USB_STORAGE_ONETOUCH |
117 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" | 126 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" |
@@ -124,3 +133,17 @@ config USB_STORAGE_ONETOUCH | |||
124 | hard drive's as an input device. An action can be associated with | 133 | hard drive's as an input device. An action can be associated with |
125 | this input in any keybinding software. (e.g. gnome's keyboard short- | 134 | this input in any keybinding software. (e.g. gnome's keyboard short- |
126 | cuts) | 135 | cuts) |
136 | |||
137 | config USB_LIBUSUAL | ||
138 | bool "The shared table of common (or usual) storage devices" | ||
139 | depends on USB | ||
140 | help | ||
141 | This module contains a table of common (or usual) devices | ||
142 | for usb-storage and ub drivers, and allows to switch binding | ||
143 | of these devices without rebuilding modules. | ||
144 | |||
145 | Typical syntax of /etc/modprobe.conf is: | ||
146 | |||
147 | options libusual bias="ub" | ||
148 | |||
149 | If unsure, say N. | ||
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 44ab8f9978fe..8cbba22508a4 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -18,7 +18,12 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o | |||
18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o | 18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o |
19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o | 19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o |
20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o | 20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o |
21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o | ||
21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | 22 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o |
22 | 23 | ||
23 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 24 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
24 | initializers.o $(usb-storage-obj-y) | 25 | initializers.o $(usb-storage-obj-y) |
26 | |||
27 | ifneq ($(CONFIG_USB_LIBUSUAL),) | ||
28 | obj-$(CONFIG_USB) += libusual.o | ||
29 | endif | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c new file mode 100644 index 000000000000..4d3cbb12b713 --- /dev/null +++ b/drivers/usb/storage/alauda.c | |||
@@ -0,0 +1,1119 @@ | |||
1 | /* | ||
2 | * Driver for Alauda-based card readers | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
6 | * | ||
7 | * The 'Alauda' is a chip manufacturered by RATOC for OEM use. | ||
8 | * | ||
9 | * Alauda implements a vendor-specific command set to access two media reader | ||
10 | * ports (XD, SmartMedia). This driver converts SCSI commands to the commands | ||
11 | * which are accepted by these devices. | ||
12 | * | ||
13 | * The driver was developed through reverse-engineering, with the help of the | ||
14 | * sddr09 driver which has many similarities, and with some help from the | ||
15 | * (very old) vendor-supplied GPL sma03 driver. | ||
16 | * | ||
17 | * For protocol info, see http://alauda.sourceforge.net | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify it | ||
20 | * under the terms of the GNU General Public License as published by the | ||
21 | * Free Software Foundation; either version 2, or (at your option) any | ||
22 | * later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, but | ||
25 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
27 | * General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License along | ||
30 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | ||
33 | |||
34 | #include <scsi/scsi.h> | ||
35 | #include <scsi/scsi_cmnd.h> | ||
36 | #include <scsi/scsi_device.h> | ||
37 | |||
38 | #include "usb.h" | ||
39 | #include "transport.h" | ||
40 | #include "protocol.h" | ||
41 | #include "debug.h" | ||
42 | #include "alauda.h" | ||
43 | |||
44 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | ||
45 | #define LSB_of(s) ((s)&0xFF) | ||
46 | #define MSB_of(s) ((s)>>8) | ||
47 | |||
48 | #define MEDIA_PORT(us) us->srb->device->lun | ||
49 | #define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)] | ||
50 | |||
51 | #define PBA_LO(pba) ((pba & 0xF) << 5) | ||
52 | #define PBA_HI(pba) (pba >> 3) | ||
53 | #define PBA_ZONE(pba) (pba >> 11) | ||
54 | |||
55 | /* | ||
56 | * Media handling | ||
57 | */ | ||
58 | |||
59 | struct alauda_card_info { | ||
60 | unsigned char id; /* id byte */ | ||
61 | unsigned char chipshift; /* 1<<cs bytes total capacity */ | ||
62 | unsigned char pageshift; /* 1<<ps bytes in a page */ | ||
63 | unsigned char blockshift; /* 1<<bs pages per block */ | ||
64 | unsigned char zoneshift; /* 1<<zs blocks per zone */ | ||
65 | }; | ||
66 | |||
67 | static struct alauda_card_info alauda_card_ids[] = { | ||
68 | /* NAND flash */ | ||
69 | { 0x6e, 20, 8, 4, 8}, /* 1 MB */ | ||
70 | { 0xe8, 20, 8, 4, 8}, /* 1 MB */ | ||
71 | { 0xec, 20, 8, 4, 8}, /* 1 MB */ | ||
72 | { 0x64, 21, 8, 4, 9}, /* 2 MB */ | ||
73 | { 0xea, 21, 8, 4, 9}, /* 2 MB */ | ||
74 | { 0x6b, 22, 9, 4, 9}, /* 4 MB */ | ||
75 | { 0xe3, 22, 9, 4, 9}, /* 4 MB */ | ||
76 | { 0xe5, 22, 9, 4, 9}, /* 4 MB */ | ||
77 | { 0xe6, 23, 9, 4, 10}, /* 8 MB */ | ||
78 | { 0x73, 24, 9, 5, 10}, /* 16 MB */ | ||
79 | { 0x75, 25, 9, 5, 10}, /* 32 MB */ | ||
80 | { 0x76, 26, 9, 5, 10}, /* 64 MB */ | ||
81 | { 0x79, 27, 9, 5, 10}, /* 128 MB */ | ||
82 | { 0x71, 28, 9, 5, 10}, /* 256 MB */ | ||
83 | |||
84 | /* MASK ROM */ | ||
85 | { 0x5d, 21, 9, 4, 8}, /* 2 MB */ | ||
86 | { 0xd5, 22, 9, 4, 9}, /* 4 MB */ | ||
87 | { 0xd6, 23, 9, 4, 10}, /* 8 MB */ | ||
88 | { 0x57, 24, 9, 4, 11}, /* 16 MB */ | ||
89 | { 0x58, 25, 9, 4, 12}, /* 32 MB */ | ||
90 | { 0,} | ||
91 | }; | ||
92 | |||
93 | static struct alauda_card_info *alauda_card_find_id(unsigned char id) { | ||
94 | int i; | ||
95 | |||
96 | for (i = 0; alauda_card_ids[i].id != 0; i++) | ||
97 | if (alauda_card_ids[i].id == id) | ||
98 | return &(alauda_card_ids[i]); | ||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * ECC computation. | ||
104 | */ | ||
105 | |||
106 | static unsigned char parity[256]; | ||
107 | static unsigned char ecc2[256]; | ||
108 | |||
109 | static void nand_init_ecc(void) { | ||
110 | int i, j, a; | ||
111 | |||
112 | parity[0] = 0; | ||
113 | for (i = 1; i < 256; i++) | ||
114 | parity[i] = (parity[i&(i-1)] ^ 1); | ||
115 | |||
116 | for (i = 0; i < 256; i++) { | ||
117 | a = 0; | ||
118 | for (j = 0; j < 8; j++) { | ||
119 | if (i & (1<<j)) { | ||
120 | if ((j & 1) == 0) | ||
121 | a ^= 0x04; | ||
122 | if ((j & 2) == 0) | ||
123 | a ^= 0x10; | ||
124 | if ((j & 4) == 0) | ||
125 | a ^= 0x40; | ||
126 | } | ||
127 | } | ||
128 | ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* compute 3-byte ecc on 256 bytes */ | ||
133 | static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) { | ||
134 | int i, j, a; | ||
135 | unsigned char par, bit, bits[8]; | ||
136 | |||
137 | par = 0; | ||
138 | for (j = 0; j < 8; j++) | ||
139 | bits[j] = 0; | ||
140 | |||
141 | /* collect 16 checksum bits */ | ||
142 | for (i = 0; i < 256; i++) { | ||
143 | par ^= data[i]; | ||
144 | bit = parity[data[i]]; | ||
145 | for (j = 0; j < 8; j++) | ||
146 | if ((i & (1<<j)) == 0) | ||
147 | bits[j] ^= bit; | ||
148 | } | ||
149 | |||
150 | /* put 4+4+4 = 12 bits in the ecc */ | ||
151 | a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0]; | ||
152 | ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
153 | |||
154 | a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4]; | ||
155 | ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
156 | |||
157 | ecc[2] = ecc2[par]; | ||
158 | } | ||
159 | |||
160 | static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) { | ||
161 | return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]); | ||
162 | } | ||
163 | |||
164 | static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | ||
165 | memcpy(data, ecc, 3); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Alauda driver | ||
170 | */ | ||
171 | |||
172 | /* | ||
173 | * Forget our PBA <---> LBA mappings for a particular port | ||
174 | */ | ||
175 | static void alauda_free_maps (struct alauda_media_info *media_info) | ||
176 | { | ||
177 | unsigned int shift = media_info->zoneshift | ||
178 | + media_info->blockshift + media_info->pageshift; | ||
179 | unsigned int num_zones = media_info->capacity >> shift; | ||
180 | unsigned int i; | ||
181 | |||
182 | if (media_info->lba_to_pba != NULL) | ||
183 | for (i = 0; i < num_zones; i++) { | ||
184 | kfree(media_info->lba_to_pba[i]); | ||
185 | media_info->lba_to_pba[i] = NULL; | ||
186 | } | ||
187 | |||
188 | if (media_info->pba_to_lba != NULL) | ||
189 | for (i = 0; i < num_zones; i++) { | ||
190 | kfree(media_info->pba_to_lba[i]); | ||
191 | media_info->pba_to_lba[i] = NULL; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Returns 2 bytes of status data | ||
197 | * The first byte describes media status, and second byte describes door status | ||
198 | */ | ||
199 | static int alauda_get_media_status(struct us_data *us, unsigned char *data) | ||
200 | { | ||
201 | int rc; | ||
202 | unsigned char command; | ||
203 | |||
204 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
205 | command = ALAUDA_GET_XD_MEDIA_STATUS; | ||
206 | else | ||
207 | command = ALAUDA_GET_SM_MEDIA_STATUS; | ||
208 | |||
209 | rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
210 | command, 0xc0, 0, 1, data, 2); | ||
211 | |||
212 | US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n", | ||
213 | data[0], data[1]); | ||
214 | |||
215 | return rc; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Clears the "media was changed" bit so that we know when it changes again | ||
220 | * in the future. | ||
221 | */ | ||
222 | static int alauda_ack_media(struct us_data *us) | ||
223 | { | ||
224 | unsigned char command; | ||
225 | |||
226 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
227 | command = ALAUDA_ACK_XD_MEDIA_CHANGE; | ||
228 | else | ||
229 | command = ALAUDA_ACK_SM_MEDIA_CHANGE; | ||
230 | |||
231 | return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, | ||
232 | command, 0x40, 0, 1, NULL, 0); | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * Retrieves a 4-byte media signature, which indicates manufacturer, capacity, | ||
237 | * and some other details. | ||
238 | */ | ||
239 | static int alauda_get_media_signature(struct us_data *us, unsigned char *data) | ||
240 | { | ||
241 | unsigned char command; | ||
242 | |||
243 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
244 | command = ALAUDA_GET_XD_MEDIA_SIG; | ||
245 | else | ||
246 | command = ALAUDA_GET_SM_MEDIA_SIG; | ||
247 | |||
248 | return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
249 | command, 0xc0, 0, 0, data, 4); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Resets the media status (but not the whole device?) | ||
254 | */ | ||
255 | static int alauda_reset_media(struct us_data *us) | ||
256 | { | ||
257 | unsigned char *command = us->iobuf; | ||
258 | |||
259 | memset(command, 0, 9); | ||
260 | command[0] = ALAUDA_BULK_CMD; | ||
261 | command[1] = ALAUDA_BULK_RESET_MEDIA; | ||
262 | command[8] = MEDIA_PORT(us); | ||
263 | |||
264 | return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
265 | command, 9, NULL); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Examines the media and deduces capacity, etc. | ||
270 | */ | ||
271 | static int alauda_init_media(struct us_data *us) | ||
272 | { | ||
273 | unsigned char *data = us->iobuf; | ||
274 | int ready = 0; | ||
275 | struct alauda_card_info *media_info; | ||
276 | unsigned int num_zones; | ||
277 | |||
278 | while (ready == 0) { | ||
279 | msleep(20); | ||
280 | |||
281 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
282 | return USB_STOR_TRANSPORT_ERROR; | ||
283 | |||
284 | if (data[0] & 0x10) | ||
285 | ready = 1; | ||
286 | } | ||
287 | |||
288 | US_DEBUGP("alauda_init_media: We are ready for action!\n"); | ||
289 | |||
290 | if (alauda_ack_media(us) != USB_STOR_XFER_GOOD) | ||
291 | return USB_STOR_TRANSPORT_ERROR; | ||
292 | |||
293 | msleep(10); | ||
294 | |||
295 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
296 | return USB_STOR_TRANSPORT_ERROR; | ||
297 | |||
298 | if (data[0] != 0x14) { | ||
299 | US_DEBUGP("alauda_init_media: Media not ready after ack\n"); | ||
300 | return USB_STOR_TRANSPORT_ERROR; | ||
301 | } | ||
302 | |||
303 | if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD) | ||
304 | return USB_STOR_TRANSPORT_ERROR; | ||
305 | |||
306 | US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n", | ||
307 | data[0], data[1], data[2], data[3]); | ||
308 | media_info = alauda_card_find_id(data[1]); | ||
309 | if (media_info == NULL) { | ||
310 | printk("alauda_init_media: Unrecognised media signature: " | ||
311 | "%02X %02X %02X %02X\n", | ||
312 | data[0], data[1], data[2], data[3]); | ||
313 | return USB_STOR_TRANSPORT_ERROR; | ||
314 | } | ||
315 | |||
316 | MEDIA_INFO(us).capacity = 1 << media_info->chipshift; | ||
317 | US_DEBUGP("Found media with capacity: %ldMB\n", | ||
318 | MEDIA_INFO(us).capacity >> 20); | ||
319 | |||
320 | MEDIA_INFO(us).pageshift = media_info->pageshift; | ||
321 | MEDIA_INFO(us).blockshift = media_info->blockshift; | ||
322 | MEDIA_INFO(us).zoneshift = media_info->zoneshift; | ||
323 | |||
324 | MEDIA_INFO(us).pagesize = 1 << media_info->pageshift; | ||
325 | MEDIA_INFO(us).blocksize = 1 << media_info->blockshift; | ||
326 | MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift; | ||
327 | |||
328 | MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125; | ||
329 | MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1; | ||
330 | |||
331 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
332 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
333 | MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
334 | MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
335 | |||
336 | if (alauda_reset_media(us) != USB_STOR_XFER_GOOD) | ||
337 | return USB_STOR_TRANSPORT_ERROR; | ||
338 | |||
339 | return USB_STOR_TRANSPORT_GOOD; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Examines the media status and does the right thing when the media has gone, | ||
344 | * appeared, or changed. | ||
345 | */ | ||
346 | static int alauda_check_media(struct us_data *us) | ||
347 | { | ||
348 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
349 | unsigned char status[2]; | ||
350 | int rc; | ||
351 | |||
352 | rc = alauda_get_media_status(us, status); | ||
353 | |||
354 | /* Check for no media or door open */ | ||
355 | if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10) | ||
356 | || ((status[1] & 0x01) == 0)) { | ||
357 | US_DEBUGP("alauda_check_media: No media, or door open\n"); | ||
358 | alauda_free_maps(&MEDIA_INFO(us)); | ||
359 | info->sense_key = 0x02; | ||
360 | info->sense_asc = 0x3A; | ||
361 | info->sense_ascq = 0x00; | ||
362 | return USB_STOR_TRANSPORT_FAILED; | ||
363 | } | ||
364 | |||
365 | /* Check for media change */ | ||
366 | if (status[0] & 0x08) { | ||
367 | US_DEBUGP("alauda_check_media: Media change detected\n"); | ||
368 | alauda_free_maps(&MEDIA_INFO(us)); | ||
369 | alauda_init_media(us); | ||
370 | |||
371 | info->sense_key = UNIT_ATTENTION; | ||
372 | info->sense_asc = 0x28; | ||
373 | info->sense_ascq = 0x00; | ||
374 | return USB_STOR_TRANSPORT_FAILED; | ||
375 | } | ||
376 | |||
377 | return USB_STOR_TRANSPORT_GOOD; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * Checks the status from the 2nd status register | ||
382 | * Returns 3 bytes of status data, only the first is known | ||
383 | */ | ||
384 | static int alauda_check_status2(struct us_data *us) | ||
385 | { | ||
386 | int rc; | ||
387 | unsigned char command[] = { | ||
388 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2, | ||
389 | 0, 0, 0, 0, 3, 0, MEDIA_PORT(us) | ||
390 | }; | ||
391 | unsigned char data[3]; | ||
392 | |||
393 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
394 | command, 9, NULL); | ||
395 | if (rc != USB_STOR_XFER_GOOD) | ||
396 | return rc; | ||
397 | |||
398 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
399 | data, 3, NULL); | ||
400 | if (rc != USB_STOR_XFER_GOOD) | ||
401 | return rc; | ||
402 | |||
403 | US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]); | ||
404 | if (data[0] & ALAUDA_STATUS_ERROR) | ||
405 | return USB_STOR_XFER_ERROR; | ||
406 | |||
407 | return USB_STOR_XFER_GOOD; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Gets the redundancy data for the first page of a PBA | ||
412 | * Returns 16 bytes. | ||
413 | */ | ||
414 | static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data) | ||
415 | { | ||
416 | int rc; | ||
417 | unsigned char command[] = { | ||
418 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA, | ||
419 | PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us) | ||
420 | }; | ||
421 | |||
422 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
423 | command, 9, NULL); | ||
424 | if (rc != USB_STOR_XFER_GOOD) | ||
425 | return rc; | ||
426 | |||
427 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
428 | data, 16, NULL); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Finds the first unused PBA in a zone | ||
433 | * Returns the absolute PBA of an unused PBA, or 0 if none found. | ||
434 | */ | ||
435 | static u16 alauda_find_unused_pba(struct alauda_media_info *info, | ||
436 | unsigned int zone) | ||
437 | { | ||
438 | u16 *pba_to_lba = info->pba_to_lba[zone]; | ||
439 | unsigned int i; | ||
440 | |||
441 | for (i = 0; i < info->zonesize; i++) | ||
442 | if (pba_to_lba[i] == UNDEF) | ||
443 | return (zone << info->zoneshift) + i; | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Reads the redundancy data for all PBA's in a zone | ||
450 | * Produces lba <--> pba mappings | ||
451 | */ | ||
452 | static int alauda_read_map(struct us_data *us, unsigned int zone) | ||
453 | { | ||
454 | unsigned char *data = us->iobuf; | ||
455 | int result; | ||
456 | int i, j; | ||
457 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
458 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
459 | unsigned int lba_offset, lba_real, blocknum; | ||
460 | unsigned int zone_base_lba = zone * uzonesize; | ||
461 | unsigned int zone_base_pba = zone * zonesize; | ||
462 | u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
463 | u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
464 | if (lba_to_pba == NULL || pba_to_lba == NULL) { | ||
465 | result = USB_STOR_TRANSPORT_ERROR; | ||
466 | goto error; | ||
467 | } | ||
468 | |||
469 | US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone); | ||
470 | |||
471 | /* 1024 PBA's per zone */ | ||
472 | for (i = 0; i < zonesize; i++) | ||
473 | lba_to_pba[i] = pba_to_lba[i] = UNDEF; | ||
474 | |||
475 | for (i = 0; i < zonesize; i++) { | ||
476 | blocknum = zone_base_pba + i; | ||
477 | |||
478 | result = alauda_get_redu_data(us, blocknum, data); | ||
479 | if (result != USB_STOR_XFER_GOOD) { | ||
480 | result = USB_STOR_TRANSPORT_ERROR; | ||
481 | goto error; | ||
482 | } | ||
483 | |||
484 | /* special PBAs have control field 0^16 */ | ||
485 | for (j = 0; j < 16; j++) | ||
486 | if (data[j] != 0) | ||
487 | goto nonz; | ||
488 | pba_to_lba[i] = UNUSABLE; | ||
489 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum); | ||
490 | continue; | ||
491 | |||
492 | nonz: | ||
493 | /* unwritten PBAs have control field FF^16 */ | ||
494 | for (j = 0; j < 16; j++) | ||
495 | if (data[j] != 0xff) | ||
496 | goto nonff; | ||
497 | continue; | ||
498 | |||
499 | nonff: | ||
500 | /* normal PBAs start with six FFs */ | ||
501 | if (j < 6) { | ||
502 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: " | ||
503 | "reserved area = %02X%02X%02X%02X " | ||
504 | "data status %02X block status %02X\n", | ||
505 | blocknum, data[0], data[1], data[2], data[3], | ||
506 | data[4], data[5]); | ||
507 | pba_to_lba[i] = UNUSABLE; | ||
508 | continue; | ||
509 | } | ||
510 | |||
511 | if ((data[6] >> 4) != 0x01) { | ||
512 | US_DEBUGP("alauda_read_map: PBA %d has invalid address " | ||
513 | "field %02X%02X/%02X%02X\n", | ||
514 | blocknum, data[6], data[7], data[11], data[12]); | ||
515 | pba_to_lba[i] = UNUSABLE; | ||
516 | continue; | ||
517 | } | ||
518 | |||
519 | /* check even parity */ | ||
520 | if (parity[data[6] ^ data[7]]) { | ||
521 | printk("alauda_read_map: Bad parity in LBA for block %d" | ||
522 | " (%02X %02X)\n", i, data[6], data[7]); | ||
523 | pba_to_lba[i] = UNUSABLE; | ||
524 | continue; | ||
525 | } | ||
526 | |||
527 | lba_offset = short_pack(data[7], data[6]); | ||
528 | lba_offset = (lba_offset & 0x07FF) >> 1; | ||
529 | lba_real = lba_offset + zone_base_lba; | ||
530 | |||
531 | /* | ||
532 | * Every 1024 physical blocks ("zone"), the LBA numbers | ||
533 | * go back to zero, but are within a higher block of LBA's. | ||
534 | * Also, there is a maximum of 1000 LBA's per zone. | ||
535 | * In other words, in PBA 1024-2047 you will find LBA 0-999 | ||
536 | * which are really LBA 1000-1999. This allows for 24 bad | ||
537 | * or special physical blocks per zone. | ||
538 | */ | ||
539 | |||
540 | if (lba_offset >= uzonesize) { | ||
541 | printk("alauda_read_map: Bad low LBA %d for block %d\n", | ||
542 | lba_real, blocknum); | ||
543 | continue; | ||
544 | } | ||
545 | |||
546 | if (lba_to_pba[lba_offset] != UNDEF) { | ||
547 | printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", | ||
548 | lba_real, lba_to_pba[lba_offset], blocknum); | ||
549 | continue; | ||
550 | } | ||
551 | |||
552 | pba_to_lba[i] = lba_real; | ||
553 | lba_to_pba[lba_offset] = blocknum; | ||
554 | continue; | ||
555 | } | ||
556 | |||
557 | MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba; | ||
558 | MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba; | ||
559 | result = 0; | ||
560 | goto out; | ||
561 | |||
562 | error: | ||
563 | kfree(lba_to_pba); | ||
564 | kfree(pba_to_lba); | ||
565 | out: | ||
566 | return result; | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Checks to see whether we have already mapped a certain zone | ||
571 | * If we haven't, the map is generated | ||
572 | */ | ||
573 | static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone) | ||
574 | { | ||
575 | if (MEDIA_INFO(us).lba_to_pba[zone] == NULL | ||
576 | || MEDIA_INFO(us).pba_to_lba[zone] == NULL) | ||
577 | alauda_read_map(us, zone); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * Erases an entire block | ||
582 | */ | ||
583 | static int alauda_erase_block(struct us_data *us, u16 pba) | ||
584 | { | ||
585 | int rc; | ||
586 | unsigned char command[] = { | ||
587 | ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba), | ||
588 | PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us) | ||
589 | }; | ||
590 | unsigned char buf[2]; | ||
591 | |||
592 | US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba); | ||
593 | |||
594 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
595 | command, 9, NULL); | ||
596 | if (rc != USB_STOR_XFER_GOOD) | ||
597 | return rc; | ||
598 | |||
599 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
600 | buf, 2, NULL); | ||
601 | if (rc != USB_STOR_XFER_GOOD) | ||
602 | return rc; | ||
603 | |||
604 | US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n", | ||
605 | buf[0], buf[1]); | ||
606 | return rc; | ||
607 | } | ||
608 | |||
609 | /* | ||
610 | * Reads data from a certain offset page inside a PBA, including interleaved | ||
611 | * redundancy data. Returns (pagesize+64)*pages bytes in data. | ||
612 | */ | ||
613 | static int alauda_read_block_raw(struct us_data *us, u16 pba, | ||
614 | unsigned int page, unsigned int pages, unsigned char *data) | ||
615 | { | ||
616 | int rc; | ||
617 | unsigned char command[] = { | ||
618 | ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba), | ||
619 | PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us) | ||
620 | }; | ||
621 | |||
622 | US_DEBUGP("alauda_read_block: pba %d page %d count %d\n", | ||
623 | pba, page, pages); | ||
624 | |||
625 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
626 | command, 9, NULL); | ||
627 | if (rc != USB_STOR_XFER_GOOD) | ||
628 | return rc; | ||
629 | |||
630 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
631 | data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL); | ||
632 | } | ||
633 | |||
634 | /* | ||
635 | * Reads data from a certain offset page inside a PBA, excluding redundancy | ||
636 | * data. Returns pagesize*pages bytes in data. Note that data must be big enough | ||
637 | * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra' | ||
638 | * trailing bytes outside this function. | ||
639 | */ | ||
640 | static int alauda_read_block(struct us_data *us, u16 pba, | ||
641 | unsigned int page, unsigned int pages, unsigned char *data) | ||
642 | { | ||
643 | int i, rc; | ||
644 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
645 | |||
646 | rc = alauda_read_block_raw(us, pba, page, pages, data); | ||
647 | if (rc != USB_STOR_XFER_GOOD) | ||
648 | return rc; | ||
649 | |||
650 | /* Cut out the redundancy data */ | ||
651 | for (i = 0; i < pages; i++) { | ||
652 | int dest_offset = i * pagesize; | ||
653 | int src_offset = i * (pagesize + 64); | ||
654 | memmove(data + dest_offset, data + src_offset, pagesize); | ||
655 | } | ||
656 | |||
657 | return rc; | ||
658 | } | ||
659 | |||
660 | /* | ||
661 | * Writes an entire block of data and checks status after write. | ||
662 | * Redundancy data must be already included in data. Data should be | ||
663 | * (pagesize+64)*blocksize bytes in length. | ||
664 | */ | ||
665 | static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data) | ||
666 | { | ||
667 | int rc; | ||
668 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
669 | unsigned char command[] = { | ||
670 | ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba), | ||
671 | PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us) | ||
672 | }; | ||
673 | |||
674 | US_DEBUGP("alauda_write_block: pba %d\n", pba); | ||
675 | |||
676 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
677 | command, 9, NULL); | ||
678 | if (rc != USB_STOR_XFER_GOOD) | ||
679 | return rc; | ||
680 | |||
681 | rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data, | ||
682 | (MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize, | ||
683 | NULL); | ||
684 | if (rc != USB_STOR_XFER_GOOD) | ||
685 | return rc; | ||
686 | |||
687 | return alauda_check_status2(us); | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Write some data to a specific LBA. | ||
692 | */ | ||
693 | static int alauda_write_lba(struct us_data *us, u16 lba, | ||
694 | unsigned int page, unsigned int pages, | ||
695 | unsigned char *ptr, unsigned char *blockbuffer) | ||
696 | { | ||
697 | u16 pba, lbap, new_pba; | ||
698 | unsigned char *bptr, *cptr, *xptr; | ||
699 | unsigned char ecc[3]; | ||
700 | int i, result; | ||
701 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
702 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
703 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
704 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
705 | unsigned int lba_offset = lba % uzonesize; | ||
706 | unsigned int new_pba_offset; | ||
707 | unsigned int zone = lba / uzonesize; | ||
708 | |||
709 | alauda_ensure_map_for_zone(us, zone); | ||
710 | |||
711 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
712 | if (pba == 1) { | ||
713 | /* Maybe it is impossible to write to PBA 1. | ||
714 | Fake success, but don't do anything. */ | ||
715 | printk("alauda_write_lba: avoid writing to pba 1\n"); | ||
716 | return USB_STOR_TRANSPORT_GOOD; | ||
717 | } | ||
718 | |||
719 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | ||
720 | if (!new_pba) { | ||
721 | printk("alauda_write_lba: Out of unused blocks\n"); | ||
722 | return USB_STOR_TRANSPORT_ERROR; | ||
723 | } | ||
724 | |||
725 | /* read old contents */ | ||
726 | if (pba != UNDEF) { | ||
727 | result = alauda_read_block_raw(us, pba, 0, | ||
728 | blocksize, blockbuffer); | ||
729 | if (result != USB_STOR_XFER_GOOD) | ||
730 | return result; | ||
731 | } else { | ||
732 | memset(blockbuffer, 0, blocksize * (pagesize + 64)); | ||
733 | } | ||
734 | |||
735 | lbap = (lba_offset << 1) | 0x1000; | ||
736 | if (parity[MSB_of(lbap) ^ LSB_of(lbap)]) | ||
737 | lbap ^= 1; | ||
738 | |||
739 | /* check old contents and fill lba */ | ||
740 | for (i = 0; i < blocksize; i++) { | ||
741 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
742 | cptr = bptr + pagesize; | ||
743 | nand_compute_ecc(bptr, ecc); | ||
744 | if (!nand_compare_ecc(cptr+13, ecc)) { | ||
745 | US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n", | ||
746 | i, pba); | ||
747 | nand_store_ecc(cptr+13, ecc); | ||
748 | } | ||
749 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
750 | if (!nand_compare_ecc(cptr+8, ecc)) { | ||
751 | US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n", | ||
752 | i, pba); | ||
753 | nand_store_ecc(cptr+8, ecc); | ||
754 | } | ||
755 | cptr[6] = cptr[11] = MSB_of(lbap); | ||
756 | cptr[7] = cptr[12] = LSB_of(lbap); | ||
757 | } | ||
758 | |||
759 | /* copy in new stuff and compute ECC */ | ||
760 | xptr = ptr; | ||
761 | for (i = page; i < page+pages; i++) { | ||
762 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
763 | cptr = bptr + pagesize; | ||
764 | memcpy(bptr, xptr, pagesize); | ||
765 | xptr += pagesize; | ||
766 | nand_compute_ecc(bptr, ecc); | ||
767 | nand_store_ecc(cptr+13, ecc); | ||
768 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
769 | nand_store_ecc(cptr+8, ecc); | ||
770 | } | ||
771 | |||
772 | result = alauda_write_block(us, new_pba, blockbuffer); | ||
773 | if (result != USB_STOR_XFER_GOOD) | ||
774 | return result; | ||
775 | |||
776 | new_pba_offset = new_pba - (zone * zonesize); | ||
777 | MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba; | ||
778 | MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba; | ||
779 | US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n", | ||
780 | lba, new_pba); | ||
781 | |||
782 | if (pba != UNDEF) { | ||
783 | unsigned int pba_offset = pba - (zone * zonesize); | ||
784 | result = alauda_erase_block(us, pba); | ||
785 | if (result != USB_STOR_XFER_GOOD) | ||
786 | return result; | ||
787 | MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF; | ||
788 | } | ||
789 | |||
790 | return USB_STOR_TRANSPORT_GOOD; | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Read data from a specific sector address | ||
795 | */ | ||
796 | static int alauda_read_data(struct us_data *us, unsigned long address, | ||
797 | unsigned int sectors) | ||
798 | { | ||
799 | unsigned char *buffer; | ||
800 | u16 lba, max_lba; | ||
801 | unsigned int page, len, index, offset; | ||
802 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
803 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
804 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
805 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
806 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
807 | int result; | ||
808 | |||
809 | /* | ||
810 | * Since we only read in one block at a time, we have to create | ||
811 | * a bounce buffer and move the data a piece at a time between the | ||
812 | * bounce buffer and the actual transfer buffer. | ||
813 | * We make this buffer big enough to hold temporary redundancy data, | ||
814 | * which we use when reading the data blocks. | ||
815 | */ | ||
816 | |||
817 | len = min(sectors, blocksize) * (pagesize + 64); | ||
818 | buffer = kmalloc(len, GFP_NOIO); | ||
819 | if (buffer == NULL) { | ||
820 | printk("alauda_read_data: Out of memory\n"); | ||
821 | return USB_STOR_TRANSPORT_ERROR; | ||
822 | } | ||
823 | |||
824 | /* Figure out the initial LBA and page */ | ||
825 | lba = address >> blockshift; | ||
826 | page = (address & MEDIA_INFO(us).blockmask); | ||
827 | max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift); | ||
828 | |||
829 | result = USB_STOR_TRANSPORT_GOOD; | ||
830 | index = offset = 0; | ||
831 | |||
832 | while (sectors > 0) { | ||
833 | unsigned int zone = lba / uzonesize; /* integer division */ | ||
834 | unsigned int lba_offset = lba - (zone * uzonesize); | ||
835 | unsigned int pages; | ||
836 | u16 pba; | ||
837 | alauda_ensure_map_for_zone(us, zone); | ||
838 | |||
839 | /* Not overflowing capacity? */ | ||
840 | if (lba >= max_lba) { | ||
841 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
842 | "maximum %u\n", lba, max_lba); | ||
843 | result = USB_STOR_TRANSPORT_ERROR; | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | /* Find number of pages we can read in this block */ | ||
848 | pages = min(sectors, blocksize - page); | ||
849 | len = pages << pageshift; | ||
850 | |||
851 | /* Find where this lba lives on disk */ | ||
852 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
853 | |||
854 | if (pba == UNDEF) { /* this lba was never written */ | ||
855 | US_DEBUGP("Read %d zero pages (LBA %d) page %d\n", | ||
856 | pages, lba, page); | ||
857 | |||
858 | /* This is not really an error. It just means | ||
859 | that the block has never been written. | ||
860 | Instead of returning USB_STOR_TRANSPORT_ERROR | ||
861 | it is better to return all zero data. */ | ||
862 | |||
863 | memset(buffer, 0, len); | ||
864 | } else { | ||
865 | US_DEBUGP("Read %d pages, from PBA %d" | ||
866 | " (LBA %d) page %d\n", | ||
867 | pages, pba, lba, page); | ||
868 | |||
869 | result = alauda_read_block(us, pba, page, pages, buffer); | ||
870 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
871 | break; | ||
872 | } | ||
873 | |||
874 | /* Store the data in the transfer buffer */ | ||
875 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
876 | &index, &offset, TO_XFER_BUF); | ||
877 | |||
878 | page = 0; | ||
879 | lba++; | ||
880 | sectors -= pages; | ||
881 | } | ||
882 | |||
883 | kfree(buffer); | ||
884 | return result; | ||
885 | } | ||
886 | |||
887 | /* | ||
888 | * Write data to a specific sector address | ||
889 | */ | ||
890 | static int alauda_write_data(struct us_data *us, unsigned long address, | ||
891 | unsigned int sectors) | ||
892 | { | ||
893 | unsigned char *buffer, *blockbuffer; | ||
894 | unsigned int page, len, index, offset; | ||
895 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
896 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
897 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
898 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
899 | u16 lba, max_lba; | ||
900 | int result; | ||
901 | |||
902 | /* | ||
903 | * Since we don't write the user data directly to the device, | ||
904 | * we have to create a bounce buffer and move the data a piece | ||
905 | * at a time between the bounce buffer and the actual transfer buffer. | ||
906 | */ | ||
907 | |||
908 | len = min(sectors, blocksize) * pagesize; | ||
909 | buffer = kmalloc(len, GFP_NOIO); | ||
910 | if (buffer == NULL) { | ||
911 | printk("alauda_write_data: Out of memory\n"); | ||
912 | return USB_STOR_TRANSPORT_ERROR; | ||
913 | } | ||
914 | |||
915 | /* | ||
916 | * We also need a temporary block buffer, where we read in the old data, | ||
917 | * overwrite parts with the new data, and manipulate the redundancy data | ||
918 | */ | ||
919 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | ||
920 | if (blockbuffer == NULL) { | ||
921 | printk("alauda_write_data: Out of memory\n"); | ||
922 | kfree(buffer); | ||
923 | return USB_STOR_TRANSPORT_ERROR; | ||
924 | } | ||
925 | |||
926 | /* Figure out the initial LBA and page */ | ||
927 | lba = address >> blockshift; | ||
928 | page = (address & MEDIA_INFO(us).blockmask); | ||
929 | max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift); | ||
930 | |||
931 | result = USB_STOR_TRANSPORT_GOOD; | ||
932 | index = offset = 0; | ||
933 | |||
934 | while (sectors > 0) { | ||
935 | /* Write as many sectors as possible in this block */ | ||
936 | unsigned int pages = min(sectors, blocksize - page); | ||
937 | len = pages << pageshift; | ||
938 | |||
939 | /* Not overflowing capacity? */ | ||
940 | if (lba >= max_lba) { | ||
941 | US_DEBUGP("alauda_write_data: Requested lba %u exceeds " | ||
942 | "maximum %u\n", lba, max_lba); | ||
943 | result = USB_STOR_TRANSPORT_ERROR; | ||
944 | break; | ||
945 | } | ||
946 | |||
947 | /* Get the data from the transfer buffer */ | ||
948 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
949 | &index, &offset, FROM_XFER_BUF); | ||
950 | |||
951 | result = alauda_write_lba(us, lba, page, pages, buffer, | ||
952 | blockbuffer); | ||
953 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
954 | break; | ||
955 | |||
956 | page = 0; | ||
957 | lba++; | ||
958 | sectors -= pages; | ||
959 | } | ||
960 | |||
961 | kfree(buffer); | ||
962 | kfree(blockbuffer); | ||
963 | return result; | ||
964 | } | ||
965 | |||
966 | /* | ||
967 | * Our interface with the rest of the world | ||
968 | */ | ||
969 | |||
970 | static void alauda_info_destructor(void *extra) | ||
971 | { | ||
972 | struct alauda_info *info = (struct alauda_info *) extra; | ||
973 | int port; | ||
974 | |||
975 | if (!info) | ||
976 | return; | ||
977 | |||
978 | for (port = 0; port < 2; port++) { | ||
979 | struct alauda_media_info *media_info = &info->port[port]; | ||
980 | |||
981 | alauda_free_maps(media_info); | ||
982 | kfree(media_info->lba_to_pba); | ||
983 | kfree(media_info->pba_to_lba); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | /* | ||
988 | * Initialize alauda_info struct and find the data-write endpoint | ||
989 | */ | ||
990 | int init_alauda(struct us_data *us) | ||
991 | { | ||
992 | struct alauda_info *info; | ||
993 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | ||
994 | nand_init_ecc(); | ||
995 | |||
996 | us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO); | ||
997 | if (!us->extra) { | ||
998 | US_DEBUGP("init_alauda: Gah! Can't allocate storage for" | ||
999 | "alauda info struct!\n"); | ||
1000 | return USB_STOR_TRANSPORT_ERROR; | ||
1001 | } | ||
1002 | info = (struct alauda_info *) us->extra; | ||
1003 | us->extra_destructor = alauda_info_destructor; | ||
1004 | |||
1005 | info->wr_ep = usb_sndbulkpipe(us->pusb_dev, | ||
1006 | altsetting->endpoint[0].desc.bEndpointAddress | ||
1007 | & USB_ENDPOINT_NUMBER_MASK); | ||
1008 | |||
1009 | return USB_STOR_TRANSPORT_GOOD; | ||
1010 | } | ||
1011 | |||
1012 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | ||
1013 | { | ||
1014 | int rc; | ||
1015 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
1016 | unsigned char *ptr = us->iobuf; | ||
1017 | static unsigned char inquiry_response[36] = { | ||
1018 | 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 | ||
1019 | }; | ||
1020 | |||
1021 | if (srb->cmnd[0] == INQUIRY) { | ||
1022 | US_DEBUGP("alauda_transport: INQUIRY. " | ||
1023 | "Returning bogus response.\n"); | ||
1024 | memcpy(ptr, inquiry_response, sizeof(inquiry_response)); | ||
1025 | fill_inquiry_response(us, ptr, 36); | ||
1026 | return USB_STOR_TRANSPORT_GOOD; | ||
1027 | } | ||
1028 | |||
1029 | if (srb->cmnd[0] == TEST_UNIT_READY) { | ||
1030 | US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n"); | ||
1031 | return alauda_check_media(us); | ||
1032 | } | ||
1033 | |||
1034 | if (srb->cmnd[0] == READ_CAPACITY) { | ||
1035 | unsigned int num_zones; | ||
1036 | unsigned long capacity; | ||
1037 | |||
1038 | rc = alauda_check_media(us); | ||
1039 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1040 | return rc; | ||
1041 | |||
1042 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
1043 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
1044 | |||
1045 | capacity = num_zones * MEDIA_INFO(us).uzonesize | ||
1046 | * MEDIA_INFO(us).blocksize; | ||
1047 | |||
1048 | /* Report capacity and page size */ | ||
1049 | ((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1); | ||
1050 | ((__be32 *) ptr)[1] = cpu_to_be32(512); | ||
1051 | |||
1052 | usb_stor_set_xfer_buf(ptr, 8, srb); | ||
1053 | return USB_STOR_TRANSPORT_GOOD; | ||
1054 | } | ||
1055 | |||
1056 | if (srb->cmnd[0] == READ_10) { | ||
1057 | unsigned int page, pages; | ||
1058 | |||
1059 | rc = alauda_check_media(us); | ||
1060 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1061 | return rc; | ||
1062 | |||
1063 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
1064 | page <<= 16; | ||
1065 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
1066 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
1067 | |||
1068 | US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n", | ||
1069 | page, pages); | ||
1070 | |||
1071 | return alauda_read_data(us, page, pages); | ||
1072 | } | ||
1073 | |||
1074 | if (srb->cmnd[0] == WRITE_10) { | ||
1075 | unsigned int page, pages; | ||
1076 | |||
1077 | rc = alauda_check_media(us); | ||
1078 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1079 | return rc; | ||
1080 | |||
1081 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
1082 | page <<= 16; | ||
1083 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
1084 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
1085 | |||
1086 | US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n", | ||
1087 | page, pages); | ||
1088 | |||
1089 | return alauda_write_data(us, page, pages); | ||
1090 | } | ||
1091 | |||
1092 | if (srb->cmnd[0] == REQUEST_SENSE) { | ||
1093 | US_DEBUGP("alauda_transport: REQUEST_SENSE.\n"); | ||
1094 | |||
1095 | memset(ptr, 0, 18); | ||
1096 | ptr[0] = 0xF0; | ||
1097 | ptr[2] = info->sense_key; | ||
1098 | ptr[7] = 11; | ||
1099 | ptr[12] = info->sense_asc; | ||
1100 | ptr[13] = info->sense_ascq; | ||
1101 | usb_stor_set_xfer_buf(ptr, 18, srb); | ||
1102 | |||
1103 | return USB_STOR_TRANSPORT_GOOD; | ||
1104 | } | ||
1105 | |||
1106 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | ||
1107 | /* sure. whatever. not like we can stop the user from popping | ||
1108 | the media out of the device (no locking doors, etc) */ | ||
1109 | return USB_STOR_TRANSPORT_GOOD; | ||
1110 | } | ||
1111 | |||
1112 | US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n", | ||
1113 | srb->cmnd[0], srb->cmnd[0]); | ||
1114 | info->sense_key = 0x05; | ||
1115 | info->sense_asc = 0x20; | ||
1116 | info->sense_ascq = 0x00; | ||
1117 | return USB_STOR_TRANSPORT_FAILED; | ||
1118 | } | ||
1119 | |||
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h new file mode 100644 index 000000000000..a700f87d0803 --- /dev/null +++ b/drivers/usb/storage/alauda.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Driver for Alauda-based card readers | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
6 | * | ||
7 | * See alauda.c for more explanation. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_ALAUDA_H | ||
25 | #define _USB_ALAUDA_H | ||
26 | |||
27 | /* | ||
28 | * Status bytes | ||
29 | */ | ||
30 | #define ALAUDA_STATUS_ERROR 0x01 | ||
31 | #define ALAUDA_STATUS_READY 0x40 | ||
32 | |||
33 | /* | ||
34 | * Control opcodes (for request field) | ||
35 | */ | ||
36 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
37 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
38 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
39 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
40 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
41 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
42 | |||
43 | /* | ||
44 | * Bulk command identity (byte 0) | ||
45 | */ | ||
46 | #define ALAUDA_BULK_CMD 0x40 | ||
47 | |||
48 | /* | ||
49 | * Bulk opcodes (byte 1) | ||
50 | */ | ||
51 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
52 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
53 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
54 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
55 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
56 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
57 | |||
58 | /* | ||
59 | * Port to operate on (byte 8) | ||
60 | */ | ||
61 | #define ALAUDA_PORT_XD 0x00 | ||
62 | #define ALAUDA_PORT_SM 0x01 | ||
63 | |||
64 | /* | ||
65 | * LBA and PBA are unsigned ints. Special values. | ||
66 | */ | ||
67 | #define UNDEF 0xffff | ||
68 | #define SPARE 0xfffe | ||
69 | #define UNUSABLE 0xfffd | ||
70 | |||
71 | int init_alauda(struct us_data *us); | ||
72 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
73 | |||
74 | struct alauda_media_info { | ||
75 | unsigned long capacity; /* total media size in bytes */ | ||
76 | unsigned int pagesize; /* page size in bytes */ | ||
77 | unsigned int blocksize; /* number of pages per block */ | ||
78 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
79 | unsigned int zonesize; /* number of blocks per zone */ | ||
80 | unsigned int blockmask; /* mask to get page from address */ | ||
81 | |||
82 | unsigned char pageshift; | ||
83 | unsigned char blockshift; | ||
84 | unsigned char zoneshift; | ||
85 | |||
86 | u16 **lba_to_pba; /* logical to physical block map */ | ||
87 | u16 **pba_to_lba; /* physical to logical block map */ | ||
88 | }; | ||
89 | |||
90 | struct alauda_info { | ||
91 | struct alauda_media_info port[2]; | ||
92 | int wr_ep; /* endpoint to write data out of */ | ||
93 | |||
94 | unsigned char sense_key; | ||
95 | unsigned long sense_asc; /* additional sense code */ | ||
96 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
97 | }; | ||
98 | |||
99 | #endif | ||
100 | |||
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 5a9321705a74..01e430654a13 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c | |||
@@ -132,6 +132,7 @@ void usb_stor_show_command(struct scsi_cmnd *srb) | |||
132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; | 132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; |
133 | case 0x5D: what = "SEND CUE SHEET"; break; | 133 | case 0x5D: what = "SEND CUE SHEET"; break; |
134 | case GPCMD_BLANK: what = "BLANK"; break; | 134 | case GPCMD_BLANK: what = "BLANK"; break; |
135 | case REPORT_LUNS: what = "REPORT LUNS"; break; | ||
135 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; | 136 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; |
136 | case READ_12: what = "READ_12"; break; | 137 | case READ_12: what = "READ_12"; break; |
137 | case WRITE_12: what = "WRITE_12"; break; | 138 | case WRITE_12: what = "WRITE_12"; break; |
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 7372386f33d5..4c1b2bd2e2e4 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -45,10 +45,6 @@ | |||
45 | * mode */ | 45 | * mode */ |
46 | int usb_stor_euscsi_init(struct us_data *us); | 46 | int usb_stor_euscsi_init(struct us_data *us); |
47 | 47 | ||
48 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
49 | int sddr09_init(struct us_data *us); | ||
50 | #endif | ||
51 | |||
52 | /* This function is required to activate all four slots on the UCR-61S2B | 48 | /* This function is required to activate all four slots on the UCR-61S2B |
53 | * flash reader */ | 49 | * flash reader */ |
54 | int usb_stor_ucr61s2b_init(struct us_data *us); | 50 | int usb_stor_ucr61s2b_init(struct us_data *us); |
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c new file mode 100644 index 000000000000..b28151d1b609 --- /dev/null +++ b/drivers/usb/storage/libusual.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * libusual | ||
3 | * | ||
4 | * The libusual contains the table of devices common for ub and usb-storage. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/usb.h> | ||
9 | #include <linux/usb_usual.h> | ||
10 | #include <linux/vmalloc.h> | ||
11 | |||
12 | /* | ||
13 | */ | ||
14 | #define USU_MOD_FL_THREAD 1 /* Thread is running */ | ||
15 | #define USU_MOD_FL_PRESENT 2 /* The module is loaded */ | ||
16 | |||
17 | struct mod_status { | ||
18 | unsigned long fls; | ||
19 | }; | ||
20 | |||
21 | static struct mod_status stat[3]; | ||
22 | static DEFINE_SPINLOCK(usu_lock); | ||
23 | |||
24 | /* | ||
25 | */ | ||
26 | #define USB_US_DEFAULT_BIAS USB_US_TYPE_STOR | ||
27 | static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); | ||
28 | |||
29 | #define BIAS_NAME_SIZE (sizeof("usb-storage")) | ||
30 | static const char *bias_names[3] = { "none", "usb-storage", "ub" }; | ||
31 | |||
32 | static DECLARE_MUTEX_LOCKED(usu_init_notify); | ||
33 | static DECLARE_COMPLETION(usu_end_notify); | ||
34 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
35 | |||
36 | static int usu_probe_thread(void *arg); | ||
37 | |||
38 | /* | ||
39 | * The table. | ||
40 | */ | ||
41 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
42 | vendorName, productName,useProtocol, useTransport, \ | ||
43 | initFunction, flags) \ | ||
44 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
45 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
46 | |||
47 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
48 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
49 | .driver_info = ((useType)<<24) } | ||
50 | |||
51 | struct usb_device_id storage_usb_ids [] = { | ||
52 | # include "unusual_devs.h" | ||
53 | { } /* Terminating entry */ | ||
54 | }; | ||
55 | |||
56 | #undef USUAL_DEV | ||
57 | #undef UNUSUAL_DEV | ||
58 | |||
59 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
60 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
61 | |||
62 | /* | ||
63 | * @type: the module type as an integer | ||
64 | */ | ||
65 | void usb_usual_set_present(int type) | ||
66 | { | ||
67 | struct mod_status *st; | ||
68 | unsigned long flags; | ||
69 | |||
70 | if (type <= 0 || type >= 3) | ||
71 | return; | ||
72 | st = &stat[type]; | ||
73 | spin_lock_irqsave(&usu_lock, flags); | ||
74 | st->fls |= USU_MOD_FL_PRESENT; | ||
75 | spin_unlock_irqrestore(&usu_lock, flags); | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(usb_usual_set_present); | ||
78 | |||
79 | void usb_usual_clear_present(int type) | ||
80 | { | ||
81 | struct mod_status *st; | ||
82 | unsigned long flags; | ||
83 | |||
84 | if (type <= 0 || type >= 3) | ||
85 | return; | ||
86 | st = &stat[type]; | ||
87 | spin_lock_irqsave(&usu_lock, flags); | ||
88 | st->fls &= ~USU_MOD_FL_PRESENT; | ||
89 | spin_unlock_irqrestore(&usu_lock, flags); | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(usb_usual_clear_present); | ||
92 | |||
93 | /* | ||
94 | * Match the calling driver type against the table. | ||
95 | * Returns: 0 if the device matches. | ||
96 | */ | ||
97 | int usb_usual_check_type(const struct usb_device_id *id, int caller_type) | ||
98 | { | ||
99 | int id_type = USB_US_TYPE(id->driver_info); | ||
100 | |||
101 | if (caller_type <= 0 || caller_type >= 3) | ||
102 | return -EINVAL; | ||
103 | |||
104 | /* Drivers grab fixed assignment devices */ | ||
105 | if (id_type == caller_type) | ||
106 | return 0; | ||
107 | /* Drivers grab devices biased to them */ | ||
108 | if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias)) | ||
109 | return 0; | ||
110 | return -ENODEV; | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(usb_usual_check_type); | ||
113 | |||
114 | /* | ||
115 | */ | ||
116 | static int usu_probe(struct usb_interface *intf, | ||
117 | const struct usb_device_id *id) | ||
118 | { | ||
119 | int type; | ||
120 | int rc; | ||
121 | unsigned long flags; | ||
122 | |||
123 | type = USB_US_TYPE(id->driver_info); | ||
124 | if (type == 0) | ||
125 | type = atomic_read(&usu_bias); | ||
126 | |||
127 | spin_lock_irqsave(&usu_lock, flags); | ||
128 | if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) { | ||
129 | spin_unlock_irqrestore(&usu_lock, flags); | ||
130 | return -ENXIO; | ||
131 | } | ||
132 | stat[type].fls |= USU_MOD_FL_THREAD; | ||
133 | spin_unlock_irqrestore(&usu_lock, flags); | ||
134 | |||
135 | rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM); | ||
136 | if (rc < 0) { | ||
137 | printk(KERN_WARNING "libusual: " | ||
138 | "Unable to start the thread for %s: %d\n", | ||
139 | bias_names[type], rc); | ||
140 | spin_lock_irqsave(&usu_lock, flags); | ||
141 | stat[type].fls &= ~USU_MOD_FL_THREAD; | ||
142 | spin_unlock_irqrestore(&usu_lock, flags); | ||
143 | return rc; /* Not being -ENXIO causes a message printed */ | ||
144 | } | ||
145 | atomic_inc(&total_threads); | ||
146 | |||
147 | return -ENXIO; | ||
148 | } | ||
149 | |||
150 | static void usu_disconnect(struct usb_interface *intf) | ||
151 | { | ||
152 | ; /* We should not be here. */ | ||
153 | } | ||
154 | |||
155 | static struct usb_driver usu_driver = { | ||
156 | .name = "libusual", | ||
157 | .probe = usu_probe, | ||
158 | .disconnect = usu_disconnect, | ||
159 | .id_table = storage_usb_ids, | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * A whole new thread for a purpose of request_module seems quite stupid. | ||
164 | * The request_module forks once inside again. However, if we attempt | ||
165 | * to load a storage module from our own modprobe thread, that module | ||
166 | * references our symbols, which cannot be resolved until our module is | ||
167 | * initialized. I wish there was a way to wait for the end of initialization. | ||
168 | * The module notifier reports MODULE_STATE_COMING only. | ||
169 | * So, we wait until module->init ends as the next best thing. | ||
170 | */ | ||
171 | static int usu_probe_thread(void *arg) | ||
172 | { | ||
173 | int type = (unsigned long) arg; | ||
174 | struct mod_status *st = &stat[type]; | ||
175 | int rc; | ||
176 | unsigned long flags; | ||
177 | |||
178 | daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */ | ||
179 | |||
180 | /* A completion does not work here because it's counted. */ | ||
181 | down(&usu_init_notify); | ||
182 | up(&usu_init_notify); | ||
183 | |||
184 | rc = request_module(bias_names[type]); | ||
185 | spin_lock_irqsave(&usu_lock, flags); | ||
186 | if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { | ||
187 | /* | ||
188 | * This should not happen, but let us keep tabs on it. | ||
189 | */ | ||
190 | printk(KERN_NOTICE "libusual: " | ||
191 | "modprobe for %s succeeded, but module is not present\n", | ||
192 | bias_names[type]); | ||
193 | } | ||
194 | st->fls &= ~USU_MOD_FL_THREAD; | ||
195 | spin_unlock_irqrestore(&usu_lock, flags); | ||
196 | |||
197 | complete_and_exit(&usu_end_notify, 0); | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | */ | ||
202 | static int __init usb_usual_init(void) | ||
203 | { | ||
204 | int rc; | ||
205 | |||
206 | rc = usb_register(&usu_driver); | ||
207 | up(&usu_init_notify); | ||
208 | return rc; | ||
209 | } | ||
210 | |||
211 | static void __exit usb_usual_exit(void) | ||
212 | { | ||
213 | /* | ||
214 | * We do not check for any drivers present, because | ||
215 | * they keep us pinned with symbol references. | ||
216 | */ | ||
217 | |||
218 | usb_deregister(&usu_driver); | ||
219 | |||
220 | while (atomic_read(&total_threads) > 0) { | ||
221 | wait_for_completion(&usu_end_notify); | ||
222 | atomic_dec(&total_threads); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * Validate and accept the bias parameter. | ||
228 | */ | ||
229 | static int usu_set_bias(const char *bias_s, struct kernel_param *kp) | ||
230 | { | ||
231 | int i; | ||
232 | int len; | ||
233 | int bias_n = 0; | ||
234 | |||
235 | len = strlen(bias_s); | ||
236 | if (len == 0) | ||
237 | return -EDOM; | ||
238 | if (bias_s[len-1] == '\n') | ||
239 | --len; | ||
240 | |||
241 | for (i = 1; i < 3; i++) { | ||
242 | if (strncmp(bias_s, bias_names[i], len) == 0) { | ||
243 | bias_n = i; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | if (bias_n == 0) | ||
248 | return -EINVAL; | ||
249 | |||
250 | atomic_set(&usu_bias, bias_n); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int usu_get_bias(char *buffer, struct kernel_param *kp) | ||
255 | { | ||
256 | return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)])); | ||
257 | } | ||
258 | |||
259 | module_init(usb_usual_init); | ||
260 | module_exit(usb_usual_exit); | ||
261 | |||
262 | module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR); | ||
263 | __MODULE_PARM_TYPE(bias, "string"); | ||
264 | MODULE_PARM_DESC(bias, "Bias to usb-storage or ub"); | ||
265 | |||
266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 89401a59f952..55ee2d36d585 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -52,6 +52,7 @@ struct usb_onetouch { | |||
52 | struct urb *irq; /* urb for interrupt in report */ | 52 | struct urb *irq; /* urb for interrupt in report */ |
53 | unsigned char *data; /* input data */ | 53 | unsigned char *data; /* input data */ |
54 | dma_addr_t data_dma; | 54 | dma_addr_t data_dma; |
55 | unsigned int is_open:1; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) | 58 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) |
@@ -89,6 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev) | |||
89 | { | 90 | { |
90 | struct usb_onetouch *onetouch = dev->private; | 91 | struct usb_onetouch *onetouch = dev->private; |
91 | 92 | ||
93 | onetouch->is_open = 1; | ||
92 | onetouch->irq->dev = onetouch->udev; | 94 | onetouch->irq->dev = onetouch->udev; |
93 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { | 95 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { |
94 | err("usb_submit_urb failed"); | 96 | err("usb_submit_urb failed"); |
@@ -103,8 +105,30 @@ static void usb_onetouch_close(struct input_dev *dev) | |||
103 | struct usb_onetouch *onetouch = dev->private; | 105 | struct usb_onetouch *onetouch = dev->private; |
104 | 106 | ||
105 | usb_kill_urb(onetouch->irq); | 107 | usb_kill_urb(onetouch->irq); |
108 | onetouch->is_open = 0; | ||
106 | } | 109 | } |
107 | 110 | ||
111 | #ifdef CONFIG_PM | ||
112 | static void usb_onetouch_pm_hook(struct us_data *us, int action) | ||
113 | { | ||
114 | struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra; | ||
115 | |||
116 | if (onetouch->is_open) { | ||
117 | switch (action) { | ||
118 | case US_SUSPEND: | ||
119 | usb_kill_urb(onetouch->irq); | ||
120 | break; | ||
121 | case US_RESUME: | ||
122 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) | ||
123 | err("usb_submit_urb failed"); | ||
124 | break; | ||
125 | default: | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | #endif /* CONFIG_PM */ | ||
131 | |||
108 | int onetouch_connect_input(struct us_data *ss) | 132 | int onetouch_connect_input(struct us_data *ss) |
109 | { | 133 | { |
110 | struct usb_device *udev = ss->pusb_dev; | 134 | struct usb_device *udev = ss->pusb_dev; |
@@ -185,6 +209,9 @@ int onetouch_connect_input(struct us_data *ss) | |||
185 | 209 | ||
186 | ss->extra_destructor = onetouch_release_input; | 210 | ss->extra_destructor = onetouch_release_input; |
187 | ss->extra = onetouch; | 211 | ss->extra = onetouch; |
212 | #ifdef CONFIG_PM | ||
213 | ss->suspend_resume_hook = usb_onetouch_pm_hook; | ||
214 | #endif | ||
188 | 215 | ||
189 | input_register_device(onetouch->dev); | 216 | input_register_device(onetouch->dev); |
190 | 217 | ||
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 02bff01ab09c..845bed4b8031 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h | |||
@@ -41,20 +41,6 @@ | |||
41 | #ifndef _PROTOCOL_H_ | 41 | #ifndef _PROTOCOL_H_ |
42 | #define _PROTOCOL_H_ | 42 | #define _PROTOCOL_H_ |
43 | 43 | ||
44 | /* Sub Classes */ | ||
45 | |||
46 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
47 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
48 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
49 | #define US_SC_UFI 0x04 /* Floppy */ | ||
50 | #define US_SC_8070 0x05 /* Removable media */ | ||
51 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
52 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
53 | #define US_SC_MIN US_SC_RBC | ||
54 | #define US_SC_MAX US_SC_ISD200 | ||
55 | |||
56 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
57 | |||
58 | /* Protocol handling routines */ | 44 | /* Protocol handling routines */ |
59 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); | 45 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); |
60 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); | 46 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 0ea2f5ab66ba..fb8bacaae27c 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -133,13 +133,11 @@ static struct nand_flash_dev nand_flash_ids[] = { | |||
133 | { 0,} | 133 | { 0,} |
134 | }; | 134 | }; |
135 | 135 | ||
136 | #define SIZE(a) (sizeof(a)/sizeof((a)[0])) | ||
137 | |||
138 | static struct nand_flash_dev * | 136 | static struct nand_flash_dev * |
139 | nand_find_id(unsigned char id) { | 137 | nand_find_id(unsigned char id) { |
140 | int i; | 138 | int i; |
141 | 139 | ||
142 | for (i = 0; i < SIZE(nand_flash_ids); i++) | 140 | for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++) |
143 | if (nand_flash_ids[i].model_id == id) | 141 | if (nand_flash_ids[i].model_id == id) |
144 | return &(nand_flash_ids[i]); | 142 | return &(nand_flash_ids[i]); |
145 | return NULL; | 143 | return NULL; |
@@ -214,6 +212,20 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
214 | * The actual driver starts here. | 212 | * The actual driver starts here. |
215 | */ | 213 | */ |
216 | 214 | ||
215 | struct sddr09_card_info { | ||
216 | unsigned long capacity; /* Size of card in bytes */ | ||
217 | int pagesize; /* Size of page in bytes */ | ||
218 | int pageshift; /* log2 of pagesize */ | ||
219 | int blocksize; /* Size of block in pages */ | ||
220 | int blockshift; /* log2 of blocksize */ | ||
221 | int blockmask; /* 2^blockshift - 1 */ | ||
222 | int *lba_to_pba; /* logical to physical map */ | ||
223 | int *pba_to_lba; /* physical to logical map */ | ||
224 | int lbact; /* number of available pages */ | ||
225 | int flags; | ||
226 | #define SDDR09_WP 1 /* write protected */ | ||
227 | }; | ||
228 | |||
217 | /* | 229 | /* |
218 | * On my 16MB card, control blocks have size 64 (16 real control bytes, | 230 | * On my 16MB card, control blocks have size 64 (16 real control bytes, |
219 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, | 231 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, |
@@ -237,7 +249,7 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
237 | #define SPARE 0xfffffffe | 249 | #define SPARE 0xfffffffe |
238 | #define UNUSABLE 0xfffffffd | 250 | #define UNUSABLE 0xfffffffd |
239 | 251 | ||
240 | static int erase_bad_lba_entries = 0; | 252 | static const int erase_bad_lba_entries = 0; |
241 | 253 | ||
242 | /* send vendor interface command (0x41) */ | 254 | /* send vendor interface command (0x41) */ |
243 | /* called for requests 0, 1, 8 */ | 255 | /* called for requests 0, 1, 8 */ |
@@ -260,8 +272,11 @@ sddr09_send_command(struct us_data *us, | |||
260 | 272 | ||
261 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, | 273 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, |
262 | 0, 0, xfer_data, xfer_len); | 274 | 0, 0, xfer_data, xfer_len); |
263 | return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : | 275 | switch (rc) { |
264 | USB_STOR_TRANSPORT_ERROR); | 276 | case USB_STOR_XFER_GOOD: return 0; |
277 | case USB_STOR_XFER_STALLED: return -EPIPE; | ||
278 | default: return -EIO; | ||
279 | } | ||
265 | } | 280 | } |
266 | 281 | ||
267 | static int | 282 | static int |
@@ -308,20 +323,12 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) { | |||
308 | command[4] = buflen; | 323 | command[4] = buflen; |
309 | 324 | ||
310 | result = sddr09_send_scsi_command(us, command, 12); | 325 | result = sddr09_send_scsi_command(us, command, 12); |
311 | if (result != USB_STOR_TRANSPORT_GOOD) { | 326 | if (result) |
312 | US_DEBUGP("request sense failed\n"); | ||
313 | return result; | 327 | return result; |
314 | } | ||
315 | 328 | ||
316 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 329 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
317 | sensebuf, buflen, NULL); | 330 | sensebuf, buflen, NULL); |
318 | if (result != USB_STOR_XFER_GOOD) { | 331 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
319 | US_DEBUGP("request sense bulk in failed\n"); | ||
320 | return USB_STOR_TRANSPORT_ERROR; | ||
321 | } else { | ||
322 | US_DEBUGP("request sense worked\n"); | ||
323 | return USB_STOR_TRANSPORT_GOOD; | ||
324 | } | ||
325 | } | 332 | } |
326 | 333 | ||
327 | /* | 334 | /* |
@@ -369,7 +376,7 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
369 | 376 | ||
370 | result = sddr09_send_scsi_command(us, command, 12); | 377 | result = sddr09_send_scsi_command(us, command, 12); |
371 | 378 | ||
372 | if (result != USB_STOR_TRANSPORT_GOOD) { | 379 | if (result) { |
373 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", | 380 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", |
374 | x, result); | 381 | x, result); |
375 | return result; | 382 | return result; |
@@ -381,9 +388,9 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
381 | if (result != USB_STOR_XFER_GOOD) { | 388 | if (result != USB_STOR_XFER_GOOD) { |
382 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", | 389 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", |
383 | x, result); | 390 | x, result); |
384 | return USB_STOR_TRANSPORT_ERROR; | 391 | return -EIO; |
385 | } | 392 | } |
386 | return USB_STOR_TRANSPORT_GOOD; | 393 | return 0; |
387 | } | 394 | } |
388 | 395 | ||
389 | /* | 396 | /* |
@@ -497,7 +504,7 @@ sddr09_erase(struct us_data *us, unsigned long Eaddress) { | |||
497 | 504 | ||
498 | result = sddr09_send_scsi_command(us, command, 12); | 505 | result = sddr09_send_scsi_command(us, command, 12); |
499 | 506 | ||
500 | if (result != USB_STOR_TRANSPORT_GOOD) | 507 | if (result) |
501 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", | 508 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", |
502 | result); | 509 | result); |
503 | 510 | ||
@@ -555,7 +562,7 @@ sddr09_writeX(struct us_data *us, | |||
555 | 562 | ||
556 | result = sddr09_send_scsi_command(us, command, 12); | 563 | result = sddr09_send_scsi_command(us, command, 12); |
557 | 564 | ||
558 | if (result != USB_STOR_TRANSPORT_GOOD) { | 565 | if (result) { |
559 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", | 566 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", |
560 | result); | 567 | result); |
561 | return result; | 568 | return result; |
@@ -567,9 +574,9 @@ sddr09_writeX(struct us_data *us, | |||
567 | if (result != USB_STOR_XFER_GOOD) { | 574 | if (result != USB_STOR_XFER_GOOD) { |
568 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", | 575 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", |
569 | result); | 576 | result); |
570 | return USB_STOR_TRANSPORT_ERROR; | 577 | return -EIO; |
571 | } | 578 | } |
572 | return USB_STOR_TRANSPORT_GOOD; | 579 | return 0; |
573 | } | 580 | } |
574 | 581 | ||
575 | /* erase address, write same address */ | 582 | /* erase address, write same address */ |
@@ -633,7 +640,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
633 | 640 | ||
634 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); | 641 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); |
635 | 642 | ||
636 | if (result != USB_STOR_TRANSPORT_GOOD) { | 643 | if (result) { |
637 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", | 644 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", |
638 | result); | 645 | result); |
639 | return result; | 646 | return result; |
@@ -641,7 +648,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
641 | 648 | ||
642 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); | 649 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); |
643 | if (!buf) | 650 | if (!buf) |
644 | return USB_STOR_TRANSPORT_ERROR; | 651 | return -ENOMEM; |
645 | 652 | ||
646 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 653 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
647 | buf, bulklen, NULL); | 654 | buf, bulklen, NULL); |
@@ -649,10 +656,10 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
649 | if (result != USB_STOR_XFER_GOOD) { | 656 | if (result != USB_STOR_XFER_GOOD) { |
650 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", | 657 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", |
651 | result); | 658 | result); |
652 | return USB_STOR_TRANSPORT_ERROR; | 659 | return -EIO; |
653 | } | 660 | } |
654 | 661 | ||
655 | return USB_STOR_TRANSPORT_GOOD; | 662 | return 0; |
656 | } | 663 | } |
657 | #endif | 664 | #endif |
658 | 665 | ||
@@ -681,14 +688,13 @@ sddr09_read_status(struct us_data *us, unsigned char *status) { | |||
681 | command[1] = LUNBITS; | 688 | command[1] = LUNBITS; |
682 | 689 | ||
683 | result = sddr09_send_scsi_command(us, command, 12); | 690 | result = sddr09_send_scsi_command(us, command, 12); |
684 | if (result != USB_STOR_TRANSPORT_GOOD) | 691 | if (result) |
685 | return result; | 692 | return result; |
686 | 693 | ||
687 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 694 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
688 | data, 64, NULL); | 695 | data, 64, NULL); |
689 | *status = data[0]; | 696 | *status = data[0]; |
690 | return (result == USB_STOR_XFER_GOOD ? | 697 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
691 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
692 | } | 698 | } |
693 | 699 | ||
694 | static int | 700 | static int |
@@ -703,6 +709,13 @@ sddr09_read_data(struct us_data *us, | |||
703 | unsigned int len, index, offset; | 709 | unsigned int len, index, offset; |
704 | int result; | 710 | int result; |
705 | 711 | ||
712 | // Figure out the initial LBA and page | ||
713 | lba = address >> info->blockshift; | ||
714 | page = (address & info->blockmask); | ||
715 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
716 | if (lba >= maxlba) | ||
717 | return -EIO; | ||
718 | |||
706 | // Since we only read in one block at a time, we have to create | 719 | // Since we only read in one block at a time, we have to create |
707 | // a bounce buffer and move the data a piece at a time between the | 720 | // a bounce buffer and move the data a piece at a time between the |
708 | // bounce buffer and the actual transfer buffer. | 721 | // bounce buffer and the actual transfer buffer. |
@@ -711,18 +724,13 @@ sddr09_read_data(struct us_data *us, | |||
711 | buffer = kmalloc(len, GFP_NOIO); | 724 | buffer = kmalloc(len, GFP_NOIO); |
712 | if (buffer == NULL) { | 725 | if (buffer == NULL) { |
713 | printk("sddr09_read_data: Out of memory\n"); | 726 | printk("sddr09_read_data: Out of memory\n"); |
714 | return USB_STOR_TRANSPORT_ERROR; | 727 | return -ENOMEM; |
715 | } | 728 | } |
716 | 729 | ||
717 | // Figure out the initial LBA and page | ||
718 | lba = address >> info->blockshift; | ||
719 | page = (address & info->blockmask); | ||
720 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
721 | |||
722 | // This could be made much more efficient by checking for | 730 | // This could be made much more efficient by checking for |
723 | // contiguous LBA's. Another exercise left to the student. | 731 | // contiguous LBA's. Another exercise left to the student. |
724 | 732 | ||
725 | result = USB_STOR_TRANSPORT_GOOD; | 733 | result = 0; |
726 | index = offset = 0; | 734 | index = offset = 0; |
727 | 735 | ||
728 | while (sectors > 0) { | 736 | while (sectors > 0) { |
@@ -735,7 +743,7 @@ sddr09_read_data(struct us_data *us, | |||
735 | if (lba >= maxlba) { | 743 | if (lba >= maxlba) { |
736 | US_DEBUGP("Error: Requested lba %u exceeds " | 744 | US_DEBUGP("Error: Requested lba %u exceeds " |
737 | "maximum %u\n", lba, maxlba); | 745 | "maximum %u\n", lba, maxlba); |
738 | result = USB_STOR_TRANSPORT_ERROR; | 746 | result = -EIO; |
739 | break; | 747 | break; |
740 | } | 748 | } |
741 | 749 | ||
@@ -749,7 +757,7 @@ sddr09_read_data(struct us_data *us, | |||
749 | 757 | ||
750 | /* This is not really an error. It just means | 758 | /* This is not really an error. It just means |
751 | that the block has never been written. | 759 | that the block has never been written. |
752 | Instead of returning USB_STOR_TRANSPORT_ERROR | 760 | Instead of returning an error |
753 | it is better to return all zero data. */ | 761 | it is better to return all zero data. */ |
754 | 762 | ||
755 | memset(buffer, 0, len); | 763 | memset(buffer, 0, len); |
@@ -764,7 +772,7 @@ sddr09_read_data(struct us_data *us, | |||
764 | 772 | ||
765 | result = sddr09_read20(us, address>>1, | 773 | result = sddr09_read20(us, address>>1, |
766 | pages, info->pageshift, buffer, 0); | 774 | pages, info->pageshift, buffer, 0); |
767 | if (result != USB_STOR_TRANSPORT_GOOD) | 775 | if (result) |
768 | break; | 776 | break; |
769 | } | 777 | } |
770 | 778 | ||
@@ -830,7 +838,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
830 | pba = sddr09_find_unused_pba(info, lba); | 838 | pba = sddr09_find_unused_pba(info, lba); |
831 | if (!pba) { | 839 | if (!pba) { |
832 | printk("sddr09_write_lba: Out of unused blocks\n"); | 840 | printk("sddr09_write_lba: Out of unused blocks\n"); |
833 | return USB_STOR_TRANSPORT_ERROR; | 841 | return -ENOSPC; |
834 | } | 842 | } |
835 | info->pba_to_lba[pba] = lba; | 843 | info->pba_to_lba[pba] = lba; |
836 | info->lba_to_pba[lba] = pba; | 844 | info->lba_to_pba[lba] = pba; |
@@ -841,7 +849,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
841 | /* Maybe it is impossible to write to PBA 1. | 849 | /* Maybe it is impossible to write to PBA 1. |
842 | Fake success, but don't do anything. */ | 850 | Fake success, but don't do anything. */ |
843 | printk("sddr09: avoid writing to pba 1\n"); | 851 | printk("sddr09: avoid writing to pba 1\n"); |
844 | return USB_STOR_TRANSPORT_GOOD; | 852 | return 0; |
845 | } | 853 | } |
846 | 854 | ||
847 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); | 855 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); |
@@ -850,7 +858,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
850 | address = (pba << (info->pageshift + info->blockshift)); | 858 | address = (pba << (info->pageshift + info->blockshift)); |
851 | result = sddr09_read22(us, address>>1, info->blocksize, | 859 | result = sddr09_read22(us, address>>1, info->blocksize, |
852 | info->pageshift, blockbuffer, 0); | 860 | info->pageshift, blockbuffer, 0); |
853 | if (result != USB_STOR_TRANSPORT_GOOD) | 861 | if (result) |
854 | return result; | 862 | return result; |
855 | 863 | ||
856 | /* check old contents and fill lba */ | 864 | /* check old contents and fill lba */ |
@@ -897,7 +905,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
897 | { | 905 | { |
898 | unsigned char status = 0; | 906 | unsigned char status = 0; |
899 | int result2 = sddr09_read_status(us, &status); | 907 | int result2 = sddr09_read_status(us, &status); |
900 | if (result2 != USB_STOR_TRANSPORT_GOOD) | 908 | if (result2) |
901 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); | 909 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); |
902 | else if (status != 0xc0) | 910 | else if (status != 0xc0) |
903 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", | 911 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", |
@@ -920,13 +928,20 @@ sddr09_write_data(struct us_data *us, | |||
920 | unsigned int sectors) { | 928 | unsigned int sectors) { |
921 | 929 | ||
922 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; | 930 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; |
923 | unsigned int lba, page, pages; | 931 | unsigned int lba, maxlba, page, pages; |
924 | unsigned int pagelen, blocklen; | 932 | unsigned int pagelen, blocklen; |
925 | unsigned char *blockbuffer; | 933 | unsigned char *blockbuffer; |
926 | unsigned char *buffer; | 934 | unsigned char *buffer; |
927 | unsigned int len, index, offset; | 935 | unsigned int len, index, offset; |
928 | int result; | 936 | int result; |
929 | 937 | ||
938 | // Figure out the initial LBA and page | ||
939 | lba = address >> info->blockshift; | ||
940 | page = (address & info->blockmask); | ||
941 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
942 | if (lba >= maxlba) | ||
943 | return -EIO; | ||
944 | |||
930 | // blockbuffer is used for reading in the old data, overwriting | 945 | // blockbuffer is used for reading in the old data, overwriting |
931 | // with the new data, and performing ECC calculations | 946 | // with the new data, and performing ECC calculations |
932 | 947 | ||
@@ -938,7 +953,7 @@ sddr09_write_data(struct us_data *us, | |||
938 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 953 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
939 | if (!blockbuffer) { | 954 | if (!blockbuffer) { |
940 | printk("sddr09_write_data: Out of memory\n"); | 955 | printk("sddr09_write_data: Out of memory\n"); |
941 | return USB_STOR_TRANSPORT_ERROR; | 956 | return -ENOMEM; |
942 | } | 957 | } |
943 | 958 | ||
944 | // Since we don't write the user data directly to the device, | 959 | // Since we don't write the user data directly to the device, |
@@ -950,14 +965,10 @@ sddr09_write_data(struct us_data *us, | |||
950 | if (buffer == NULL) { | 965 | if (buffer == NULL) { |
951 | printk("sddr09_write_data: Out of memory\n"); | 966 | printk("sddr09_write_data: Out of memory\n"); |
952 | kfree(blockbuffer); | 967 | kfree(blockbuffer); |
953 | return USB_STOR_TRANSPORT_ERROR; | 968 | return -ENOMEM; |
954 | } | 969 | } |
955 | 970 | ||
956 | // Figure out the initial LBA and page | 971 | result = 0; |
957 | lba = address >> info->blockshift; | ||
958 | page = (address & info->blockmask); | ||
959 | |||
960 | result = USB_STOR_TRANSPORT_GOOD; | ||
961 | index = offset = 0; | 972 | index = offset = 0; |
962 | 973 | ||
963 | while (sectors > 0) { | 974 | while (sectors > 0) { |
@@ -967,13 +978,21 @@ sddr09_write_data(struct us_data *us, | |||
967 | pages = min(sectors, info->blocksize - page); | 978 | pages = min(sectors, info->blocksize - page); |
968 | len = (pages << info->pageshift); | 979 | len = (pages << info->pageshift); |
969 | 980 | ||
981 | /* Not overflowing capacity? */ | ||
982 | if (lba >= maxlba) { | ||
983 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
984 | "maximum %u\n", lba, maxlba); | ||
985 | result = -EIO; | ||
986 | break; | ||
987 | } | ||
988 | |||
970 | // Get the data from the transfer buffer | 989 | // Get the data from the transfer buffer |
971 | usb_stor_access_xfer_buf(buffer, len, us->srb, | 990 | usb_stor_access_xfer_buf(buffer, len, us->srb, |
972 | &index, &offset, FROM_XFER_BUF); | 991 | &index, &offset, FROM_XFER_BUF); |
973 | 992 | ||
974 | result = sddr09_write_lba(us, lba, page, pages, | 993 | result = sddr09_write_lba(us, lba, page, pages, |
975 | buffer, blockbuffer); | 994 | buffer, blockbuffer); |
976 | if (result != USB_STOR_TRANSPORT_GOOD) | 995 | if (result) |
977 | break; | 996 | break; |
978 | 997 | ||
979 | page = 0; | 998 | page = 0; |
@@ -1022,7 +1041,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
1022 | command[1] = LUNBITS; | 1041 | command[1] = LUNBITS; |
1023 | 1042 | ||
1024 | result = sddr09_send_scsi_command(us, command, 12); | 1043 | result = sddr09_send_scsi_command(us, command, 12); |
1025 | if (result != USB_STOR_TRANSPORT_GOOD) | 1044 | if (result) |
1026 | return result; | 1045 | return result; |
1027 | 1046 | ||
1028 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 1047 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
@@ -1031,8 +1050,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
1031 | for (i = 0; i < 4; i++) | 1050 | for (i = 0; i < 4; i++) |
1032 | deviceID[i] = content[i]; | 1051 | deviceID[i] = content[i]; |
1033 | 1052 | ||
1034 | return (result == USB_STOR_XFER_GOOD ? | 1053 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
1035 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
1036 | } | 1054 | } |
1037 | 1055 | ||
1038 | static int | 1056 | static int |
@@ -1041,7 +1059,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
1041 | unsigned char status; | 1059 | unsigned char status; |
1042 | 1060 | ||
1043 | result = sddr09_read_status(us, &status); | 1061 | result = sddr09_read_status(us, &status); |
1044 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1062 | if (result) { |
1045 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); | 1063 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); |
1046 | return result; | 1064 | return result; |
1047 | } | 1065 | } |
@@ -1057,7 +1075,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
1057 | if (status & 0x1) | 1075 | if (status & 0x1) |
1058 | US_DEBUGP(" Error"); | 1076 | US_DEBUGP(" Error"); |
1059 | US_DEBUGP("\n"); | 1077 | US_DEBUGP("\n"); |
1060 | return USB_STOR_TRANSPORT_GOOD; | 1078 | return 0; |
1061 | } | 1079 | } |
1062 | 1080 | ||
1063 | #if 0 | 1081 | #if 0 |
@@ -1089,7 +1107,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1089 | 1107 | ||
1090 | result = sddr09_read_deviceID(us, deviceID); | 1108 | result = sddr09_read_deviceID(us, deviceID); |
1091 | 1109 | ||
1092 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1110 | if (result) { |
1093 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1111 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
1094 | printk("sddr09: could not read card info\n"); | 1112 | printk("sddr09: could not read card info\n"); |
1095 | return NULL; | 1113 | return NULL; |
@@ -1200,7 +1218,7 @@ sddr09_read_map(struct us_data *us) { | |||
1200 | us, address>>1, | 1218 | us, address>>1, |
1201 | min(alloc_blocks, numblocks - i), | 1219 | min(alloc_blocks, numblocks - i), |
1202 | buffer, 0); | 1220 | buffer, 0); |
1203 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1221 | if (result) { |
1204 | result = -1; | 1222 | result = -1; |
1205 | goto done; | 1223 | goto done; |
1206 | } | 1224 | } |
@@ -1342,29 +1360,53 @@ sddr09_card_info_destructor(void *extra) { | |||
1342 | kfree(info->pba_to_lba); | 1360 | kfree(info->pba_to_lba); |
1343 | } | 1361 | } |
1344 | 1362 | ||
1345 | static void | 1363 | static int |
1346 | sddr09_init_card_info(struct us_data *us) { | 1364 | sddr09_common_init(struct us_data *us) { |
1347 | if (!us->extra) { | 1365 | int result; |
1348 | us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | 1366 | |
1349 | if (us->extra) { | 1367 | /* set the configuration -- STALL is an acceptable response here */ |
1350 | memset(us->extra, 0, sizeof(struct sddr09_card_info)); | 1368 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { |
1351 | us->extra_destructor = sddr09_card_info_destructor; | 1369 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev |
1352 | } | 1370 | ->actconfig->desc.bConfigurationValue); |
1371 | return -EINVAL; | ||
1372 | } | ||
1373 | |||
1374 | result = usb_reset_configuration(us->pusb_dev); | ||
1375 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
1376 | if (result == -EPIPE) { | ||
1377 | US_DEBUGP("-- stall on control interface\n"); | ||
1378 | } else if (result != 0) { | ||
1379 | /* it's not a stall, but another error -- time to bail */ | ||
1380 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
1381 | return -EINVAL; | ||
1353 | } | 1382 | } |
1383 | |||
1384 | us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | ||
1385 | if (!us->extra) | ||
1386 | return -ENOMEM; | ||
1387 | us->extra_destructor = sddr09_card_info_destructor; | ||
1388 | |||
1389 | nand_init_ecc(); | ||
1390 | return 0; | ||
1354 | } | 1391 | } |
1355 | 1392 | ||
1393 | |||
1356 | /* | 1394 | /* |
1357 | * This is needed at a very early stage. If this is not listed in the | 1395 | * This is needed at a very early stage. If this is not listed in the |
1358 | * unusual devices list but called from here then LUN 0 of the combo reader | 1396 | * unusual devices list but called from here then LUN 0 of the combo reader |
1359 | * is not recognized. But I do not know what precisely these calls do. | 1397 | * is not recognized. But I do not know what precisely these calls do. |
1360 | */ | 1398 | */ |
1361 | int | 1399 | int |
1362 | sddr09_init(struct us_data *us) { | 1400 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
1363 | int result; | 1401 | int result; |
1364 | unsigned char *data = us->iobuf; | 1402 | unsigned char *data = us->iobuf; |
1365 | 1403 | ||
1404 | result = sddr09_common_init(us); | ||
1405 | if (result) | ||
1406 | return result; | ||
1407 | |||
1366 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); | 1408 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); |
1367 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1409 | if (result) { |
1368 | US_DEBUGP("sddr09_init: send_command fails\n"); | 1410 | US_DEBUGP("sddr09_init: send_command fails\n"); |
1369 | return result; | 1411 | return result; |
1370 | } | 1412 | } |
@@ -1373,7 +1415,7 @@ sddr09_init(struct us_data *us) { | |||
1373 | // get 07 02 | 1415 | // get 07 02 |
1374 | 1416 | ||
1375 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); | 1417 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); |
1376 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1418 | if (result) { |
1377 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); | 1419 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); |
1378 | return result; | 1420 | return result; |
1379 | } | 1421 | } |
@@ -1382,7 +1424,7 @@ sddr09_init(struct us_data *us) { | |||
1382 | // get 07 00 | 1424 | // get 07 00 |
1383 | 1425 | ||
1384 | result = sddr09_request_sense(us, data, 18); | 1426 | result = sddr09_request_sense(us, data, 18); |
1385 | if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) { | 1427 | if (result == 0 && data[2] != 0) { |
1386 | int j; | 1428 | int j; |
1387 | for (j=0; j<18; j++) | 1429 | for (j=0; j<18; j++) |
1388 | printk(" %02X", data[j]); | 1430 | printk(" %02X", data[j]); |
@@ -1398,7 +1440,7 @@ sddr09_init(struct us_data *us) { | |||
1398 | 1440 | ||
1399 | // test unit ready | 1441 | // test unit ready |
1400 | 1442 | ||
1401 | return USB_STOR_TRANSPORT_GOOD; /* not result */ | 1443 | return 0; /* not result */ |
1402 | } | 1444 | } |
1403 | 1445 | ||
1404 | /* | 1446 | /* |
@@ -1427,13 +1469,6 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1427 | }; | 1469 | }; |
1428 | 1470 | ||
1429 | info = (struct sddr09_card_info *)us->extra; | 1471 | info = (struct sddr09_card_info *)us->extra; |
1430 | if (!info) { | ||
1431 | nand_init_ecc(); | ||
1432 | sddr09_init_card_info(us); | ||
1433 | info = (struct sddr09_card_info *)us->extra; | ||
1434 | if (!info) | ||
1435 | return USB_STOR_TRANSPORT_ERROR; | ||
1436 | } | ||
1437 | 1472 | ||
1438 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { | 1473 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { |
1439 | /* for a faked command, we have to follow with a faked sense */ | 1474 | /* for a faked command, we have to follow with a faked sense */ |
@@ -1536,7 +1571,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1536 | US_DEBUGP("READ_10: read page %d pagect %d\n", | 1571 | US_DEBUGP("READ_10: read page %d pagect %d\n", |
1537 | page, pages); | 1572 | page, pages); |
1538 | 1573 | ||
1539 | return sddr09_read_data(us, page, pages); | 1574 | result = sddr09_read_data(us, page, pages); |
1575 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
1576 | USB_STOR_TRANSPORT_ERROR); | ||
1540 | } | 1577 | } |
1541 | 1578 | ||
1542 | if (srb->cmnd[0] == WRITE_10) { | 1579 | if (srb->cmnd[0] == WRITE_10) { |
@@ -1549,7 +1586,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1549 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", | 1586 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", |
1550 | page, pages); | 1587 | page, pages); |
1551 | 1588 | ||
1552 | return sddr09_write_data(us, page, pages); | 1589 | result = sddr09_write_data(us, page, pages); |
1590 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
1591 | USB_STOR_TRANSPORT_ERROR); | ||
1553 | } | 1592 | } |
1554 | 1593 | ||
1555 | /* catch-all for all other commands, except | 1594 | /* catch-all for all other commands, except |
@@ -1575,10 +1614,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1575 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); | 1614 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); |
1576 | 1615 | ||
1577 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); | 1616 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); |
1578 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1617 | if (result) { |
1579 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " | 1618 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " |
1580 | "returns %d\n", result); | 1619 | "returns %d\n", result); |
1581 | return result; | 1620 | return USB_STOR_TRANSPORT_ERROR; |
1582 | } | 1621 | } |
1583 | 1622 | ||
1584 | if (srb->request_bufflen == 0) | 1623 | if (srb->request_bufflen == 0) |
@@ -1606,3 +1645,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1606 | return USB_STOR_TRANSPORT_GOOD; | 1645 | return USB_STOR_TRANSPORT_GOOD; |
1607 | } | 1646 | } |
1608 | 1647 | ||
1648 | /* | ||
1649 | * Initialization routine for the sddr09 subdriver | ||
1650 | */ | ||
1651 | int | ||
1652 | usb_stor_sddr09_init(struct us_data *us) { | ||
1653 | return sddr09_common_init(us); | ||
1654 | } | ||
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h index c9d78d6188b1..c03089a9ec38 100644 --- a/drivers/usb/storage/sddr09.h +++ b/drivers/usb/storage/sddr09.h | |||
@@ -31,18 +31,7 @@ | |||
31 | 31 | ||
32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | 32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); |
33 | 33 | ||
34 | struct sddr09_card_info { | 34 | extern int usb_stor_sddr09_dpcm_init(struct us_data *us); |
35 | unsigned long capacity; /* Size of card in bytes */ | 35 | extern int usb_stor_sddr09_init(struct us_data *us); |
36 | int pagesize; /* Size of page in bytes */ | ||
37 | int pageshift; /* log2 of pagesize */ | ||
38 | int blocksize; /* Size of block in pages */ | ||
39 | int blockshift; /* log2 of blocksize */ | ||
40 | int blockmask; /* 2^blockshift - 1 */ | ||
41 | int *lba_to_pba; /* logical to physical map */ | ||
42 | int *pba_to_lba; /* physical to logical map */ | ||
43 | int lbact; /* number of available pages */ | ||
44 | int flags; | ||
45 | #define SDDR09_WP 1 /* write protected */ | ||
46 | }; | ||
47 | 36 | ||
48 | #endif | 37 | #endif |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 0a362cc781ad..633a715850a4 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
@@ -41,39 +41,8 @@ | |||
41 | #ifndef _TRANSPORT_H_ | 41 | #ifndef _TRANSPORT_H_ |
42 | #define _TRANSPORT_H_ | 42 | #define _TRANSPORT_H_ |
43 | 43 | ||
44 | #include <linux/config.h> | ||
45 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
46 | 45 | ||
47 | /* Protocols */ | ||
48 | |||
49 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
51 | #define US_PR_BULK 0x50 /* bulk only */ | ||
52 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
53 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
54 | #endif | ||
55 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
57 | #endif | ||
58 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
59 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
60 | #endif | ||
61 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
62 | |||
63 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
64 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
68 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
72 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
73 | #endif | ||
74 | |||
75 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
76 | |||
77 | /* | 46 | /* |
78 | * Bulk only data structures | 47 | * Bulk only data structures |
79 | */ | 48 | */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index f5f47a34b168..dc301e567cfc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -79,13 +79,6 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | |||
79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), | 79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
83 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
84 | "VIA Technologies Inc.", | ||
85 | "USB 2.0 Card Reader", | ||
86 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
87 | US_FL_IGNORE_RESIDUE ), | ||
88 | |||
89 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> | 82 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> |
90 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) | 83 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) |
91 | * for USB floppies that need the SINGLE_LUN enforcement. | 84 | * for USB floppies that need the SINGLE_LUN enforcement. |
@@ -96,6 +89,13 @@ UNUSUAL_DEV( 0x0409, 0x0040, 0x0000, 0x9999, | |||
96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 89 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
97 | US_FL_SINGLE_LUN ), | 90 | US_FL_SINGLE_LUN ), |
98 | 91 | ||
92 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
93 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
94 | "VIA Technologies Inc.", | ||
95 | "USB 2.0 Card Reader", | ||
96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
97 | US_FL_IGNORE_RESIDUE ), | ||
98 | |||
99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | 99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message | 100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message |
101 | * always fails and confuses drive. | 101 | * always fails and confuses drive. |
@@ -187,6 +187,14 @@ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, | |||
187 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 187 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
188 | US_FL_FIX_CAPACITY), | 188 | US_FL_FIX_CAPACITY), |
189 | 189 | ||
190 | /* Patch for Nikon coolpix 2000 | ||
191 | * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/ | ||
192 | UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, | ||
193 | "NIKON", | ||
194 | "NIKON DSC E2000", | ||
195 | US_SC_DEVICE, US_PR_DEVICE,NULL, | ||
196 | US_FL_NOT_LOCKABLE ), | ||
197 | |||
190 | /* BENQ DC5330 | 198 | /* BENQ DC5330 |
191 | * Reported by Manuel Fombuena <mfombuena@ya.com> and | 199 | * Reported by Manuel Fombuena <mfombuena@ya.com> and |
192 | * Frank Copeland <fjc@thingy.apana.org.au> */ | 200 | * Frank Copeland <fjc@thingy.apana.org.au> */ |
@@ -276,14 +284,14 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, | |||
276 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | 284 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, |
277 | "Sandisk", | 285 | "Sandisk", |
278 | "ImageMate SDDR09", | 286 | "ImageMate SDDR09", |
279 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 287 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
280 | US_FL_SINGLE_LUN ), | 288 | 0), |
281 | 289 | ||
282 | /* This entry is from Andries.Brouwer@cwi.nl */ | 290 | /* This entry is from Andries.Brouwer@cwi.nl */ |
283 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | 291 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, |
284 | "SCM Microsystems", | 292 | "SCM Microsystems", |
285 | "eUSB SmartMedia / CompactFlash Adapter", | 293 | "eUSB SmartMedia / CompactFlash Adapter", |
286 | US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, | 294 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, |
287 | 0), | 295 | 0), |
288 | #endif | 296 | #endif |
289 | 297 | ||
@@ -527,6 +535,13 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, | |||
527 | "Silicon Media R/W", | 535 | "Silicon Media R/W", |
528 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), | 536 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), |
529 | 537 | ||
538 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
539 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
540 | "Fujifilm", | ||
541 | "DPC-R1 (Alauda)", | ||
542 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
543 | #endif | ||
544 | |||
530 | /* Fabrizio Fellini <fello@libero.it> */ | 545 | /* Fabrizio Fellini <fello@libero.it> */ |
531 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, | 546 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, |
532 | "Fujifilm", | 547 | "Fujifilm", |
@@ -673,8 +688,8 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, | |||
673 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | 688 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, |
674 | "Olympus", | 689 | "Olympus", |
675 | "Camedia MAUSB-2", | 690 | "Camedia MAUSB-2", |
676 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 691 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
677 | US_FL_SINGLE_LUN ), | 692 | 0), |
678 | #endif | 693 | #endif |
679 | 694 | ||
680 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ | 695 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ |
@@ -739,8 +754,8 @@ UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | |||
739 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | 754 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, |
740 | "Sandisk", | 755 | "Sandisk", |
741 | "ImageMate SDDR-09", | 756 | "ImageMate SDDR-09", |
742 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 757 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
743 | US_FL_SINGLE_LUN ), | 758 | 0), |
744 | #endif | 759 | #endif |
745 | 760 | ||
746 | #ifdef CONFIG_USB_STORAGE_FREECOM | 761 | #ifdef CONFIG_USB_STORAGE_FREECOM |
@@ -776,6 +791,13 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
776 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | 791 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), |
777 | #endif | 792 | #endif |
778 | 793 | ||
794 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
795 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
796 | "Olympus", | ||
797 | "MAUSB-10 (Alauda)", | ||
798 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
799 | #endif | ||
800 | |||
779 | #ifdef CONFIG_USB_STORAGE_DATAFAB | 801 | #ifdef CONFIG_USB_STORAGE_DATAFAB |
780 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | 802 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, |
781 | "Datafab", | 803 | "Datafab", |
@@ -1134,3 +1156,27 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | |||
1134 | US_SC_SCSI, US_PR_SDDR55, NULL, | 1156 | US_SC_SCSI, US_PR_SDDR55, NULL, |
1135 | US_FL_SINGLE_LUN), | 1157 | US_FL_SINGLE_LUN), |
1136 | #endif | 1158 | #endif |
1159 | |||
1160 | /* Control/Bulk transport for all SubClass values */ | ||
1161 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | ||
1162 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | ||
1163 | USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR), | ||
1164 | USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR), | ||
1165 | USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR), | ||
1166 | USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR), | ||
1167 | |||
1168 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
1169 | USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1170 | USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR), | ||
1171 | USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1172 | USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1173 | USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR), | ||
1174 | USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1175 | |||
1176 | /* Bulk-only transport for all SubClass values */ | ||
1177 | USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1178 | USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR), | ||
1179 | USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1180 | USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR), | ||
1181 | USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR), | ||
1182 | USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0), | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3847ebed2aa4..dbcf23980ff1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -94,6 +94,9 @@ | |||
94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | 94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH |
95 | #include "onetouch.h" | 95 | #include "onetouch.h" |
96 | #endif | 96 | #endif |
97 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
98 | #include "alauda.h" | ||
99 | #endif | ||
97 | 100 | ||
98 | /* Some informational data */ | 101 | /* Some informational data */ |
99 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 102 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
@@ -112,49 +115,33 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
112 | static DECLARE_COMPLETION(threads_gone); | 115 | static DECLARE_COMPLETION(threads_gone); |
113 | 116 | ||
114 | 117 | ||
115 | /* The entries in this table, except for final ones here | 118 | /* |
116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 119 | * The entries in this table correspond, line for line, |
117 | * line for line with the entries of us_unsuaul_dev_list[]. | 120 | * with the entries of us_unusual_dev_list[]. |
118 | */ | 121 | */ |
122 | #ifndef CONFIG_USB_LIBUSUAL | ||
119 | 123 | ||
120 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 124 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
121 | vendorName, productName,useProtocol, useTransport, \ | 125 | vendorName, productName,useProtocol, useTransport, \ |
122 | initFunction, flags) \ | 126 | initFunction, flags) \ |
123 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) } | 127 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ |
128 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
129 | |||
130 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
132 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
124 | 133 | ||
125 | static struct usb_device_id storage_usb_ids [] = { | 134 | static struct usb_device_id storage_usb_ids [] = { |
126 | 135 | ||
127 | # include "unusual_devs.h" | 136 | # include "unusual_devs.h" |
128 | #undef UNUSUAL_DEV | 137 | #undef UNUSUAL_DEV |
129 | /* Control/Bulk transport for all SubClass values */ | 138 | #undef USUAL_DEV |
130 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) }, | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) }, | ||
132 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) }, | ||
133 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) }, | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) }, | ||
135 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) }, | ||
136 | |||
137 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
138 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) }, | ||
139 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) }, | ||
140 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) }, | ||
141 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) }, | ||
142 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) }, | ||
143 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) }, | ||
144 | |||
145 | /* Bulk-only transport for all SubClass values */ | ||
146 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) }, | ||
147 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) }, | ||
148 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) }, | ||
149 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) }, | ||
150 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) }, | ||
151 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | ||
152 | |||
153 | /* Terminating entry */ | 139 | /* Terminating entry */ |
154 | { } | 140 | { } |
155 | }; | 141 | }; |
156 | 142 | ||
157 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | 143 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
144 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
158 | 145 | ||
159 | /* This is the list of devices we recognize, along with their flag data */ | 146 | /* This is the list of devices we recognize, along with their flag data */ |
160 | 147 | ||
@@ -167,7 +154,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
167 | * are free to use as many characters as you like. | 154 | * are free to use as many characters as you like. |
168 | */ | 155 | */ |
169 | 156 | ||
170 | #undef UNUSUAL_DEV | ||
171 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | 157 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ |
172 | vendor_name, product_name, use_protocol, use_transport, \ | 158 | vendor_name, product_name, use_protocol, use_transport, \ |
173 | init_function, Flags) \ | 159 | init_function, Flags) \ |
@@ -177,53 +163,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
177 | .useProtocol = use_protocol, \ | 163 | .useProtocol = use_protocol, \ |
178 | .useTransport = use_transport, \ | 164 | .useTransport = use_transport, \ |
179 | .initFunction = init_function, \ | 165 | .initFunction = init_function, \ |
180 | .flags = Flags, \ | 166 | } |
167 | |||
168 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ | ||
169 | { \ | ||
170 | .useProtocol = use_protocol, \ | ||
171 | .useTransport = use_transport, \ | ||
181 | } | 172 | } |
182 | 173 | ||
183 | static struct us_unusual_dev us_unusual_dev_list[] = { | 174 | static struct us_unusual_dev us_unusual_dev_list[] = { |
184 | # include "unusual_devs.h" | 175 | # include "unusual_devs.h" |
185 | # undef UNUSUAL_DEV | 176 | # undef UNUSUAL_DEV |
186 | /* Control/Bulk transport for all SubClass values */ | 177 | # undef USUAL_DEV |
187 | { .useProtocol = US_SC_RBC, | ||
188 | .useTransport = US_PR_CB}, | ||
189 | { .useProtocol = US_SC_8020, | ||
190 | .useTransport = US_PR_CB}, | ||
191 | { .useProtocol = US_SC_QIC, | ||
192 | .useTransport = US_PR_CB}, | ||
193 | { .useProtocol = US_SC_UFI, | ||
194 | .useTransport = US_PR_CB}, | ||
195 | { .useProtocol = US_SC_8070, | ||
196 | .useTransport = US_PR_CB}, | ||
197 | { .useProtocol = US_SC_SCSI, | ||
198 | .useTransport = US_PR_CB}, | ||
199 | |||
200 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
201 | { .useProtocol = US_SC_RBC, | ||
202 | .useTransport = US_PR_CBI}, | ||
203 | { .useProtocol = US_SC_8020, | ||
204 | .useTransport = US_PR_CBI}, | ||
205 | { .useProtocol = US_SC_QIC, | ||
206 | .useTransport = US_PR_CBI}, | ||
207 | { .useProtocol = US_SC_UFI, | ||
208 | .useTransport = US_PR_CBI}, | ||
209 | { .useProtocol = US_SC_8070, | ||
210 | .useTransport = US_PR_CBI}, | ||
211 | { .useProtocol = US_SC_SCSI, | ||
212 | .useTransport = US_PR_CBI}, | ||
213 | |||
214 | /* Bulk-only transport for all SubClass values */ | ||
215 | { .useProtocol = US_SC_RBC, | ||
216 | .useTransport = US_PR_BULK}, | ||
217 | { .useProtocol = US_SC_8020, | ||
218 | .useTransport = US_PR_BULK}, | ||
219 | { .useProtocol = US_SC_QIC, | ||
220 | .useTransport = US_PR_BULK}, | ||
221 | { .useProtocol = US_SC_UFI, | ||
222 | .useTransport = US_PR_BULK}, | ||
223 | { .useProtocol = US_SC_8070, | ||
224 | .useTransport = US_PR_BULK}, | ||
225 | { .useProtocol = US_SC_SCSI, | ||
226 | .useTransport = US_PR_BULK}, | ||
227 | 178 | ||
228 | /* Terminating entry */ | 179 | /* Terminating entry */ |
229 | { NULL } | 180 | { NULL } |
@@ -240,6 +191,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
240 | down(&us->dev_semaphore); | 191 | down(&us->dev_semaphore); |
241 | 192 | ||
242 | US_DEBUGP("%s\n", __FUNCTION__); | 193 | US_DEBUGP("%s\n", __FUNCTION__); |
194 | if (us->suspend_resume_hook) | ||
195 | (us->suspend_resume_hook)(us, US_SUSPEND); | ||
243 | iface->dev.power.power_state.event = message.event; | 196 | iface->dev.power.power_state.event = message.event; |
244 | 197 | ||
245 | /* When runtime PM is working, we'll set a flag to indicate | 198 | /* When runtime PM is working, we'll set a flag to indicate |
@@ -256,6 +209,8 @@ static int storage_resume(struct usb_interface *iface) | |||
256 | down(&us->dev_semaphore); | 209 | down(&us->dev_semaphore); |
257 | 210 | ||
258 | US_DEBUGP("%s\n", __FUNCTION__); | 211 | US_DEBUGP("%s\n", __FUNCTION__); |
212 | if (us->suspend_resume_hook) | ||
213 | (us->suspend_resume_hook)(us, US_RESUME); | ||
259 | iface->dev.power.power_state.event = PM_EVENT_ON; | 214 | iface->dev.power.power_state.event = PM_EVENT_ON; |
260 | 215 | ||
261 | up(&us->dev_semaphore); | 216 | up(&us->dev_semaphore); |
@@ -484,14 +439,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
484 | return 0; | 439 | return 0; |
485 | } | 440 | } |
486 | 441 | ||
442 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
443 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
444 | { | ||
445 | const int id_index = id - storage_usb_ids; | ||
446 | return &us_unusual_dev_list[id_index]; | ||
447 | } | ||
448 | |||
487 | /* Get the unusual_devs entries and the string descriptors */ | 449 | /* Get the unusual_devs entries and the string descriptors */ |
488 | static void get_device_info(struct us_data *us, int id_index) | 450 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) |
489 | { | 451 | { |
490 | struct usb_device *dev = us->pusb_dev; | 452 | struct usb_device *dev = us->pusb_dev; |
491 | struct usb_interface_descriptor *idesc = | 453 | struct usb_interface_descriptor *idesc = |
492 | &us->pusb_intf->cur_altsetting->desc; | 454 | &us->pusb_intf->cur_altsetting->desc; |
493 | struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; | 455 | struct us_unusual_dev *unusual_dev = find_unusual(id); |
494 | struct usb_device_id *id = &storage_usb_ids[id_index]; | ||
495 | 456 | ||
496 | /* Store the entries */ | 457 | /* Store the entries */ |
497 | us->unusual_dev = unusual_dev; | 458 | us->unusual_dev = unusual_dev; |
@@ -501,7 +462,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
501 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? | 462 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? |
502 | idesc->bInterfaceProtocol : | 463 | idesc->bInterfaceProtocol : |
503 | unusual_dev->useTransport; | 464 | unusual_dev->useTransport; |
504 | us->flags = unusual_dev->flags; | 465 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
505 | 466 | ||
506 | /* | 467 | /* |
507 | * This flag is only needed when we're in high-speed, so let's | 468 | * This flag is only needed when we're in high-speed, so let's |
@@ -516,7 +477,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
516 | * from the unusual_devs.h table. | 477 | * from the unusual_devs.h table. |
517 | */ | 478 | */ |
518 | if (id->idVendor || id->idProduct) { | 479 | if (id->idVendor || id->idProduct) { |
519 | static char *msgs[3] = { | 480 | static const char *msgs[3] = { |
520 | "an unneeded SubClass entry", | 481 | "an unneeded SubClass entry", |
521 | "an unneeded Protocol entry", | 482 | "an unneeded Protocol entry", |
522 | "unneeded SubClass and Protocol entries"}; | 483 | "unneeded SubClass and Protocol entries"}; |
@@ -529,7 +490,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
529 | if (unusual_dev->useTransport != US_PR_DEVICE && | 490 | if (unusual_dev->useTransport != US_PR_DEVICE && |
530 | us->protocol == idesc->bInterfaceProtocol) | 491 | us->protocol == idesc->bInterfaceProtocol) |
531 | msg += 2; | 492 | msg += 2; |
532 | if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE)) | 493 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
533 | printk(KERN_NOTICE USB_STORAGE "This device " | 494 | printk(KERN_NOTICE USB_STORAGE "This device " |
534 | "(%04x,%04x,%04x S %02x P %02x)" | 495 | "(%04x,%04x,%04x S %02x P %02x)" |
535 | " has %s in unusual_devs.h\n" | 496 | " has %s in unusual_devs.h\n" |
@@ -686,6 +647,15 @@ static int get_protocol(struct us_data *us) | |||
686 | break; | 647 | break; |
687 | #endif | 648 | #endif |
688 | 649 | ||
650 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
651 | case US_PR_ALAUDA: | ||
652 | us->transport_name = "Alauda Control/Bulk"; | ||
653 | us->transport = alauda_transport; | ||
654 | us->transport_reset = usb_stor_Bulk_reset; | ||
655 | us->max_lun = 1; | ||
656 | break; | ||
657 | #endif | ||
658 | |||
689 | default: | 659 | default: |
690 | return -EIO; | 660 | return -EIO; |
691 | } | 661 | } |
@@ -921,10 +891,12 @@ static int storage_probe(struct usb_interface *intf, | |||
921 | { | 891 | { |
922 | struct Scsi_Host *host; | 892 | struct Scsi_Host *host; |
923 | struct us_data *us; | 893 | struct us_data *us; |
924 | const int id_index = id - storage_usb_ids; | ||
925 | int result; | 894 | int result; |
926 | struct task_struct *th; | 895 | struct task_struct *th; |
927 | 896 | ||
897 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
898 | return -ENXIO; | ||
899 | |||
928 | US_DEBUGP("USB Mass Storage device detected\n"); | 900 | US_DEBUGP("USB Mass Storage device detected\n"); |
929 | 901 | ||
930 | /* | 902 | /* |
@@ -957,29 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
957 | * of the match from the usb_device_id table, so we can find the | 929 | * of the match from the usb_device_id table, so we can find the |
958 | * corresponding entry in the private table. | 930 | * corresponding entry in the private table. |
959 | */ | 931 | */ |
960 | get_device_info(us, id_index); | 932 | get_device_info(us, id); |
961 | |||
962 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
963 | if (us->protocol == US_PR_EUSB_SDDR09 || | ||
964 | us->protocol == US_PR_DPCM_USB) { | ||
965 | /* set the configuration -- STALL is an acceptable response here */ | ||
966 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { | ||
967 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev | ||
968 | ->actconfig->desc.bConfigurationValue); | ||
969 | goto BadDevice; | ||
970 | } | ||
971 | result = usb_reset_configuration(us->pusb_dev); | ||
972 | |||
973 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
974 | if (result == -EPIPE) { | ||
975 | US_DEBUGP("-- stall on control interface\n"); | ||
976 | } else if (result != 0) { | ||
977 | /* it's not a stall, but another error -- time to bail */ | ||
978 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
979 | goto BadDevice; | ||
980 | } | ||
981 | } | ||
982 | #endif | ||
983 | 933 | ||
984 | /* Get the transport, protocol, and pipe settings */ | 934 | /* Get the transport, protocol, and pipe settings */ |
985 | result = get_transport(us); | 935 | result = get_transport(us); |
@@ -1044,7 +994,6 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1044 | ***********************************************************************/ | 994 | ***********************************************************************/ |
1045 | 995 | ||
1046 | static struct usb_driver usb_storage_driver = { | 996 | static struct usb_driver usb_storage_driver = { |
1047 | .owner = THIS_MODULE, | ||
1048 | .name = "usb-storage", | 997 | .name = "usb-storage", |
1049 | .probe = storage_probe, | 998 | .probe = storage_probe, |
1050 | .disconnect = storage_disconnect, | 999 | .disconnect = storage_disconnect, |
@@ -1062,9 +1011,10 @@ static int __init usb_stor_init(void) | |||
1062 | 1011 | ||
1063 | /* register the driver, return usb_register return code if error */ | 1012 | /* register the driver, return usb_register return code if error */ |
1064 | retval = usb_register(&usb_storage_driver); | 1013 | retval = usb_register(&usb_storage_driver); |
1065 | if (retval == 0) | 1014 | if (retval == 0) { |
1066 | printk(KERN_INFO "USB Mass Storage support registered.\n"); | 1015 | printk(KERN_INFO "USB Mass Storage support registered.\n"); |
1067 | 1016 | usb_usual_set_present(USB_US_TYPE_STOR); | |
1017 | } | ||
1068 | return retval; | 1018 | return retval; |
1069 | } | 1019 | } |
1070 | 1020 | ||
@@ -1088,6 +1038,8 @@ static void __exit usb_stor_exit(void) | |||
1088 | wait_for_completion(&threads_gone); | 1038 | wait_for_completion(&threads_gone); |
1089 | atomic_dec(&total_threads); | 1039 | atomic_dec(&total_threads); |
1090 | } | 1040 | } |
1041 | |||
1042 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
1091 | } | 1043 | } |
1092 | 1044 | ||
1093 | module_init(usb_stor_init); | 1045 | module_init(usb_stor_init); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 98b09711a739..7259fd1f6b0d 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define _USB_H_ | 45 | #define _USB_H_ |
46 | 46 | ||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/usb_usual.h> | ||
48 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
49 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
50 | #include <linux/completion.h> | 51 | #include <linux/completion.h> |
@@ -63,38 +64,8 @@ struct us_unusual_dev { | |||
63 | __u8 useProtocol; | 64 | __u8 useProtocol; |
64 | __u8 useTransport; | 65 | __u8 useTransport; |
65 | int (*initFunction)(struct us_data *); | 66 | int (*initFunction)(struct us_data *); |
66 | unsigned int flags; | ||
67 | }; | 67 | }; |
68 | 68 | ||
69 | /* | ||
70 | * Static flag definitions. We use this roundabout technique so that the | ||
71 | * proc_info() routine can automatically display a message for each flag. | ||
72 | */ | ||
73 | #define US_DO_ALL_FLAGS \ | ||
74 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
75 | /* allow access to only LUN 0 */ \ | ||
76 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
77 | /* unusual_devs entry is necessary */ \ | ||
78 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
79 | /* supports multiple targets */ \ | ||
80 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
81 | /* INQUIRY response needs faking */ \ | ||
82 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
83 | /* READ CAPACITY response too big */ \ | ||
84 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
85 | /* reported residue is wrong */ \ | ||
86 | US_FLAG(BULK32, 0x00000040) \ | ||
87 | /* Uses 32-byte CBW length */ \ | ||
88 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
89 | /* PREVENT/ALLOW not supported */ \ | ||
90 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
91 | /* Need delay after Command phase */ \ | ||
92 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
93 | /* Don't check for write-protect */ \ | ||
94 | |||
95 | #define US_FLAG(name, value) US_FL_##name = value , | ||
96 | enum { US_DO_ALL_FLAGS }; | ||
97 | #undef US_FLAG | ||
98 | 69 | ||
99 | /* Dynamic flag definitions: used in set_bit() etc. */ | 70 | /* Dynamic flag definitions: used in set_bit() etc. */ |
100 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ | 71 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ |
@@ -122,7 +93,11 @@ enum { US_DO_ALL_FLAGS }; | |||
122 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 93 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); |
123 | typedef int (*trans_reset)(struct us_data*); | 94 | typedef int (*trans_reset)(struct us_data*); |
124 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); | 95 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); |
125 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ | 96 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ |
97 | typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ | ||
98 | |||
99 | #define US_SUSPEND 0 | ||
100 | #define US_RESUME 1 | ||
126 | 101 | ||
127 | /* we allocate one of these for every device that we remember */ | 102 | /* we allocate one of these for every device that we remember */ |
128 | struct us_data { | 103 | struct us_data { |
@@ -178,6 +153,9 @@ struct us_data { | |||
178 | /* subdriver information */ | 153 | /* subdriver information */ |
179 | void *extra; /* Any extra data */ | 154 | void *extra; /* Any extra data */ |
180 | extra_data_destructor extra_destructor;/* extra data destructor */ | 155 | extra_data_destructor extra_destructor;/* extra data destructor */ |
156 | #ifdef CONFIG_PM | ||
157 | pm_hook suspend_resume_hook; | ||
158 | #endif | ||
181 | }; | 159 | }; |
182 | 160 | ||
183 | /* Convert between us_data and the corresponding Scsi_Host */ | 161 | /* Convert between us_data and the corresponding Scsi_Host */ |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 6c3a53f8f26c..5d02f16b7d0e 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -39,10 +39,15 @@ MODULE_DEVICE_TABLE (usb, skel_table); | |||
39 | /* Get a minor range for your devices from the usb maintainer */ | 39 | /* Get a minor range for your devices from the usb maintainer */ |
40 | #define USB_SKEL_MINOR_BASE 192 | 40 | #define USB_SKEL_MINOR_BASE 192 |
41 | 41 | ||
42 | /* our private defines. if this grows any larger, use your own .h file */ | ||
43 | #define MAX_TRANSFER ( PAGE_SIZE - 512 ) | ||
44 | #define WRITES_IN_FLIGHT 8 | ||
45 | |||
42 | /* Structure to hold all of our device specific stuff */ | 46 | /* Structure to hold all of our device specific stuff */ |
43 | struct usb_skel { | 47 | struct usb_skel { |
44 | struct usb_device * udev; /* the usb device for this device */ | 48 | struct usb_device * udev; /* the usb device for this device */ |
45 | struct usb_interface * interface; /* the interface for this device */ | 49 | struct usb_interface * interface; /* the interface for this device */ |
50 | struct semaphore limit_sem; /* limiting the number of writes in progress */ | ||
46 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ | 51 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ |
47 | size_t bulk_in_size; /* the size of the receive buffer */ | 52 | size_t bulk_in_size; /* the size of the receive buffer */ |
48 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ | 53 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ |
@@ -152,6 +157,7 @@ static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
152 | /* free up our allocated buffer */ | 157 | /* free up our allocated buffer */ |
153 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 158 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
154 | urb->transfer_buffer, urb->transfer_dma); | 159 | urb->transfer_buffer, urb->transfer_dma); |
160 | up(&dev->limit_sem); | ||
155 | } | 161 | } |
156 | 162 | ||
157 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) | 163 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) |
@@ -160,6 +166,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
160 | int retval = 0; | 166 | int retval = 0; |
161 | struct urb *urb = NULL; | 167 | struct urb *urb = NULL; |
162 | char *buf = NULL; | 168 | char *buf = NULL; |
169 | size_t writesize = min(count, (size_t)MAX_TRANSFER); | ||
163 | 170 | ||
164 | dev = (struct usb_skel *)file->private_data; | 171 | dev = (struct usb_skel *)file->private_data; |
165 | 172 | ||
@@ -167,6 +174,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
167 | if (count == 0) | 174 | if (count == 0) |
168 | goto exit; | 175 | goto exit; |
169 | 176 | ||
177 | /* limit the number of URBs in flight to stop a user from using up all RAM */ | ||
178 | if (down_interruptible(&dev->limit_sem)) { | ||
179 | retval = -ERESTARTSYS; | ||
180 | goto exit; | ||
181 | } | ||
182 | |||
170 | /* create a urb, and a buffer for it, and copy the data to the urb */ | 183 | /* create a urb, and a buffer for it, and copy the data to the urb */ |
171 | urb = usb_alloc_urb(0, GFP_KERNEL); | 184 | urb = usb_alloc_urb(0, GFP_KERNEL); |
172 | if (!urb) { | 185 | if (!urb) { |
@@ -174,13 +187,13 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
174 | goto error; | 187 | goto error; |
175 | } | 188 | } |
176 | 189 | ||
177 | buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); | 190 | buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); |
178 | if (!buf) { | 191 | if (!buf) { |
179 | retval = -ENOMEM; | 192 | retval = -ENOMEM; |
180 | goto error; | 193 | goto error; |
181 | } | 194 | } |
182 | 195 | ||
183 | if (copy_from_user(buf, user_buffer, count)) { | 196 | if (copy_from_user(buf, user_buffer, writesize)) { |
184 | retval = -EFAULT; | 197 | retval = -EFAULT; |
185 | goto error; | 198 | goto error; |
186 | } | 199 | } |
@@ -188,7 +201,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
188 | /* initialize the urb properly */ | 201 | /* initialize the urb properly */ |
189 | usb_fill_bulk_urb(urb, dev->udev, | 202 | usb_fill_bulk_urb(urb, dev->udev, |
190 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), | 203 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), |
191 | buf, count, skel_write_bulk_callback, dev); | 204 | buf, writesize, skel_write_bulk_callback, dev); |
192 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 205 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
193 | 206 | ||
194 | /* send the data out the bulk port */ | 207 | /* send the data out the bulk port */ |
@@ -202,11 +215,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
202 | usb_free_urb(urb); | 215 | usb_free_urb(urb); |
203 | 216 | ||
204 | exit: | 217 | exit: |
205 | return count; | 218 | return writesize; |
206 | 219 | ||
207 | error: | 220 | error: |
208 | usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); | 221 | usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); |
209 | usb_free_urb(urb); | 222 | usb_free_urb(urb); |
223 | up(&dev->limit_sem); | ||
210 | return retval; | 224 | return retval; |
211 | } | 225 | } |
212 | 226 | ||
@@ -238,13 +252,13 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
238 | int retval = -ENOMEM; | 252 | int retval = -ENOMEM; |
239 | 253 | ||
240 | /* allocate memory for our device state and initialize it */ | 254 | /* allocate memory for our device state and initialize it */ |
241 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 255 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
242 | if (dev == NULL) { | 256 | if (dev == NULL) { |
243 | err("Out of memory"); | 257 | err("Out of memory"); |
244 | goto error; | 258 | goto error; |
245 | } | 259 | } |
246 | memset(dev, 0x00, sizeof(*dev)); | ||
247 | kref_init(&dev->kref); | 260 | kref_init(&dev->kref); |
261 | sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); | ||
248 | 262 | ||
249 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 263 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
250 | dev->interface = interface; | 264 | dev->interface = interface; |
@@ -330,7 +344,6 @@ static void skel_disconnect(struct usb_interface *interface) | |||
330 | } | 344 | } |
331 | 345 | ||
332 | static struct usb_driver skel_driver = { | 346 | static struct usb_driver skel_driver = { |
333 | .owner = THIS_MODULE, | ||
334 | .name = "skeleton", | 347 | .name = "skeleton", |
335 | .probe = skel_probe, | 348 | .probe = skel_probe, |
336 | .disconnect = skel_disconnect, | 349 | .disconnect = skel_disconnect, |