aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ir-usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ir-usb.c')
-rw-r--r--drivers/usb/serial/ir-usb.c272
1 files changed, 83 insertions, 189 deletions
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 4a0f51974232..ccbce4066d04 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2002 Gary Brubaker (xavyer@ix.netcom.com) 5 * Copyright (C) 2002 Gary Brubaker (xavyer@ix.netcom.com)
6 * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -72,8 +73,8 @@
72/* 73/*
73 * Version Information 74 * Version Information
74 */ 75 */
75#define DRIVER_VERSION "v0.4" 76#define DRIVER_VERSION "v0.5"
76#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" 77#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Johan Hovold <jhovold@gmail.com>"
77#define DRIVER_DESC "USB IR Dongle driver" 78#define DRIVER_DESC "USB IR Dongle driver"
78 79
79static int debug; 80static int debug;
@@ -87,11 +88,9 @@ static int xbof = -1;
87 88
88static int ir_startup (struct usb_serial *serial); 89static int ir_startup (struct usb_serial *serial);
89static int ir_open(struct tty_struct *tty, struct usb_serial_port *port); 90static int ir_open(struct tty_struct *tty, struct usb_serial_port *port);
90static void ir_close(struct usb_serial_port *port); 91static int ir_prepare_write_buffer(struct usb_serial_port *port,
91static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, 92 void *dest, size_t size);
92 const unsigned char *buf, int count); 93static void ir_process_read_urb(struct urb *urb);
93static void ir_write_bulk_callback (struct urb *urb);
94static void ir_read_bulk_callback (struct urb *urb);
95static void ir_set_termios(struct tty_struct *tty, 94static void ir_set_termios(struct tty_struct *tty,
96 struct usb_serial_port *port, struct ktermios *old_termios); 95 struct usb_serial_port *port, struct ktermios *old_termios);
97 96
@@ -130,10 +129,8 @@ static struct usb_serial_driver ir_device = {
130 .set_termios = ir_set_termios, 129 .set_termios = ir_set_termios,
131 .attach = ir_startup, 130 .attach = ir_startup,
132 .open = ir_open, 131 .open = ir_open,
133 .close = ir_close, 132 .prepare_write_buffer = ir_prepare_write_buffer,
134 .write = ir_write, 133 .process_read_urb = ir_process_read_urb,
135 .write_bulk_callback = ir_write_bulk_callback,
136 .read_bulk_callback = ir_read_bulk_callback,
137}; 134};
138 135
139static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc) 136static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc)
@@ -198,7 +195,6 @@ error:
198 return NULL; 195 return NULL;
199} 196}
200 197
201
202static u8 ir_xbof_change(u8 xbof) 198static u8 ir_xbof_change(u8 xbof)
203{ 199{
204 u8 result; 200 u8 result;
@@ -237,7 +233,6 @@ static u8 ir_xbof_change(u8 xbof)
237 return(result); 233 return(result);
238} 234}
239 235
240
241static int ir_startup(struct usb_serial *serial) 236static int ir_startup(struct usb_serial *serial)
242{ 237{
243 struct usb_irda_cs_descriptor *irda_desc; 238 struct usb_irda_cs_descriptor *irda_desc;
@@ -297,83 +292,22 @@ static int ir_startup(struct usb_serial *serial)
297 292
298static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) 293static int ir_open(struct tty_struct *tty, struct usb_serial_port *port)
299{ 294{
300 char *buffer; 295 int i;
301 int result = 0;
302 296
303 dbg("%s - port %d", __func__, port->number); 297 dbg("%s - port %d", __func__, port->number);
304 298
305 if (buffer_size) { 299 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
306 /* override the default buffer sizes */ 300 port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET;
307 buffer = kmalloc(buffer_size, GFP_KERNEL);
308 if (!buffer) {
309 dev_err(&port->dev, "%s - out of memory.\n", __func__);
310 return -ENOMEM;
311 }
312 kfree(port->read_urb->transfer_buffer);
313 port->read_urb->transfer_buffer = buffer;
314 port->read_urb->transfer_buffer_length = buffer_size;
315
316 buffer = kmalloc(buffer_size, GFP_KERNEL);
317 if (!buffer) {
318 dev_err(&port->dev, "%s - out of memory.\n", __func__);
319 return -ENOMEM;
320 }
321 kfree(port->write_urb->transfer_buffer);
322 port->write_urb->transfer_buffer = buffer;
323 port->write_urb->transfer_buffer_length = buffer_size;
324 port->bulk_out_size = buffer_size;
325 }
326 301
327 /* Start reading from the device */ 302 /* Start reading from the device */
328 usb_fill_bulk_urb( 303 return usb_serial_generic_open(tty, port);
329 port->read_urb,
330 port->serial->dev,
331 usb_rcvbulkpipe(port->serial->dev,
332 port->bulk_in_endpointAddress),
333 port->read_urb->transfer_buffer,
334 port->read_urb->transfer_buffer_length,
335 ir_read_bulk_callback,
336 port);
337 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
338 if (result)
339 dev_err(&port->dev,
340 "%s - failed submitting read urb, error %d\n",
341 __func__, result);
342
343 return result;
344} 304}
345 305
346static void ir_close(struct usb_serial_port *port) 306static int ir_prepare_write_buffer(struct usb_serial_port *port,
307 void *dest, size_t size)
347{ 308{
348 dbg("%s - port %d", __func__, port->number); 309 unsigned char *buf = dest;
349 310 int count;
350 /* shutdown our bulk read */
351 usb_kill_urb(port->read_urb);
352}
353
354static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
355 const unsigned char *buf, int count)
356{
357 unsigned char *transfer_buffer;
358 int result;
359 int transfer_size;
360
361 dbg("%s - port = %d, count = %d", __func__, port->number, count);
362
363 if (count == 0)
364 return 0;
365
366 spin_lock_bh(&port->lock);
367 if (port->write_urb_busy) {
368 spin_unlock_bh(&port->lock);
369 dbg("%s - already writing", __func__);
370 return 0;
371 }
372 port->write_urb_busy = 1;
373 spin_unlock_bh(&port->lock);
374
375 transfer_buffer = port->write_urb->transfer_buffer;
376 transfer_size = min(count, port->bulk_out_size - 1);
377 311
378 /* 312 /*
379 * The first byte of the packet we send to the device contains an 313 * The first byte of the packet we send to the device contains an
@@ -382,119 +316,57 @@ static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
382 * 316 *
383 * See section 5.4.2.2 of the USB IrDA spec. 317 * See section 5.4.2.2 of the USB IrDA spec.
384 */ 318 */
385 *transfer_buffer = ir_xbof | ir_baud; 319 *buf = ir_xbof | ir_baud;
386 ++transfer_buffer;
387
388 memcpy(transfer_buffer, buf, transfer_size);
389 320
390 usb_fill_bulk_urb( 321 count = kfifo_out_locked(&port->write_fifo, buf + 1, size - 1,
391 port->write_urb, 322 &port->lock);
392 port->serial->dev, 323 return count + 1;
393 usb_sndbulkpipe(port->serial->dev,
394 port->bulk_out_endpointAddress),
395 port->write_urb->transfer_buffer,
396 transfer_size + 1,
397 ir_write_bulk_callback,
398 port);
399
400 port->write_urb->transfer_flags = URB_ZERO_PACKET;
401
402 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
403 if (result) {
404 port->write_urb_busy = 0;
405 dev_err(&port->dev,
406 "%s - failed submitting write urb, error %d\n",
407 __func__, result);
408 } else
409 result = transfer_size;
410
411 return result;
412} 324}
413 325
414static void ir_write_bulk_callback(struct urb *urb) 326static void ir_process_read_urb(struct urb *urb)
415{ 327{
416 struct usb_serial_port *port = urb->context; 328 struct usb_serial_port *port = urb->context;
417 int status = urb->status; 329 unsigned char *data = urb->transfer_buffer;
418 330 struct tty_struct *tty;
419 dbg("%s - port %d", __func__, port->number);
420 331
421 port->write_urb_busy = 0; 332 if (!urb->actual_length)
422 if (status) {
423 dbg("%s - nonzero write bulk status received: %d",
424 __func__, status);
425 return; 333 return;
426 } 334 /*
335 * The first byte of the packet we get from the device
336 * contains a busy indicator and baud rate change.
337 * See section 5.4.1.2 of the USB IrDA spec.
338 */
339 if (*data & 0x0f)
340 ir_baud = *data & 0x0f;
427 341
428 usb_serial_debug_data( 342 if (urb->actual_length == 1)
429 debug, 343 return;
430 &port->dev,
431 __func__,
432 urb->actual_length,
433 urb->transfer_buffer);
434 344
435 usb_serial_port_softint(port); 345 tty = tty_port_tty_get(&port->port);
346 if (!tty)
347 return;
348 tty_insert_flip_string(tty, data + 1, urb->actual_length - 1);
349 tty_flip_buffer_push(tty);
350 tty_kref_put(tty);
436} 351}
437 352
438static void ir_read_bulk_callback(struct urb *urb) 353static void ir_set_termios_callback(struct urb *urb)
439{ 354{
440 struct usb_serial_port *port = urb->context; 355 struct usb_serial_port *port = urb->context;
441 struct tty_struct *tty;
442 unsigned char *data = urb->transfer_buffer;
443 int result;
444 int status = urb->status; 356 int status = urb->status;
445 357
446 dbg("%s - port %d", __func__, port->number); 358 dbg("%s - port %d", __func__, port->number);
447 359
448 switch (status) { 360 kfree(urb->transfer_buffer);
449 case 0: /* Successful */ 361
450 /* 362 if (status)
451 * The first byte of the packet we get from the device 363 dbg("%s - non-zero urb status: %d", __func__, status);
452 * contains a busy indicator and baud rate change.
453 * See section 5.4.1.2 of the USB IrDA spec.
454 */
455 if ((*data & 0x0f) > 0)
456 ir_baud = *data & 0x0f;
457 usb_serial_debug_data(debug, &port->dev, __func__,
458 urb->actual_length, data);
459 tty = tty_port_tty_get(&port->port);
460 tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
461 tty_flip_buffer_push(tty);
462 tty_kref_put(tty);
463
464 /*
465 * No break here.
466 * We want to resubmit the urb so we can read
467 * again.
468 */
469
470 case -EPROTO: /* taking inspiration from pl2303.c */
471 /* Continue trying to always read */
472 usb_fill_bulk_urb(
473 port->read_urb,
474 port->serial->dev,
475 usb_rcvbulkpipe(port->serial->dev,
476 port->bulk_in_endpointAddress),
477 port->read_urb->transfer_buffer,
478 port->read_urb->transfer_buffer_length,
479 ir_read_bulk_callback,
480 port);
481
482 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
483 if (result)
484 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
485 __func__, result);
486 break ;
487 default:
488 dbg("%s - nonzero read bulk status received: %d",
489 __func__, status);
490 break ;
491 }
492 return;
493} 364}
494 365
495static void ir_set_termios(struct tty_struct *tty, 366static void ir_set_termios(struct tty_struct *tty,
496 struct usb_serial_port *port, struct ktermios *old_termios) 367 struct usb_serial_port *port, struct ktermios *old_termios)
497{ 368{
369 struct urb *urb;
498 unsigned char *transfer_buffer; 370 unsigned char *transfer_buffer;
499 int result; 371 int result;
500 speed_t baud; 372 speed_t baud;
@@ -548,41 +420,63 @@ static void ir_set_termios(struct tty_struct *tty,
548 else 420 else
549 ir_xbof = ir_xbof_change(xbof) ; 421 ir_xbof = ir_xbof_change(xbof) ;
550 422
551 /* FIXME need to check to see if our write urb is busy right 423 /* Only speed changes are supported */
552 * now, or use a urb pool. 424 tty_termios_copy_hw(tty->termios, old_termios);
553 * 425 tty_encode_baud_rate(tty, baud, baud);
426
427 /*
554 * send the baud change out on an "empty" data packet 428 * send the baud change out on an "empty" data packet
555 */ 429 */
556 transfer_buffer = port->write_urb->transfer_buffer; 430 urb = usb_alloc_urb(0, GFP_KERNEL);
431 if (!urb) {
432 dev_err(&port->dev, "%s - no more urbs\n", __func__);
433 return;
434 }
435 transfer_buffer = kmalloc(1, GFP_KERNEL);
436 if (!transfer_buffer) {
437 dev_err(&port->dev, "%s - out of memory\n", __func__);
438 goto err_buf;
439 }
440
557 *transfer_buffer = ir_xbof | ir_baud; 441 *transfer_buffer = ir_xbof | ir_baud;
558 442
559 usb_fill_bulk_urb( 443 usb_fill_bulk_urb(
560 port->write_urb, 444 urb,
561 port->serial->dev, 445 port->serial->dev,
562 usb_sndbulkpipe(port->serial->dev, 446 usb_sndbulkpipe(port->serial->dev,
563 port->bulk_out_endpointAddress), 447 port->bulk_out_endpointAddress),
564 port->write_urb->transfer_buffer, 448 transfer_buffer,
565 1, 449 1,
566 ir_write_bulk_callback, 450 ir_set_termios_callback,
567 port); 451 port);
568 452
569 port->write_urb->transfer_flags = URB_ZERO_PACKET; 453 urb->transfer_flags = URB_ZERO_PACKET;
570 454
571 result = usb_submit_urb(port->write_urb, GFP_KERNEL); 455 result = usb_submit_urb(urb, GFP_KERNEL);
572 if (result) 456 if (result) {
573 dev_err(&port->dev, 457 dev_err(&port->dev, "%s - failed to submit urb: %d\n",
574 "%s - failed submitting write urb, error %d\n", 458 __func__, result);
575 __func__, result); 459 goto err_subm;
460 }
576 461
577 /* Only speed changes are supported */ 462 usb_free_urb(urb);
578 tty_termios_copy_hw(tty->termios, old_termios); 463
579 tty_encode_baud_rate(tty, baud, baud); 464 return;
465err_subm:
466 kfree(transfer_buffer);
467err_buf:
468 usb_free_urb(urb);
580} 469}
581 470
582static int __init ir_init(void) 471static int __init ir_init(void)
583{ 472{
584 int retval; 473 int retval;
585 474
475 if (buffer_size) {
476 ir_device.bulk_in_size = buffer_size;
477 ir_device.bulk_out_size = buffer_size;
478 }
479
586 retval = usb_serial_register(&ir_device); 480 retval = usb_serial_register(&ir_device);
587 if (retval) 481 if (retval)
588 goto failed_usb_serial_register; 482 goto failed_usb_serial_register;