aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/ChangeLog.history730
-rw-r--r--drivers/usb/serial/baseband_usb_chr.c1124
-rw-r--r--drivers/usb/serial/baseband_usb_chr.h106
-rw-r--r--drivers/usb/serial/ezusb.c61
4 files changed, 2021 insertions, 0 deletions
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
new file mode 100644
index 00000000000..f13fd488ebe
--- /dev/null
+++ b/drivers/usb/serial/ChangeLog.history
@@ -0,0 +1,730 @@
1This is the contents of some of the drivers/usb/serial/ files that had old
2changelog comments. They were quite old, and out of date, and we don't keep
3them anymore, so I've put them here, away from the source files, in case
4people still care to see them.
5
6- Greg Kroah-Hartman <greg@kroah.com> October 20, 2005
7
8-----------------------------------------------------------------------
9usb-serial.h Change Log comments:
10
11 (03/26/2002) gkh
12 removed the port->tty check from port_paranoia_check() due to serial
13 consoles not having a tty device assigned to them.
14
15 (12/03/2001) gkh
16 removed active from the port structure.
17 added documentation to the usb_serial_device_type structure
18
19 (10/10/2001) gkh
20 added vendor and product to serial structure. Needed to determine device
21 owner when the device is disconnected.
22
23 (05/30/2001) gkh
24 added sem to port structure and removed port_lock
25
26 (10/05/2000) gkh
27 Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
28 fix bug with urb->dev not being set properly, now that the usb core
29 needs it.
30
31 (09/11/2000) gkh
32 Added usb_serial_debug_data function to help get rid of #DEBUG in the
33 drivers.
34
35 (08/28/2000) gkh
36 Added port_lock to port structure.
37
38 (08/08/2000) gkh
39 Added open_count to port structure.
40
41 (07/23/2000) gkh
42 Added bulk_out_endpointAddress to port structure.
43
44 (07/19/2000) gkh, pberger, and borchers
45 Modifications to allow usb-serial drivers to be modules.
46
47-----------------------------------------------------------------------
48usb-serial.c Change Log comments:
49
50 (12/10/2002) gkh
51 Split the ports off into their own struct device, and added a
52 usb-serial bus driver.
53
54 (11/19/2002) gkh
55 removed a few #ifdefs for the generic code and cleaned up the failure
56 logic in initialization.
57
58 (10/02/2002) gkh
59 moved the console code to console.c and out of this file.
60
61 (06/05/2002) gkh
62 moved location of startup() call in serial_probe() until after all
63 of the port information and endpoints are initialized. This makes
64 things easier for some drivers.
65
66 (04/10/2002) gkh
67 added serial_read_proc function which creates a
68 /proc/tty/driver/usb-serial file.
69
70 (03/27/2002) gkh
71 Got USB serial console code working properly and merged into the main
72 version of the tree. Thanks to Randy Dunlap for the initial version
73 of this code, and for pushing me to finish it up.
74 The USB serial console works with any usb serial driver device.
75
76 (03/21/2002) gkh
77 Moved all manipulation of port->open_count into the core. Now the
78 individual driver's open and close functions are called only when the
79 first open() and last close() is called. Making the drivers a bit
80 smaller and simpler.
81 Fixed a bug if a driver didn't have the owner field set.
82
83 (02/26/2002) gkh
84 Moved all locking into the main serial_* functions, instead of having
85 the individual drivers have to grab the port semaphore. This should
86 reduce races.
87 Reworked the MOD_INC logic a bit to always increment and decrement, even
88 if the generic driver is being used.
89
90 (10/10/2001) gkh
91 usb_serial_disconnect() now sets the serial->dev pointer is to NULL to
92 help prevent child drivers from accessing the device since it is now
93 gone.
94
95 (09/13/2001) gkh
96 Moved generic driver initialize after we have registered with the USB
97 core. Thanks to Randy Dunlap for pointing this problem out.
98
99 (07/03/2001) gkh
100 Fixed module paramater size. Thanks to John Brockmeyer for the pointer.
101 Fixed vendor and product getting defined through the MODULE_PARM macro
102 if the Generic driver wasn't compiled in.
103 Fixed problem with generic_shutdown() not being called for drivers that
104 don't have a shutdown() function.
105
106 (06/06/2001) gkh
107 added evil hack that is needed for the prolific pl2303 device due to the
108 crazy way its endpoints are set up.
109
110 (05/30/2001) gkh
111 switched from using spinlock to a semaphore, which fixes lots of problems.
112
113 (04/08/2001) gb
114 Identify version on module load.
115
116 2001_02_05 gkh
117 Fixed buffer overflows bug with the generic serial driver. Thanks to
118 Todd Squires <squirest@ct0.com> for fixing this.
119
120 (01/10/2001) gkh
121 Fixed bug where the generic serial adaptor grabbed _any_ device that was
122 offered to it.
123
124 (12/12/2000) gkh
125 Removed MOD_INC and MOD_DEC from poll and disconnect functions, and
126 moved them to the serial_open and serial_close functions.
127 Also fixed bug with there not being a MOD_DEC for the generic driver
128 (thanks to Gary Brubaker for finding this.)
129
130 (11/29/2000) gkh
131 Small NULL pointer initialization cleanup which saves a bit of disk image
132
133 (11/01/2000) Adam J. Richter
134 instead of using idVendor/idProduct pairs, usb serial drivers
135 now identify their hardware interest with usb_device_id tables,
136 which they usually have anyhow for use with MODULE_DEVICE_TABLE.
137
138 (10/05/2000) gkh
139 Fixed bug with urb->dev not being set properly, now that the usb
140 core needs it.
141
142 (09/11/2000) gkh
143 Removed DEBUG #ifdefs with call to usb_serial_debug_data
144
145 (08/28/2000) gkh
146 Added port_lock to port structure.
147 Added locks for SMP safeness to generic driver
148 Fixed the ability to open a generic device's port more than once.
149
150 (07/23/2000) gkh
151 Added bulk_out_endpointAddress to port structure.
152
153 (07/19/2000) gkh, pberger, and borchers
154 Modifications to allow usb-serial drivers to be modules.
155
156 (07/03/2000) gkh
157 Added more debugging to serial_ioctl call
158
159 (06/25/2000) gkh
160 Changed generic_write_bulk_callback to not call wake_up_interruptible
161 directly, but to have port_softint do it at a safer time.
162
163 (06/23/2000) gkh
164 Cleaned up debugging statements in a quest to find UHCI timeout bug.
165
166 (05/22/2000) gkh
167 Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be
168 removed from the individual device source files.
169
170 (05/03/2000) gkh
171 Added the Digi Acceleport driver from Al Borchers and Peter Berger.
172
173 (05/02/2000) gkh
174 Changed devfs and tty register code to work properly now. This was based on
175 the ACM driver changes by Vojtech Pavlik.
176
177 (04/27/2000) Ryan VanderBijl
178 Put calls to *_paranoia_checks into one function.
179
180 (04/23/2000) gkh
181 Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports.
182 Moved when the startup code printed out the devices that are supported.
183
184 (04/19/2000) gkh
185 Added driver for ZyXEL omni.net lcd plus ISDN TA
186 Made startup info message specify which drivers were compiled in.
187
188 (04/03/2000) gkh
189 Changed the probe process to remove the module unload races.
190 Changed where the tty layer gets initialized to have devfs work nicer.
191 Added initial devfs support.
192
193 (03/26/2000) gkh
194 Split driver up into device specific pieces.
195
196 (03/19/2000) gkh
197 Fixed oops that could happen when device was removed while a program
198 was talking to the device.
199 Removed the static urbs and now all urbs are created and destroyed
200 dynamically.
201 Reworked the internal interface. Now everything is based on the
202 usb_serial_port structure instead of the larger usb_serial structure.
203 This fixes the bug that a multiport device could not have more than
204 one port open at one time.
205
206 (03/17/2000) gkh
207 Added config option for debugging messages.
208 Added patch for keyspan pda from Brian Warner.
209
210 (03/06/2000) gkh
211 Added the keyspan pda code from Brian Warner <warner@lothar.com>
212 Moved a bunch of the port specific stuff into its own structure. This
213 is in anticipation of the true multiport devices (there's a bug if you
214 try to access more than one port of any multiport device right now)
215
216 (02/21/2000) gkh
217 Made it so that any serial devices only have to specify which functions
218 they want to overload from the generic function calls (great,
219 inheritance in C, in a driver, just what I wanted...)
220 Added support for set_termios and ioctl function calls. No drivers take
221 advantage of this yet.
222 Removed the #ifdef MODULE, now there is no module specific code.
223 Cleaned up a few comments in usb-serial.h that were wrong (thanks again
224 to Miles Lott).
225 Small fix to get_free_serial.
226
227 (02/14/2000) gkh
228 Removed the Belkin and Peracom functionality from the driver due to
229 the lack of support from the vendor, and me not wanting people to
230 accidenatly buy the device, expecting it to work with Linux.
231 Added read_bulk_callback and write_bulk_callback to the type structure
232 for the needs of the FTDI and WhiteHEAT driver.
233 Changed all reverences to FTDI to FTDI_SIO at the request of Bill
234 Ryder.
235 Changed the output urb size back to the max endpoint size to make
236 the ftdi_sio driver have it easier, and due to the fact that it didn't
237 really increase the speed any.
238
239 (02/11/2000) gkh
240 Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a
241 patch from Miles Lott (milos@insync.net).
242 Fixed bug with not restoring the minor range that a device grabs, if
243 the startup function fails (thanks Miles for finding this).
244
245 (02/05/2000) gkh
246 Added initial framework for the Keyspan PDA serial converter so that
247 Brian Warner has a place to put his code.
248 Made the ezusb specific functions generic enough that different
249 devices can use them (whiteheat and keyspan_pda both need them).
250 Split out a whole bunch of structure and other stuff to a separate
251 usb-serial.h file.
252 Made the Visor connection messages a little more understandable, now
253 that Miles Lott (milos@insync.net) has gotten the Generic channel to
254 work. Also made them always show up in the log file.
255
256 (01/25/2000) gkh
257 Added initial framework for FTDI serial converter so that Bill Ryder
258 has a place to put his code.
259 Added the vendor specific info from Handspring. Now we can print out
260 informational debug messages as well as understand what is happening.
261
262 (01/23/2000) gkh
263 Fixed problem of crash when trying to open a port that didn't have a
264 device assigned to it. Made the minor node finding a little smarter,
265 now it looks to find a continuous space for the new device.
266
267 (01/21/2000) gkh
268 Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net)
269 Fixed get_serial_by_minor which was all messed up for multi port
270 devices. Fixed multi port problem for generic devices. Now the number
271 of ports is determined by the number of bulk out endpoints for the
272 generic device.
273
274 (01/19/2000) gkh
275 Removed lots of cruft that was around from the old (pre urb) driver
276 interface.
277 Made the serial_table dynamic. This should save lots of memory when
278 the number of minor nodes goes up to 256.
279 Added initial support for devices that have more than one port.
280 Added more debugging comments for the Visor, and added a needed
281 set_configuration call.
282
283 (01/17/2000) gkh
284 Fixed the WhiteHEAT firmware (my processing tool had a bug)
285 and added new debug loader firmware for it.
286 Removed the put_char function as it isn't really needed.
287 Added visor startup commands as found by the Win98 dump.
288
289 (01/13/2000) gkh
290 Fixed the vendor id for the generic driver to the one I meant it to be.
291
292 (01/12/2000) gkh
293 Forget the version numbering...that's pretty useless...
294 Made the driver able to be compiled so that the user can select which
295 converter they want to use. This allows people who only want the Visor
296 support to not pay the memory size price of the WhiteHEAT.
297 Fixed bug where the generic driver (idVendor=0000 and idProduct=0000)
298 grabbed the root hub. Not good.
299
300 version 0.4.0 (01/10/2000) gkh
301 Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT
302 device. Added startup function to allow firmware to be downloaded to
303 a device if it needs to be.
304 Added firmware download logic to the WhiteHEAT device.
305 Started to add #defines to split up the different drivers for potential
306 configuration option.
307
308 version 0.3.1 (12/30/99) gkh
309 Fixed problems with urb for bulk out.
310 Added initial support for multiple sets of endpoints. This enables
311 the Handspring Visor to be attached successfully. Only the first
312 bulk in / bulk out endpoint pair is being used right now.
313
314 version 0.3.0 (12/27/99) gkh
315 Added initial support for the Handspring Visor based on a patch from
316 Miles Lott (milos@sneety.insync.net)
317 Cleaned up the code a bunch and converted over to using urbs only.
318
319 version 0.2.3 (12/21/99) gkh
320 Added initial support for the Connect Tech WhiteHEAT converter.
321 Incremented the number of ports in expectation of getting the
322 WhiteHEAT to work properly (4 ports per connection).
323 Added notification on insertion and removal of what port the
324 device is/was connected to (and what kind of device it was).
325
326 version 0.2.2 (12/16/99) gkh
327 Changed major number to the new allocated number. We're legal now!
328
329 version 0.2.1 (12/14/99) gkh
330 Fixed bug that happens when device node is opened when there isn't a
331 device attached to it. Thanks to marek@webdesign.no for noticing this.
332
333 version 0.2.0 (11/10/99) gkh
334 Split up internals to make it easier to add different types of serial
335 converters to the code.
336 Added a "generic" driver that gets it's vendor and product id
337 from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net)
338 for the idea and sample code (from the usb scanner driver.)
339 Cleared up any licensing questions by releasing it under the GNU GPL.
340
341 version 0.1.2 (10/25/99) gkh
342 Fixed bug in detecting device.
343
344 version 0.1.1 (10/05/99) gkh
345 Changed the major number to not conflict with anything else.
346
347 version 0.1 (09/28/99) gkh
348 Can recognize the two different devices and start up a read from
349 device when asked to. Writes also work. No control signals yet, this
350 all is vendor specific data (i.e. no spec), also no control for
351 different baud rates or other bit settings.
352 Currently we are using the same devid as the acm driver. This needs
353 to change.
354
355-----------------------------------------------------------------------
356visor.c Change Log comments:
357
358 (06/03/2003) Judd Montgomery <judd at jpilot.org>
359 Added support for module parameter options for untested/unknown
360 devices.
361
362 (03/09/2003) gkh
363 Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl
364 <brachtl@redgrep.cz> for the information.
365
366 (03/05/2003) gkh
367 Think Treo support is now working.
368
369 (04/03/2002) gkh
370 Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI
371 <hiro@zob.ne.jp> for the information.
372
373 (03/27/2002) gkh
374 Removed assumptions that port->tty was always valid (is not true
375 for usb serial console devices.)
376
377 (03/23/2002) gkh
378 Added support for the Palm i705 device, thanks to Thomas Riemer
379 <tom@netmech.com> for the information.
380
381 (03/21/2002) gkh
382 Added support for the Palm m130 device, thanks to Udo Eisenbarth
383 <udo.eisenbarth@web.de> for the information.
384
385 (02/27/2002) gkh
386 Reworked the urb handling logic. We have no more pool, but dynamically
387 allocate the urb and the transfer buffer on the fly. In testing this
388 does not incure any measurable overhead. This also relies on the fact
389 that we have proper reference counting logic for urbs.
390
391 (02/21/2002) SilaS
392 Added initial support for the Palm m515 devices.
393
394 (02/14/2002) gkh
395 Added support for the Clie S-360 device.
396
397 (12/18/2001) gkh
398 Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand
399 for the patch.
400
401 (11/11/2001) gkh
402 Added support for the m125 devices, and added check to prevent oopses
403 for Clié devices that lie about the number of ports they have.
404
405 (08/30/2001) gkh
406 Added support for the Clie devices, both the 3.5 and 4.0 os versions.
407 Many thanks to Daniel Burke, and Bryan Payne for helping with this.
408
409 (08/23/2001) gkh
410 fixed a few potential bugs pointed out by Oliver Neukum.
411
412 (05/30/2001) gkh
413 switched from using spinlock to a semaphore, which fixes lots of problems.
414
415 (05/28/2000) gkh
416 Added initial support for the Palm m500 and Palm m505 devices.
417
418 (04/08/2001) gb
419 Identify version on module load.
420
421 (01/21/2000) gkh
422 Added write_room and chars_in_buffer, as they were previously using the
423 generic driver versions which is all wrong now that we are using an urb
424 pool. Thanks to Wolfgang Grandegger for pointing this out to me.
425 Removed count assignment in the write function, which was not needed anymore
426 either. Thanks to Al Borchers for pointing this out.
427
428 (12/12/2000) gkh
429 Moved MOD_DEC to end of visor_close to be nicer, as the final write
430 message can sleep.
431
432 (11/12/2000) gkh
433 Fixed bug with data being dropped on the floor by forcing tty->low_latency
434 to be on. Hopefully this fixes the OHCI issue!
435
436 (11/01/2000) Adam J. Richter
437 usb_device_id table support
438
439 (10/05/2000) gkh
440 Fixed bug with urb->dev not being set properly, now that the usb
441 core needs it.
442
443 (09/11/2000) gkh
444 Got rid of always calling kmalloc for every urb we wrote out to the
445 device.
446 Added visor_read_callback so we can keep track of bytes in and out for
447 those people who like to know the speed of their device.
448 Removed DEBUG #ifdefs with call to usb_serial_debug_data
449
450 (09/06/2000) gkh
451 Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_
452 the host controller drivers set urb->dev = NULL when the urb is finished.
453
454 (08/28/2000) gkh
455 Added locks for SMP safeness.
456
457 (08/08/2000) gkh
458 Fixed endian problem in visor_startup.
459 Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
460 than once.
461
462 (07/23/2000) gkh
463 Added pool of write urbs to speed up transfers to the visor.
464
465 (07/19/2000) gkh
466 Added module_init and module_exit functions to handle the fact that this
467 driver is a loadable module now.
468
469 (07/03/2000) gkh
470 Added visor_set_ioctl and visor_set_termios functions (they don't do much
471 of anything, but are good for debugging.)
472
473 (06/25/2000) gkh
474 Fixed bug in visor_unthrottle that should help with the disconnect in PPP
475 bug that people have been reporting.
476
477 (06/23/2000) gkh
478 Cleaned up debugging statements in a quest to find UHCI timeout bug.
479
480 (04/27/2000) Ryan VanderBijl
481 Fixed memory leak in visor_close
482
483 (03/26/2000) gkh
484 Split driver up into device specific pieces.
485
486-----------------------------------------------------------------------
487pl2303.c Change Log comments:
488
489 2002_Mar_26 gkh
490 allowed driver to work properly if there is no tty assigned to a port
491 (this happens for serial console devices.)
492
493 2001_Oct_06 gkh
494 Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it.
495
496 2001_Sep_19 gkh
497 Added break support.
498
499 2001_Aug_30 gkh
500 fixed oops in write_bulk_callback.
501
502 2001_Aug_28 gkh
503 reworked buffer logic to be like other usb-serial drivers. Hopefully
504 removing some reported problems.
505
506 2001_Jun_06 gkh
507 finished porting to 2.4 format.
508
509
510-----------------------------------------------------------------------
511io_edgeport.c Change Log comments:
512
513 2003_04_03 al borchers
514 - fixed a bug (that shows up with dosemu) where the tty struct is
515 used in a callback after it has been freed
516
517 2.3 2002_03_08 greg kroah-hartman
518 - fixed bug when multiple devices were attached at the same time.
519
520 2.2 2001_11_14 greg kroah-hartman
521 - fixed bug in edge_close that kept the port from being used more
522 than once.
523 - fixed memory leak on device removal.
524 - fixed potential double free of memory when command urb submitting
525 failed.
526 - other small cleanups when the device is removed
527
528 2.1 2001_07_09 greg kroah-hartman
529 - added support for TIOCMBIS and TIOCMBIC.
530
531 (04/08/2001) gb
532 - Identify version on module load.
533
534 2.0 2001_03_05 greg kroah-hartman
535 - reworked entire driver to fit properly in with the other usb-serial
536 drivers. Occasional oopses still happen, but it's a good start.
537
538 1.2.3 (02/23/2001) greg kroah-hartman
539 - changed device table to work properly for 2.4.x final format.
540 - fixed problem with dropping data at high data rates.
541
542 1.2.2 (11/27/2000) greg kroah-hartman
543 - cleaned up more NTisms.
544 - Added device table for 2.4.0-test11
545
546 1.2.1 (11/08/2000) greg kroah-hartman
547 - Started to clean up NTisms.
548 - Fixed problem with dev field of urb for kernels >= 2.4.0-test9
549
550 1.2 (10/17/2000) David Iacovelli
551 Remove all EPIC code and GPL source
552 Fix RELEVANT_IFLAG macro to include flow control
553 changes port configuration changes.
554 Fix redefinition of SERIAL_MAGIC
555 Change all timeout values to 5 seconds
556 Tried to fix the UHCI multiple urb submission, but failed miserably.
557 it seems to work fine with OHCI.
558 ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must
559 find a way to work arount this UHCI bug )
560
561 1.1 (10/11/2000) David Iacovelli
562 Fix XON/XOFF flow control to support both IXON and IXOFF
563
564 0.9.27 (06/30/2000) David Iacovelli
565 Added transmit queue and now allocate urb for command writes.
566
567 0.9.26 (06/29/2000) David Iacovelli
568 Add support for 80251 based edgeport
569
570 0.9.25 (06/27/2000) David Iacovelli
571 Do not close the port if it has multiple opens.
572
573 0.9.24 (05/26/2000) David Iacovelli
574 Add IOCTLs to support RXTX and JAVA POS
575 and first cut at running BlackBox Demo
576
577 0.9.23 (05/24/2000) David Iacovelli
578 Add IOCTLs to support RXTX and JAVA POS
579
580 0.9.22 (05/23/2000) David Iacovelli
581 fixed bug in enumeration. If epconfig turns on mapping by
582 path after a device is already plugged in, we now update
583 the mapping correctly
584
585 0.9.21 (05/16/2000) David Iacovelli
586 Added BlockUntilChaseResp() to also wait for txcredits
587 Updated the way we allocate and handle write URBs
588 Add debug code to dump buffers
589
590 0.9.20 (05/01/2000) David Iacovelli
591 change driver to use usb/tts/
592
593 0.9.19 (05/01/2000) David Iacovelli
594 Update code to compile if DEBUG is off
595
596 0.9.18 (04/28/2000) David Iacovelli
597 cleanup and test tty_register with devfs
598
599 0.9.17 (04/27/2000) greg kroah-hartman
600 changed tty_register around to be like the way it
601 was before, but now it works properly with devfs.
602
603 0.9.16 (04/26/2000) david iacovelli
604 Fixed bug in GetProductInfo()
605
606 0.9.15 (04/25/2000) david iacovelli
607 Updated enumeration
608
609 0.9.14 (04/24/2000) david iacovelli
610 Removed all config/status IOCTLS and
611 converted to using /proc/edgeport
612 still playing with devfs
613
614 0.9.13 (04/24/2000) david iacovelli
615 Removed configuration based on ttyUSB0
616 Added support for configuration using /prod/edgeport
617 first attempt at using devfs (not working yet!)
618 Added IOCTL to GetProductInfo()
619 Added support for custom baud rates
620 Add support for random port numbers
621
622 0.9.12 (04/18/2000) david iacovelli
623 added additional configuration IOCTLs
624 use ttyUSB0 for configuration
625
626 0.9.11 (04/17/2000) greg kroah-hartman
627 fixed module initialization race conditions.
628 made all urbs dynamically allocated.
629 made driver devfs compatible. now it only registers the tty device
630 when the device is actually plugged in.
631
632 0.9.10 (04/13/2000) greg kroah-hartman
633 added proc interface framework.
634
635 0.9.9 (04/13/2000) david iacovelli
636 added enumeration code and ioctls to configure the device
637
638 0.9.8 (04/12/2000) david iacovelli
639 Change interrupt read start when device is plugged in
640 and stop when device is removed
641 process interrupt reads when all ports are closed
642 (keep value of rxBytesAvail consistent with the edgeport)
643 set the USB_BULK_QUEUE flag so that we can shove a bunch
644 of urbs at once down the pipe
645
646 0.9.7 (04/10/2000) david iacovelli
647 start to add enumeration code.
648 generate serial number for epic devices
649 add support for kdb
650
651 0.9.6 (03/30/2000) david iacovelli
652 add IOCTL to get string, manufacture, and boot descriptors
653
654 0.9.5 (03/14/2000) greg kroah-hartman
655 more error checking added to SerialOpen to try to fix UHCI open problem
656
657 0.9.4 (03/09/2000) greg kroah-hartman
658 added more error checking to handle oops when data is hanging
659 around and tty is abruptly closed.
660
661 0.9.3 (03/09/2000) david iacovelli
662 Add epic support for xon/xoff chars
663 play with performance
664
665 0.9.2 (03/08/2000) greg kroah-hartman
666 changed most "info" calls to "dbg"
667 implemented flow control properly in the termios call
668
669 0.9.1 (03/08/2000) david iacovelli
670 added EPIC support
671 enabled bootloader update
672
673 0.9 (03/08/2000) greg kroah-hartman
674 Release to IO networks.
675 Integrated changes that David made
676 made getting urbs for writing SMP safe
677
678 0.8 (03/07/2000) greg kroah-hartman
679 Release to IO networks.
680 Fixed problems that were seen in code by David.
681 Now both Edgeport/4 and Edgeport/2 works properly.
682 Changed most of the functions to use port instead of serial.
683
684 0.7 (02/27/2000) greg kroah-hartman
685 Milestone 3 release.
686 Release to IO Networks
687 ioctl for waiting on line change implemented.
688 ioctl for getting statistics implemented.
689 multiport support working.
690 lsr and msr registers are now handled properly.
691 change break now hooked up and working.
692 support for all known Edgeport devices.
693
694 0.6 (02/22/2000) greg kroah-hartman
695 Release to IO networks.
696 CHASE is implemented correctly when port is closed.
697 SerialOpen now blocks correctly until port is fully opened.
698
699 0.5 (02/20/2000) greg kroah-hartman
700 Release to IO networks.
701 Known problems:
702 modem status register changes are not sent on to the user
703 CHASE is not implemented when the port is closed.
704
705 0.4 (02/16/2000) greg kroah-hartman
706 Second cut at the CeBit demo.
707 Doesn't leak memory on every write to the port
708 Still small leaks on startup.
709 Added support for Edgeport/2 and Edgeport/8
710
711 0.3 (02/15/2000) greg kroah-hartman
712 CeBit demo release.
713 Force the line settings to 4800, 8, 1, e for the demo.
714 Warning! This version leaks memory like crazy!
715
716 0.2 (01/30/2000) greg kroah-hartman
717 Milestone 1 release.
718 Device is found by USB subsystem, enumerated, firmware is downloaded
719 and the descriptors are printed to the debug log, config is set, and
720 green light starts to blink. Open port works, and data can be sent
721 and received at the default settings of the UART. Loopback connector
722 and debug log confirms this.
723
724 0.1 (01/23/2000) greg kroah-hartman
725 Initial release to help IO Networks try to set up their test system.
726 Edgeport4 is recognized, firmware is downloaded, config is set so
727 device blinks green light every 3 sec. Port is bound, but opening,
728 closing, and sending data do not work properly.
729
730
diff --git a/drivers/usb/serial/baseband_usb_chr.c b/drivers/usb/serial/baseband_usb_chr.c
new file mode 100644
index 00000000000..6d691a40312
--- /dev/null
+++ b/drivers/usb/serial/baseband_usb_chr.c
@@ -0,0 +1,1124 @@
1/*
2 * baseband_usb_chr.c
3 *
4 * USB character driver to communicate with baseband modems.
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/types.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/cdev.h>
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/list.h>
33#include <linux/errno.h>
34#include <linux/usb.h>
35#include <linux/workqueue.h>
36#include <asm/ioctls.h>
37#include <linux/uaccess.h>
38#include "baseband_usb_chr.h"
39
40MODULE_LICENSE("GPL");
41
42unsigned long baseband_usb_chr_vid = 0x058b;
43unsigned long baseband_usb_chr_pid = 0x0041;
44unsigned long baseband_usb_chr_intf = 0x01;
45
46module_param(baseband_usb_chr_vid, ulong, 0644);
47MODULE_PARM_DESC(baseband_usb_chr_vid, "baseband (usb chr) - USB VID");
48module_param(baseband_usb_chr_pid, ulong, 0644);
49MODULE_PARM_DESC(baseband_usb_chr_pid, "baseband (usb chr) - USB PID");
50module_param(baseband_usb_chr_intf, ulong, 0644);
51MODULE_PARM_DESC(baseband_usb_chr_intf, "baseband (usb chr) - USB interface");
52
53static struct baseband_usb *baseband_usb_chr;
54static bool usb_device_connection;
55
56static atomic_t g_rx_count = ATOMIC_INIT(0);
57
58/* baseband ipc functions */
59
60static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
61 const void *buf, size_t bufsiz)
62{
63 size_t i;
64
65 for (i = 0; i < bufsiz; i += 16) {
66 pr_debug("%s"
67 "[%lx+%x] %p "
68 "%02x %02x %02x %02x "
69 "%02x %02x %02x %02x "
70 "%02x %02x %02x %02x "
71 "%02x %02x %02x %02x\n",
72 prefix,
73 offset,
74 i,
75 ((const unsigned char *) buf) + i,
76 (i + 0 < bufsiz) ? ((const unsigned char *) buf)[i+0]
77 : 0xff,
78 (i + 1 < bufsiz) ? ((const unsigned char *) buf)[i+1]
79 : 0xff,
80 (i + 2 < bufsiz) ? ((const unsigned char *) buf)[i+2]
81 : 0xff,
82 (i + 3 < bufsiz) ? ((const unsigned char *) buf)[i+3]
83 : 0xff,
84 (i + 4 < bufsiz) ? ((const unsigned char *) buf)[i+4]
85 : 0xff,
86 (i + 5 < bufsiz) ? ((const unsigned char *) buf)[i+5]
87 : 0xff,
88 (i + 6 < bufsiz) ? ((const unsigned char *) buf)[i+6]
89 : 0xff,
90 (i + 7 < bufsiz) ? ((const unsigned char *) buf)[i+7]
91 : 0xff,
92 (i + 8 < bufsiz) ? ((const unsigned char *) buf)[i+8]
93 : 0xff,
94 (i + 9 < bufsiz) ? ((const unsigned char *) buf)[i+9]
95 : 0xff,
96 (i + 10 < bufsiz) ? ((const unsigned char *) buf)[i+10]
97 : 0xff,
98 (i + 11 < bufsiz) ? ((const unsigned char *) buf)[i+11]
99 : 0xff,
100 (i + 12 < bufsiz) ? ((const unsigned char *) buf)[i+12]
101 : 0xff,
102 (i + 13 < bufsiz) ? ((const unsigned char *) buf)[i+13]
103 : 0xff,
104 (i + 14 < bufsiz) ? ((const unsigned char *) buf)[i+14]
105 : 0xff,
106 (i + 15 < bufsiz) ? ((const unsigned char *) buf)[i+15]
107 : 0xff);
108 }
109
110}
111
112static size_t peek_ipc_tx_bufsiz(struct baseband_ipc *ipc,
113 size_t bufsiz)
114{
115 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
116 size_t tx_bufsiz;
117
118 pr_debug("peek_ipc_tx_bufsiz\n");
119
120 /* check input */
121 if (!ipc) {
122 pr_err("!ipc\n");
123 return 0;
124 }
125
126 /* acquire tx buffer semaphores */
127 if (down_interruptible(&ipc->buf_sem)) {
128 pr_err("peek_ipc_tx_bufsiz - "
129 "cannot acquire buffer semaphore\n");
130 return -ERESTARTSYS;
131 }
132
133 /* calculate maximum number of tx buffers which can be sent */
134 tx_bufsiz = 0;
135 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
136 {
137 pr_debug("peek_ipc_tx_bufsiz - "
138 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
139 ipc_buf, ipc_buf->offset, ipc_buf->count);
140 if (ipc_buf->count > bufsiz - tx_bufsiz)
141 break;
142 else
143 tx_bufsiz += ipc_buf->count;
144 }
145
146 /* release tx buffer semaphores */
147 up(&ipc->buf_sem);
148
149 return tx_bufsiz;
150}
151
152static size_t get_ipc_tx_buf(struct baseband_ipc *ipc,
153 void *buf, size_t bufsiz)
154{
155 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
156 size_t tx_bufsiz;
157
158 pr_debug("get_ipc_tx_buf\n");
159
160 /* check input */
161 if (!ipc || !buf) {
162 pr_err("!ipc || !buf\n");
163 return 0;
164 }
165 if (!bufsiz)
166 return 0;
167
168 /* acquire tx buffer semaphores */
169 if (down_interruptible(&ipc->buf_sem)) {
170 pr_err("get_ipc_tx_buf - "
171 "cannot acquire buffer semaphore\n");
172 return -ERESTARTSYS;
173 }
174
175 /* get tx data from tx linked list */
176 tx_bufsiz = 0;
177 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
178 {
179 pr_debug("get_ipc_tx_buf - "
180 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
181 ipc_buf, ipc_buf->offset, ipc_buf->count);
182 pr_debug("get_ipc_tx_buf - "
183 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
184 ipc_buf->data[0],
185 ipc_buf->data[1],
186 ipc_buf->data[2],
187 ipc_buf->data[3]);
188 if (ipc_buf->count > bufsiz - tx_bufsiz) {
189 /* copy part of tx buffer */
190 memcpy(buf + tx_bufsiz,
191 ipc_buf->data + ipc_buf->offset,
192 bufsiz - tx_bufsiz);
193 ipc_buf->offset += bufsiz - tx_bufsiz;
194 ipc_buf->count -= bufsiz - tx_bufsiz;
195 tx_bufsiz = bufsiz;
196 } else {
197 /* copy all data from tx buffer */
198 memcpy(buf + tx_bufsiz,
199 ipc_buf->data + ipc_buf->offset,
200 ipc_buf->count);
201 tx_bufsiz += ipc_buf->count;
202 ipc_buf->offset = 0;
203 ipc_buf->count = 0;
204 /* add tx buffer to tx free list */
205 list_move_tail(&ipc_buf->list, &ipc->tx_free.buf);
206 wake_up(&ipc->tx_free.wait);
207 }
208 /* check if done */
209 if (tx_bufsiz == bufsiz)
210 break;
211 }
212
213 /* release tx buffer semaphores */
214 up(&ipc->buf_sem);
215
216 return tx_bufsiz;
217}
218
219static size_t put_ipc_rx_buf(struct baseband_ipc *ipc,
220 const void *buf, size_t bufsiz)
221{
222 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
223 size_t rx_bufsiz;
224
225 pr_debug("put_ipc_rx_buf\n");
226
227 /* check input */
228 if (!ipc || !buf) {
229 pr_err("!ipc || !buf\n");
230 return 0;
231 }
232 if (!bufsiz)
233 return 0;
234
235 /* acquire rx buffer semaphores */
236retry:
237 if (down_interruptible(&ipc->buf_sem)) {
238 pr_err("put_ipc_rx_buf - "
239 "cannot acquire buffer semaphore\n");
240 return -ERESTARTSYS;
241 }
242
243 /* put rx data in rx linked list */
244 rx_bufsiz = 0;
245 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list)
246 {
247 pr_debug("put_ipc_rx_buf - "
248 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
249 ipc_buf, ipc_buf->offset, ipc_buf->count);
250 if (sizeof(ipc_buf->data) > bufsiz - rx_bufsiz) {
251 /* partially fill rx free buffer */
252 memcpy(ipc_buf->data,
253 buf + rx_bufsiz,
254 bufsiz - rx_bufsiz);
255 ipc_buf->offset = 0;
256 ipc_buf->count = bufsiz - rx_bufsiz;
257 rx_bufsiz = bufsiz;
258 } else {
259 /* fill entire rx free buffer */
260 memcpy(ipc_buf->data,
261 buf + rx_bufsiz,
262 sizeof(ipc_buf->data));
263 ipc_buf->offset = 0;
264 ipc_buf->count = sizeof(ipc_buf->data);
265 rx_bufsiz += sizeof(ipc_buf->data);
266 }
267 /* add filled rx free buffer to rx linked list */
268 list_move_tail(&ipc_buf->list, &ipc->rx.buf);
269 wake_up(&ipc->rx.wait);
270 /* check if done */
271 if (rx_bufsiz == bufsiz)
272 break;
273 }
274
275 /* release rx buffer semaphores */
276 up(&ipc->buf_sem);
277
278 /* wait for rx free buffer available */
279 if (!rx_bufsiz) {
280 if (wait_event_interruptible(ipc->rx_free.wait,
281 !list_empty(&ipc->rx_free.buf))) {
282 pr_err("put_ipc_rx_buf - "
283 "interrupted wait\n");
284 return -ERESTARTSYS;
285 }
286 goto retry;
287 }
288
289 return rx_bufsiz;
290
291}
292
293static ssize_t baseband_ipc_file_read(struct baseband_ipc *ipc,
294 struct file *file, char *buf, size_t count, loff_t *pos)
295{
296 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
297 size_t read_count;
298
299 pr_debug("baseband_ipc_file_read\n");
300
301 /* check input */
302 if (!ipc) {
303 pr_err("!ipc\n");
304 return -EIO;
305 }
306
307 /* acquire rx buffer semaphores */
308retry:
309 if (down_interruptible(&ipc->buf_sem)) {
310 pr_err("baseband_ipc_file_read - "
311 "cannot acquire buffer semaphore\n");
312 return -ERESTARTSYS;
313 }
314
315 /* get read data from rx linked list */
316 read_count = 0;
317 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list)
318 {
319 pr_debug("baseband_ipc_file_read - "
320 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
321 ipc_buf, ipc_buf->offset, ipc_buf->count);
322 pr_debug("baseband_ipc_file_read - "
323 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
324 ipc_buf->data[0],
325 ipc_buf->data[1],
326 ipc_buf->data[2],
327 ipc_buf->data[3]);
328 if (ipc_buf->count > count - read_count) {
329 /* copy part of rx buffer */
330 if (copy_to_user(buf + read_count,
331 ipc_buf->data + ipc_buf->offset,
332 count - read_count)) {
333 pr_err("copy_to_user failed\n");
334 up(&ipc->buf_sem);
335 return -EFAULT;
336 }
337 ipc_buf->offset += count - read_count;
338 ipc_buf->count -= count - read_count;
339 read_count = count;
340 } else {
341 /* copy all data from rx buffer */
342 if (copy_to_user(buf + read_count,
343 ipc_buf->data + ipc_buf->offset,
344 ipc_buf->count)) {
345 pr_err("copy_to_user failed\n");
346 up(&ipc->buf_sem);
347 return -EFAULT;
348 }
349 read_count += ipc_buf->count;
350 ipc_buf->offset = 0;
351 ipc_buf->count = 0;
352 /* add rx buffer to rx free list */
353 list_move_tail(&ipc_buf->list, &ipc->rx_free.buf);
354 wake_up(&ipc->rx_free.wait);
355 }
356 /* check if done */
357 if (read_count == count)
358 break;
359 }
360
361 /* release rx buffer semaphores */
362 up(&ipc->buf_sem);
363
364 /* wait for rx buffer available */
365 if (!read_count) {
366 if (wait_event_interruptible(ipc->rx.wait,
367 !list_empty(&ipc->rx.buf))) {
368 pr_err("baseband_ipc_file_read - "
369 "interrupted wait\n");
370 return -ERESTARTSYS;
371 }
372 goto retry;
373 }
374
375 return read_count;
376}
377
378static ssize_t baseband_ipc_file_write(struct baseband_ipc *ipc,
379 struct file *file, const char *buf, size_t count, loff_t *pos)
380{
381 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
382 size_t write_count;
383
384 pr_debug("baseband_ipc_file_write\n");
385
386 /* check input */
387 if (!ipc) {
388 pr_err("!ipc\n");
389 return -EIO;
390 }
391
392 /* acquire tx buffer semaphores */
393retry:
394 if (down_interruptible(&ipc->buf_sem)) {
395 pr_err("baseband_ipc_file_write - "
396 "cannot acquire buffer semaphore\n");
397 return -ERESTARTSYS;
398 }
399
400 /* put write data in tx linked list */
401 write_count = 0;
402 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list)
403 {
404 pr_debug("baseband_ipc_file_write - "
405 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
406 ipc_buf, ipc_buf->offset, ipc_buf->count);
407 if (sizeof(ipc_buf->data) > count - write_count) {
408 /* partially fill tx free buffer */
409 if (copy_from_user(ipc_buf->data,
410 buf + write_count,
411 count - write_count)) {
412 pr_err("copy_from_user failed\n");
413 up(&ipc->buf_sem);
414 return -EFAULT;
415 }
416 ipc_buf->offset = 0;
417 ipc_buf->count = count - write_count;
418 write_count = count;
419 } else {
420 /* fill entire tx free buffer */
421 if (copy_from_user(ipc_buf->data,
422 buf + write_count,
423 sizeof(ipc_buf->data))) {
424 pr_err("copy_from_user failed\n");
425 up(&ipc->buf_sem);
426 return -EFAULT;
427 }
428 ipc_buf->offset = 0;
429 ipc_buf->count = sizeof(ipc_buf->data);
430 write_count += sizeof(ipc_buf->data);
431 }
432 /* add filled tx free buffer to tx linked list */
433 pr_debug("baseband_ipc_file_write - "
434 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
435 ipc_buf->data[0],
436 ipc_buf->data[1],
437 ipc_buf->data[2],
438 ipc_buf->data[3]);
439 list_move_tail(&ipc_buf->list, &ipc->tx.buf);
440 wake_up(&ipc->tx.wait);
441 /* check if done */
442 if (write_count == count)
443 break;
444 }
445
446 /* release tx buffer semaphores */
447 up(&ipc->buf_sem);
448
449 /* wait for tx buffer available */
450 if (!write_count) {
451 if (wait_event_interruptible(ipc->tx_free.wait,
452 !list_empty(&ipc->tx_free.buf))) {
453 pr_err("baseband_ipc_file_write - "
454 "interrupted wait\n");
455 return -ERESTARTSYS;
456 }
457 goto retry;
458 }
459
460 /* queue ipc transaction work */
461 queue_work(ipc->workqueue, &ipc->work);
462
463 return write_count;
464}
465
466static void baseband_ipc_close(struct baseband_ipc *ipc)
467{
468 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
469
470 pr_debug("baseband_ipc_close {\n");
471
472 /* check input */
473 if (!ipc)
474 return;
475
476 /* destroy work queue */
477 if (ipc->workqueue) {
478 pr_debug("destroy workqueue {\n");
479 cancel_work_sync(&ipc->work);
480 destroy_workqueue(ipc->workqueue);
481 ipc->workqueue = (struct workqueue_struct *) 0;
482 pr_debug("destroy workqueue }\n");
483 }
484 memset(&ipc->work, 0, sizeof(ipc->work));
485
486 /* destroy wait queues */
487 memset(&ipc->tx_free.wait, 0, sizeof(ipc->tx_free.wait));
488 memset(&ipc->rx_free.wait, 0, sizeof(ipc->rx_free.wait));
489 memset(&ipc->tx.wait, 0, sizeof(ipc->tx.wait));
490 memset(&ipc->rx.wait, 0, sizeof(ipc->rx.wait));
491
492 /* destroy data buffers */
493 kfree(ipc->ipc_tx);
494 ipc->ipc_tx = (unsigned char *) 0;
495 kfree(ipc->ipc_rx);
496 ipc->ipc_rx = (unsigned char *) 0;
497 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list)
498 {
499 kfree(ipc_buf);
500 }
501 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list)
502 {
503 kfree(ipc_buf);
504 }
505 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
506 {
507 kfree(ipc_buf);
508 }
509 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list)
510 {
511 kfree(ipc_buf);
512 }
513
514 /* destroy semaphores */
515 memset(&ipc->buf_sem, 0, sizeof(ipc->buf_sem));
516
517 /* free baseband ipc structure */
518 kfree(ipc);
519
520 pr_debug("baseband_ipc_close }\n");
521}
522
523static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
524 work_func_t rx_work_func,
525 work_func_t tx_work_func)
526{
527 struct baseband_ipc *ipc;
528 struct baseband_ipc_buf *ipc_buf;
529 int i;
530
531 pr_debug("baseband_ipc_open {\n");
532
533 /* allocate baseband ipc structure */
534 ipc = kzalloc(sizeof(struct baseband_ipc), GFP_KERNEL);
535 if (!ipc)
536 return (struct baseband_ipc *) 0;
537
538 /* create semaphores */
539 sema_init(&ipc->buf_sem, 1);
540
541 /* create data buffers */
542 INIT_LIST_HEAD(&ipc->rx.buf);
543 INIT_LIST_HEAD(&ipc->tx.buf);
544 INIT_LIST_HEAD(&ipc->rx_free.buf);
545 INIT_LIST_HEAD(&ipc->tx_free.buf);
546 for (i = 0; i < BASEBAND_IPC_NUM_RX_BUF; i++) {
547 ipc_buf = (struct baseband_ipc_buf *)
548 kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
549 if (!ipc_buf) {
550 pr_err("cannot allocate baseband ipc rx buffer #%d\n",
551 i);
552 goto error_exit;
553 }
554 pr_debug("baseband_ipc_open - "
555 "rx_free: ipc_buf %p\n",
556 ipc_buf);
557 list_add_tail(&ipc_buf->list, &ipc->rx_free.buf);
558 }
559 for (i = 0; i < BASEBAND_IPC_NUM_TX_BUF; i++) {
560 ipc_buf = (struct baseband_ipc_buf *)
561 kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
562 if (!ipc_buf) {
563 pr_err("cannot allocate baseband ipc tx buffer #%d\n",
564 i);
565 goto error_exit;
566 }
567 pr_debug("baseband_ipc_open - "
568 "tx_free: ipc_buf %p\n",
569 ipc_buf);
570 list_add_tail(&ipc_buf->list, &ipc->tx_free.buf);
571 }
572 ipc->ipc_rx = (unsigned char *) 0;
573 ipc->ipc_tx = (unsigned char *) 0;
574
575 /* create wait queues */
576 init_waitqueue_head(&ipc->rx.wait);
577 init_waitqueue_head(&ipc->tx.wait);
578 init_waitqueue_head(&ipc->rx_free.wait);
579 init_waitqueue_head(&ipc->tx_free.wait);
580
581 /* create work queue */
582 ipc->workqueue = create_singlethread_workqueue
583 ("baseband_usb_chr_ipc_workqueue");
584 if (!ipc->workqueue) {
585 pr_err("cannot create workqueue\n");
586 goto error_exit;
587 }
588 if (work_func)
589 INIT_WORK(&ipc->work, work_func);
590 if (rx_work_func)
591 INIT_WORK(&ipc->rx_work, rx_work_func);
592 if (tx_work_func)
593 INIT_WORK(&ipc->tx_work, tx_work_func);
594
595 pr_debug("baseband_ipc_open }\n");
596 return ipc;
597
598error_exit:
599 baseband_ipc_close(ipc);
600 return (struct baseband_ipc *) 0;
601}
602
603/* usb rx */
604
605static void baseband_usb_chr_rx_urb_comp(struct urb *urb)
606{
607 struct baseband_usb *usb = (struct baseband_usb *) urb->context;
608
609 pr_debug("baseband_usb_chr_rx_urb_comp { urb %p\n", urb);
610
611 /* queue rx urb completion work */
612 queue_work(usb->ipc->workqueue, &usb->ipc->rx_work);
613
614 pr_debug("baseband_usb_chr_rx_urb_comp }\n");
615}
616
617static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb)
618{
619 struct urb *urb;
620 void *buf;
621 int err;
622
623 pr_debug("baseband_usb_chr_rx_urb_submit { usb %p\n", usb);
624
625 if (!usb_device_connection) {
626 pr_err("!!no usb device conenction!!!!!\n");
627 return -1;
628 }
629
630 /* check input */
631 if (usb->usb.rx_urb) {
632 pr_err("previous urb still active\n");
633 return -1;
634 }
635
636 /* allocate rx urb */
637 urb = usb_alloc_urb(0, GFP_ATOMIC);
638 if (!urb) {
639 pr_err("usb_alloc_urb() failed\n");
640 return -ENOMEM;
641 }
642 buf = kzalloc(USB_CHR_RX_BUFSIZ, GFP_ATOMIC);
643 if (!buf) {
644 pr_err("usb buffer kzalloc() failed\n");
645 usb_free_urb(urb);
646 return -ENOMEM;
647 }
648 usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.in,
649 buf, USB_CHR_RX_BUFSIZ,
650 baseband_usb_chr_rx_urb_comp,
651 usb);
652 urb->transfer_flags = 0;
653
654 /* submit rx urb */
655 usb->usb.rx_urb = urb;
656 err = usb_submit_urb(urb, GFP_ATOMIC);
657 if (err < 0) {
658 pr_err("usb_submit_urb() failed - err %d\n", err);
659 usb->usb.rx_urb = (struct urb *) 0;
660 kfree(urb->transfer_buffer);
661 usb_free_urb(urb);
662 return err;
663 }
664
665 pr_debug("baseband_usb_chr_rx_urb_submit }\n");
666 return err;
667}
668
669static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work)
670{
671 struct baseband_usb *usb = baseband_usb_chr;
672 struct urb *urb = usb->usb.rx_urb;
673 size_t len;
674
675 pr_debug("baseband_usb_chr_rx_urb_comp_work { work %p\n", work);
676
677 /* put rx urb data in rx buffer */
678 if (urb->actual_length) {
679 pr_debug("baseband_usb_chr_rx_urb_comp_work - "
680 "urb->actual_length %d\n", urb->actual_length);
681 len = put_ipc_rx_buf(usb->ipc,
682 urb->transfer_buffer, urb->actual_length);
683 baseband_ipc_dump("baseband_usb_chr_rx_urb_comp_work"
684 " - rx buf ", 0,
685 urb->transfer_buffer, len > 16 ? 16 : len);
686 if (len != urb->actual_length) {
687 pr_err("baseband_usb_chr_rx_urb_comp_work - "
688 "put_ipx_rx_buf() only put %d/%d bytes\n",
689 len, urb->actual_length);
690 }
691 /* increment count of available rx bytes */
692 atomic_add(len, &g_rx_count);
693 }
694
695 /* free rx urb */
696 kfree(urb->transfer_buffer);
697 urb->transfer_buffer = (void *) 0;
698 usb_free_urb(urb);
699 usb->usb.rx_urb = (struct urb *) 0;
700
701 /* submit next rx urb */
702 baseband_usb_chr_rx_urb_submit(usb);
703
704 pr_debug("baseband_usb_chr_rx_urb_comp_work }\n");
705}
706
707/* usb functions */
708
709static void find_usb_pipe(struct baseband_usb *usb)
710{
711 struct usb_device *usbdev = usb->usb.device;
712 struct usb_interface *intf = usb->usb.interface;
713 unsigned char numendpoint = intf->cur_altsetting->desc.bNumEndpoints;
714 struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint;
715 unsigned char n;
716
717 for (n = 0; n < numendpoint; n++) {
718 if (usb_endpoint_is_isoc_in(&endpoint[n].desc)) {
719 pr_debug("endpoint[%d] isochronous in\n", n);
720 usb->usb.pipe.isoch.in = usb_rcvisocpipe(usbdev,
721 endpoint[n].desc.bEndpointAddress);
722 } else if (usb_endpoint_is_isoc_out(&endpoint[n].desc)) {
723 pr_debug("endpoint[%d] isochronous out\n", n);
724 usb->usb.pipe.isoch.out = usb_sndisocpipe(usbdev,
725 endpoint[n].desc.bEndpointAddress);
726 } else if (usb_endpoint_is_bulk_in(&endpoint[n].desc)) {
727 pr_debug("endpoint[%d] bulk in\n", n);
728 usb->usb.pipe.bulk.in = usb_rcvbulkpipe(usbdev,
729 endpoint[n].desc.bEndpointAddress);
730 } else if (usb_endpoint_is_bulk_out(&endpoint[n].desc)) {
731 pr_debug("endpoint[%d] bulk out\n", n);
732 usb->usb.pipe.bulk.out = usb_sndbulkpipe(usbdev,
733 endpoint[n].desc.bEndpointAddress);
734 } else if (usb_endpoint_is_int_in(&endpoint[n].desc)) {
735 pr_debug("endpoint[%d] interrupt in\n", n);
736 usb->usb.pipe.interrupt.in = usb_rcvintpipe(usbdev,
737 endpoint[n].desc.bEndpointAddress);
738 } else if (usb_endpoint_is_int_out(&endpoint[n].desc)) {
739 pr_debug("endpoint[%d] interrupt out\n", n);
740 usb->usb.pipe.interrupt.out = usb_sndintpipe(usbdev,
741 endpoint[n].desc.bEndpointAddress);
742 } else {
743 pr_debug("endpoint[%d] skipped\n", n);
744 }
745 }
746}
747
748static int baseband_usb_driver_probe(struct usb_interface *intf,
749 const struct usb_device_id *id)
750{
751 int err;
752
753 pr_debug("%s(%d) { intf %p id %p\n", __func__, __LINE__, intf, id);
754
755 pr_debug("intf->cur_altsetting->desc.bInterfaceNumber %02x\n",
756 intf->cur_altsetting->desc.bInterfaceNumber);
757 pr_debug("intf->cur_altsetting->desc.bAlternateSetting %02x\n",
758 intf->cur_altsetting->desc.bAlternateSetting);
759 pr_debug("intf->cur_altsetting->desc.bNumEndpoints %02x\n",
760 intf->cur_altsetting->desc.bNumEndpoints);
761 pr_debug("intf->cur_altsetting->desc.bInterfaceClass %02x\n",
762 intf->cur_altsetting->desc.bInterfaceClass);
763 pr_debug("intf->cur_altsetting->desc.bInterfaceSubClass %02x\n",
764 intf->cur_altsetting->desc.bInterfaceSubClass);
765 pr_debug("intf->cur_altsetting->desc.bInterfaceProtocol %02x\n",
766 intf->cur_altsetting->desc.bInterfaceProtocol);
767 pr_debug("intf->cur_altsetting->desc.iInterface %02x\n",
768 intf->cur_altsetting->desc.iInterface);
769
770 /* usb interface mismatch */
771 if (baseband_usb_chr_intf !=
772 intf->cur_altsetting->desc.bInterfaceNumber) {
773 pr_debug("%s(%d) } -ENODEV\n", __func__, __LINE__);
774 return -ENODEV;
775 }
776
777 /* usb interface match */
778 baseband_usb_chr->usb.device = interface_to_usbdev(intf);
779 baseband_usb_chr->usb.interface = intf;
780 find_usb_pipe(baseband_usb_chr);
781 baseband_usb_chr->usb.rx_urb = (struct urb *) 0;
782 baseband_usb_chr->usb.tx_urb = (struct urb *) 0;
783 pr_debug("baseband_usb_chr->usb.driver->name %s\n",
784 baseband_usb_chr->usb.driver->name);
785 pr_debug("baseband_usb_chr->usb.device %p\n",
786 baseband_usb_chr->usb.device);
787 pr_debug("baseband_usb_chr->usb.interface %p\n",
788 baseband_usb_chr->usb.interface);
789 pr_debug("baseband_usb_chr->usb.pipe.isoch.in %x\n",
790 baseband_usb_chr->usb.pipe.isoch.in);
791 pr_debug("baseband_usb_chr->usb.pipe.isoch.out %x\n",
792 baseband_usb_chr->usb.pipe.isoch.out);
793 pr_debug("baseband_usb_chr->usb.pipe.bulk.in %x\n",
794 baseband_usb_chr->usb.pipe.bulk.in);
795 pr_debug("baseband_usb_chr->usb.pipe.bulk.out %x\n",
796 baseband_usb_chr->usb.pipe.bulk.out);
797 pr_debug("baseband_usb_chr->usb.pipe.interrupt.in %x\n",
798 baseband_usb_chr->usb.pipe.interrupt.in);
799 pr_debug("baseband_usb_chr->usb.pipe.interrupt.out %x\n",
800 baseband_usb_chr->usb.pipe.interrupt.out);
801 usb_device_connection = true;
802
803 /* start usb rx */
804 err = baseband_usb_chr_rx_urb_submit(baseband_usb_chr);
805 if (err < 0) {
806 pr_err("submit rx failed - err %d\n", err);
807 return -ENODEV;
808 }
809
810 pr_debug("%s(%d) }\n", __func__, __LINE__);
811 return 0;
812}
813
814static void baseband_usb_driver_disconnect(struct usb_interface *intf)
815{
816 struct usb_device *usb_dev = interface_to_usbdev(intf);
817 pr_debug("%s(%d) { intf %p\n", __func__, __LINE__, intf);
818 pr_debug("%s(%d) }\n", __func__, __LINE__);
819 if (baseband_usb_chr->usb.interface != intf) {
820 pr_info("%s(%d) -ENODEV\n", __func__, __LINE__);
821 return;
822 }
823 if (baseband_usb_chr->usb.device == usb_dev) {
824 pr_info("%s: Matching usb device: Flush workqueue\n", __func__);
825 flush_workqueue(baseband_usb_chr->ipc->workqueue);
826 usb_device_connection = false;
827 }
828
829}
830
831static char baseband_usb_driver_name[32];
832
833static struct usb_device_id baseband_usb_driver_id_table[2];
834
835static struct usb_driver baseband_usb_driver = {
836 .name = baseband_usb_driver_name,
837 .probe = baseband_usb_driver_probe,
838 .disconnect = baseband_usb_driver_disconnect,
839 .id_table = baseband_usb_driver_id_table,
840};
841
842static void baseband_usb_chr_work(struct work_struct *work)
843{
844 struct baseband_usb *usb = baseband_usb_chr;
845 struct {
846 unsigned char *buf;
847 unsigned int bufsiz_byte;
848 } rx, tx;
849 int ipc_tx_byte;
850 int err;
851
852 pr_debug("baseband_usb_chr_work {\n");
853
854 /* check input */
855 if (!usb || !usb->ipc) {
856 pr_err("baseband_usb_chr_work - "
857 "usb not open\n");
858 return;
859 }
860 if (!usb->usb.device) {
861 pr_err("baseband_usb_chr_work - "
862 "usb device not probed yet\n");
863 mdelay(10);
864 queue_work(usb->ipc->workqueue, &usb->ipc->work);
865 return;
866 }
867
868 /* allocate buffers on first transaction (will be freed on close) */
869 if (!usb->ipc->ipc_rx) {
870 usb->ipc->ipc_rx = kzalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
871 if (!usb->ipc->ipc_rx) {
872 pr_err("baseband_usb_chr_work - "
873 "cannot allocate usb->ipc->ipc_rx\n");
874 return;
875 }
876 }
877 if (!usb->ipc->ipc_tx) {
878 usb->ipc->ipc_tx = kzalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
879 if (!usb->ipc->ipc_tx) {
880 pr_err("baseband_usb_chr_work - "
881 "cannot allocate usb->ipc->ipc_tx\n");
882 return;
883 }
884 }
885
886 /* usb transaction loop */
887 rx.buf = usb->ipc->ipc_rx;
888 tx.buf = usb->ipc->ipc_tx;
889 while ((tx.bufsiz_byte = peek_ipc_tx_bufsiz(usb->ipc,
890 USB_CHR_TX_BUFSIZ)) != 0) {
891 get_ipc_tx_buf(usb->ipc, tx.buf, tx.bufsiz_byte);
892 err = usb_bulk_msg(usb->usb.device, usb->usb.pipe.bulk.out,
893 tx.buf, tx.bufsiz_byte, &ipc_tx_byte, USB_CHR_TIMEOUT);
894 if (err < 0) {
895 pr_err("baseband_usb_chr_work - "
896 "usb_bulk_msg err %d\n", err);
897 continue;
898 }
899 if (tx.bufsiz_byte != ipc_tx_byte) {
900 pr_err("tx.bufsiz_byte %d != ipc_tx_byte %d\n",
901 tx.bufsiz_byte, ipc_tx_byte);
902 continue;
903 }
904 }
905
906 pr_debug("baseband_usb_chr_work }\n");
907}
908
909/* usb character file operations */
910
911static int baseband_usb_chr_open(struct inode *inode, struct file *file)
912{
913 pr_debug("baseband_usb_chr_open\n");
914 return 0;
915}
916
917static int baseband_usb_chr_release(struct inode *inode, struct file *file)
918{
919 pr_debug("baseband_usb_chr_release\n");
920 return 0;
921}
922
923static ssize_t baseband_usb_chr_read(struct file *file, char *buf,
924 size_t count, loff_t *pos)
925{
926 ssize_t ret;
927
928 pr_debug("baseband_usb_chr_read\n");
929
930 ret = baseband_ipc_file_read(baseband_usb_chr->ipc,
931 file, buf, count, pos);
932 if (ret > 0) {
933 /* decrement count of available rx bytes */
934 int val = atomic_read(&g_rx_count);
935 pr_debug("baseband_usb_chr_read - read %d unread %d\n",
936 ret, val - ret);
937 atomic_sub(ret, &g_rx_count);
938 }
939 return ret;
940}
941
942static ssize_t baseband_usb_chr_write(struct file *file, const char *buf,
943 size_t count, loff_t *pos)
944{
945 pr_debug("baseband_usb_chr_write\n");
946 return baseband_ipc_file_write(baseband_usb_chr->ipc,
947 file, buf, count, pos);
948}
949
950static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd,
951 unsigned long arg)
952{
953 pr_debug("baseband_usb_chr_ioctl\n");
954 switch (cmd) {
955 case TCFLSH:
956 pr_debug("TCFLSH\n");
957 /* flush queued ipc transaction work */
958 flush_workqueue(baseband_usb_chr->ipc->workqueue);
959 return 0;
960 case FIONREAD:
961 pr_debug("FIONREAD\n");
962 /* return count of available rx bytes */
963 {
964 int __user *p = (int __user *) arg;
965 int val = atomic_read(&g_rx_count);
966 if (put_user(val, p))
967 break;
968 }
969 return 0;
970 default:
971 pr_err("unsupported ioctl cmd %x\n", cmd);
972 }
973 return -ENODEV;
974}
975
976static const struct file_operations baseband_usb_chr_fops = {
977 .open = baseband_usb_chr_open,
978 .release = baseband_usb_chr_release,
979 .read = baseband_usb_chr_read,
980 .write = baseband_usb_chr_write,
981 .unlocked_ioctl = baseband_usb_chr_ioctl,
982};
983
984/* usb device driver functions */
985
986static void baseband_usb_close(struct baseband_usb *usb)
987{
988 pr_debug("baseband_usb_close {\n");
989
990 /* check input */
991 if (!usb)
992 return;
993
994 /* close usb driver */
995 if (usb->usb.driver) {
996 pr_debug("close usb driver {\n");
997 usb_deregister(usb->usb.driver);
998 usb->usb.driver = (struct usb_driver *) 0;
999 pr_debug("close usb driver }\n");
1000 }
1001
1002 /* close baseband ipc */
1003 if (usb->ipc) {
1004 baseband_ipc_close(usb->ipc);
1005 usb->ipc = (struct baseband_ipc *) 0;
1006 }
1007
1008 /* free baseband usb structure */
1009 kfree(usb);
1010
1011 pr_debug("baseband_usb_close }\n");
1012}
1013
1014static struct baseband_usb *baseband_usb_open(unsigned int vid,
1015 unsigned int pid,
1016 unsigned int intf,
1017 work_func_t work_func,
1018 work_func_t rx_work_func,
1019 work_func_t tx_work_func)
1020{
1021 struct baseband_usb *usb;
1022 int err;
1023
1024 pr_debug("baseband_usb_open {\n");
1025
1026 /* allocate baseband usb structure */
1027 usb = kzalloc(sizeof(struct baseband_usb), GFP_KERNEL);
1028 if (!usb)
1029 return (struct baseband_usb *) 0;
1030 baseband_usb_chr = usb;
1031
1032 /* open baseband ipc */
1033 usb->ipc = baseband_ipc_open(work_func,
1034 rx_work_func,
1035 tx_work_func);
1036 if (!usb->ipc) {
1037 pr_err("open baseband ipc failed\n");
1038 goto error_exit;
1039 }
1040
1041 /* open usb driver */
1042 sprintf(baseband_usb_driver_name,
1043 "baseband_usb_%x_%x_%x",
1044 vid, pid, intf);
1045 baseband_usb_driver_id_table[0].match_flags
1046 = USB_DEVICE_ID_MATCH_DEVICE;
1047 baseband_usb_driver_id_table[0].idVendor = vid;
1048 baseband_usb_driver_id_table[0].idProduct = pid;
1049 usb->usb.driver = &baseband_usb_driver;
1050 err = usb_register(&baseband_usb_driver);
1051 if (err < 0) {
1052 pr_err("cannot open usb driver - err %d\n", err);
1053 goto error_exit;
1054 }
1055
1056 pr_debug("baseband_usb_open }\n");
1057 return usb;
1058
1059error_exit:
1060 baseband_usb_close(usb);
1061 baseband_usb_chr = (struct baseband_usb *) 0;
1062 return (struct baseband_usb *) 0;
1063}
1064
1065/* module init / exit functions */
1066
1067static int baseband_usb_chr_init(void)
1068{
1069 int err;
1070
1071 pr_debug("baseband_usb_chr_init {\n");
1072
1073 /* open baseband usb */
1074 baseband_usb_chr = baseband_usb_open
1075 (baseband_usb_chr_vid,
1076 baseband_usb_chr_pid,
1077 baseband_usb_chr_intf,
1078 baseband_usb_chr_work,
1079 baseband_usb_chr_rx_urb_comp_work,
1080 (work_func_t) 0);
1081 if (!baseband_usb_chr) {
1082 pr_err("cannot open baseband usb chr\n");
1083 err = -1;
1084 goto err1;
1085 }
1086
1087 /* register character device */
1088 err = register_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
1089 BASEBAND_USB_CHR_DEV_NAME,
1090 &baseband_usb_chr_fops);
1091 if (err < 0) {
1092 pr_err("cannot register character device - %d\n", err);
1093 goto err2;
1094 }
1095 pr_debug("registered baseband usb character device - major %d\n",
1096 BASEBAND_USB_CHR_DEV_MAJOR);
1097
1098 pr_debug("baseband_usb_chr_init }\n");
1099 return 0;
1100err2: baseband_usb_close(baseband_usb_chr);
1101 baseband_usb_chr = (struct baseband_usb *) 0;
1102err1: return err;
1103}
1104
1105static void baseband_usb_chr_exit(void)
1106{
1107 pr_debug("baseband_usb_chr_exit {\n");
1108
1109 /* unregister character device */
1110 unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
1111 BASEBAND_USB_CHR_DEV_NAME);
1112
1113 /* close baseband usb */
1114 if (baseband_usb_chr) {
1115 baseband_usb_close(baseband_usb_chr);
1116 baseband_usb_chr = (struct baseband_usb *) 0;
1117 }
1118
1119 pr_debug("baseband_usb_chr_exit }\n");
1120}
1121
1122module_init(baseband_usb_chr_init)
1123module_exit(baseband_usb_chr_exit)
1124
diff --git a/drivers/usb/serial/baseband_usb_chr.h b/drivers/usb/serial/baseband_usb_chr.h
new file mode 100644
index 00000000000..7935e795a54
--- /dev/null
+++ b/drivers/usb/serial/baseband_usb_chr.h
@@ -0,0 +1,106 @@
1/*
2 * baseband_usb_chr.h
3 *
4 * USB character driver to communicate with baseband modems.
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef __BASEBAND_USB_CHR_H__
24#define __BASEBAND_USB_CHR_H__
25
26#define BASEBAND_USB_CHR_DEV_NAME "baseband_usb_chr"
27#define BASEBAND_USB_CHR_DEV_MAJOR 66
28
29#ifndef USB_CHR_RX_BUFSIZ
30#define USB_CHR_RX_BUFSIZ (128*1024)
31#endif /* USB_CHR_RX_BUFSIZ */
32
33#ifndef USB_CHR_TX_BUFSIZ
34#define USB_CHR_TX_BUFSIZ (128*1024)
35#endif /* USB_CHR_TX_BUFSIZ */
36
37#ifndef USB_CHR_TIMEOUT
38#define USB_CHR_TIMEOUT 5000 /* ms */
39#endif /* USB_CHR_TIMEOUT */
40
41#ifndef BASEBAND_IPC_NUM_RX_BUF
42#define BASEBAND_IPC_NUM_RX_BUF 32
43#endif /* BASEBAND_IPC_NUM_RX_BUF */
44
45#ifndef BASEBAND_IPC_NUM_TX_BUF
46#define BASEBAND_IPC_NUM_TX_BUF 16
47#endif /* BASEBAND_IPC_NUM_TX_BUF */
48
49#ifndef BASEBAND_IPC_BUFSIZ
50#define BASEBAND_IPC_BUFSIZ 65536
51#endif /* BASEBAND_IPC_BUFSIZ */
52
53struct baseband_ipc {
54 /* rx / tx data */
55 struct semaphore buf_sem;
56 struct {
57 /* linked list of data buffers */
58 struct list_head buf;
59 /* wait queue of processes trying to access data buffers */
60 wait_queue_head_t wait;
61 } rx, tx, rx_free, tx_free;
62 unsigned char *ipc_rx;
63 unsigned char *ipc_tx;
64 /* work queue
65 * - queued per ipc transaction
66 * - initiated by either:
67 * = interrupt on gpio line (rx data available)
68 * = tx data packet being added to tx linked list
69 */
70 struct workqueue_struct *workqueue;
71 struct work_struct work;
72 struct work_struct rx_work;
73 struct work_struct tx_work;
74};
75
76struct baseband_ipc_buf {
77 struct list_head list;
78 /* data buffer */
79 unsigned char data[BASEBAND_IPC_BUFSIZ];
80 /* offset of first data byte */
81 size_t offset;
82 /* number of valid data bytes */
83 size_t count;
84};
85
86struct baseband_usb {
87 struct baseband_ipc *ipc;
88 struct {
89 struct usb_driver *driver;
90 struct usb_device *device;
91 struct usb_interface *interface;
92 struct {
93 struct {
94 unsigned int in;
95 unsigned int out;
96 } isoch, bulk, interrupt;
97 } pipe;
98 /* currently active rx urb */
99 struct urb *rx_urb;
100 /* currently active tx urb */
101 struct urb *tx_urb;
102 } usb;
103};
104
105#endif /* __BASEBAND_USB_CHR_H__ */
106
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
new file mode 100644
index 00000000000..3cfc762f505
--- /dev/null
+++ b/drivers/usb/serial/ezusb.c
@@ -0,0 +1,61 @@
1/*
2 * EZ-USB specific functions used by some of the USB to Serial drivers.
3 *
4 * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/tty.h>
16#include <linux/module.h>
17#include <linux/usb.h>
18#include <linux/usb/serial.h>
19
20/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
21#define CPUCS_REG 0x7F92
22
23int ezusb_writememory(struct usb_serial *serial, int address,
24 unsigned char *data, int length, __u8 request)
25{
26 int result;
27 unsigned char *transfer_buffer;
28
29 /* dbg("ezusb_writememory %x, %d", address, length); */
30 if (!serial->dev) {
31 printk(KERN_ERR "ezusb: %s - no physical device present, "
32 "failing.\n", __func__);
33 return -ENODEV;
34 }
35
36 transfer_buffer = kmemdup(data, length, GFP_KERNEL);
37 if (!transfer_buffer) {
38 dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
39 __func__, length);
40 return -ENOMEM;
41 }
42 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
43 request, 0x40, address, 0, transfer_buffer, length, 3000);
44 kfree(transfer_buffer);
45 return result;
46}
47EXPORT_SYMBOL_GPL(ezusb_writememory);
48
49int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit)
50{
51 int response;
52
53 /* dbg("%s - %d", __func__, reset_bit); */
54 response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
55 if (response < 0)
56 dev_err(&serial->dev->dev, "%s- %d failed\n",
57 __func__, reset_bit);
58 return response;
59}
60EXPORT_SYMBOL_GPL(ezusb_set_reset);
61