aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
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