aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/usb-gigaset.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/usb-gigaset.c')
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c92
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 0bd5d4ba11cd..d81c0e3f7702 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -104,6 +104,7 @@ MODULE_DEVICE_TABLE(usb, gigaset_table);
104 * flags per packet. 104 * flags per packet.
105 */ 105 */
106 106
107/* functions called if a device of this driver is connected/disconnected */
107static int gigaset_probe(struct usb_interface *interface, 108static int gigaset_probe(struct usb_interface *interface,
108 const struct usb_device_id *id); 109 const struct usb_device_id *id);
109static void gigaset_disconnect(struct usb_interface *interface); 110static void gigaset_disconnect(struct usb_interface *interface);
@@ -362,18 +363,12 @@ static void gigaset_read_int_callback(struct urb *urb)
362 struct inbuf_t *inbuf = urb->context; 363 struct inbuf_t *inbuf = urb->context;
363 struct cardstate *cs = inbuf->cs; 364 struct cardstate *cs = inbuf->cs;
364 int status = urb->status; 365 int status = urb->status;
365 int resubmit = 0;
366 int r; 366 int r;
367 unsigned numbytes; 367 unsigned numbytes;
368 unsigned char *src; 368 unsigned char *src;
369 unsigned long flags; 369 unsigned long flags;
370 370
371 if (!status) { 371 if (!status) {
372 if (!cs->connected) {
373 err("%s: disconnected", __func__); /* should never happen */
374 return;
375 }
376
377 numbytes = urb->actual_length; 372 numbytes = urb->actual_length;
378 373
379 if (numbytes) { 374 if (numbytes) {
@@ -390,28 +385,26 @@ static void gigaset_read_int_callback(struct urb *urb)
390 } 385 }
391 } else 386 } else
392 gig_dbg(DEBUG_INTR, "Received zero block length"); 387 gig_dbg(DEBUG_INTR, "Received zero block length");
393 resubmit = 1;
394 } else { 388 } else {
395 /* The urb might have been killed. */ 389 /* The urb might have been killed. */
396 gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", 390 gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",
397 __func__, status); 391 __func__, status);
398 if (status != -ENOENT) { /* not killed */ 392 if (status == -ENOENT || status == -ESHUTDOWN)
399 if (!cs->connected) { 393 /* killed or endpoint shutdown: don't resubmit */
400 err("%s: disconnected", __func__); /* should never happen */ 394 return;
401 return;
402 }
403 resubmit = 1;
404 }
405 } 395 }
406 396
407 if (resubmit) { 397 /* resubmit URB */
408 spin_lock_irqsave(&cs->lock, flags); 398 spin_lock_irqsave(&cs->lock, flags);
409 r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV; 399 if (!cs->connected) {
410 spin_unlock_irqrestore(&cs->lock, flags); 400 spin_unlock_irqrestore(&cs->lock, flags);
411 if (r) 401 err("%s: disconnected", __func__);
412 dev_err(cs->dev, "error %d when resubmitting urb.\n", 402 return;
413 -r);
414 } 403 }
404 r = usb_submit_urb(urb, GFP_ATOMIC);
405 spin_unlock_irqrestore(&cs->lock, flags);
406 if (r)
407 dev_err(cs->dev, "error %d resubmitting URB\n", -r);
415} 408}
416 409
417 410
@@ -422,11 +415,19 @@ static void gigaset_write_bulk_callback(struct urb *urb)
422 int status = urb->status; 415 int status = urb->status;
423 unsigned long flags; 416 unsigned long flags;
424 417
425 if (status) 418 switch (status) {
419 case 0: /* normal completion */
420 break;
421 case -ENOENT: /* killed */
422 gig_dbg(DEBUG_ANY, "%s: killed", __func__);
423 atomic_set(&cs->hw.usb->busy, 0);
424 return;
425 default:
426 dev_err(cs->dev, "bulk transfer failed (status %d)\n", 426 dev_err(cs->dev, "bulk transfer failed (status %d)\n",
427 -status); 427 -status);
428 /* That's all we can do. Communication problems 428 /* That's all we can do. Communication problems
429 are handled by timeouts or network protocols. */ 429 are handled by timeouts or network protocols. */
430 }
430 431
431 spin_lock_irqsave(&cs->lock, flags); 432 spin_lock_irqsave(&cs->lock, flags);
432 if (!cs->connected) { 433 if (!cs->connected) {
@@ -682,43 +683,35 @@ static int gigaset_probe(struct usb_interface *interface,
682{ 683{
683 int retval; 684 int retval;
684 struct usb_device *udev = interface_to_usbdev(interface); 685 struct usb_device *udev = interface_to_usbdev(interface);
685 unsigned int ifnum; 686 struct usb_host_interface *hostif = interface->cur_altsetting;
686 struct usb_host_interface *hostif;
687 struct cardstate *cs = NULL; 687 struct cardstate *cs = NULL;
688 struct usb_cardstate *ucs = NULL; 688 struct usb_cardstate *ucs = NULL;
689 struct usb_endpoint_descriptor *endpoint; 689 struct usb_endpoint_descriptor *endpoint;
690 int buffer_size; 690 int buffer_size;
691 int alt;
692
693 gig_dbg(DEBUG_ANY,
694 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
695 __func__, le16_to_cpu(udev->descriptor.idVendor),
696 le16_to_cpu(udev->descriptor.idProduct));
697 691
698 retval = -ENODEV; //FIXME 692 gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__);
699 693
700 /* See if the device offered us matches what we can accept */ 694 /* See if the device offered us matches what we can accept */
701 if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || 695 if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) ||
702 (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) 696 (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) {
697 gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip",
698 le16_to_cpu(udev->descriptor.idVendor),
699 le16_to_cpu(udev->descriptor.idProduct));
703 return -ENODEV; 700 return -ENODEV;
704 701 }
705 /* this starts to become ascii art... */ 702 if (hostif->desc.bInterfaceNumber != 0) {
706 hostif = interface->cur_altsetting; 703 gig_dbg(DEBUG_ANY, "interface %d not for me - skip",
707 alt = hostif->desc.bAlternateSetting; 704 hostif->desc.bInterfaceNumber);
708 ifnum = hostif->desc.bInterfaceNumber; // FIXME ? 705 return -ENODEV;
709 706 }
710 if (alt != 0 || ifnum != 0) { 707 if (hostif->desc.bAlternateSetting != 0) {
711 dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); 708 dev_notice(&udev->dev, "unsupported altsetting %d - skip",
709 hostif->desc.bAlternateSetting);
712 return -ENODEV; 710 return -ENODEV;
713 } 711 }
714
715 /* Reject application specific intefaces
716 *
717 */
718 if (hostif->desc.bInterfaceClass != 255) { 712 if (hostif->desc.bInterfaceClass != 255) {
719 dev_info(&udev->dev, 713 dev_notice(&udev->dev, "unsupported interface class %d - skip",
720 "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", 714 hostif->desc.bInterfaceClass);
721 __func__, ifnum, hostif->desc.bInterfaceClass);
722 return -ENODEV; 715 return -ENODEV;
723 } 716 }
724 717
@@ -826,6 +819,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
826 819
827 cs = usb_get_intfdata(interface); 820 cs = usb_get_intfdata(interface);
828 ucs = cs->hw.usb; 821 ucs = cs->hw.usb;
822
823 dev_info(cs->dev, "disconnecting Gigaset USB adapter\n");
824
829 usb_kill_urb(ucs->read_urb); 825 usb_kill_urb(ucs->read_urb);
830 826
831 gigaset_stop(cs); 827 gigaset_stop(cs);
@@ -833,7 +829,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
833 usb_set_intfdata(interface, NULL); 829 usb_set_intfdata(interface, NULL);
834 tasklet_kill(&cs->write_tasklet); 830 tasklet_kill(&cs->write_tasklet);
835 831
836 usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ 832 usb_kill_urb(ucs->bulk_out_urb);
837 833
838 kfree(ucs->bulk_out_buffer); 834 kfree(ucs->bulk_out_buffer);
839 usb_free_urb(ucs->bulk_out_urb); 835 usb_free_urb(ucs->bulk_out_urb);