diff options
-rw-r--r-- | drivers/usb/serial/sierra.c | 130 |
1 files changed, 41 insertions, 89 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 551c6ce89f66..e7db20343d1a 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 | ||
472 | static void sierra_close(struct usb_serial_port *port, struct file *filp) | 478 | static 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 */ | ||
495 | static 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; |
519 | static 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 | ||
540 | static int sierra_startup(struct usb_serial *serial) | 503 | static 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 | ||