diff options
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r-- | drivers/usb/serial/generic.c | 122 |
1 files changed, 70 insertions, 52 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 537f12a027c2..fe84c88ec20c 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/moduleparam.h> | 18 | #include <linux/moduleparam.h> |
19 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
20 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
21 | #include <asm/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | 22 | ||
23 | 23 | ||
24 | static int debug; | 24 | static int debug; |
@@ -81,7 +81,7 @@ static int generic_probe(struct usb_interface *interface, | |||
81 | } | 81 | } |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | int usb_serial_generic_register (int _debug) | 84 | int usb_serial_generic_register(int _debug) |
85 | { | 85 | { |
86 | int retval = 0; | 86 | int retval = 0; |
87 | 87 | ||
@@ -89,10 +89,11 @@ int usb_serial_generic_register (int _debug) | |||
89 | #ifdef CONFIG_USB_SERIAL_GENERIC | 89 | #ifdef CONFIG_USB_SERIAL_GENERIC |
90 | generic_device_ids[0].idVendor = vendor; | 90 | generic_device_ids[0].idVendor = vendor; |
91 | generic_device_ids[0].idProduct = product; | 91 | generic_device_ids[0].idProduct = product; |
92 | generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; | 92 | generic_device_ids[0].match_flags = |
93 | USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; | ||
93 | 94 | ||
94 | /* register our generic driver with ourselves */ | 95 | /* register our generic driver with ourselves */ |
95 | retval = usb_serial_register (&usb_serial_generic_device); | 96 | retval = usb_serial_register(&usb_serial_generic_device); |
96 | if (retval) | 97 | if (retval) |
97 | goto exit; | 98 | goto exit; |
98 | retval = usb_register(&generic_driver); | 99 | retval = usb_register(&generic_driver); |
@@ -103,16 +104,17 @@ exit: | |||
103 | return retval; | 104 | return retval; |
104 | } | 105 | } |
105 | 106 | ||
106 | void usb_serial_generic_deregister (void) | 107 | void usb_serial_generic_deregister(void) |
107 | { | 108 | { |
108 | #ifdef CONFIG_USB_SERIAL_GENERIC | 109 | #ifdef CONFIG_USB_SERIAL_GENERIC |
109 | /* remove our generic driver */ | 110 | /* remove our generic driver */ |
110 | usb_deregister(&generic_driver); | 111 | usb_deregister(&generic_driver); |
111 | usb_serial_deregister (&usb_serial_generic_device); | 112 | usb_serial_deregister(&usb_serial_generic_device); |
112 | #endif | 113 | #endif |
113 | } | 114 | } |
114 | 115 | ||
115 | int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) | 116 | int usb_serial_generic_open(struct tty_struct *tty, |
117 | struct usb_serial_port *port, struct file *filp) | ||
116 | { | 118 | { |
117 | struct usb_serial *serial = port->serial; | 119 | struct usb_serial *serial = port->serial; |
118 | int result = 0; | 120 | int result = 0; |
@@ -120,11 +122,11 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) | |||
120 | 122 | ||
121 | dbg("%s - port %d", __func__, port->number); | 123 | dbg("%s - port %d", __func__, port->number); |
122 | 124 | ||
123 | /* force low_latency on so that our tty_push actually forces the data through, | 125 | /* force low_latency on so that our tty_push actually forces the data |
124 | otherwise it is scheduled, and with high data rates (like with OHCI) data | 126 | through, otherwise it is scheduled, and with high data rates (like |
125 | can get lost. */ | 127 | with OHCI) data can get lost. */ |
126 | if (port->tty) | 128 | if (tty) |
127 | port->tty->low_latency = 1; | 129 | tty->low_latency = 1; |
128 | 130 | ||
129 | /* clear the throttle flags */ | 131 | /* clear the throttle flags */ |
130 | spin_lock_irqsave(&port->lock, flags); | 132 | spin_lock_irqsave(&port->lock, flags); |
@@ -135,8 +137,9 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) | |||
135 | /* if we have a bulk endpoint, start reading from it */ | 137 | /* if we have a bulk endpoint, start reading from it */ |
136 | if (serial->num_bulk_in) { | 138 | if (serial->num_bulk_in) { |
137 | /* Start reading from the device */ | 139 | /* Start reading from the device */ |
138 | usb_fill_bulk_urb (port->read_urb, serial->dev, | 140 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
139 | usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), | 141 | usb_rcvbulkpipe(serial->dev, |
142 | port->bulk_in_endpointAddress), | ||
140 | port->read_urb->transfer_buffer, | 143 | port->read_urb->transfer_buffer, |
141 | port->read_urb->transfer_buffer_length, | 144 | port->read_urb->transfer_buffer_length, |
142 | ((serial->type->read_bulk_callback) ? | 145 | ((serial->type->read_bulk_callback) ? |
@@ -145,14 +148,16 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) | |||
145 | port); | 148 | port); |
146 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | 149 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
147 | if (result) | 150 | if (result) |
148 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); | 151 | dev_err(&port->dev, |
152 | "%s - failed resubmitting read urb, error %d\n", | ||
153 | __func__, result); | ||
149 | } | 154 | } |
150 | 155 | ||
151 | return result; | 156 | return result; |
152 | } | 157 | } |
153 | EXPORT_SYMBOL_GPL(usb_serial_generic_open); | 158 | EXPORT_SYMBOL_GPL(usb_serial_generic_open); |
154 | 159 | ||
155 | static void generic_cleanup (struct usb_serial_port *port) | 160 | static void generic_cleanup(struct usb_serial_port *port) |
156 | { | 161 | { |
157 | struct usb_serial *serial = port->serial; | 162 | struct usb_serial *serial = port->serial; |
158 | 163 | ||
@@ -182,7 +187,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
182 | #endif | 187 | #endif |
183 | for (i = 0; i < serial->num_ports; i++) { | 188 | for (i = 0; i < serial->num_ports; i++) { |
184 | port = serial->port[i]; | 189 | port = serial->port[i]; |
185 | if (port->open_count && port->read_urb) { | 190 | if (port->port.count && port->read_urb) { |
186 | r = usb_submit_urb(port->read_urb, GFP_NOIO); | 191 | r = usb_submit_urb(port->read_urb, GFP_NOIO); |
187 | if (r < 0) | 192 | if (r < 0) |
188 | c++; | 193 | c++; |
@@ -192,13 +197,15 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
192 | return c ? -EIO : 0; | 197 | return c ? -EIO : 0; |
193 | } | 198 | } |
194 | 199 | ||
195 | void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) | 200 | void usb_serial_generic_close(struct tty_struct *tty, |
201 | struct usb_serial_port *port, struct file *filp) | ||
196 | { | 202 | { |
197 | dbg("%s - port %d", __func__, port->number); | 203 | dbg("%s - port %d", __func__, port->number); |
198 | generic_cleanup (port); | 204 | generic_cleanup(port); |
199 | } | 205 | } |
200 | 206 | ||
201 | int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *buf, int count) | 207 | int usb_serial_generic_write(struct tty_struct *tty, |
208 | struct usb_serial_port *port, const unsigned char *buf, int count) | ||
202 | { | 209 | { |
203 | struct usb_serial *serial = port->serial; | 210 | struct usb_serial *serial = port->serial; |
204 | int result; | 211 | int result; |
@@ -208,7 +215,7 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * | |||
208 | 215 | ||
209 | if (count == 0) { | 216 | if (count == 0) { |
210 | dbg("%s - write request of 0 bytes", __func__); | 217 | dbg("%s - write request of 0 bytes", __func__); |
211 | return (0); | 218 | return 0; |
212 | } | 219 | } |
213 | 220 | ||
214 | /* only do something if we have a bulk out endpoint */ | 221 | /* only do something if we have a bulk out endpoint */ |
@@ -223,27 +230,32 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * | |||
223 | port->write_urb_busy = 1; | 230 | port->write_urb_busy = 1; |
224 | spin_unlock_irqrestore(&port->lock, flags); | 231 | spin_unlock_irqrestore(&port->lock, flags); |
225 | 232 | ||
226 | count = (count > port->bulk_out_size) ? port->bulk_out_size : count; | 233 | count = (count > port->bulk_out_size) ? |
234 | port->bulk_out_size : count; | ||
227 | 235 | ||
228 | memcpy (port->write_urb->transfer_buffer, buf, count); | 236 | memcpy(port->write_urb->transfer_buffer, buf, count); |
229 | data = port->write_urb->transfer_buffer; | 237 | data = port->write_urb->transfer_buffer; |
230 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | 238 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); |
231 | 239 | ||
232 | /* set up our urb */ | 240 | /* set up our urb */ |
233 | usb_fill_bulk_urb (port->write_urb, serial->dev, | 241 | usb_fill_bulk_urb(port->write_urb, serial->dev, |
234 | usb_sndbulkpipe (serial->dev, | 242 | usb_sndbulkpipe(serial->dev, |
235 | port->bulk_out_endpointAddress), | 243 | port->bulk_out_endpointAddress), |
236 | port->write_urb->transfer_buffer, count, | 244 | port->write_urb->transfer_buffer, count, |
237 | ((serial->type->write_bulk_callback) ? | 245 | ((serial->type->write_bulk_callback) ? |
238 | serial->type->write_bulk_callback : | 246 | serial->type->write_bulk_callback : |
239 | usb_serial_generic_write_bulk_callback), port); | 247 | usb_serial_generic_write_bulk_callback), |
248 | port); | ||
240 | 249 | ||
241 | /* send the data out the bulk port */ | 250 | /* send the data out the bulk port */ |
242 | port->write_urb_busy = 1; | 251 | port->write_urb_busy = 1; |
243 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 252 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
244 | if (result) { | 253 | if (result) { |
245 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); | 254 | dev_err(&port->dev, |
246 | /* don't have to grab the lock here, as we will retry if != 0 */ | 255 | "%s - failed submitting write urb, error %d\n", |
256 | __func__, result); | ||
257 | /* don't have to grab the lock here, as we will | ||
258 | retry if != 0 */ | ||
247 | port->write_urb_busy = 0; | 259 | port->write_urb_busy = 0; |
248 | } else | 260 | } else |
249 | result = count; | 261 | result = count; |
@@ -255,8 +267,9 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * | |||
255 | return 0; | 267 | return 0; |
256 | } | 268 | } |
257 | 269 | ||
258 | int usb_serial_generic_write_room (struct usb_serial_port *port) | 270 | int usb_serial_generic_write_room(struct tty_struct *tty) |
259 | { | 271 | { |
272 | struct usb_serial_port *port = tty->driver_data; | ||
260 | struct usb_serial *serial = port->serial; | 273 | struct usb_serial *serial = port->serial; |
261 | int room = 0; | 274 | int room = 0; |
262 | 275 | ||
@@ -272,8 +285,9 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) | |||
272 | return room; | 285 | return room; |
273 | } | 286 | } |
274 | 287 | ||
275 | int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) | 288 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) |
276 | { | 289 | { |
290 | struct usb_serial_port *port = tty->driver_data; | ||
277 | struct usb_serial *serial = port->serial; | 291 | struct usb_serial *serial = port->serial; |
278 | int chars = 0; | 292 | int chars = 0; |
279 | 293 | ||
@@ -286,7 +300,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) | |||
286 | } | 300 | } |
287 | 301 | ||
288 | dbg("%s - returns %d", __func__, chars); | 302 | dbg("%s - returns %d", __func__, chars); |
289 | return (chars); | 303 | return chars; |
290 | } | 304 | } |
291 | 305 | ||
292 | 306 | ||
@@ -297,24 +311,26 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
297 | int result; | 311 | int result; |
298 | 312 | ||
299 | /* Continue reading from device */ | 313 | /* Continue reading from device */ |
300 | usb_fill_bulk_urb (urb, serial->dev, | 314 | usb_fill_bulk_urb(urb, serial->dev, |
301 | usb_rcvbulkpipe (serial->dev, | 315 | usb_rcvbulkpipe(serial->dev, |
302 | port->bulk_in_endpointAddress), | 316 | port->bulk_in_endpointAddress), |
303 | urb->transfer_buffer, | 317 | urb->transfer_buffer, |
304 | urb->transfer_buffer_length, | 318 | urb->transfer_buffer_length, |
305 | ((serial->type->read_bulk_callback) ? | 319 | ((serial->type->read_bulk_callback) ? |
306 | serial->type->read_bulk_callback : | 320 | serial->type->read_bulk_callback : |
307 | usb_serial_generic_read_bulk_callback), port); | 321 | usb_serial_generic_read_bulk_callback), port); |
308 | result = usb_submit_urb(urb, mem_flags); | 322 | result = usb_submit_urb(urb, mem_flags); |
309 | if (result) | 323 | if (result) |
310 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); | 324 | dev_err(&port->dev, |
325 | "%s - failed resubmitting read urb, error %d\n", | ||
326 | __func__, result); | ||
311 | } | 327 | } |
312 | 328 | ||
313 | /* Push data to tty layer and resubmit the bulk read URB */ | 329 | /* Push data to tty layer and resubmit the bulk read URB */ |
314 | static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | 330 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) |
315 | { | 331 | { |
316 | struct urb *urb = port->read_urb; | 332 | struct urb *urb = port->read_urb; |
317 | struct tty_struct *tty = port->tty; | 333 | struct tty_struct *tty = port->port.tty; |
318 | int room; | 334 | int room; |
319 | 335 | ||
320 | /* Push data to tty */ | 336 | /* Push data to tty */ |
@@ -329,7 +345,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port) | |||
329 | resubmit_read_urb(port, GFP_ATOMIC); | 345 | resubmit_read_urb(port, GFP_ATOMIC); |
330 | } | 346 | } |
331 | 347 | ||
332 | void usb_serial_generic_read_bulk_callback (struct urb *urb) | 348 | void usb_serial_generic_read_bulk_callback(struct urb *urb) |
333 | { | 349 | { |
334 | struct usb_serial_port *port = urb->context; | 350 | struct usb_serial_port *port = urb->context; |
335 | unsigned char *data = urb->transfer_buffer; | 351 | unsigned char *data = urb->transfer_buffer; |
@@ -344,20 +360,21 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) | |||
344 | return; | 360 | return; |
345 | } | 361 | } |
346 | 362 | ||
347 | usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); | 363 | usb_serial_debug_data(debug, &port->dev, __func__, |
364 | urb->actual_length, data); | ||
348 | 365 | ||
349 | /* Throttle the device if requested by tty */ | 366 | /* Throttle the device if requested by tty */ |
350 | spin_lock_irqsave(&port->lock, flags); | 367 | spin_lock_irqsave(&port->lock, flags); |
351 | if (!(port->throttled = port->throttle_req)) { | 368 | port->throttled = port->throttle_req; |
369 | if (!port->throttled) { | ||
352 | spin_unlock_irqrestore(&port->lock, flags); | 370 | spin_unlock_irqrestore(&port->lock, flags); |
353 | flush_and_resubmit_read_urb(port); | 371 | flush_and_resubmit_read_urb(port); |
354 | } else { | 372 | } else |
355 | spin_unlock_irqrestore(&port->lock, flags); | 373 | spin_unlock_irqrestore(&port->lock, flags); |
356 | } | ||
357 | } | 374 | } |
358 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | 375 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
359 | 376 | ||
360 | void usb_serial_generic_write_bulk_callback (struct urb *urb) | 377 | void usb_serial_generic_write_bulk_callback(struct urb *urb) |
361 | { | 378 | { |
362 | struct usb_serial_port *port = urb->context; | 379 | struct usb_serial_port *port = urb->context; |
363 | int status = urb->status; | 380 | int status = urb->status; |
@@ -374,8 +391,9 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb) | |||
374 | } | 391 | } |
375 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 392 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
376 | 393 | ||
377 | void usb_serial_generic_throttle (struct usb_serial_port *port) | 394 | void usb_serial_generic_throttle(struct tty_struct *tty) |
378 | { | 395 | { |
396 | struct usb_serial_port *port = tty->driver_data; | ||
379 | unsigned long flags; | 397 | unsigned long flags; |
380 | 398 | ||
381 | dbg("%s - port %d", __func__, port->number); | 399 | dbg("%s - port %d", __func__, port->number); |
@@ -387,8 +405,9 @@ void usb_serial_generic_throttle (struct usb_serial_port *port) | |||
387 | spin_unlock_irqrestore(&port->lock, flags); | 405 | spin_unlock_irqrestore(&port->lock, flags); |
388 | } | 406 | } |
389 | 407 | ||
390 | void usb_serial_generic_unthrottle (struct usb_serial_port *port) | 408 | void usb_serial_generic_unthrottle(struct tty_struct *tty) |
391 | { | 409 | { |
410 | struct usb_serial_port *port = tty->driver_data; | ||
392 | int was_throttled; | 411 | int was_throttled; |
393 | unsigned long flags; | 412 | unsigned long flags; |
394 | 413 | ||
@@ -406,15 +425,14 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port) | |||
406 | } | 425 | } |
407 | } | 426 | } |
408 | 427 | ||
409 | void usb_serial_generic_shutdown (struct usb_serial *serial) | 428 | void usb_serial_generic_shutdown(struct usb_serial *serial) |
410 | { | 429 | { |
411 | int i; | 430 | int i; |
412 | 431 | ||
413 | dbg("%s", __func__); | 432 | dbg("%s", __func__); |
414 | 433 | ||
415 | /* stop reads and writes on all ports */ | 434 | /* stop reads and writes on all ports */ |
416 | for (i=0; i < serial->num_ports; ++i) { | 435 | for (i = 0; i < serial->num_ports; ++i) |
417 | generic_cleanup(serial->port[i]); | 436 | generic_cleanup(serial->port[i]); |
418 | } | ||
419 | } | 437 | } |
420 | 438 | ||