Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
846 | giacomo | 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 | |||
438 | if (serial == NULL) |
||
439 | return; |
||
440 | |||
441 | for (i = 0; i < serial->num_ports; ++i) { |
||
442 | serial_table[serial->minor + i] = NULL; |
||
443 | } |
||
444 | |||
445 | return; |
||
446 | } |
||
447 | |||
448 | /***************************************************************************** |
||
449 | * Driver tty interface functions |
||
450 | *****************************************************************************/ |
||
451 | /*static*/ int serial_open (struct tty_struct *tty, struct file * filp) |
||
452 | { |
||
453 | struct usb_serial *serial; |
||
454 | struct usb_serial_port *port; |
||
455 | unsigned int portNumber; |
||
456 | int retval = 0; |
||
457 | |||
458 | dbg("%s", __FUNCTION__); |
||
459 | |||
460 | /* initialize the pointer incase something fails */ |
||
461 | tty->driver_data = NULL; |
||
462 | |||
463 | /* get the serial object associated with this tty pointer */ |
||
464 | serial = usb_serial_get_by_index(tty->index); |
||
465 | |||
466 | if (serial_paranoia_check (serial, __FUNCTION__)) |
||
467 | return -ENODEV; |
||
468 | |||
469 | /* set up our port structure making the tty driver remember our port object, and us it */ |
||
470 | portNumber = tty->index - serial->minor; |
||
471 | port = serial->port[portNumber]; |
||
472 | tty->driver_data = port; |
||
473 | |||
474 | port->tty = tty; |
||
475 | |||
476 | /* lock this module before we call it, |
||
477 | this may, which means we must bail out, safe because we are called with BKL held */ |
||
478 | if (!try_module_get(serial->type->owner)) { |
||
479 | retval = -ENODEV; |
||
480 | goto bailout; |
||
481 | } |
||
482 | |||
483 | ++port->open_count; |
||
484 | if (port->open_count == 1) { |
||
485 | /* only call the device specific open if this |
||
486 | * is the first time the port is opened */ |
||
487 | retval = serial->type->open(port, filp); |
||
488 | if (retval) { |
||
489 | port->open_count = 0; |
||
490 | module_put(serial->type->owner); |
||
491 | kobject_put(&serial->kobj); |
||
492 | } |
||
493 | } |
||
494 | bailout: |
||
495 | return retval; |
||
496 | } |
||
497 | |||
498 | static void serial_close(struct tty_struct *tty, struct file * filp) |
||
499 | { |
||
500 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
501 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
502 | |||
503 | if (!serial) |
||
504 | return; |
||
505 | |||
506 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
507 | |||
508 | --port->open_count; |
||
509 | if (port->open_count <= 0) { |
||
510 | /* only call the device specific close if this |
||
511 | * port is being closed by the last owner */ |
||
512 | port->serial->type->close(port, filp); |
||
513 | port->open_count = 0; |
||
514 | |||
515 | if (port->tty) { |
||
516 | if (port->tty->driver_data) |
||
517 | port->tty->driver_data = NULL; |
||
518 | port->tty = NULL; |
||
519 | } |
||
520 | } |
||
521 | |||
522 | module_put(port->serial->type->owner); |
||
523 | kobject_put(&port->serial->kobj); |
||
524 | } |
||
525 | |||
526 | /*static*/ int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) |
||
527 | { |
||
528 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
529 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
530 | int retval = -EINVAL; |
||
531 | |||
532 | if (!serial) |
||
533 | return -ENODEV; |
||
534 | |||
535 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
||
536 | |||
537 | if (!port->open_count) { |
||
538 | dbg("%s - port not opened", __FUNCTION__); |
||
539 | goto exit; |
||
540 | } |
||
541 | |||
542 | /* pass on to the driver specific version of this function */ |
||
543 | retval = serial->type->write(port, from_user, buf, count); |
||
544 | |||
545 | exit: |
||
546 | return retval; |
||
547 | } |
||
548 | |||
549 | static int serial_write_room (struct tty_struct *tty) |
||
550 | { |
||
551 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
552 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
553 | int retval = -EINVAL; |
||
554 | |||
555 | if (!serial) |
||
556 | return -ENODEV; |
||
557 | |||
558 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
559 | |||
560 | if (!port->open_count) { |
||
561 | dbg("%s - port not open", __FUNCTION__); |
||
562 | goto exit; |
||
563 | } |
||
564 | |||
565 | /* pass on to the driver specific version of this function */ |
||
566 | retval = serial->type->write_room(port); |
||
567 | |||
568 | exit: |
||
569 | return retval; |
||
570 | } |
||
571 | |||
572 | static int serial_chars_in_buffer (struct tty_struct *tty) |
||
573 | { |
||
574 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
575 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
576 | int retval = -EINVAL; |
||
577 | |||
578 | if (!serial) |
||
579 | return -ENODEV; |
||
580 | |||
581 | dbg("%s = port %d", __FUNCTION__, port->number); |
||
582 | |||
583 | if (!port->open_count) { |
||
584 | dbg("%s - port not open", __FUNCTION__); |
||
585 | goto exit; |
||
586 | } |
||
587 | |||
588 | /* pass on to the driver specific version of this function */ |
||
589 | retval = serial->type->chars_in_buffer(port); |
||
590 | |||
591 | exit: |
||
592 | return retval; |
||
593 | } |
||
594 | |||
595 | static void serial_throttle (struct tty_struct * tty) |
||
596 | { |
||
597 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
598 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
599 | |||
600 | if (!serial) |
||
601 | return; |
||
602 | |||
603 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
604 | |||
605 | if (!port->open_count) { |
||
606 | dbg ("%s - port not open", __FUNCTION__); |
||
607 | goto exit; |
||
608 | } |
||
609 | |||
610 | /* pass on to the driver specific version of this function */ |
||
611 | if (serial->type->throttle) |
||
612 | serial->type->throttle(port); |
||
613 | |||
614 | exit: |
||
615 | ; |
||
616 | } |
||
617 | |||
618 | static void serial_unthrottle (struct tty_struct * tty) |
||
619 | { |
||
620 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
621 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
622 | |||
623 | if (!serial) |
||
624 | return; |
||
625 | |||
626 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
627 | |||
628 | if (!port->open_count) { |
||
629 | dbg("%s - port not open", __FUNCTION__); |
||
630 | goto exit; |
||
631 | } |
||
632 | |||
633 | /* pass on to the driver specific version of this function */ |
||
634 | if (serial->type->unthrottle) |
||
635 | serial->type->unthrottle(port); |
||
636 | |||
637 | exit: |
||
638 | ; |
||
639 | } |
||
640 | |||
641 | static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) |
||
642 | { |
||
643 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
644 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
645 | int retval = -ENODEV; |
||
646 | |||
647 | if (!serial) |
||
648 | return -ENODEV; |
||
649 | |||
650 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); |
||
651 | |||
652 | if (!port->open_count) { |
||
653 | dbg ("%s - port not open", __FUNCTION__); |
||
654 | goto exit; |
||
655 | } |
||
656 | |||
657 | /* pass on to the driver specific version of this function if it is available */ |
||
658 | if (serial->type->ioctl) |
||
659 | retval = serial->type->ioctl(port, file, cmd, arg); |
||
660 | else |
||
661 | retval = -ENOIOCTLCMD; |
||
662 | |||
663 | exit: |
||
664 | return retval; |
||
665 | } |
||
666 | |||
667 | static void serial_set_termios (struct tty_struct *tty, struct termios * old) |
||
668 | { |
||
669 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
670 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
671 | |||
672 | if (!serial) |
||
673 | return; |
||
674 | |||
675 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
676 | |||
677 | if (!port->open_count) { |
||
678 | dbg("%s - port not open", __FUNCTION__); |
||
679 | goto exit; |
||
680 | } |
||
681 | |||
682 | /* pass on to the driver specific version of this function if it is available */ |
||
683 | if (serial->type->set_termios) |
||
684 | serial->type->set_termios(port, old); |
||
685 | |||
686 | exit: |
||
687 | ; |
||
688 | } |
||
689 | |||
690 | static void serial_break (struct tty_struct *tty, int break_state) |
||
691 | { |
||
692 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
693 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
694 | |||
695 | if (!serial) |
||
696 | return; |
||
697 | |||
698 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
699 | |||
700 | if (!port->open_count) { |
||
701 | dbg("%s - port not open", __FUNCTION__); |
||
702 | goto exit; |
||
703 | } |
||
704 | |||
705 | /* pass on to the driver specific version of this function if it is available */ |
||
706 | if (serial->type->break_ctl) |
||
707 | serial->type->break_ctl(port, break_state); |
||
708 | |||
709 | exit: |
||
710 | ; |
||
711 | } |
||
712 | |||
713 | static void serial_shutdown (struct usb_serial *serial) |
||
714 | { |
||
715 | dbg ("%s", __FUNCTION__); |
||
716 | |||
717 | serial->type->shutdown(serial); |
||
718 | } |
||
719 | |||
720 | static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) |
||
721 | { |
||
722 | struct usb_serial *serial; |
||
723 | int length = 0; |
||
724 | int i; |
||
725 | off_t begin = 0; |
||
726 | char tmp[40]; |
||
727 | |||
728 | dbg("%s", __FUNCTION__); |
||
729 | length += sprintf26 (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION); |
||
730 | for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { |
||
731 | serial = usb_serial_get_by_index(i); |
||
732 | if (serial == NULL) |
||
733 | continue; |
||
734 | |||
735 | length += sprintf26 (page+length, "%d:", i); |
||
736 | if (serial->type->owner) |
||
737 | length += sprintf26 (page+length, " module:%s", module_name(serial->type->owner)); |
||
738 | length += sprintf26 (page+length, " name:\"%s\"", serial->type->name); |
||
739 | length += sprintf26 (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product); |
||
740 | length += sprintf26 (page+length, " num_ports:%d", serial->num_ports); |
||
741 | length += sprintf26 (page+length, " port:%d", i - serial->minor + 1); |
||
742 | |||
743 | usb_make_path(serial->dev, tmp, sizeof(tmp)); |
||
744 | length += sprintf26 (page+length, " path:%s", tmp); |
||
745 | |||
746 | length += sprintf26 (page+length, "\n"); |
||
747 | if ((length + begin) > (off + count)) |
||
748 | goto done; |
||
749 | if ((length + begin) < off) { |
||
750 | begin += length; |
||
751 | length = 0; |
||
752 | } |
||
753 | kobject_put(&serial->kobj); |
||
754 | } |
||
755 | *eof = 1; |
||
756 | done: |
||
757 | if (off >= (length + begin)) |
||
758 | return 0; |
||
759 | *start = page + (off-begin); |
||
760 | return ((count < begin+length-off) ? count : begin+length-off); |
||
761 | } |
||
762 | |||
763 | static int serial_tiocmget (struct tty_struct *tty, struct file *file) |
||
764 | { |
||
765 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
766 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
767 | |||
768 | if (!serial) |
||
769 | goto exit; |
||
770 | |||
771 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
772 | |||
773 | if (!port->open_count) { |
||
774 | dbg("%s - port not open", __FUNCTION__); |
||
775 | goto exit; |
||
776 | } |
||
777 | |||
778 | if (serial->type->tiocmget) |
||
779 | return serial->type->tiocmget(port, file); |
||
780 | |||
781 | exit: |
||
782 | return -EINVAL; |
||
783 | } |
||
784 | |||
785 | static int serial_tiocmset (struct tty_struct *tty, struct file *file, |
||
786 | unsigned int set, unsigned int clear) |
||
787 | { |
||
788 | struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
||
789 | struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
||
790 | |||
791 | if (!serial) |
||
792 | goto exit; |
||
793 | |||
794 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
795 | |||
796 | if (!port->open_count) { |
||
797 | dbg("%s - port not open", __FUNCTION__); |
||
798 | goto exit; |
||
799 | } |
||
800 | |||
801 | if (serial->type->tiocmset) |
||
802 | return serial->type->tiocmset(port, file, set, clear); |
||
803 | |||
804 | exit: |
||
805 | return -EINVAL; |
||
806 | } |
||
807 | |||
808 | void usb_serial_port_softint(void *private) |
||
809 | { |
||
810 | struct usb_serial_port *port = (struct usb_serial_port *)private; |
||
811 | struct usb_serial *serial; |
||
812 | struct tty_struct *tty; |
||
813 | |||
814 | dbg("%s - port %d", __FUNCTION__, port->number); |
||
815 | |||
816 | if (!port) |
||
817 | return; |
||
818 | |||
819 | serial = get_usb_serial (port, __FUNCTION__); |
||
820 | if (!serial) |
||
821 | return; |
||
822 | |||
823 | tty = port->tty; |
||
824 | if (!tty) |
||
825 | return; |
||
826 | |||
827 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { |
||
828 | dbg("%s - write wakeup call.", __FUNCTION__); |
||
829 | (tty->ldisc.write_wakeup)(tty); |
||
830 | } |
||
831 | |||
832 | wake_up_interruptible(&tty->write_wait); |
||
833 | } |
||
834 | |||
835 | static void destroy_serial (struct kobject *kobj) |
||
836 | { |
||
837 | struct usb_serial *serial; |
||
838 | struct usb_serial_port *port; |
||
839 | int i; |
||
840 | |||
841 | dbg ("%s - %s", __FUNCTION__, kobj->name); |
||
842 | |||
843 | serial = to_usb_serial(kobj); |
||
844 | serial_shutdown (serial); |
||
845 | |||
846 | /* return the minor range that this device had */ |
||
847 | return_serial(serial); |
||
848 | |||
849 | for (i = 0; i < serial->num_ports; ++i) |
||
850 | serial->port[i]->open_count = 0; |
||
851 | |||
852 | /* the ports are cleaned up and released in port_release() */ |
||
853 | for (i = 0; i < serial->num_ports; ++i) |
||
854 | if (serial->port[i]->dev.parent != NULL) { |
||
855 | device_unregister(&serial->port[i]->dev); |
||
856 | serial->port[i] = NULL; |
||
857 | } |
||
858 | |||
859 | /* If this is a "fake" port, we have to clean it up here, as it will |
||
860 | * not get cleaned up in port_release() as it was never registered with |
||
861 | * the driver core */ |
||
862 | if (serial->num_ports < serial->num_port_pointers) { |
||
863 | for (i = serial->num_ports; i < serial->num_port_pointers; ++i) { |
||
864 | port = serial->port[i]; |
||
865 | if (!port) |
||
866 | continue; |
||
867 | if (port->read_urb) { |
||
868 | usb_unlink_urb(port->read_urb); |
||
869 | usb_free_urb(port->read_urb); |
||
870 | } |
||
871 | if (port->write_urb) { |
||
872 | usb_unlink_urb(port->write_urb); |
||
873 | usb_free_urb(port->write_urb); |
||
874 | } |
||
875 | if (port->interrupt_in_urb) { |
||
876 | usb_unlink_urb(port->interrupt_in_urb); |
||
877 | usb_free_urb(port->interrupt_in_urb); |
||
878 | } |
||
879 | kfree(port->bulk_in_buffer); |
||
880 | kfree(port->bulk_out_buffer); |
||
881 | kfree(port->interrupt_in_buffer); |
||
882 | } |
||
883 | } |
||
884 | |||
885 | usb_put_dev(serial->dev); |
||
886 | |||
887 | /* free up any memory that we allocated */ |
||
888 | kfree (serial); |
||
889 | } |
||
890 | |||
891 | static struct kobj_type usb_serial_kobj_type = { |
||
892 | .release = destroy_serial, |
||
893 | }; |
||
894 | |||
895 | static void port_release(struct device *dev) |
||
896 | { |
||
897 | struct usb_serial_port *port = to_usb_serial_port(dev); |
||
898 | |||
899 | dbg ("%s - %s", __FUNCTION__, dev->bus_id); |
||
900 | if (port->read_urb) { |
||
901 | usb_unlink_urb(port->read_urb); |
||
902 | usb_free_urb(port->read_urb); |
||
903 | } |
||
904 | if (port->write_urb) { |
||
905 | usb_unlink_urb(port->write_urb); |
||
906 | usb_free_urb(port->write_urb); |
||
907 | } |
||
908 | if (port->interrupt_in_urb) { |
||
909 | usb_unlink_urb(port->interrupt_in_urb); |
||
910 | usb_free_urb(port->interrupt_in_urb); |
||
911 | } |
||
912 | kfree(port->bulk_in_buffer); |
||
913 | kfree(port->bulk_out_buffer); |
||
914 | kfree(port->interrupt_in_buffer); |
||
915 | kfree(port); |
||
916 | } |
||
917 | |||
918 | static struct usb_serial * create_serial (struct usb_device *dev, |
||
919 | struct usb_interface *interface, |
||
920 | struct usb_serial_device_type *type) |
||
921 | { |
||
922 | struct usb_serial *serial; |
||
923 | |||
924 | serial = kmalloc (sizeof (*serial), GFP_KERNEL); |
||
925 | if (!serial) { |
||
926 | dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); |
||
927 | return NULL; |
||
928 | } |
||
929 | memset (serial, 0, sizeof(*serial)); |
||
930 | serial->dev = usb_get_dev(dev); |
||
931 | serial->type = type; |
||
932 | serial->interface = interface; |
||
933 | serial->vendor = dev->descriptor.idVendor; |
||
934 | serial->product = dev->descriptor.idProduct; |
||
935 | |||
936 | /* initialize the kobject portion of the usb_device */ |
||
937 | kobject_init(&serial->kobj); |
||
938 | serial->kobj.ktype = &usb_serial_kobj_type; |
||
939 | |||
940 | return serial; |
||
941 | } |
||
942 | |||
943 | int usb_serial_probe(struct usb_interface *interface, |
||
944 | const struct usb_device_id *id) |
||
945 | { |
||
946 | struct usb_device *dev = interface_to_usbdev (interface); |
||
947 | struct usb_serial *serial = NULL; |
||
948 | struct usb_serial_port *port; |
||
949 | struct usb_host_interface *iface_desc; |
||
950 | struct usb_endpoint_descriptor *endpoint; |
||
951 | struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS]; |
||
952 | struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; |
||
953 | struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; |
||
954 | struct usb_serial_device_type *type = NULL; |
||
955 | struct list_head *tmp; |
||
956 | int retval; |
||
957 | int found; |
||
958 | int minor; |
||
959 | int buffer_size; |
||
960 | int i; |
||
961 | int num_interrupt_in = 0; |
||
962 | int num_bulk_in = 0; |
||
963 | int num_bulk_out = 0; |
||
964 | int num_ports = 0; |
||
965 | int max_endpoints; |
||
966 | const struct usb_device_id *id_pattern = NULL; |
||
967 | |||
968 | /* loop through our list of known serial converters, and see if this |
||
969 | device matches. */ |
||
970 | found = 0; |
||
971 | list_for_each (tmp, &usb_serial_driver_list) { |
||
972 | type = list_entry(tmp, struct usb_serial_device_type, driver_list); |
||
973 | id_pattern = usb_match_id(interface, type->id_table); |
||
974 | if (id_pattern != NULL) { |
||
975 | dbg("descriptor matches"); |
||
976 | found = 1; |
||
977 | break; |
||
978 | } |
||
979 | } |
||
980 | if (!found) { |
||
981 | /* no match */ |
||
982 | dbg("none matched"); |
||
983 | return -ENODEV; |
||
984 | } |
||
985 | serial = create_serial (dev, interface, type); |
||
986 | if (!serial) { |
||
987 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); |
||
988 | return -ENODEV; |
||
989 | } |
||
990 | |||
991 | /* if this device type has a probe function, call it */ |
||
992 | if (type->probe) { |
||
993 | if (!try_module_get(type->owner)) { |
||
994 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
995 | kfree (serial); |
||
996 | return -EIO; |
||
997 | } |
||
998 | retval = type->probe (serial, id_pattern); |
||
999 | module_put(type->owner); |
||
1000 | |||
1001 | if (retval) { |
||
1002 | dbg ("sub driver rejected device"); |
||
1003 | kfree (serial); |
||
1004 | return retval; |
||
1005 | } |
||
1006 | } |
||
1007 | |||
1008 | /* descriptor matches, let's find the endpoints needed */ |
||
1009 | /* check out the endpoints */ |
||
1010 | iface_desc = &interface->altsetting[0]; |
||
1011 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
||
1012 | endpoint = &iface_desc->endpoint[i].desc; |
||
1013 | |||
1014 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1015 | ((endpoint->bmAttributes & 3) == 0x02)) { |
||
1016 | /* we found a bulk in endpoint */ |
||
1017 | dbg("found bulk in"); |
||
1018 | bulk_in_endpoint[num_bulk_in] = endpoint; |
||
1019 | ++num_bulk_in; |
||
1020 | } |
||
1021 | |||
1022 | if (((endpoint->bEndpointAddress & 0x80) == 0x00) && |
||
1023 | ((endpoint->bmAttributes & 3) == 0x02)) { |
||
1024 | /* we found a bulk out endpoint */ |
||
1025 | dbg("found bulk out"); |
||
1026 | bulk_out_endpoint[num_bulk_out] = endpoint; |
||
1027 | ++num_bulk_out; |
||
1028 | } |
||
1029 | |||
1030 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1031 | ((endpoint->bmAttributes & 3) == 0x03)) { |
||
1032 | /* we found a interrupt in endpoint */ |
||
1033 | dbg("found interrupt in"); |
||
1034 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
||
1035 | ++num_interrupt_in; |
||
1036 | } |
||
1037 | } |
||
1038 | |||
1039 | #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE) |
||
1040 | /* BEGIN HORRIBLE HACK FOR PL2303 */ |
||
1041 | /* this is needed due to the looney way its endpoints are set up */ |
||
1042 | if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) && |
||
1043 | (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) || |
||
1044 | ((dev->descriptor.idVendor == ATEN_VENDOR_ID) && |
||
1045 | (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) { |
||
1046 | if (interface != dev->actconfig->interface[0]) { |
||
1047 | /* check out the endpoints of the other interface*/ |
||
1048 | iface_desc = &dev->actconfig->interface[0]->altsetting[0]; |
||
1049 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
||
1050 | endpoint = &iface_desc->endpoint[i].desc; |
||
1051 | if ((endpoint->bEndpointAddress & 0x80) && |
||
1052 | ((endpoint->bmAttributes & 3) == 0x03)) { |
||
1053 | /* we found a interrupt in endpoint */ |
||
1054 | dbg("found interrupt in for Prolific device on separate interface"); |
||
1055 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
||
1056 | ++num_interrupt_in; |
||
1057 | } |
||
1058 | } |
||
1059 | } |
||
1060 | |||
1061 | /* Now make sure the PL-2303 is configured correctly. |
||
1062 | * If not, give up now and hope this hack will work |
||
1063 | * properly during a later invocation of usb_serial_probe |
||
1064 | */ |
||
1065 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
||
1066 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
||
1067 | kfree (serial); |
||
1068 | return -ENODEV; |
||
1069 | } |
||
1070 | } |
||
1071 | /* END HORRIBLE HACK FOR PL2303 */ |
||
1072 | #endif |
||
1073 | |||
1074 | /* found all that we need */ |
||
1075 | dev_info(&interface->dev, "%s converter detected\n", type->name); |
||
1076 | |||
1077 | #ifdef CONFIG_USB_SERIAL_GENERIC |
||
1078 | if (type == &usb_serial_generic_device) { |
||
1079 | num_ports = num_bulk_out; |
||
1080 | if (num_ports == 0) { |
||
1081 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); |
||
1082 | kfree (serial); |
||
1083 | return -EIO; |
||
1084 | } |
||
1085 | } |
||
1086 | #endif |
||
1087 | if (!num_ports) { |
||
1088 | /* if this device type has a calc_num_ports function, call it */ |
||
1089 | if (type->calc_num_ports) { |
||
1090 | if (!try_module_get(type->owner)) { |
||
1091 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
1092 | kfree (serial); |
||
1093 | return -EIO; |
||
1094 | } |
||
1095 | num_ports = type->calc_num_ports (serial); |
||
1096 | module_put(type->owner); |
||
1097 | } |
||
1098 | if (!num_ports) |
||
1099 | num_ports = type->num_ports; |
||
1100 | } |
||
1101 | |||
1102 | if (get_free_serial (serial, num_ports, &minor) == NULL) { |
||
1103 | dev_err(&interface->dev, "No more free serial devices\n"); |
||
1104 | kfree (serial); |
||
1105 | return -ENOMEM; |
||
1106 | } |
||
1107 | |||
1108 | serial->minor = minor; |
||
1109 | serial->num_ports = num_ports; |
||
1110 | serial->num_bulk_in = num_bulk_in; |
||
1111 | serial->num_bulk_out = num_bulk_out; |
||
1112 | serial->num_interrupt_in = num_interrupt_in; |
||
1113 | |||
1114 | /* create our ports, we need as many as the max endpoints */ |
||
1115 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ |
||
1116 | max_endpoints = max(num_bulk_in, num_bulk_out); |
||
1117 | max_endpoints = max(max_endpoints, num_interrupt_in); |
||
1118 | max_endpoints = max(max_endpoints, (int)serial->num_ports); |
||
1119 | serial->num_port_pointers = max_endpoints; |
||
1120 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); |
||
1121 | for (i = 0; i < max_endpoints; ++i) { |
||
1122 | port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
||
1123 | if (!port) |
||
1124 | goto probe_error; |
||
1125 | memset(port, 0x00, sizeof(struct usb_serial_port)); |
||
1126 | port->number = i + serial->minor; |
||
1127 | port->serial = serial; |
||
1128 | port->magic = USB_SERIAL_PORT_MAGIC; |
||
1129 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
||
1130 | serial->port[i] = port; |
||
1131 | } |
||
1132 | |||
1133 | /* set up the endpoint information */ |
||
1134 | for (i = 0; i < num_bulk_in; ++i) { |
||
1135 | endpoint = bulk_in_endpoint[i]; |
||
1136 | port = serial->port[i]; |
||
1137 | port->read_urb = usb_alloc_urb (0, GFP_KERNEL); |
||
1138 | if (!port->read_urb) { |
||
1139 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1140 | goto probe_error; |
||
1141 | } |
||
1142 | buffer_size = endpoint->wMaxPacketSize; |
||
1143 | |||
1144 | port->bulk_in_endpointAddress = endpoint->bEndpointAddress; |
||
1145 | port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1146 | if (!port->bulk_in_buffer) { |
||
1147 | dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n"); |
||
1148 | goto probe_error; |
||
1149 | } |
||
1150 | usb_fill_bulk_urb (port->read_urb, dev, |
||
1151 | usb_rcvbulkpipe (dev, |
||
1152 | endpoint->bEndpointAddress), |
||
1153 | port->bulk_in_buffer, buffer_size, |
||
1154 | serial->type->read_bulk_callback, |
||
1155 | port); |
||
1156 | } |
||
1157 | |||
1158 | for (i = 0; i < num_bulk_out; ++i) { |
||
1159 | endpoint = bulk_out_endpoint[i]; |
||
1160 | port = serial->port[i]; |
||
1161 | port->write_urb = usb_alloc_urb(0, GFP_KERNEL); |
||
1162 | if (!port->write_urb) { |
||
1163 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1164 | goto probe_error; |
||
1165 | } |
||
1166 | buffer_size = endpoint->wMaxPacketSize; |
||
1167 | port->bulk_out_size = buffer_size; |
||
1168 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; |
||
1169 | port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1170 | if (!port->bulk_out_buffer) { |
||
1171 | dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n"); |
||
1172 | goto probe_error; |
||
1173 | } |
||
1174 | usb_fill_bulk_urb (port->write_urb, dev, |
||
1175 | usb_sndbulkpipe (dev, |
||
1176 | endpoint->bEndpointAddress), |
||
1177 | port->bulk_out_buffer, buffer_size, |
||
1178 | serial->type->write_bulk_callback, |
||
1179 | port); |
||
1180 | } |
||
1181 | |||
1182 | for (i = 0; i < num_interrupt_in; ++i) { |
||
1183 | endpoint = interrupt_in_endpoint[i]; |
||
1184 | port = serial->port[i]; |
||
1185 | port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
||
1186 | if (!port->interrupt_in_urb) { |
||
1187 | dev_err(&interface->dev, "No free urbs available\n"); |
||
1188 | goto probe_error; |
||
1189 | } |
||
1190 | buffer_size = endpoint->wMaxPacketSize; |
||
1191 | port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; |
||
1192 | port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); |
||
1193 | if (!port->interrupt_in_buffer) { |
||
1194 | dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n"); |
||
1195 | goto probe_error; |
||
1196 | } |
||
1197 | usb_fill_int_urb (port->interrupt_in_urb, dev, |
||
1198 | usb_rcvintpipe (dev, |
||
1199 | endpoint->bEndpointAddress), |
||
1200 | port->interrupt_in_buffer, buffer_size, |
||
1201 | serial->type->read_int_callback, port, |
||
1202 | endpoint->bInterval); |
||
1203 | } |
||
1204 | |||
1205 | /* if this device type has an attach function, call it */ |
||
1206 | if (type->attach) { |
||
1207 | if (!try_module_get(type->owner)) { |
||
1208 | dev_err(&interface->dev, "module get failed, exiting\n"); |
||
1209 | goto probe_error; |
||
1210 | } |
||
1211 | retval = type->attach (serial); |
||
1212 | module_put(type->owner); |
||
1213 | if (retval < 0) |
||
1214 | goto probe_error; |
||
1215 | if (retval > 0) { |
||
1216 | /* quietly accept this device, but don't bind to a serial port |
||
1217 | * as it's about to disappear */ |
||
1218 | goto exit; |
||
1219 | } |
||
1220 | } |
||
1221 | |||
1222 | /* register all of the individual ports with the driver core */ |
||
1223 | for (i = 0; i < num_ports; ++i) { |
||
1224 | port = serial->port[i]; |
||
1225 | port->dev.parent = &interface->dev; |
||
1226 | port->dev.driver = NULL; |
||
1227 | port->dev.bus = &usb_serial_bus_type; |
||
1228 | port->dev.release = &port_release; |
||
1229 | |||
1230 | snprintf26(&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number); |
||
1231 | dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id); |
||
1232 | device_register (&port->dev); |
||
1233 | } |
||
1234 | |||
1235 | usb_serial_console_init (debug, minor); |
||
1236 | |||
1237 | exit: |
||
1238 | /* success */ |
||
1239 | usb_set_intfdata (interface, serial); |
||
1240 | return 0; |
||
1241 | |||
1242 | probe_error: |
||
1243 | for (i = 0; i < num_bulk_in; ++i) { |
||
1244 | port = serial->port[i]; |
||
1245 | if (!port) |
||
1246 | continue; |
||
1247 | if (port->read_urb) |
||
1248 | usb_free_urb (port->read_urb); |
||
1249 | kfree(port->bulk_in_buffer); |
||
1250 | } |
||
1251 | for (i = 0; i < num_bulk_out; ++i) { |
||
1252 | port = serial->port[i]; |
||
1253 | if (!port) |
||
1254 | continue; |
||
1255 | if (port->write_urb) |
||
1256 | usb_free_urb (port->write_urb); |
||
1257 | kfree(port->bulk_out_buffer); |
||
1258 | } |
||
1259 | for (i = 0; i < num_interrupt_in; ++i) { |
||
1260 | port = serial->port[i]; |
||
1261 | if (!port) |
||
1262 | continue; |
||
1263 | if (port->interrupt_in_urb) |
||
1264 | usb_free_urb (port->interrupt_in_urb); |
||
1265 | kfree(port->interrupt_in_buffer); |
||
1266 | } |
||
1267 | |||
1268 | /* return the minor range that this device had */ |
||
1269 | return_serial (serial); |
||
1270 | |||
1271 | /* free up any memory that we allocated */ |
||
1272 | for (i = 0; i < serial->num_port_pointers; ++i) |
||
1273 | kfree(serial->port[i]); |
||
1274 | kfree (serial); |
||
1275 | return -EIO; |
||
1276 | } |
||
1277 | |||
1278 | void usb_serial_disconnect(struct usb_interface *interface) |
||
1279 | { |
||
1280 | struct usb_serial *serial = usb_get_intfdata (interface); |
||
1281 | struct device *dev = &interface->dev; |
||
1282 | |||
1283 | dbg ("%s", __FUNCTION__); |
||
1284 | |||
1285 | usb_set_intfdata (interface, NULL); |
||
1286 | if (serial) { |
||
1287 | /* let the last holder of this object |
||
1288 | * cause it to be cleaned up */ |
||
1289 | kobject_put (&serial->kobj); |
||
1290 | } |
||
1291 | dev_info(dev, "device disconnected\n"); |
||
1292 | } |
||
1293 | |||
1294 | static struct tty_operations serial_ops = { |
||
1295 | .open = serial_open, |
||
1296 | .close = serial_close, |
||
1297 | .write = serial_write, |
||
1298 | .write_room = serial_write_room, |
||
1299 | .ioctl = serial_ioctl, |
||
1300 | .set_termios = serial_set_termios, |
||
1301 | .throttle = serial_throttle, |
||
1302 | .unthrottle = serial_unthrottle, |
||
1303 | .break_ctl = serial_break, |
||
1304 | .chars_in_buffer = serial_chars_in_buffer, |
||
1305 | .read_proc = serial_read_proc, |
||
1306 | .tiocmget = serial_tiocmget, |
||
1307 | .tiocmset = serial_tiocmset, |
||
1308 | }; |
||
1309 | |||
1310 | struct tty_driver *usb_serial_tty_driver; |
||
1311 | |||
1312 | /*static*/ int __init usb_serial_init(void) |
||
1313 | { |
||
1314 | int i; |
||
1315 | int result = 0; |
||
1316 | |||
1317 | usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS); |
||
1318 | if (!usb_serial_tty_driver) |
||
1319 | return -ENOMEM; |
||
1320 | |||
1321 | /* Initialize our global data */ |
||
1322 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
||
1323 | serial_table[i] = NULL; |
||
1324 | } |
||
1325 | |||
1326 | bus_register(&usb_serial_bus_type); |
||
1327 | |||
1328 | /* register the generic driver, if we should */ |
||
1329 | result = usb_serial_generic_register(debug); |
||
1330 | if (result < 0) { |
||
1331 | err("%s - registering generic driver failed", __FUNCTION__); |
||
1332 | goto exit; |
||
1333 | } |
||
1334 | |||
1335 | usb_serial_tty_driver->owner = THIS_MODULE; |
||
1336 | usb_serial_tty_driver->driver_name = "usbserial"; |
||
1337 | usb_serial_tty_driver->devfs_name = "usb/tts/"; |
||
1338 | usb_serial_tty_driver->name = "ttyUSB"; |
||
1339 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; |
||
1340 | usb_serial_tty_driver->minor_start = 0; |
||
1341 | usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
||
1342 | usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
||
1343 | usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; |
||
1344 | usb_serial_tty_driver->init_termios = tty_std_termios; |
||
1345 | usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
||
1346 | tty_set_operations(usb_serial_tty_driver, &serial_ops); |
||
1347 | result = tty_register_driver(usb_serial_tty_driver); |
||
1348 | if (result) { |
||
1349 | err("%s - tty_register_driver failed", __FUNCTION__); |
||
1350 | goto exit_generic; |
||
1351 | } |
||
1352 | |||
1353 | /* register the USB driver */ |
||
1354 | result = usb_register(&usb_serial_driver); |
||
1355 | if (result < 0) { |
||
1356 | err("%s - usb_register failed", __FUNCTION__); |
||
1357 | goto exit_tty; |
||
1358 | } |
||
1359 | |||
1360 | info(DRIVER_DESC " " DRIVER_VERSION); |
||
1361 | |||
1362 | return result; |
||
1363 | |||
1364 | exit_tty: |
||
1365 | tty_unregister_driver(usb_serial_tty_driver); |
||
1366 | |||
1367 | exit_generic: |
||
1368 | usb_serial_generic_deregister(); |
||
1369 | |||
1370 | exit: |
||
1371 | err ("%s - returning with error %d", __FUNCTION__, result); |
||
1372 | put_tty_driver(usb_serial_tty_driver); |
||
1373 | return result; |
||
1374 | } |
||
1375 | |||
1376 | |||
1377 | /*static*/ void __exit usb_serial_exit(void) |
||
1378 | { |
||
1379 | usb_serial_console_exit(); |
||
1380 | |||
1381 | usb_serial_generic_deregister(); |
||
1382 | |||
1383 | usb_deregister(&usb_serial_driver); |
||
1384 | tty_unregister_driver(usb_serial_tty_driver); |
||
1385 | put_tty_driver(usb_serial_tty_driver); |
||
1386 | bus_unregister(&usb_serial_bus_type); |
||
1387 | } |
||
1388 | |||
1389 | |||
1390 | module_init(usb_serial_init); |
||
1391 | module_exit(usb_serial_exit); |
||
1392 | |||
1393 | #define set_to_generic_if_null(type, function) \ |
||
1394 | do { \ |
||
1395 | if (!type->function) { \ |
||
1396 | type->function = usb_serial_generic_##function; \ |
||
1397 | dbg("Had to override the " #function \ |
||
1398 | " usb serial operation with the generic one.");\ |
||
1399 | } \ |
||
1400 | } while (0) |
||
1401 | |||
1402 | static void fixup_generic(struct usb_serial_device_type *device) |
||
1403 | { |
||
1404 | set_to_generic_if_null(device, open); |
||
1405 | set_to_generic_if_null(device, write); |
||
1406 | set_to_generic_if_null(device, close); |
||
1407 | set_to_generic_if_null(device, write_room); |
||
1408 | set_to_generic_if_null(device, chars_in_buffer); |
||
1409 | set_to_generic_if_null(device, read_bulk_callback); |
||
1410 | set_to_generic_if_null(device, write_bulk_callback); |
||
1411 | set_to_generic_if_null(device, shutdown); |
||
1412 | } |
||
1413 | |||
1414 | int usb_serial_register(struct usb_serial_device_type *new_device) |
||
1415 | { |
||
1416 | int retval; |
||
1417 | |||
1418 | fixup_generic(new_device); |
||
1419 | |||
1420 | /* Add this device to our list of devices */ |
||
1421 | list_add(&new_device->driver_list, &usb_serial_driver_list); |
||
1422 | |||
1423 | retval = usb_serial_bus_register (new_device); |
||
1424 | |||
1425 | if (retval) |
||
1426 | goto error; |
||
1427 | |||
1428 | info("USB Serial support registered for %s", new_device->name); |
||
1429 | |||
1430 | return retval; |
||
1431 | error: |
||
1432 | err("problem %d when registering driver %s", retval, new_device->name); |
||
1433 | list_del(&new_device->driver_list); |
||
1434 | |||
1435 | return retval; |
||
1436 | } |
||
1437 | |||
1438 | |||
1439 | void usb_serial_deregister(struct usb_serial_device_type *device) |
||
1440 | { |
||
1441 | struct usb_serial *serial; |
||
1442 | int i; |
||
1443 | |||
1444 | info("USB Serial deregistering driver %s", device->name); |
||
1445 | |||
1446 | /* clear out the serial_table if the device is attached to a port */ |
||
1447 | for(i = 0; i < SERIAL_TTY_MINORS; ++i) { |
||
1448 | serial = serial_table[i]; |
||
1449 | if ((serial != NULL) && (serial->type == device)) { |
||
1450 | usb_driver_release_interface (&usb_serial_driver, serial->interface); |
||
1451 | usb_serial_disconnect (serial->interface); |
||
1452 | } |
||
1453 | } |
||
1454 | |||
1455 | list_del(&device->driver_list); |
||
1456 | usb_serial_bus_deregister (device); |
||
1457 | } |
||
1458 | |||
1459 | |||
1460 | |||
1461 | /* If the usb-serial core is built into the core, the usb-serial drivers |
||
1462 | need these symbols to load properly as modules. */ |
||
1463 | EXPORT_SYMBOL(usb_serial_register); |
||
1464 | EXPORT_SYMBOL(usb_serial_deregister); |
||
1465 | EXPORT_SYMBOL(usb_serial_probe); |
||
1466 | EXPORT_SYMBOL(usb_serial_disconnect); |
||
1467 | EXPORT_SYMBOL(usb_serial_port_softint); |
||
1468 | |||
1469 | |||
1470 | /* Module information */ |
||
1471 | MODULE_AUTHOR( DRIVER_AUTHOR ); |
||
1472 | MODULE_DESCRIPTION( DRIVER_DESC ); |
||
1473 | MODULE_LICENSE("GPL"); |
||
1474 | |||
1475 | MODULE_PARM(debug, "i"); |
||
1476 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |