Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * USB Serial Converter Generic functions | |
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 | ||
1da177e4 LT |
12 | #include <linux/kernel.h> |
13 | #include <linux/errno.h> | |
14 | #include <linux/slab.h> | |
15 | #include <linux/tty.h> | |
16 | #include <linux/tty_flip.h> | |
17 | #include <linux/module.h> | |
18 | #include <linux/moduleparam.h> | |
19 | #include <linux/usb.h> | |
a969888c | 20 | #include <linux/usb/serial.h> |
1da177e4 | 21 | #include <asm/uaccess.h> |
1da177e4 | 22 | |
d9b1b787 | 23 | |
1da177e4 LT |
24 | static int debug; |
25 | ||
26 | #ifdef CONFIG_USB_SERIAL_GENERIC | |
b46d60fc DB |
27 | |
28 | static int generic_probe(struct usb_interface *interface, | |
29 | const struct usb_device_id *id); | |
30 | ||
1da177e4 LT |
31 | static __u16 vendor = 0x05f9; |
32 | static __u16 product = 0xffff; | |
33 | ||
34 | module_param(vendor, ushort, 0); | |
35 | MODULE_PARM_DESC(vendor, "User specified USB idVendor"); | |
36 | ||
37 | module_param(product, ushort, 0); | |
38 | MODULE_PARM_DESC(product, "User specified USB idProduct"); | |
39 | ||
40 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | |
41 | ||
d9b1b787 JH |
42 | /* we want to look at all devices, as the vendor/product id can change |
43 | * depending on the command line argument */ | |
44 | static struct usb_device_id generic_serial_ids[] = { | |
45 | {.driver_info = 42}, | |
46 | {} | |
47 | }; | |
48 | ||
49 | static struct usb_driver generic_driver = { | |
50 | .name = "usbserial_generic", | |
51 | .probe = generic_probe, | |
52 | .disconnect = usb_serial_disconnect, | |
53 | .id_table = generic_serial_ids, | |
54 | .no_dynamic_id = 1, | |
55 | }; | |
56 | ||
1da177e4 | 57 | /* All of the device info needed for the Generic Serial Converter */ |
ea65370d | 58 | struct usb_serial_driver usb_serial_generic_device = { |
18fcac35 GKH |
59 | .driver = { |
60 | .owner = THIS_MODULE, | |
269bda1c | 61 | .name = "generic", |
18fcac35 | 62 | }, |
1da177e4 | 63 | .id_table = generic_device_ids, |
d9b1b787 | 64 | .usb_driver = &generic_driver, |
1da177e4 LT |
65 | .num_ports = 1, |
66 | .shutdown = usb_serial_generic_shutdown, | |
253ca923 JR |
67 | .throttle = usb_serial_generic_throttle, |
68 | .unthrottle = usb_serial_generic_unthrottle, | |
ec22559e | 69 | .resume = usb_serial_generic_resume, |
1da177e4 LT |
70 | }; |
71 | ||
1da177e4 LT |
72 | static int generic_probe(struct usb_interface *interface, |
73 | const struct usb_device_id *id) | |
74 | { | |
75 | const struct usb_device_id *id_pattern; | |
76 | ||
77 | id_pattern = usb_match_id(interface, generic_device_ids); | |
78 | if (id_pattern != NULL) | |
79 | return usb_serial_probe(interface, id); | |
80 | return -ENODEV; | |
81 | } | |
1da177e4 LT |
82 | #endif |
83 | ||
84 | int usb_serial_generic_register (int _debug) | |
85 | { | |
86 | int retval = 0; | |
87 | ||
88 | debug = _debug; | |
89 | #ifdef CONFIG_USB_SERIAL_GENERIC | |
90 | generic_device_ids[0].idVendor = vendor; | |
91 | generic_device_ids[0].idProduct = product; | |
92 | generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; | |
93 | ||
94 | /* register our generic driver with ourselves */ | |
95 | retval = usb_serial_register (&usb_serial_generic_device); | |
96 | if (retval) | |
97 | goto exit; | |
98 | retval = usb_register(&generic_driver); | |
99 | if (retval) | |
100 | usb_serial_deregister(&usb_serial_generic_device); | |
101 | exit: | |
102 | #endif | |
103 | return retval; | |
104 | } | |
105 | ||
106 | void usb_serial_generic_deregister (void) | |
107 | { | |
108 | #ifdef CONFIG_USB_SERIAL_GENERIC | |
109 | /* remove our generic driver */ | |
110 | usb_deregister(&generic_driver); | |
111 | usb_serial_deregister (&usb_serial_generic_device); | |
112 | #endif | |
113 | } | |
114 | ||
115 | int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) | |
116 | { | |
117 | struct usb_serial *serial = port->serial; | |
118 | int result = 0; | |
253ca923 | 119 | unsigned long flags; |
1da177e4 LT |
120 | |
121 | dbg("%s - port %d", __FUNCTION__, port->number); | |
122 | ||
123 | /* force low_latency on so that our tty_push actually forces the data through, | |
124 | otherwise it is scheduled, and with high data rates (like with OHCI) data | |
125 | can get lost. */ | |
126 | if (port->tty) | |
127 | port->tty->low_latency = 1; | |
128 | ||
253ca923 JR |
129 | /* clear the throttle flags */ |
130 | spin_lock_irqsave(&port->lock, flags); | |
131 | port->throttled = 0; | |
132 | port->throttle_req = 0; | |
133 | spin_unlock_irqrestore(&port->lock, flags); | |
134 | ||
135 | /* if we have a bulk endpoint, start reading from it */ | |
1da177e4 LT |
136 | if (serial->num_bulk_in) { |
137 | /* Start reading from the device */ | |
138 | usb_fill_bulk_urb (port->read_urb, serial->dev, | |
139 | usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), | |
140 | port->read_urb->transfer_buffer, | |
141 | port->read_urb->transfer_buffer_length, | |
142 | ((serial->type->read_bulk_callback) ? | |
143 | serial->type->read_bulk_callback : | |
144 | usb_serial_generic_read_bulk_callback), | |
145 | port); | |
146 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | |
147 | if (result) | |
148 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); | |
149 | } | |
150 | ||
151 | return result; | |
152 | } | |
815ddc99 | 153 | EXPORT_SYMBOL_GPL(usb_serial_generic_open); |
1da177e4 LT |
154 | |
155 | static void generic_cleanup (struct usb_serial_port *port) | |
156 | { | |
157 | struct usb_serial *serial = port->serial; | |
158 | ||
159 | dbg("%s - port %d", __FUNCTION__, port->number); | |
160 | ||
161 | if (serial->dev) { | |
162 | /* shutdown any bulk reads that might be going on */ | |
163 | if (serial->num_bulk_out) | |
164 | usb_kill_urb(port->write_urb); | |
165 | if (serial->num_bulk_in) | |
166 | usb_kill_urb(port->read_urb); | |
167 | } | |
168 | } | |
169 | ||
ec22559e ON |
170 | int usb_serial_generic_resume(struct usb_serial *serial) |
171 | { | |
172 | struct usb_serial_port *port; | |
173 | int i, c = 0, r; | |
174 | ||
f0fbd5b9 SS |
175 | #ifdef CONFIG_PM |
176 | /* | |
177 | * If this is an autoresume, don't submit URBs. | |
178 | * They will be submitted in the open function instead. | |
179 | */ | |
180 | if (serial->dev->auto_pm) | |
181 | return 0; | |
182 | #endif | |
ec22559e ON |
183 | for (i = 0; i < serial->num_ports; i++) { |
184 | port = serial->port[i]; | |
185 | if (port->open_count && port->read_urb) { | |
186 | r = usb_submit_urb(port->read_urb, GFP_NOIO); | |
187 | if (r < 0) | |
188 | c++; | |
189 | } | |
190 | } | |
191 | ||
192 | return c ? -EIO : 0; | |
193 | } | |
194 | ||
1da177e4 LT |
195 | void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) |
196 | { | |
197 | dbg("%s - port %d", __FUNCTION__, port->number); | |
198 | generic_cleanup (port); | |
199 | } | |
200 | ||
201 | int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *buf, int count) | |
202 | { | |
203 | struct usb_serial *serial = port->serial; | |
204 | int result; | |
205 | unsigned char *data; | |
206 | ||
207 | dbg("%s - port %d", __FUNCTION__, port->number); | |
208 | ||
209 | if (count == 0) { | |
210 | dbg("%s - write request of 0 bytes", __FUNCTION__); | |
211 | return (0); | |
212 | } | |
213 | ||
214 | /* only do something if we have a bulk out endpoint */ | |
215 | if (serial->num_bulk_out) { | |
acd2a847 JK |
216 | unsigned long flags; |
217 | spin_lock_irqsave(&port->lock, flags); | |
507ca9bc | 218 | if (port->write_urb_busy) { |
acd2a847 | 219 | spin_unlock_irqrestore(&port->lock, flags); |
1da177e4 | 220 | dbg("%s - already writing", __FUNCTION__); |
507ca9bc | 221 | return 0; |
1da177e4 | 222 | } |
507ca9bc | 223 | port->write_urb_busy = 1; |
acd2a847 | 224 | spin_unlock_irqrestore(&port->lock, flags); |
1da177e4 LT |
225 | |
226 | count = (count > port->bulk_out_size) ? port->bulk_out_size : count; | |
227 | ||
228 | memcpy (port->write_urb->transfer_buffer, buf, count); | |
229 | data = port->write_urb->transfer_buffer; | |
230 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, data); | |
231 | ||
232 | /* set up our urb */ | |
233 | usb_fill_bulk_urb (port->write_urb, serial->dev, | |
234 | usb_sndbulkpipe (serial->dev, | |
235 | port->bulk_out_endpointAddress), | |
236 | port->write_urb->transfer_buffer, count, | |
237 | ((serial->type->write_bulk_callback) ? | |
238 | serial->type->write_bulk_callback : | |
239 | usb_serial_generic_write_bulk_callback), port); | |
240 | ||
241 | /* send the data out the bulk port */ | |
507ca9bc | 242 | port->write_urb_busy = 1; |
1da177e4 | 243 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
507ca9bc | 244 | if (result) { |
1da177e4 | 245 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); |
507ca9bc GKH |
246 | /* don't have to grab the lock here, as we will retry if != 0 */ |
247 | port->write_urb_busy = 0; | |
248 | } else | |
1da177e4 LT |
249 | result = count; |
250 | ||
251 | return result; | |
252 | } | |
253 | ||
254 | /* no bulk out, so return 0 bytes written */ | |
507ca9bc | 255 | return 0; |
1da177e4 LT |
256 | } |
257 | ||
258 | int usb_serial_generic_write_room (struct usb_serial_port *port) | |
259 | { | |
260 | struct usb_serial *serial = port->serial; | |
261 | int room = 0; | |
262 | ||
263 | dbg("%s - port %d", __FUNCTION__, port->number); | |
507ca9bc | 264 | |
1da177e4 | 265 | if (serial->num_bulk_out) { |
7a3ca7d2 | 266 | if (!(port->write_urb_busy)) |
1da177e4 LT |
267 | room = port->bulk_out_size; |
268 | } | |
269 | ||
270 | dbg("%s - returns %d", __FUNCTION__, room); | |
271 | return (room); | |
272 | } | |
273 | ||
274 | int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) | |
275 | { | |
276 | struct usb_serial *serial = port->serial; | |
277 | int chars = 0; | |
278 | ||
279 | dbg("%s - port %d", __FUNCTION__, port->number); | |
280 | ||
281 | if (serial->num_bulk_out) { | |
507ca9bc | 282 | if (port->write_urb_busy) |
1da177e4 LT |
283 | chars = port->write_urb->transfer_buffer_length; |
284 | } | |
285 | ||
286 | dbg("%s - returns %d", __FUNCTION__, chars); | |
287 | return (chars); | |
288 | } | |
289 | ||
1abdeeb1 ON |
290 | |
291 | static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |
1da177e4 | 292 | { |
253ca923 | 293 | struct urb *urb = port->read_urb; |
1abdeeb1 | 294 | struct usb_serial *serial = port->serial; |
1da177e4 LT |
295 | int result; |
296 | ||
253ca923 | 297 | /* Continue reading from device */ |
1abdeeb1 | 298 | usb_fill_bulk_urb (urb, serial->dev, |
1da177e4 LT |
299 | usb_rcvbulkpipe (serial->dev, |
300 | port->bulk_in_endpointAddress), | |
1abdeeb1 ON |
301 | urb->transfer_buffer, |
302 | urb->transfer_buffer_length, | |
1da177e4 LT |
303 | ((serial->type->read_bulk_callback) ? |
304 | serial->type->read_bulk_callback : | |
305 | usb_serial_generic_read_bulk_callback), port); | |
1abdeeb1 | 306 | result = usb_submit_urb(urb, mem_flags); |
1da177e4 LT |
307 | if (result) |
308 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); | |
309 | } | |
253ca923 | 310 | |
1abdeeb1 ON |
311 | /* Push data to tty layer and resubmit the bulk read URB */ |
312 | static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | |
313 | { | |
314 | struct urb *urb = port->read_urb; | |
315 | struct tty_struct *tty = port->tty; | |
316 | int room; | |
317 | ||
318 | /* Push data to tty */ | |
319 | if (tty && urb->actual_length) { | |
320 | room = tty_buffer_request_room(tty, urb->actual_length); | |
321 | if (room) { | |
322 | tty_insert_flip_string(tty, urb->transfer_buffer, room); | |
b507cc97 | 323 | tty_flip_buffer_push(tty); |
1abdeeb1 ON |
324 | } |
325 | } | |
326 | ||
327 | resubmit_read_urb(port, GFP_ATOMIC); | |
328 | } | |
329 | ||
253ca923 JR |
330 | void usb_serial_generic_read_bulk_callback (struct urb *urb) |
331 | { | |
332 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | |
333 | unsigned char *data = urb->transfer_buffer; | |
fbd27225 | 334 | int status = urb->status; |
bfaeafcf | 335 | unsigned long flags; |
253ca923 JR |
336 | |
337 | dbg("%s - port %d", __FUNCTION__, port->number); | |
338 | ||
fbd27225 GKH |
339 | if (unlikely(status != 0)) { |
340 | dbg("%s - nonzero read bulk status received: %d", | |
341 | __FUNCTION__, status); | |
253ca923 JR |
342 | return; |
343 | } | |
344 | ||
345 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | |
346 | ||
347 | /* Throttle the device if requested by tty */ | |
bfaeafcf | 348 | spin_lock_irqsave(&port->lock, flags); |
b507cc97 PZ |
349 | if (!(port->throttled = port->throttle_req)) { |
350 | spin_unlock_irqrestore(&port->lock, flags); | |
1abdeeb1 | 351 | flush_and_resubmit_read_urb(port); |
b507cc97 PZ |
352 | } else { |
353 | spin_unlock_irqrestore(&port->lock, flags); | |
354 | } | |
253ca923 | 355 | } |
166ffccf | 356 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
1da177e4 | 357 | |
7d12e780 | 358 | void usb_serial_generic_write_bulk_callback (struct urb *urb) |
1da177e4 LT |
359 | { |
360 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | |
fbd27225 | 361 | int status = urb->status; |
1da177e4 LT |
362 | |
363 | dbg("%s - port %d", __FUNCTION__, port->number); | |
364 | ||
507ca9bc | 365 | port->write_urb_busy = 0; |
fbd27225 GKH |
366 | if (status) { |
367 | dbg("%s - nonzero write bulk status received: %d", | |
368 | __FUNCTION__, status); | |
1da177e4 LT |
369 | return; |
370 | } | |
371 | ||
cf2c7481 | 372 | usb_serial_port_softint(port); |
1da177e4 | 373 | } |
bb833986 | 374 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
1da177e4 | 375 | |
253ca923 JR |
376 | void usb_serial_generic_throttle (struct usb_serial_port *port) |
377 | { | |
378 | unsigned long flags; | |
379 | ||
380 | dbg("%s - port %d", __FUNCTION__, port->number); | |
381 | ||
382 | /* Set the throttle request flag. It will be picked up | |
383 | * by usb_serial_generic_read_bulk_callback(). */ | |
384 | spin_lock_irqsave(&port->lock, flags); | |
385 | port->throttle_req = 1; | |
386 | spin_unlock_irqrestore(&port->lock, flags); | |
387 | } | |
388 | ||
389 | void usb_serial_generic_unthrottle (struct usb_serial_port *port) | |
390 | { | |
391 | int was_throttled; | |
392 | unsigned long flags; | |
393 | ||
394 | dbg("%s - port %d", __FUNCTION__, port->number); | |
395 | ||
396 | /* Clear the throttle flags */ | |
397 | spin_lock_irqsave(&port->lock, flags); | |
398 | was_throttled = port->throttled; | |
399 | port->throttled = port->throttle_req = 0; | |
400 | spin_unlock_irqrestore(&port->lock, flags); | |
401 | ||
402 | if (was_throttled) { | |
1abdeeb1 ON |
403 | /* Resume reading from device */ |
404 | resubmit_read_urb(port, GFP_KERNEL); | |
253ca923 JR |
405 | } |
406 | } | |
407 | ||
1da177e4 LT |
408 | void usb_serial_generic_shutdown (struct usb_serial *serial) |
409 | { | |
410 | int i; | |
411 | ||
412 | dbg("%s", __FUNCTION__); | |
413 | ||
414 | /* stop reads and writes on all ports */ | |
415 | for (i=0; i < serial->num_ports; ++i) { | |
416 | generic_cleanup(serial->port[i]); | |
417 | } | |
418 | } | |
419 |