aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-05-13 15:02:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:46 -0400
commitf4a4cbb2047ec6b0175a08e5bcd78a697773390d (patch)
treed0fcb5bf284dbfc82775524bbc7f8fc240429b10 /drivers/usb
parentdf66e8a2afef506e303f931741193c7cf8fe0794 (diff)
USB: ir-usb: reimplement using generic framework
Compile-only tested. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/ir-usb.c197
1 files changed, 38 insertions, 159 deletions
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index d8490eaeb234..e7087f9fe479 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,60 +292,21 @@ 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 int result = 0; 295 int i;
301 296
302 dbg("%s - port %d", __func__, port->number); 297 dbg("%s - port %d", __func__, port->number);
303 298
304 /* Start reading from the device */ 299 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
305 usb_fill_bulk_urb( 300 port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET;
306 port->read_urb,
307 port->serial->dev,
308 usb_rcvbulkpipe(port->serial->dev,
309 port->bulk_in_endpointAddress),
310 port->read_urb->transfer_buffer,
311 port->read_urb->transfer_buffer_length,
312 ir_read_bulk_callback,
313 port);
314 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
315 if (result)
316 dev_err(&port->dev,
317 "%s - failed submitting read urb, error %d\n",
318 __func__, result);
319
320 return result;
321}
322
323static void ir_close(struct usb_serial_port *port)
324{
325 dbg("%s - port %d", __func__, port->number);
326 301
327 /* shutdown our bulk read */ 302 /* Start reading from the device */
328 usb_kill_urb(port->read_urb); 303 return usb_serial_generic_open(tty, port);
329} 304}
330 305
331static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, 306static int ir_prepare_write_buffer(struct usb_serial_port *port,
332 const unsigned char *buf, int count) 307 void *dest, size_t size)
333{ 308{
334 unsigned char *transfer_buffer; 309 unsigned char *buf = dest;
335 int result;
336 int transfer_size;
337
338 dbg("%s - port = %d, count = %d", __func__, port->number, count);
339
340 if (count == 0)
341 return 0;
342
343 spin_lock_bh(&port->lock);
344 if (port->write_urb_busy) {
345 spin_unlock_bh(&port->lock);
346 dbg("%s - already writing", __func__);
347 return 0;
348 }
349 port->write_urb_busy = 1;
350 spin_unlock_bh(&port->lock);
351
352 transfer_buffer = port->write_urb->transfer_buffer;
353 transfer_size = min(count, port->bulk_out_size - 1);
354 310
355 /* 311 /*
356 * The first byte of the packet we send to the device contains an 312 * The first byte of the packet we send to the device contains an
@@ -359,114 +315,37 @@ static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
359 * 315 *
360 * See section 5.4.2.2 of the USB IrDA spec. 316 * See section 5.4.2.2 of the USB IrDA spec.
361 */ 317 */
362 *transfer_buffer = ir_xbof | ir_baud; 318 *buf = ir_xbof | ir_baud;
363 ++transfer_buffer;
364
365 memcpy(transfer_buffer, buf, transfer_size);
366
367 usb_fill_bulk_urb(
368 port->write_urb,
369 port->serial->dev,
370 usb_sndbulkpipe(port->serial->dev,
371 port->bulk_out_endpointAddress),
372 port->write_urb->transfer_buffer,
373 transfer_size + 1,
374 ir_write_bulk_callback,
375 port);
376 319
377 port->write_urb->transfer_flags = URB_ZERO_PACKET; 320 return kfifo_out_locked(&port->write_fifo, buf + 1, size - 1,
378 321 &port->lock);
379 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
380 if (result) {
381 port->write_urb_busy = 0;
382 dev_err(&port->dev,
383 "%s - failed submitting write urb, error %d\n",
384 __func__, result);
385 } else
386 result = transfer_size;
387
388 return result;
389} 322}
390 323
391static void ir_write_bulk_callback(struct urb *urb) 324static void ir_process_read_urb(struct urb *urb)
392{ 325{
393 struct usb_serial_port *port = urb->context; 326 struct usb_serial_port *port = urb->context;
394 int status = urb->status; 327 unsigned char *data = urb->transfer_buffer;
395 328 struct tty_struct *tty;
396 dbg("%s - port %d", __func__, port->number);
397 329
398 port->write_urb_busy = 0; 330 if (!urb->actual_length)
399 if (status) {
400 dbg("%s - nonzero write bulk status received: %d",
401 __func__, status);
402 return; 331 return;
403 } 332 /*
404 333 * The first byte of the packet we get from the device
405 usb_serial_debug_data( 334 * contains a busy indicator and baud rate change.
406 debug, 335 * See section 5.4.1.2 of the USB IrDA spec.
407 &port->dev, 336 */
408 __func__, 337 if (*data & 0x0f)
409 urb->actual_length, 338 ir_baud = *data & 0x0f;
410 urb->transfer_buffer);
411
412 usb_serial_port_softint(port);
413}
414
415static void ir_read_bulk_callback(struct urb *urb)
416{
417 struct usb_serial_port *port = urb->context;
418 struct tty_struct *tty;
419 unsigned char *data = urb->transfer_buffer;
420 int result;
421 int status = urb->status;
422 339
423 dbg("%s - port %d", __func__, port->number); 340 if (urb->actual_length == 1)
341 return;
424 342
425 switch (status) { 343 tty = tty_port_tty_get(&port->port);
426 case 0: /* Successful */ 344 if (!tty)
427 /* 345 return;
428 * The first byte of the packet we get from the device 346 tty_insert_flip_string(tty, data + 1, urb->actual_length - 1);
429 * contains a busy indicator and baud rate change. 347 tty_flip_buffer_push(tty);
430 * See section 5.4.1.2 of the USB IrDA spec. 348 tty_kref_put(tty);
431 */
432 if ((*data & 0x0f) > 0)
433 ir_baud = *data & 0x0f;
434 usb_serial_debug_data(debug, &port->dev, __func__,
435 urb->actual_length, data);
436 tty = tty_port_tty_get(&port->port);
437 tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
438 tty_flip_buffer_push(tty);
439 tty_kref_put(tty);
440
441 /*
442 * No break here.
443 * We want to resubmit the urb so we can read
444 * again.
445 */
446
447 case -EPROTO: /* taking inspiration from pl2303.c */
448 /* Continue trying to always read */
449 usb_fill_bulk_urb(
450 port->read_urb,
451 port->serial->dev,
452 usb_rcvbulkpipe(port->serial->dev,
453 port->bulk_in_endpointAddress),
454 port->read_urb->transfer_buffer,
455 port->read_urb->transfer_buffer_length,
456 ir_read_bulk_callback,
457 port);
458
459 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
460 if (result)
461 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
462 __func__, result);
463 break ;
464 default:
465 dbg("%s - nonzero read bulk status received: %d",
466 __func__, status);
467 break ;
468 }
469 return;
470} 349}
471 350
472static void ir_set_termios_callback(struct urb *urb) 351static void ir_set_termios_callback(struct urb *urb)