aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb_wwan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb_wwan.c')
-rw-r--r--drivers/usb/serial/usb_wwan.c130
1 files changed, 53 insertions, 77 deletions
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index e42aa398ed37..a3e9c095f0d8 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -447,15 +447,14 @@ void usb_wwan_close(struct usb_serial_port *port)
447EXPORT_SYMBOL(usb_wwan_close); 447EXPORT_SYMBOL(usb_wwan_close);
448 448
449/* Helper functions used by usb_wwan_setup_urbs */ 449/* Helper functions used by usb_wwan_setup_urbs */
450static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, 450static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
451 int endpoint,
451 int dir, void *ctx, char *buf, int len, 452 int dir, void *ctx, char *buf, int len,
452 void (*callback) (struct urb *)) 453 void (*callback) (struct urb *))
453{ 454{
455 struct usb_serial *serial = port->serial;
454 struct urb *urb; 456 struct urb *urb;
455 457
456 if (endpoint == -1)
457 return NULL; /* endpoint not needed */
458
459 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ 458 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
460 if (urb == NULL) { 459 if (urb == NULL) {
461 dev_dbg(&serial->interface->dev, 460 dev_dbg(&serial->interface->dev,
@@ -472,101 +471,78 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
472 return urb; 471 return urb;
473} 472}
474 473
475/* Setup urbs */ 474int usb_wwan_port_probe(struct usb_serial_port *port)
476static void usb_wwan_setup_urbs(struct usb_serial *serial)
477{ 475{
478 int i, j;
479 struct usb_serial_port *port;
480 struct usb_wwan_port_private *portdata; 476 struct usb_wwan_port_private *portdata;
477 struct urb *urb;
478 u8 *buffer;
479 int err;
480 int i;
481 481
482 for (i = 0; i < serial->num_ports; i++) { 482 portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
483 port = serial->port[i]; 483 if (!portdata)
484 portdata = usb_get_serial_port_data(port); 484 return -ENOMEM;
485 485
486 /* Do indat endpoints first */ 486 init_usb_anchor(&portdata->delayed);
487 for (j = 0; j < N_IN_URB; ++j) {
488 portdata->in_urbs[j] = usb_wwan_setup_urb(serial,
489 port->
490 bulk_in_endpointAddress,
491 USB_DIR_IN,
492 port,
493 portdata->
494 in_buffer[j],
495 IN_BUFLEN,
496 usb_wwan_indat_callback);
497 }
498 487
499 /* outdat endpoints */ 488 for (i = 0; i < N_IN_URB; i++) {
500 for (j = 0; j < N_OUT_URB; ++j) { 489 if (!port->bulk_in_size)
501 portdata->out_urbs[j] = usb_wwan_setup_urb(serial, 490 break;
502 port->
503 bulk_out_endpointAddress,
504 USB_DIR_OUT,
505 port,
506 portdata->
507 out_buffer
508 [j],
509 OUT_BUFLEN,
510 usb_wwan_outdat_callback);
511 }
512 }
513}
514 491
515int usb_wwan_startup(struct usb_serial *serial) 492 buffer = (u8 *)__get_free_page(GFP_KERNEL);
516{ 493 if (!buffer)
517 int i, j, err; 494 goto bail_out_error;
518 struct usb_serial_port *port; 495 portdata->in_buffer[i] = buffer;
519 struct usb_wwan_port_private *portdata;
520 u8 *buffer;
521 496
522 /* Now setup per port private data */ 497 urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
523 for (i = 0; i < serial->num_ports; i++) { 498 USB_DIR_IN, port,
524 port = serial->port[i]; 499 buffer, IN_BUFLEN,
525 portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); 500 usb_wwan_indat_callback);
526 if (!portdata) { 501 portdata->in_urbs[i] = urb;
527 dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n", 502 }
528 __func__, i);
529 return 1;
530 }
531 init_usb_anchor(&portdata->delayed);
532 503
533 for (j = 0; j < N_IN_URB; j++) { 504 for (i = 0; i < N_OUT_URB; i++) {
534 buffer = (u8 *) __get_free_page(GFP_KERNEL); 505 if (!port->bulk_out_size)
535 if (!buffer) 506 break;
536 goto bail_out_error;
537 portdata->in_buffer[j] = buffer;
538 }
539 507
540 for (j = 0; j < N_OUT_URB; j++) { 508 buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
541 buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); 509 if (!buffer)
542 if (!buffer) 510 goto bail_out_error2;
543 goto bail_out_error2; 511 portdata->out_buffer[i] = buffer;
544 portdata->out_buffer[j] = buffer;
545 }
546 512
547 usb_set_serial_port_data(port, portdata); 513 urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
514 USB_DIR_OUT, port,
515 buffer, OUT_BUFLEN,
516 usb_wwan_outdat_callback);
517 portdata->out_urbs[i] = urb;
518 }
548 519
549 if (!port->interrupt_in_urb) 520 usb_set_serial_port_data(port, portdata);
550 continue; 521
522 if (port->interrupt_in_urb) {
551 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 523 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
552 if (err) 524 if (err)
553 dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", 525 dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n",
554 __func__, err); 526 __func__, err);
555 } 527 }
556 usb_wwan_setup_urbs(serial); 528
557 return 0; 529 return 0;
558 530
559bail_out_error2: 531bail_out_error2:
560 for (j = 0; j < N_OUT_URB; j++) 532 for (i = 0; i < N_OUT_URB; i++) {
561 kfree(portdata->out_buffer[j]); 533 usb_free_urb(portdata->out_urbs[i]);
534 kfree(portdata->out_buffer[i]);
535 }
562bail_out_error: 536bail_out_error:
563 for (j = 0; j < N_IN_URB; j++) 537 for (i = 0; i < N_IN_URB; i++) {
564 if (portdata->in_buffer[j]) 538 usb_free_urb(portdata->in_urbs[i]);
565 free_page((unsigned long)portdata->in_buffer[j]); 539 free_page((unsigned long)portdata->in_buffer[i]);
540 }
566 kfree(portdata); 541 kfree(portdata);
567 return 1; 542
543 return -ENOMEM;
568} 544}
569EXPORT_SYMBOL(usb_wwan_startup); 545EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
570 546
571int usb_wwan_port_remove(struct usb_serial_port *port) 547int usb_wwan_port_remove(struct usb_serial_port *port)
572{ 548{