Rev 1049 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1049 | mauro | 1 | /* |
2 | * USB Serial Converter driver |
||
3 | * |
||
4 | * Copyright (C) 1999 - 2003 Greg Kroah-Hartman (greg@kroah.com) |
||
5 | * Copyright (C) 2000 Peter Berger (pberger@brimson.com) |
||
6 | * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License version |
||
10 | * 2 as published by the Free Software Foundation. |
||
11 | * |
||
12 | * This driver was originally based on the ACM driver by Armin Fuerst (which was |
||
13 | * based on a driver by Brad Keryan) |
||
14 | * |
||
15 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
||
16 | * |
||
17 | * (12/10/2002) gkh |
||
18 | * Split the ports off into their own struct device, and added a |
||
19 | * usb-serial bus driver. |
||
20 | * |
||
21 | * (11/19/2002) gkh |
||
22 | * removed a few #ifdefs for the generic code and cleaned up the failure |
||
23 | * logic in initialization. |
||
24 | * |
||
25 | * (10/02/2002) gkh |
||
26 | * moved the console code to console.c and out of this file. |
||
27 | * |
||
28 | * (06/05/2002) gkh |
||
29 | * moved location of startup() call in serial_probe() until after all |
||
30 | * of the port information and endpoints are initialized. This makes |
||
31 | * things easier for some drivers. |
||
32 | * |
||
33 | * (04/10/2002) gkh |
||
34 | * added serial_read_proc function which creates a |
||
35 | * /proc/tty/driver/usb-serial file. |
||
36 | * |
||
37 | * (03/27/2002) gkh |
||
38 | * Got USB serial console code working properly and merged into the main |
||
39 | * version of the tree. Thanks to Randy Dunlap for the initial version |
||
40 | * of this code, and for pushing me to finish it up. |
||
41 | * The USB serial console works with any usb serial driver device. |
||
42 | * |
||
43 | * (03/21/2002) gkh |
||
44 | * Moved all manipulation of port->open_count into the core. Now the |
||
45 | * individual driver's open and close functions are called only when the |
||
46 | * first open() and last close() is called. Making the drivers a bit |
||
47 | * smaller and simpler. |
||
48 | * Fixed a bug if a driver didn't have the owner field set. |
||
49 | * |
||
50 | * (02/26/2002) gkh |
||
51 | * Moved all locking into the main serial_* functions, instead of having |
||
52 | * the individual drivers have to grab the port semaphore. This should |
||
53 | * reduce races. |
||
54 | * Reworked the MOD_INC logic a bit to always increment and decrement, even |
||
55 | * if the generic driver is being used. |
||
56 | * |
||
57 | * (10/10/2001) gkh |
||
58 | * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to |
||
59 | * help prevent child drivers from accessing the device since it is now |
||
60 | * gone. |
||
61 | * |
||
62 | * (09/13/2001) gkh |
||
63 | * Moved generic driver initialize after we have registered with the USB |
||
64 | * core. Thanks to Randy Dunlap for pointing this problem out. |
||
65 | * |
||
66 | * (07/03/2001) gkh |
||
67 | * Fixed module paramater size. Thanks to John Brockmeyer for the pointer. |
||
68 | * Fixed vendor and product getting defined through the MODULE_PARM macro |
||
69 | * if the Generic driver wasn't compiled in. |
||
70 | * Fixed problem with generic_shutdown() not being called for drivers that |
||
71 | * don't have a shutdown() function. |
||
72 | * |
||
73 | * (06/06/2001) gkh |
||
74 | * added evil hack that is needed for the prolific pl2303 device due to the |
||
75 | * crazy way its endpoints are set up. |
||
76 | * |
||
77 | * (05/30/2001) gkh |
||
78 | * switched from using spinlock to a semaphore, which fixes lots of problems. |
||
79 | * |
||
80 | * (04/08/2001) gb |
||
81 | * Identify version on module load. |
||
82 | * |
||
83 | * 2001_02_05 gkh |
||
84 | * Fixed buffer overflows bug with the generic serial driver. Thanks to |
||
85 | * Todd Squires <squirest@ct0.com> for fixing this. |
||
86 | * |
||
87 | * (01/10/2001) gkh |
||
88 | * Fixed bug where the generic serial adaptor grabbed _any_ device that was |
||
89 | * offered to it. |
||
90 | * |
||
91 | * (12/12/2000) gkh |
||
92 | * Removed MOD_INC and MOD_DEC from poll and disconnect functions, and |
||
93 | * moved them to the serial_open and serial_close functions. |
||
94 | * Also fixed bug with there not being a MOD_DEC for the generic driver |
||
95 | * (thanks to Gary Brubaker for finding this.) |
||
96 | * |
||
97 | * (11/29/2000) gkh |
||
98 | * Small NULL pointer initialization cleanup which saves a bit of disk image |
||
99 | * |
||
100 | * (11/01/2000) Adam J. Richter |
||
101 | * instead of using idVendor/idProduct pairs, usb serial drivers |
||
102 | * now identify their hardware interest with usb_device_id tables, |
||
103 | * which they usually have anyhow for use with MODULE_DEVICE_TABLE. |
||
104 | * |
||
105 | * (10/05/2000) gkh |
||
106 | * Fixed bug with urb->dev not being set properly, now that the usb |
||
107 | * core needs it. |
||
108 | * |
||
109 | * (09/11/2000) gkh |
||
110 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data |
||
111 | * |
||
112 | * (08/28/2000) gkh |
||
113 | * Added port_lock to port structure. |
||
114 | * Added locks for SMP safeness to generic driver |
||
115 | * Fixed the ability to open a generic device's port more than once. |
||
116 | * |
||
117 | * (07/23/2000) gkh |
||
118 | * Added bulk_out_endpointAddress to port structure. |
||
119 | * |
||
120 | * (07/19/2000) gkh, pberger, and borchers |
||
121 | * Modifications to allow usb-serial drivers to be modules. |
||
122 | * |
||
123 | * (07/03/2000) gkh |
||
124 | * Added more debugging to serial_ioctl call |
||
125 | * |
||
126 | * (06/25/2000) gkh |
||
127 | * Changed generic_write_bulk_callback to not call wake_up_interruptible |
||
128 | * directly, but to have port_softint do it at a safer time. |
||
129 | * |
||
130 | * (06/23/2000) gkh |
||
131 | * Cleaned up debugging statements in a quest to find UHCI timeout bug. |
||
132 | * |
||
133 | * (05/22/2000) gkh |
||
134 | * Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be |
||
135 | * removed from the individual device source files. |
||
136 | * |
||
137 | * (05/03/2000) gkh |
||
138 | * Added the Digi Acceleport driver from Al Borchers and Peter Berger. |
||
139 | * |
||
140 | * (05/02/2000) gkh |
||
141 | * Changed devfs and tty register code to work properly now. This was based on |
||
142 | * the ACM driver changes by Vojtech Pavlik. |
||
143 | * |
||
144 | * (04/27/2000) Ryan VanderBijl |
||
145 | * Put calls to *_paranoia_checks into one function. |
||
146 | * |
||
147 | * (04/23/2000) gkh |
||
148 | * Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. |
||
149 | * Moved when the startup code printed out the devices that are supported. |
||
150 | * |
||
151 | * (04/19/2000) gkh |
||
152 | * Added driver for ZyXEL omni.net lcd plus ISDN TA |
||
153 | * Made startup info message specify which drivers were compiled in. |
||
154 | * |
||
155 | * (04/03/2000) gkh |
||
156 | * Changed the probe process to remove the module unload races. |
||
157 | * Changed where the tty layer gets initialized to have devfs work nicer. |
||
158 | * Added initial devfs support. |
||
159 | * |
||
160 | * (03/26/2000) gkh |
||
161 | * Split driver up into device specific pieces. |
||
162 | * |
||
163 | * (03/19/2000) gkh |
||
164 | * Fixed oops that could happen when device was removed while a program |
||
165 | * was talking to the device. |
||
166 | * Removed the static urbs and now all urbs are created and destroyed |
||
167 | * dynamically. |
||
168 | * Reworked the internal interface. Now everything is based on the |
||
169 | * usb_serial_port structure instead of the larger usb_serial structure. |
||
170 | * This fixes the bug that a multiport device could not have more than |
||
171 | * one port open at one time. |
||
172 | * |
||
173 | * (03/17/2000) gkh |
||
174 | * Added config option for debugging messages. |
||
175 | * Added patch for keyspan pda from Brian Warner. |
||
176 | * |
||
177 | * (03/06/2000) gkh |
||
178 | * Added the keyspan pda code from Brian Warner <warner@lothar.com> |
||
179 | * Moved a bunch of the port specific stuff into its own structure. This |
||
180 | * is in anticipation of the true multiport devices (there's a bug if you |
||
181 | * try to access more than one port of any multiport device right now) |
||
182 | * |
||
183 | * (02/21/2000) gkh |
||
184 | * Made it so that any serial devices only have to specify which functions |
||
185 | * they want to overload from the generic function calls (great, |
||
186 | * inheritance in C, in a driver, just what I wanted...) |
||
187 | * Added support for set_termios and ioctl function calls. No drivers take |
||
188 | * advantage of this yet. |
||
189 | * Removed the #ifdef MODULE, now there is no module specific code. |
||
190 | * Cleaned up a few comments in usb-serial.h that were wrong (thanks again |
||
191 | * to Miles Lott). |
||
192 | * Small fix to get_free_serial. |
||
193 | * |
||
194 | * (02/14/2000) gkh |
||
195 | * Removed the Belkin and Peracom functionality from the driver due to |
||
196 | * the lack of support from the vendor, and me not wanting people to |
||
197 | * accidenatly buy the device, expecting it to work with Linux. |
||
198 | * Added read_bulk_callback and write_bulk_callback to the type structure |
||
199 | * for the needs of the FTDI and WhiteHEAT driver. |
||
200 | * Changed all reverences to FTDI to FTDI_SIO at the request of Bill |
||
201 | * Ryder. |
||
202 | * Changed the output urb size back to the max endpoint size to make |
||
203 | * the ftdi_sio driver have it easier, and due to the fact that it didn't |
||
204 | * really increase the speed any. |
||
205 | * |
||
206 | * (02/11/2000) gkh |
||
207 | * Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a |
||
208 | * patch from Miles Lott (milos@insync.net). |
||
209 | * Fixed bug with not restoring the minor range that a device grabs, if |
||
210 | * the startup function fails (thanks Miles for finding this). |
||
211 | * |
||
212 | * (02/05/2000) gkh |
||
213 | * Added initial framework for the Keyspan PDA serial converter so that |
||
214 | * Brian Warner has a place to put his code. |
||
215 | * Made the ezusb specific functions generic enough that different |
||
216 | * devices can use them (whiteheat and keyspan_pda both need them). |
||
217 | * Split out a whole bunch of structure and other stuff to a separate |
||
218 | * usb-serial.h file. |
||
219 | * Made the Visor connection messages a little more understandable, now |
||
220 | * that Miles Lott (milos@insync.net) has gotten the Generic channel to |
||
221 | * work. Also made them always show up in the log file. |
||
222 | * |
||
223 | * (01/25/2000) gkh |
||
224 | * Added initial framework for FTDI serial converter so that Bill Ryder |
||
225 | * has a place to put his code. |
||
226 | * Added the vendor specific info from Handspring. Now we can print out |
||
227 | * informational debug messages as well as understand what is happening. |
||
228 | * |
||
229 | * (01/23/2000) gkh |
||
230 | * Fixed problem of crash when trying to open a port that didn't have a |
||
231 | * device assigned to it. Made the minor node finding a little smarter, |
||
232 | * now it looks to find a continuous space for the new device. |
||
233 | * |
||
234 | * (01/21/2000) gkh |
||
235 | * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) |
||
236 | * Fixed get_serial_by_minor which was all messed up for multi port |
||
237 | * devices. Fixed multi port problem for generic devices. Now the number |
||
238 | * of ports is determined by the number of bulk out endpoints for the |
||
239 | * generic device. |
||
240 | * |
||
241 | * (01/19/2000) gkh |
||
242 | * Removed lots of cruft that was around from the old (pre urb) driver |
||
243 | * interface. |
||
244 | * Made the serial_table dynamic. This should save lots of memory when |
||
245 | * the number of minor nodes goes up to 256. |
||
246 | * Added initial support for devices that have more than one port. |
||
247 | * Added more debugging comments for the Visor, and added a needed |
||
248 | * set_configuration call. |
||
249 | * |
||
250 | * (01/17/2000) gkh |
||
251 | * Fixed the WhiteHEAT firmware (my processing tool had a bug) |
||
252 | * and added new debug loader firmware for it. |
||
253 | * Removed the put_char function as it isn't really needed. |
||
254 | * Added visor startup commands as found by the Win98 dump. |
||
255 | * |
||
256 | * (01/13/2000) gkh |
||
257 | * Fixed the vendor id for the generic driver to the one I meant it to be. |
||
258 | * |
||
259 | * (01/12/2000) gkh |
||
260 | * Forget the version numbering...that's pretty useless... |
||
261 | * Made the driver able to be compiled so that the user can select which |
||
262 | * converter they want to use. This allows people who only want the Visor |
||
263 | * support to not pay the memory size price of the WhiteHEAT. |
||
264 | * Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) |
||
265 | * grabbed the root hub. Not good. |
||
266 | * |
||
267 | * version 0.4.0 (01/10/2000) gkh |
||
268 | * Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT |
||
269 | * device. Added startup function to allow firmware to be downloaded to |
||
270 | * a device if it needs to be. |
||
271 | * Added firmware download logic to the WhiteHEAT device. |
||
272 | * Started to add #defines to split up the different drivers for potential |
||
273 | * configuration option. |
||
274 | * |
||
275 | * version 0.3.1 (12/30/99) gkh |
||
276 | * Fixed problems with urb for bulk out. |
||
277 | * Added initial support for multiple sets of endpoints. This enables |
||
278 | * the Handspring Visor to be attached successfully. Only the first |
||
279 | * bulk in / bulk out endpoint pair is being used right now. |
||
280 | * |
||
281 | * version 0.3.0 (12/27/99) gkh |
||
282 | * Added initial support for the Handspring Visor based on a patch from |
||
283 | * Miles Lott (milos@sneety.insync.net) |
||
284 | * Cleaned up the code a bunch and converted over to using urbs only. |
||
285 | * |
||
286 | * version 0.2.3 (12/21/99) gkh |
||
287 | * Added initial support for the Connect Tech WhiteHEAT converter. |
||
288 | * Incremented the number of ports in expectation of getting the |
||
289 | * WhiteHEAT to work properly (4 ports per connection). |
||
290 | * Added notification on insertion and removal of what port the |
||
291 | * device is/was connected to (and what kind of device it was). |
||
292 | * |
||
293 | * version 0.2.2 (12/16/99) gkh |
||
294 | * Changed major number to the new allocated number. We're legal now! |
||
295 | * |
||
296 | * version 0.2.1 (12/14/99) gkh |
||
297 | * Fixed bug that happens when device node is opened when there isn't a |
||
298 | * device attached to it. Thanks to marek@webdesign.no for noticing this. |
||
299 | * |
||
300 | * version 0.2.0 (11/10/99) gkh |
||
301 | * Split up internals to make it easier to add different types of serial |
||
302 | * converters to the code. |
||
303 | * Added a "generic" driver that gets it's vendor and product id |
||
304 | * from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) |
||
305 | * for the idea and sample code (from the usb scanner driver.) |
||
306 | * Cleared up any licensing questions by releasing it under the GNU GPL. |
||
307 | * |
||
308 | * version 0.1.2 (10/25/99) gkh |
||
309 | * Fixed bug in detecting device. |
||
310 | * |
||
311 | * version 0.1.1 (10/05/99) gkh |
||
312 | * Changed the major number to not conflict with anything else. |
||
313 | * |
||
314 | * version 0.1 (09/28/99) gkh |
||
315 | * Can recognize the two different devices and start up a read from |
||
316 | * device when asked to. Writes also work. No control signals yet, this |
||
317 | * all is vendor specific data (i.e. no spec), also no control for |
||
318 | * different baud rates or other bit settings. |
||
319 | * Currently we are using the same devid as the acm driver. This needs |
||
320 | * to change. |
||
321 | * |
||
322 | */ |
||
323 | |||
324 | #include <linuxcomp.h> |
||
325 | |||
326 | #include <linux/config.h> |
||
327 | #include <linux/kernel.h> |
||
328 | #include <linux/errno.h> |
||
329 | #include <linux/init.h> |
||
330 | #include <linux/slab.h> |
||
331 | #include <linux/tty.h> |
||
332 | #include <linux/tty_driver.h> |
||
333 | #include <linux/tty_flip.h> |
||
334 | #include <linux/module.h> |
||
335 | #include <linux/spinlock.h> |
||
336 | #include <linux/list.h> |
||
337 | #include <linux/smp_lock.h> |
||
338 | #include <asm/uaccess.h> |
||
339 | #include <linux/usb.h> |
||
340 | |||
341 | |||
342 | #ifdef CONFIG_USB_SERIAL_DEBUG |
||
343 | static int debug = 1; |
||
344 | #else |
||
345 | static int debug; |
||
346 | #endif |
||
347 | |||
348 | #include "usb-serial.h" |
||
349 | #include "pl2303.h" |
||
350 | |||
351 | /* |
||
352 | * Version Information |
||
353 | */ |
||
354 | #define DRIVER_VERSION "v2.0" |
||
355 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" |
||
356 | #define DRIVER_DESC "USB Serial Driver core" |
||
357 | |||
358 | |||
359 | #ifdef CONFIG_USB_SERIAL_GENERIC |
||
360 | /* we want to look at all devices, as the vendor/product id can change |
||
361 | * depending on the command line argument */ |
||
362 | static struct usb_device_id generic_serial_ids[] = { |
||
363 | {.driver_info = 42}, |
||
364 | {} |
||
365 | }; |
||
366 | |||
367 | #endif /* CONFIG_USB_SERIAL_GENERIC */ |
||
368 | |||
369 | /* Driver structure we register with the USB core */ |
||
370 | static struct usb_driver usb_serial_driver = { |
||
371 | .owner = THIS_MODULE, |
||
372 | .name = "usbserial", |
||
373 | .probe = usb_serial_probe, |
||
374 | .disconnect = usb_serial_disconnect, |
||
375 | #ifdef CONFIG_USB_SERIAL_GENERIC |
||
376 | .id_table = generic_serial_ids, |
||
377 | #endif |
||
378 | }; |
||
379 | |||
380 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead |
||
381 | the MODULE_DEVICE_TABLE declarations in each serial driver |
||
382 | cause the "hotplug" program to pull in whatever module is necessary |
||
383 | via modprobe, and modprobe will load usbserial because the serial |
||
384 | drivers depend on it. |
||
385 | */ |
||
386 | |||
387 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ |
||
388 | static LIST_HEAD(usb_serial_driver_list); |
||
389 | |||
390 | |||
391 | struct usb_serial *usb_serial_get_by_index(unsigned index) |
||
392 | { |
||
393 | struct usb_serial *serial = serial_table[index]; |
||
394 | |||
395 | if (serial) |
||
396 | kobject_get (&serial->kobj); |
||
397 | return serial; |
||
398 | } |
||
399 | |||
400 | static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor) |
||
401 | { |
||
402 | unsigned int i, j; |
||
403 | int good_spot; |
||
404 | |||
405 | dbg("%s %d", __FUNCTION__, num_ports); |
||
406 | |||
407 | *minor = 0; |
||
408 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
||
409 | if (serial_table[i]) |
||
410 | continue; |
||
411 | |||
412 | good_spot = 1; |
||
413 | for (j = 1; j <= num_ports-1; ++j) |
||
414 | if ((serial_table[i+j]) || (i+j >= SERIAL_TTY_MINORS)) { |
||
415 | good_spot = 0; |
||
416 | i += j; |
||
417 | break; |
||
418 | } |
||
419 | if (good_spot == 0) |
||
420 | continue; |
||
421 | |||
422 | serial->magic = USB_SERIAL_MAGIC; |
||
423 | *minor = i; |
||
424 | dbg("%s - minor base = %d", __FUNCTION__, *minor); |
||
425 | for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) |
||
426 | serial_table[i] = serial; |
||
427 | return serial; |
||
428 | } |
||
429 | return NULL; |
||
430 | } |
||
431 | |||
432 | static void return_serial (struct usb_serial *serial) |
||
433 | { |
||
434 | int i; |
||
435 | |||
436 | dbg("%s", __FUNCTION__); |
||
437 | printk("Returning serial %d ports %d\n", serial->minor, serial->num_ports); |
||
438 | |||
439 | if (serial == NULL) |
||
440 | return; |
||
441 | |||
442 | for (i = 0; i < serial->num_ports; ++i) { |
||
443 | serial_table[serial->minor + i] = NULL; |
||
444 | } |
||
445 | |||
446 | return; |
||
447 | } |
||
448 | |||
449 | /***************************************************************************** |
||
450 | * Driver tty interface functions |
||
451 | *****************************************************************************/ |
||
452 | /*static*/ int serial_open (struct tty_struct *tty, struct file * filp) |
||
453 | { |
||
454 | struct usb_serial *serial; |
||
455 | struct usb_serial_port *port; |
||
456 | unsigned int portNumber; |
||
457 | int retval = 0; |
||
458 | |||
459 | dbg("%s", __FUNCTION__); |
||
460 | |||
461 | /* initialize the pointer incase something fails */ |
||
462 | tty->driver_data = NULL; |
||
463 | |||
464 | /* get the serial object associated with this tty pointer */ |
||
465 | serial = usb_serial_get_by_index(tty->index); |
||
466 | |||
467 | if (serial_paranoia_check (serial, __FUNCTION__)) |
||
468 | return -ENODEV; |
||
469 | |||
470 | /* set up our port structure making the tty driver remember our port object, and us it */ |
||
471 | portNumber = tty->index - serial->minor; |
||
472 | port = serial->port[portNumber]; |
||
473 | tty->driver_data = port; |
||
474 | |||
475 | port->tty = tty; |
||
476 | |||
477 | /* lock this module before we call it, |
||
478 | this may, which means we must bail out, safe because we are called with BKL held */ |
||
479 | if (!try_module_get(serial->type->owner)) { |
||
480 | retval = -ENODEV; |
||
481 | goto bailout; |
||
482 | } |
||
483 | |||
484 | ++port->open_count; |
||
485 | if (port->open_count == 1) { |
||
486 | /* only call the device specific open if this |
||
487 | * is the first time the port is opened */ |
||
488 | retval = serial->type->open(port, filp); |
||
489 | if (retval) { |
||
490 | port->open_count = 0; |
||
491 | module_put(serial->type->owner); |
||
492 | kobject_put(&serial->kobj); |
||
493 | } |
||
494 | } |
||
495 | bailout: |
||
496 | return retval; |
||
497 | } |
||
498 | |||
499 | static void serial_close(struct tty_struct *tty, struct file * filp) |
||
500 | { |
||
501 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
502 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
503 | |||
504 | if (!serial) |
||
505 | return; |
||
506 | |||
507 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
508 | |||
509 | --port->open_count; |
||
510 | if (port->open_count <= 0) { |
||
511 | /* only call the device specific close if this |
||
512 | * port is being closed by the last owner */ |
||
513 | port->serial->type->close(port, filp); |
||
514 | port->open_count = 0; |
||
515 | |||
516 | if (port->tty) { |
||
517 | if (port->tty->driver_data) |
||
518 | port->tty->driver_data = NULL; |
||
519 | port->tty = NULL; |
||
520 | } |
||
521 | } |
||
522 | |||
523 | module_put(port->serial->type->owner); |
||
524 | kobject_put(&port->serial->kobj); |
||
525 | } |
||
526 | |||
527 | /*static*/ int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) |
||
528 | { |
||
529 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
530 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
531 | int retval = -EINVAL; |
||
532 | |||
533 | if (!serial) |
||
534 | return -ENODEV; |
||
535 | |||
536 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
||
537 | |||
538 | if (!port->open_count) { |
||
539 | dbg("%s - port not opened", __FUNCTION__); |
||
540 | goto exit; |
||
541 | } |
||
542 | |||
543 | /* pass on to the driver specific version of this function */ |
||
544 | retval = serial->type->write(port, from_user, buf, count); |
||
545 | |||
546 | exit: |
||
547 | return retval; |
||
548 | } |
||
549 | |||
550 | static int serial_write_room (struct tty_struct *tty) |
||
551 | { |
||
552 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
553 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
554 | int retval = -EINVAL; |
||
555 | |||
556 | if (!serial) |
||
557 | return -ENODEV; |
||
558 | |||
559 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
560 | |||
561 | if (!port->open_count) { |
||
562 | dbg("%s - port not open", __FUNCTION__); |
||
563 | goto exit; |
||
564 | } |
||
565 | |||
566 | /* pass on to the driver specific version of this function */ |
||
567 | retval = serial->type->write_room(port); |
||
568 | |||
569 | exit: |
||
570 | return retval; |
||
571 | } |
||
572 | |||
573 | static int serial_chars_in_buffer (struct tty_struct *tty) |
||
574 | { |
||
575 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
576 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
577 | int retval = -EINVAL; |
||
578 | |||
579 | if (!serial) |
||
580 | return -ENODEV; |
||
581 | |||
582 | dbg("%s = port %d", __FUNCTION__, port->number); |
||
583 | |||
584 | if (!port->open_count) { |
||
585 | dbg("%s - port not open", __FUNCTION__); |
||
586 | goto exit; |
||
587 | } |
||
588 | |||
589 | /* pass on to the driver specific version of this function */ |
||
590 | retval = serial->type->chars_in_buffer(port); |
||
591 | |||
592 | exit: |
||
593 | return retval; |
||
594 | } |
||
595 | |||
596 | static void serial_throttle (struct tty_struct * tty) |
||
597 | { |
||
598 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
599 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
600 | |||
601 | if (!serial) |
||
602 | return; |
||
603 | |||
604 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
605 | |||
606 | if (!port->open_count) { |
||
607 | dbg ("%s - port not open", __FUNCTION__); |
||
608 | goto exit; |
||
609 | } |
||
610 | |||
611 | /* pass on to the driver specific version of this function */ |
||
612 | if (serial->type->throttle) |
||
613 | serial->type->throttle(port); |
||
614 | |||
615 | exit: |
||
616 | ; |
||
617 | } |
||
618 | |||
619 | static void serial_unthrottle (struct tty_struct * tty) |
||
620 | { |
||
621 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
622 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
623 | |||
624 | if (!serial) |
||
625 | return; |
||
626 | |||
627 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
628 | |||
629 | if (!port->open_count) { |
||
630 | dbg("%s - port not open", __FUNCTION__); |
||
631 | goto exit; |
||
632 | } |
||
633 | |||
634 | /* pass on to the driver specific version of this function */ |
||
635 | if (serial->type->unthrottle) |
||
636 | serial->type->unthrottle(port); |
||
637 | |||
638 | exit: |
||
639 | ; |
||
640 | } |
||
641 | |||
642 | static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) |
||
643 | { |
||
644 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
645 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
646 | int retval = -ENODEV; |
||
647 | |||
648 | if (!serial) |
||
649 | return -ENODEV; |
||
650 | |||
651 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); |
||
652 | |||
653 | if (!port->open_count) { |
||
654 | dbg ("%s - port not open", __FUNCTION__); |
||
655 | goto exit; |
||
656 | } |
||
657 | |||
658 | /* pass on to the driver specific version of this function if it is available */ |
||
659 | if (serial->type->ioctl) |
||
660 | retval = serial->type->ioctl(port, file, cmd, arg); |
||
661 | else |
||
662 | retval = -ENOIOCTLCMD; |
||
663 | |||
664 | exit: |
||
665 | return retval; |
||
666 | } |
||
667 | |||
668 | static void serial_set_termios (struct tty_struct *tty, struct termios * old) |
||
669 | { |
||
670 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
671 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
672 | |||
673 | if (!serial) |
||
674 | return; |
||
675 | |||
676 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
677 | |||
678 | if (!port->open_count) { |
||
679 | dbg("%s - port not open", __FUNCTION__); |
||
680 | goto exit; |
||
681 | } |
||
682 | |||
683 | /* pass on to the driver specific version of this function if it is available */ |
||
684 | if (serial->type->set_termios) |
||
685 | serial->type->set_termios(port, old); |
||
686 | |||
687 | exit: |
||
688 | ; |
||
689 | } |
||
690 | |||
691 | static void serial_break (struct tty_struct *tty, int break_state) |
||
692 | { |
||
693 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
694 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
695 | |||
696 | if (!serial) |
||
697 | return; |
||
698 | |||
699 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
700 | |||
701 | if (!port->open_count) { |
||
702 | dbg("%s - port not open", __FUNCTION__); |
||
703 | goto exit; |
||
704 | } |
||
705 | |||
706 | /* pass on to the driver specific version of this function if it is available */ |
||
707 | if (serial->type->break_ctl) |
||
708 | serial->type->break_ctl(port, break_state); |
||
709 | |||
710 | exit: |
||
711 | ; |
||
712 | } |
||
713 | |||
714 | static void serial_shutdown (struct usb_serial *serial) |
||
715 | { |
||
716 | dbg ("%s", __FUNCTION__); |
||
717 | |||
718 | serial->type->shutdown(serial); |
||
719 | } |
||
720 | |||
721 | static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) |
||
722 | { |
||
723 | struct usb_serial *serial; |
||
724 | int length = 0; |
||
725 | int i; |
||
726 | off_t begin = 0; |
||
727 | char tmp[40]; |
||
728 | |||
729 | dbg("%s", __FUNCTION__); |
||
730 | length += sprintf26 (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION); |
||
731 | for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { |
||
732 | serial = usb_serial_get_by_index(i); |
||
733 | if (serial == NULL) |
||
734 | continue; |
||
735 | |||
736 | length += sprintf26 (page+length, "%d:", i); |
||
737 | if (serial->type->owner) |
||
738 | length += sprintf26 (page+length, " module:%s", module_name(serial->type->owner)); |
||
739 | length += sprintf26 (page+length, " name:\"%s\"", serial->type->name); |
||
740 | length += sprintf26 (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product); |
||
741 | length += sprintf26 (page+length, " num_ports:%d", serial->num_ports); |
||
742 | length += sprintf26 (page+length, " port:%d", i - serial->minor + 1); |
||
743 | |||
744 | usb_make_path(serial->dev, tmp, sizeof(tmp)); |
||
745 | length += sprintf26 (page+length, " path:%s", tmp); |
||
746 | |||
747 | length += sprintf26 (page+length, "\n"); |
||
748 | if ((length + begin) > (off + count)) |
||
749 | goto done; |
||
750 | if ((length + begin) < off) { |
||
751 | begin += length; |
||
752 | length = 0; |
||
753 | } |
||
754 | kobject_put(&serial->kobj); |
||
755 | } |
||
756 | *eof = 1; |
||
757 | done: |
||
758 | if (off >= (length + begin)) |
||
759 | return 0; |
||
760 | *start = page + (off-begin); |
||
761 | return ((count < begin+length-off) ? count : begin+length-off); |
||
762 | } |
||
763 | |||
764 | static int serial_tiocmget (struct tty_struct *tty, struct file *file) |
||
765 | { |
||
766 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
767 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
768 | |||
769 | if (!serial) |
||
770 | goto exit; |
||
771 | |||
772 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
773 | |||
774 | if (!port->open_count) { |
||
775 | dbg("%s - port not open", __FUNCTION__); |
||
776 | goto exit; |
||
777 | } |
||
778 | |||
779 | if (serial->type->tiocmget) |
||
780 | return serial->type->tiocmget(port, file); |
||
781 | |||
782 | exit: |
||
783 | return -EINVAL; |
||
784 | } |
||
785 | |||
786 | static int serial_tiocmset (struct tty_struct *tty, struct file *file, |
||
787 | unsigned int set, unsigned int clear) |
||
788 | { |
||
789 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
790 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
791 | |||
792 | if (!serial) |
||
793 | goto exit; |
||
794 | |||
795 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
796 | |||
797 | if (!port->open_count) { |
||
798 | dbg("%s - port not open", __FUNCTION__); |
||
799 | goto exit; |
||
800 | } |
||
801 | |||
802 | if (serial->type->tiocmset) |
||
803 | return serial->type->tiocmset(port, file, set, clear); |
||
804 | |||
805 | exit: |
||
806 | return -EINVAL; |
||
807 | } |
||
808 | |||
809 | void usb_serial_port_softint(void *private) |
||
810 | { |
||
811 | struct usb_serial_port *port = (struct usb_serial_port *)private; |
||
812 | struct usb_serial *serial; |
||
813 | struct tty_struct *tty; |
||
814 | |||
815 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
816 | |||
817 | if (!port) |
||
818 | return; |
||
819 | |||
820 | serial = get_usb_serial (port, __FUNCTION__); |
||
821 | if (!serial) |
||
822 | return; |
||
823 | |||
824 | tty = port->tty; |
||
825 | if (!tty) |
||
826 | return; |
||
827 | |||
828 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { |
||
829 | dbg("%s - write wakeup call.", __FUNCTION__); |
||
830 | (tty->ldisc.write_wakeup)(tty); |
||
831 | } |
||
832 | |||
833 | wake_up_interruptible(&tty->write_wait); |
||
834 | } |
||
835 | |||
836 | static void destroy_serial (struct kobject *kobj) |
||
837 | { |
||
838 | struct usb_serial *serial; |
||
839 | struct usb_serial_port *port; |
||
840 | int i; |
||
841 | |||
842 | dbg ("%s - %s", __FUNCTION__, kobj->name); |
||
843 | |||
844 | serial = to_usb_serial(kobj); |
||
845 | serial_shutdown (serial); |
||
846 | |||
847 | /* return the minor range that this device had */ |
||
848 | return_serial(serial); |
||
849 | |||
850 | for (i = 0; i < serial->num_ports; ++i) |
||
851 | serial->port[i]->open_count = 0; |
||
852 | |||
853 | /* the ports are cleaned up and released in port_release() */ |
||
854 | for (i = 0; i < serial->num_ports; ++i) |
||
855 | if (serial->port[i]->dev.parent != NULL) { |
||
856 | device_unregister(&serial->port[i]->dev); |
||
857 | serial->port[i] = NULL; |
||
858 | } |
||
859 | |||
860 | /* If this is a "fake" port, we have to clean it up here, as it will |
||
861 | * not get cleaned up in port_release() as it was never registered with |
||
862 | * the driver core */ |
||
863 | if (serial->num_ports < serial->num_port_pointers) { |
||
864 | for (i = serial->num_ports; i < serial->num_port_pointers; ++i) { |
||
865 | port = serial->port[i]; |
||
866 | if (!port) |
||
867 | continue; |
||
868 | if (port->read_urb) { |
||
869 | usb_unlink_urb(port->read_urb); |
||
870 | usb_free_urb(port->read_urb); |
||
871 | } |
||
872 | if (port->write_urb) { |
||
873 | usb_unlink_urb(port->write_urb); |
||
874 | usb_free_urb(port->write_urb); |
||
875 | } |
||
876 | if (port->interrupt_in_urb) { |
||
877 | usb_unlink_urb(port->interrupt_in_urb); |
||
878 | usb_free_urb(port->interrupt_in_urb); |
||
879 | } |
||
880 | kfree(port->bulk_in_buffer); |
||
881 | kfree(port->bulk_out_buffer); |
||
882 | kfree(port->interrupt_in_buffer); |
||
883 | } |
||
884 | } |
||
885 | |||
886 | usb_put_dev(serial->dev); |
||
887 | |||
888 | /* free up any memory that we allocated */ |
||
889 | kfree (serial); |
||
890 | } |
||
891 | |||
892 | static struct kobj_type usb_serial_kobj_type = { |
||
893 | .release = destroy_serial, |
||
894 | }; |
||
895 | |||
896 | static void port_release(struct device *dev) |
||
897 | { |
||
898 | struct usb_serial_port *port = to_usb_serial_port(dev); |
||
899 | |||
900 | dbg ("%s - %s", __FUNCTION__, dev->bus_id); |
||
901 | if (port->read_urb) { |
||
902 | usb_unlink_urb(port->read_urb); |
||
903 | usb_free_urb(port->read_urb); |
||
904 | } |
||
905 | if (port->write_urb) { |
||
906 | usb_unlink_urb(port->write_urb); |
||
907 | usb_free_urb(port->write_urb); |
||
908 | } |
||
909 | if (port->interrupt_in_urb) { |
||
910 | usb_unlink_urb(port->interrupt_in_urb); |
||
911 | usb_free_urb(port->interrupt_in_urb); |
||
912 | } |
||
913 | kfree(port->bulk_in_buffer); |
||
914 | kfree(port->bulk_out_buffer); |
||
915 | kfree(port->interrupt_in_buffer); |
||
916 | kfree(port); |
||
917 | } |
||
918 | |||
919 | static struct usb_serial * create_serial (struct usb_device *dev, |
||
920 | struct usb_interface *interface, |
||
921 | struct usb_serial_device_type *type) |
||
922 | { |
||
923 | struct usb_serial *serial; |
||
924 | |||
925 | serial = kmalloc (sizeof (*serial), GFP_KERNEL); |
||
926 | if (!serial) { |
||
927 | dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); |
||
928 | return NULL; |
||
929 | } |
||
930 | memset (serial, 0, sizeof(*serial)); |
||
931 | serial->dev = usb_get_dev(dev); |
||
932 | serial->type = type; |
||
933 | serial->interface = interface; |
||
934 | serial->vendor = dev->descriptor.idVendor; |
||
935 | serial->product = dev->descriptor.idProduct; |
||
936 | |||
937 | /* initialize the kobject portion of the usb_device */ |
||
938 | kobject_init(&serial->kobj); |
||
939 | serial->kobj.ktype = &usb_serial_kobj_type; |
||
940 | |||
941 | return serial; |
||
942 | } |
||
943 | |||
944 | int usb_serial_probe(struct usb_interface *interface, |
||
945 | const struct usb_device_id *id) |
||
946 | { |
||
947 | struct usb_device *dev = interface_to_usbdev (interface); |
||
948 | struct usb_serial *serial = NULL; |
||
949 | struct usb_serial_port *port; |
||
950 | struct usb_host_interface *iface_desc; |
||
951 | struct usb_endpoint_descriptor *endpoint; |
||
952 | struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS]; |
||
953 | struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; |
||
954 | struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; |
||
955 | struct usb_serial_device_type *type = NULL; |
||
956 | struct list_head *tmp; |
||
957 | int retval; |
||
958 | int found; |
||
959 | int minor; |
||
960 | int buffer_size; |
||
961 | int i; |
||
962 | int num_interrupt_in = 0; |
||
963 | int num_bulk_in = 0; |
||
964 | int num_bulk_out = 0; |
||
965 | int num_ports = 0; |
||
966 | int max_endpoints; |
||
967 | const struct usb_device_id *id_pattern = NULL; |
||
968 | |||
969 | /* loop through our list of known serial converters, and see if this |
||
970 | device matches. */ |
||
971 | found = 0; |
||
972 | list_for_each (tmp, &usb_serial_driver_list) { |
||
973 | type = list_entry(tmp, struct usb_serial_device_type, driver_list); |
||
974 | id_pattern = usb_match_id(interface, type->id_table); |
||
975 | if (id_pattern != NULL) { |
||
976 | dbg("descriptor matches"); |
||
977 | found = 1; |
||
978 | break; |
||
979 | } |
||
980 | } |
||
981 | if (!found) { |
||
982 | /* no match */ |
||
983 | dbg("none matched"); |
||
984 | return -ENODEV; |
||
985 | } |
||
986 | serial = create_serial (dev, interface, type); |
||
987 | if (!serial) { |
||
988 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); |
||
989 | return -ENODEV; |
||
990 | } |
||
991 | |||
992 | /* if this device type has a probe function, call it */ |
||
993 | if (type->probe) { |
||
994 | if (!try_module_get(type->owner)) { |
||
995 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
996 | kfree (serial); |
||
997 | return -EIO; |
||
998 | } |
||
999 | retval = type->probe (serial, id_pattern); |
||
1000 | module_put(type->owner); |
||
1001 | |||
1002 | if (retval) { |
||
1003 | dbg ("sub driver rejected device"); |
||
1004 | kfree (serial); |
||
1005 | return retval; |
||
1006 | } |
||
1007 | } |
||
1008 | |||
1009 | /* descriptor matches, let's find the endpoints needed */ |
||
1010 | /* check out the endpoints */ |
||
1011 | iface_desc = &interface->altsetting[0]; |
||
1012 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
||
1013 | endpoint = &iface_desc->endpoint[i].desc; |
||
1014 | |||
1015 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1016 | ((endpoint->bmAttributes & 3) == 0x02)) { |
||
1017 | /* we found a bulk in endpoint */ |
||
1018 | dbg("found bulk in"); |
||
1019 | bulk_in_endpoint[num_bulk_in] = endpoint; |
||
1020 | ++num_bulk_in; |
||
1021 | } |
||
1022 | |||
1023 | if (((endpoint->bEndpointAddress & 0x80) == 0x00) && |
||
1024 | ((endpoint->bmAttributes & 3) == 0x02)) { |
||
1025 | /* we found a bulk out endpoint */ |
||
1026 | dbg("found bulk out"); |
||
1027 | bulk_out_endpoint[num_bulk_out] = endpoint; |
||
1028 | ++num_bulk_out; |
||
1029 | } |
||
1030 | |||
1031 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1032 | ((endpoint->bmAttributes & 3) == 0x03)) { |
||
1033 | /* we found a interrupt in endpoint */ |
||
1034 | dbg("found interrupt in"); |
||
1035 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
||
1036 | ++num_interrupt_in; |
||
1037 | } |
||
1038 | } |
||
1039 | |||
1040 | #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE) |
||
1041 | /* BEGIN HORRIBLE HACK FOR PL2303 */ |
||
1042 | /* this is needed due to the looney way its endpoints are set up */ |
||
1043 | if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) && |
||
1044 | (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) || |
||
1045 | ((dev->descriptor.idVendor == ATEN_VENDOR_ID) && |
||
1046 | (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) { |
||
1047 | if (interface != dev->actconfig->interface[0]) { |
||
1048 | /* check out the endpoints of the other interface*/ |
||
1049 | iface_desc = &dev->actconfig->interface[0]->altsetting[0]; |
||
1050 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
||
1051 | endpoint = &iface_desc->endpoint[i].desc; |
||
1052 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1053 | ((endpoint->bmAttributes & 3) == 0x03)) { |
||
1054 | /* we found a interrupt in endpoint */ |
||
1055 | dbg("found interrupt in for Prolific device on separate interface"); |
||
1056 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
||
1057 | ++num_interrupt_in; |
||
1058 | } |
||
1059 | } |
||
1060 | } |
||
1061 | |||
1062 | /* Now make sure the PL-2303 is configured correctly. |
||
1063 | * If not, give up now and hope this hack will work |
||
1064 | * properly during a later invocation of usb_serial_probe |
||
1065 | */ |
||
1066 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
||
1067 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
||
1068 | kfree (serial); |
||
1069 | return -ENODEV; |
||
1070 | } |
||
1071 | } |
||
1072 | /* END HORRIBLE HACK FOR PL2303 */ |
||
1073 | #endif |
||
1074 | |||
1075 | /* found all that we need */ |
||
1076 | dev_info(&interface->dev, "%s converter detected\n", type->name); |
||
1077 | |||
1078 | #ifdef CONFIG_USB_SERIAL_GENERIC |
||
1079 | if (type == &usb_serial_generic_device) { |
||
1080 | num_ports = num_bulk_out; |
||
1081 | if (num_ports == 0) { |
||
1082 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); |
||
1083 | kfree (serial); |
||
1084 | return -EIO; |
||
1085 | } |
||
1086 | } |
||
1087 | #endif |
||
1088 | if (!num_ports) { |
||
1089 | /* if this device type has a calc_num_ports function, call it */ |
||
1090 | if (type->calc_num_ports) { |
||
1091 | if (!try_module_get(type->owner)) { |
||
1092 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
1093 | kfree (serial); |
||
1094 | return -EIO; |
||
1095 | } |
||
1096 | num_ports = type->calc_num_ports (serial); |
||
1097 | module_put(type->owner); |
||
1098 | } |
||
1099 | if (!num_ports) |
||
1100 | num_ports = type->num_ports; |
||
1101 | } |
||
1102 | |||
1103 | if (get_free_serial (serial, num_ports, &minor) == NULL) { |
||
1104 | dev_err(&interface->dev, "No more free serial devices\n"); |
||
1105 | kfree (serial); |
||
1106 | return -ENOMEM; |
||
1107 | } |
||
1108 | |||
1109 | serial->minor = minor; |
||
1110 | serial->num_ports = num_ports; |
||
1111 | serial->num_bulk_in = num_bulk_in; |
||
1112 | serial->num_bulk_out = num_bulk_out; |
||
1113 | serial->num_interrupt_in = num_interrupt_in; |
||
1114 | |||
1115 | /* create our ports, we need as many as the max endpoints */ |
||
1116 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ |
||
1117 | max_endpoints = max(num_bulk_in, num_bulk_out); |
||
1118 | max_endpoints = max(max_endpoints, num_interrupt_in); |
||
1119 | max_endpoints = max(max_endpoints, (int)serial->num_ports); |
||
1120 | serial->num_port_pointers = max_endpoints; |
||
1121 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); |
||
1122 | for (i = 0; i < max_endpoints; ++i) { |
||
1123 | port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
||
1124 | if (!port) |
||
1125 | goto probe_error; |
||
1126 | memset(port, 0x00, sizeof(struct usb_serial_port)); |
||
1127 | port->number = i + serial->minor; |
||
1128 | port->serial = serial; |
||
1129 | port->magic = USB_SERIAL_PORT_MAGIC; |
||
1130 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
||
1131 | serial->port[i] = port; |
||
1132 | } |
||
1133 | |||
1134 | /* set up the endpoint information */ |
||
1135 | for (i = 0; i < num_bulk_in; ++i) { |
||
1136 | endpoint = bulk_in_endpoint[i]; |
||
1137 | port = serial->port[i]; |
||
1138 | port->read_urb = usb_alloc_urb (0, GFP_KERNEL); |
||
1139 | if (!port->read_urb) { |
||
1140 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1141 | goto probe_error; |
||
1142 | } |
||
1143 | buffer_size = endpoint->wMaxPacketSize; |
||
1144 | |||
1145 | port->bulk_in_endpointAddress = endpoint->bEndpointAddress; |
||
1146 | port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1147 | if (!port->bulk_in_buffer) { |
||
1148 | dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n"); |
||
1149 | goto probe_error; |
||
1150 | } |
||
1151 | usb_fill_bulk_urb (port->read_urb, dev, |
||
1152 | usb_rcvbulkpipe (dev, |
||
1153 | endpoint->bEndpointAddress), |
||
1154 | port->bulk_in_buffer, buffer_size, |
||
1155 | serial->type->read_bulk_callback, |
||
1156 | port); |
||
1157 | } |
||
1158 | |||
1159 | for (i = 0; i < num_bulk_out; ++i) { |
||
1160 | endpoint = bulk_out_endpoint[i]; |
||
1161 | port = serial->port[i]; |
||
1162 | port->write_urb = usb_alloc_urb(0, GFP_KERNEL); |
||
1163 | if (!port->write_urb) { |
||
1164 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1165 | goto probe_error; |
||
1166 | } |
||
1167 | buffer_size = endpoint->wMaxPacketSize; |
||
1168 | port->bulk_out_size = buffer_size; |
||
1169 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; |
||
1170 | port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1171 | if (!port->bulk_out_buffer) { |
||
1172 | dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n"); |
||
1173 | goto probe_error; |
||
1174 | } |
||
1175 | usb_fill_bulk_urb (port->write_urb, dev, |
||
1176 | usb_sndbulkpipe (dev, |
||
1177 | endpoint->bEndpointAddress), |
||
1178 | port->bulk_out_buffer, buffer_size, |
||
1179 | serial->type->write_bulk_callback, |
||
1180 | port); |
||
1181 | } |
||
1182 | |||
1183 | for (i = 0; i < num_interrupt_in; ++i) { |
||
1184 | endpoint = interrupt_in_endpoint[i]; |
||
1185 | port = serial->port[i]; |
||
1186 | port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
||
1187 | if (!port->interrupt_in_urb) { |
||
1188 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1189 | goto probe_error; |
||
1190 | } |
||
1191 | buffer_size = endpoint->wMaxPacketSize; |
||
1192 | port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; |
||
1193 | port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1194 | if (!port->interrupt_in_buffer) { |
||
1195 | dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n"); |
||
1196 | goto probe_error; |
||
1197 | } |
||
1198 | usb_fill_int_urb (port->interrupt_in_urb, dev, |
||
1199 | usb_rcvintpipe (dev, |
||
1200 | endpoint->bEndpointAddress), |
||
1201 | port->interrupt_in_buffer, buffer_size, |
||
1202 | serial->type->read_int_callback, port, |
||
1203 | endpoint->bInterval); |
||
1204 | } |
||
1205 | |||
1206 | /* if this device type has an attach function, call it */ |
||
1207 | if (type->attach) { |
||
1208 | if (!try_module_get(type->owner)) { |
||
1209 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
1210 | goto probe_error; |
||
1211 | } |
||
1212 | retval = type->attach (serial); |
||
1213 | module_put(type->owner); |
||
1214 | if (retval < 0) |
||
1215 | goto probe_error; |
||
1216 | if (retval > 0) { |
||
1217 | /* quietly accept this device, but don't bind to a serial port |
||
1218 | * as it's about to disappear */ |
||
1219 | goto exit; |
||
1220 | } |
||
1221 | } |
||
1222 | |||
1223 | /* register all of the individual ports with the driver core */ |
||
1224 | for (i = 0; i < num_ports; ++i) { |
||
1225 | port = serial->port[i]; |
||
1226 | port->dev.parent = &interface->dev; |
||
1227 | port->dev.driver = NULL; |
||
1228 | port->dev.bus = &usb_serial_bus_type; |
||
1229 | port->dev.release = &port_release; |
||
1230 | |||
1231 | snprintf26(&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number); |
||
1232 | /*dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);*/ |
||
1233 | device_register (&port->dev); |
||
1234 | } |
||
1235 | |||
1236 | usb_serial_console_init (debug, minor); |
||
1237 | |||
1238 | exit: |
||
1239 | /* success */ |
||
1240 | usb_set_intfdata (interface, serial); |
||
1241 | return 0; |
||
1242 | |||
1243 | probe_error: |
||
1244 | for (i = 0; i < num_bulk_in; ++i) { |
||
1245 | port = serial->port[i]; |
||
1246 | if (!port) |
||
1247 | continue; |
||
1248 | if (port->read_urb) |
||
1249 | usb_free_urb (port->read_urb); |
||
1250 | kfree(port->bulk_in_buffer); |
||
1251 | } |
||
1252 | for (i = 0; i < num_bulk_out; ++i) { |
||
1253 | port = serial->port[i]; |
||
1254 | if (!port) |
||
1255 | continue; |
||
1256 | if (port->write_urb) |
||
1257 | usb_free_urb (port->write_urb); |
||
1258 | kfree(port->bulk_out_buffer); |
||
1259 | } |
||
1260 | for (i = 0; i < num_interrupt_in; ++i) { |
||
1261 | port = serial->port[i]; |
||
1262 | if (!port) |
||
1263 | continue; |
||
1264 | if (port->interrupt_in_urb) |
||
1265 | usb_free_urb (port->interrupt_in_urb); |
||
1266 | kfree(port->interrupt_in_buffer); |
||
1267 | } |
||
1268 | |||
1269 | /* return the minor range that this device had */ |
||
1270 | return_serial (serial); |
||
1271 | |||
1272 | /* free up any memory that we allocated */ |
||
1273 | for (i = 0; i < serial->num_port_pointers; ++i) |
||
1274 | kfree(serial->port[i]); |
||
1275 | kfree (serial); |
||
1276 | return -EIO; |
||
1277 | } |
||
1278 | |||
1279 | void usb_serial_disconnect(struct usb_interface *interface) |
||
1280 | { |
||
1281 | struct usb_serial *serial = usb_get_intfdata (interface); |
||
1282 | struct device *dev = &interface->dev; |
||
1283 | |||
1284 | dbg ("%s", __FUNCTION__); |
||
1285 | |||
1286 | usb_set_intfdata (interface, NULL); |
||
1287 | if (serial) { |
||
1288 | /* let the last holder of this object |
||
1289 | * cause it to be cleaned up */ |
||
1290 | kobject_put (&serial->kobj); |
||
1291 | } |
||
1292 | dev_info(dev, "device disconnected\n"); |
||
1293 | } |
||
1294 | |||
1295 | static struct tty_operations serial_ops = { |
||
1296 | .open = serial_open, |
||
1297 | .close = serial_close, |
||
1298 | .write = serial_write, |
||
1299 | .write_room = serial_write_room, |
||
1300 | .ioctl = serial_ioctl, |
||
1301 | .set_termios = serial_set_termios, |
||
1302 | .throttle = serial_throttle, |
||
1303 | .unthrottle = serial_unthrottle, |
||
1304 | .break_ctl = serial_break, |
||
1305 | .chars_in_buffer = serial_chars_in_buffer, |
||
1306 | .read_proc = serial_read_proc, |
||
1307 | .tiocmget = serial_tiocmget, |
||
1308 | .tiocmset = serial_tiocmset, |
||
1309 | }; |
||
1310 | |||
1311 | struct tty_driver *usb_serial_tty_driver; |
||
1312 | |||
1313 | /*static*/ int __init usb_serial_init(void) |
||
1314 | { |
||
1315 | int i; |
||
1316 | int result = 0; |
||
1317 | |||
1318 | usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS); |
||
1319 | if (!usb_serial_tty_driver) |
||
1320 | return -ENOMEM; |
||
1321 | |||
1322 | /* Initialize our global data */ |
||
1323 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
||
1324 | serial_table[i] = NULL; |
||
1325 | } |
||
1326 | |||
1327 | bus_register(&usb_serial_bus_type); |
||
1328 | |||
1329 | /* register the generic driver, if we should */ |
||
1330 | result = usb_serial_generic_register(debug); |
||
1331 | if (result < 0) { |
||
1332 | err("%s - registering generic driver failed", __FUNCTION__); |
||
1333 | goto exit; |
||
1334 | } |
||
1335 | |||
1336 | usb_serial_tty_driver->owner = THIS_MODULE; |
||
1337 | usb_serial_tty_driver->driver_name = "usbserial"; |
||
1338 | usb_serial_tty_driver->devfs_name = "usb/tts/"; |
||
1339 | usb_serial_tty_driver->name = "ttyUSB"; |
||
1340 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; |
||
1341 | usb_serial_tty_driver->minor_start = 0; |
||
1342 | usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
||
1343 | usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
||
1344 | usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; |
||
1345 | usb_serial_tty_driver->init_termios = tty_std_termios; |
||
1346 | usb_serial_tty_driver->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; |
||
1347 | tty_set_operations(usb_serial_tty_driver, &serial_ops); |
||
1348 | result = tty_register_driver(usb_serial_tty_driver); |
||
1349 | if (result) { |
||
1350 | err("%s - tty_register_driver failed", __FUNCTION__); |
||
1351 | goto exit_generic; |
||
1352 | } |
||
1353 | |||
1354 | /* register the USB driver */ |
||
1355 | result = usb_register(&usb_serial_driver); |
||
1356 | if (result < 0) { |
||
1357 | err("%s - usb_register failed", __FUNCTION__); |
||
1358 | goto exit_tty; |
||
1359 | } |
||
1360 | |||
1361 | info(DRIVER_DESC " " DRIVER_VERSION); |
||
1362 | |||
1363 | return result; |
||
1364 | |||
1365 | exit_tty: |
||
1366 | tty_unregister_driver(usb_serial_tty_driver); |
||
1367 | |||
1368 | exit_generic: |
||
1369 | usb_serial_generic_deregister(); |
||
1370 | |||
1371 | exit: |
||
1372 | err ("%s - returning with error %d", __FUNCTION__, result); |
||
1373 | put_tty_driver(usb_serial_tty_driver); |
||
1374 | return result; |
||
1375 | } |
||
1376 | |||
1377 | |||
1378 | /*static*/ void __exit usb_serial_exit(void) |
||
1379 | { |
||
1380 | usb_serial_console_exit(); |
||
1381 | |||
1382 | usb_serial_generic_deregister(); |
||
1383 | |||
1384 | usb_deregister(&usb_serial_driver); |
||
1385 | tty_unregister_driver(usb_serial_tty_driver); |
||
1386 | put_tty_driver(usb_serial_tty_driver); |
||
1387 | bus_unregister(&usb_serial_bus_type); |
||
1388 | } |
||
1389 | |||
1390 | |||
1391 | module_init(usb_serial_init); |
||
1392 | module_exit(usb_serial_exit); |
||
1393 | |||
1394 | #define set_to_generic_if_null(type, function) \ |
||
1395 | do { \ |
||
1396 | if (!type->function) { \ |
||
1397 | type->function = usb_serial_generic_##function; \ |
||
1398 | dbg("Had to override the " #function \ |
||
1399 | " usb serial operation with the generic one.");\ |
||
1400 | } \ |
||
1401 | } while (0) |
||
1402 | |||
1403 | static void fixup_generic(struct usb_serial_device_type *device) |
||
1404 | { |
||
1405 | set_to_generic_if_null(device, open); |
||
1406 | set_to_generic_if_null(device, write); |
||
1407 | set_to_generic_if_null(device, close); |
||
1408 | set_to_generic_if_null(device, write_room); |
||
1409 | set_to_generic_if_null(device, chars_in_buffer); |
||
1410 | set_to_generic_if_null(device, read_bulk_callback); |
||
1411 | set_to_generic_if_null(device, write_bulk_callback); |
||
1412 | set_to_generic_if_null(device, shutdown); |
||
1413 | } |
||
1414 | |||
1415 | int usb_serial_register(struct usb_serial_device_type *new_device) |
||
1416 | { |
||
1417 | int retval; |
||
1418 | |||
1419 | fixup_generic(new_device); |
||
1420 | |||
1421 | /* Add this device to our list of devices */ |
||
1422 | list_add(&new_device->driver_list, &usb_serial_driver_list); |
||
1423 | |||
1424 | retval = usb_serial_bus_register (new_device); |
||
1425 | |||
1426 | if (retval) |
||
1427 | goto error; |
||
1428 | |||
1429 | info("USB Serial support registered for %s", new_device->name); |
||
1430 | |||
1431 | return retval; |
||
1432 | error: |
||
1433 | err("problem %d when registering driver %s", retval, new_device->name); |
||
1434 | list_del(&new_device->driver_list); |
||
1435 | |||
1436 | return retval; |
||
1437 | } |
||
1438 | |||
1439 | |||
1440 | void usb_serial_deregister(struct usb_serial_device_type *device) |
||
1441 | { |
||
1442 | struct usb_serial *serial; |
||
1443 | int i; |
||
1444 | |||
1445 | info("USB Serial deregistering driver %s", device->name); |
||
1446 | |||
1447 | /* clear out the serial_table if the device is attached to a port */ |
||
1448 | for(i = 0; i < SERIAL_TTY_MINORS; ++i) { |
||
1449 | serial = serial_table[i]; |
||
1450 | if ((serial != NULL) && (serial->type == device)) { |
||
1451 | usb_driver_release_interface (&usb_serial_driver, serial->interface); |
||
1452 | usb_serial_disconnect (serial->interface); |
||
1453 | } |
||
1454 | } |
||
1455 | |||
1456 | list_del(&device->driver_list); |
||
1457 | usb_serial_bus_deregister (device); |
||
1458 | } |
||
1459 | |||
1460 | |||
1461 | |||
1462 | /* If the usb-serial core is built into the core, the usb-serial drivers |
||
1463 | need these symbols to load properly as modules. */ |
||
1464 | EXPORT_SYMBOL(usb_serial_register); |
||
1465 | EXPORT_SYMBOL(usb_serial_deregister); |
||
1466 | EXPORT_SYMBOL(usb_serial_probe); |
||
1467 | EXPORT_SYMBOL(usb_serial_disconnect); |
||
1468 | EXPORT_SYMBOL(usb_serial_port_softint); |
||
1469 | |||
1470 | |||
1471 | /* Module information */ |
||
1472 | MODULE_AUTHOR( DRIVER_AUTHOR ); |
||
1473 | MODULE_DESCRIPTION( DRIVER_DESC ); |
||
1474 | MODULE_LICENSE("GPL"); |
||
1475 | |||
1476 | MODULE_PARM(debug, "i"); |
||
1477 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |