aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2007-06-20 01:22:23 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 19:34:37 -0400
commit9e85c5f63268a5700860f53e52b090973652a5b2 (patch)
tree4d0258d76ceab4621e57b646ad80ace80f5911aa /drivers/usb/serial/sierra.c
parent17c2327419a889293fb955baf0c69a7d38c5809c (diff)
USB: sierra: cleanup the startup and shutdown path
This removes the ugly code that was copied from the keyspan driver and allocates the in urbs in a much shorter code path that can be understood easier. Also turned off the interrupt urb when no port was open as it's not nice to keep the bus busy for no good reason at all (this should be a power savings.) All in all, this saved over 40 lines of code and cleaned things up better. Cc: Kevin Lloyd <linux@sierrawireless.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c130
1 files changed, 41 insertions, 89 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 551c6ce89f6..e7db20343d1 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -418,7 +418,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
418{ 418{
419 struct sierra_port_private *portdata; 419 struct sierra_port_private *portdata;
420 struct usb_serial *serial = port->serial; 420 struct usb_serial *serial = port->serial;
421 int i, err; 421 int i;
422 struct urb *urb; 422 struct urb *urb;
423 int result; 423 int result;
424 __u16 set_mode_dzero = 0x0000; 424 __u16 set_mode_dzero = 0x0000;
@@ -434,7 +434,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
434 /* Reset low level data toggle and start reading from endpoints */ 434 /* Reset low level data toggle and start reading from endpoints */
435 for (i = 0; i < N_IN_URB; i++) { 435 for (i = 0; i < N_IN_URB; i++) {
436 urb = portdata->in_urbs[i]; 436 urb = portdata->in_urbs[i];
437 if (! urb) 437 if (!urb)
438 continue; 438 continue;
439 if (urb->dev != serial->dev) { 439 if (urb->dev != serial->dev) {
440 dbg("%s: dev %p != %p", __FUNCTION__, 440 dbg("%s: dev %p != %p", __FUNCTION__,
@@ -448,11 +448,10 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
448 */ 448 */
449 usb_clear_halt(urb->dev, urb->pipe); 449 usb_clear_halt(urb->dev, urb->pipe);
450 450
451 err = usb_submit_urb(urb, GFP_KERNEL); 451 result = usb_submit_urb(urb, GFP_KERNEL);
452 if (err) { 452 if (result) {
453 dbg("%s: submit urb %d failed (%d) %d", 453 dev_err(&port->dev, "submit urb %d failed (%d) %d",
454 __FUNCTION__, i, err, 454 i, result, urb->transfer_buffer_length);
455 urb->transfer_buffer_length);
456 } 455 }
457 } 456 }
458 457
@@ -466,7 +465,14 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
466 465
467 sierra_send_setup(port); 466 sierra_send_setup(port);
468 467
469 return (0); 468 /* start up the interrupt endpoint if we have one */
469 if (port->interrupt_in_urb) {
470 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
471 if (result)
472 dev_err(&port->dev, "submit irq_in urb failed %d",
473 result);
474 }
475 return 0;
470} 476}
471 477
472static void sierra_close(struct usb_serial_port *port, struct file *filp) 478static void sierra_close(struct usb_serial_port *port, struct file *filp)
@@ -486,62 +492,21 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
486 492
487 /* Stop reading/writing urbs */ 493 /* Stop reading/writing urbs */
488 for (i = 0; i < N_IN_URB; i++) 494 for (i = 0; i < N_IN_URB; i++)
489 usb_unlink_urb(portdata->in_urbs[i]); 495 usb_kill_urb(portdata->in_urbs[i]);
490 }
491 port->tty = NULL;
492}
493
494/* Helper functions used by sierra_setup_urbs */
495static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
496 int dir, void *ctx, char *buf, int len,
497 usb_complete_t callback)
498{
499 struct urb *urb;
500
501 if (endpoint == -1)
502 return NULL; /* endpoint not needed */
503
504 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
505 if (urb == NULL) {
506 dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
507 return NULL;
508 } 496 }
509 497
510 /* Fill URB using supplied data. */ 498 usb_kill_urb(port->interrupt_in_urb);
511 usb_fill_bulk_urb(urb, serial->dev,
512 usb_sndbulkpipe(serial->dev, endpoint) | dir,
513 buf, len, callback, ctx);
514
515 return urb;
516}
517 499
518/* Setup urbs */ 500 port->tty = NULL;
519static void sierra_setup_urbs(struct usb_serial *serial)
520{
521 int i,j;
522 struct usb_serial_port *port;
523 struct sierra_port_private *portdata;
524
525 dbg("%s", __FUNCTION__);
526
527 for (i = 0; i < serial->num_ports; i++) {
528 port = serial->port[i];
529 portdata = usb_get_serial_port_data(port);
530
531 /* Do indat endpoints first */
532 for (j = 0; j < N_IN_URB; ++j) {
533 portdata->in_urbs[j] = sierra_setup_urb (serial,
534 port->bulk_in_endpointAddress, USB_DIR_IN, port,
535 portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback);
536 }
537 }
538} 501}
539 502
540static int sierra_startup(struct usb_serial *serial) 503static int sierra_startup(struct usb_serial *serial)
541{ 504{
542 int i, err;
543 struct usb_serial_port *port; 505 struct usb_serial_port *port;
544 struct sierra_port_private *portdata; 506 struct sierra_port_private *portdata;
507 struct urb *urb;
508 int i;
509 int j;
545 510
546 dbg("%s", __FUNCTION__); 511 dbg("%s", __FUNCTION__);
547 512
@@ -558,16 +523,24 @@ static int sierra_startup(struct usb_serial *serial)
558 523
559 usb_set_serial_port_data(port, portdata); 524 usb_set_serial_port_data(port, portdata);
560 525
561 if (! port->interrupt_in_urb) 526 /* initialize the in urbs */
562 continue; 527 for (j = 0; j < N_IN_URB; ++j) {
563 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 528 urb = usb_alloc_urb(0, GFP_KERNEL);
564 if (err) 529 if (urb == NULL) {
565 dbg("%s: submit irq_in urb failed %d", 530 dbg("%s: alloc for in port failed.",
566 __FUNCTION__, err); 531 __FUNCTION__);
532 continue;
533 }
534 /* Fill URB using supplied data. */
535 usb_fill_bulk_urb(urb, serial->dev,
536 usb_rcvbulkpipe(serial->dev,
537 port->bulk_in_endpointAddress),
538 portdata->in_buffer[j], IN_BUFLEN,
539 sierra_indat_callback, port);
540 portdata->in_urbs[j] = urb;
541 }
567 } 542 }
568 543
569 sierra_setup_urbs(serial);
570
571 return 0; 544 return 0;
572} 545}
573 546
@@ -579,20 +552,6 @@ static void sierra_shutdown(struct usb_serial *serial)
579 552
580 dbg("%s", __FUNCTION__); 553 dbg("%s", __FUNCTION__);
581 554
582 /* Stop reading/writing urbs */
583 for (i = 0; i < serial->num_ports; ++i) {
584 port = serial->port[i];
585 if (!port)
586 continue;
587 portdata = usb_get_serial_port_data(port);
588 if (!portdata)
589 continue;
590
591 for (j = 0; j < N_IN_URB; j++)
592 usb_unlink_urb(portdata->in_urbs[j]);
593 }
594
595 /* Now free them */
596 for (i = 0; i < serial->num_ports; ++i) { 555 for (i = 0; i < serial->num_ports; ++i) {
597 port = serial->port[i]; 556 port = serial->port[i];
598 if (!port) 557 if (!port)
@@ -602,19 +561,12 @@ static void sierra_shutdown(struct usb_serial *serial)
602 continue; 561 continue;
603 562
604 for (j = 0; j < N_IN_URB; j++) { 563 for (j = 0; j < N_IN_URB; j++) {
605 if (portdata->in_urbs[j]) { 564 usb_kill_urb(portdata->in_urbs[j]);
606 usb_free_urb(portdata->in_urbs[j]); 565 usb_free_urb(portdata->in_urbs[j]);
607 portdata->in_urbs[j] = NULL; 566 portdata->in_urbs[j] = NULL;
608 }
609 } 567 }
610 } 568 kfree(portdata);
611 569 usb_set_serial_port_data(port, NULL);
612 /* Now free per port private data */
613 for (i = 0; i < serial->num_ports; i++) {
614 port = serial->port[i];
615 if (!port)
616 continue;
617 kfree(usb_get_serial_port_data(port));
618 } 570 }
619} 571}
620 572