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.c206
1 files changed, 127 insertions, 79 deletions
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index ca4bee173cfb..77d20ab0cd4d 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -104,12 +104,17 @@ 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);
110 111
112/* functions called before/after suspend */
113static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
114static int gigaset_resume(struct usb_interface *intf);
115static int gigaset_pre_reset(struct usb_interface *intf);
116
111static struct gigaset_driver *driver = NULL; 117static struct gigaset_driver *driver = NULL;
112static struct cardstate *cardstate = NULL;
113 118
114/* usb specific object needed to register this driver with the usb subsystem */ 119/* usb specific object needed to register this driver with the usb subsystem */
115static struct usb_driver gigaset_usb_driver = { 120static struct usb_driver gigaset_usb_driver = {
@@ -117,12 +122,17 @@ static struct usb_driver gigaset_usb_driver = {
117 .probe = gigaset_probe, 122 .probe = gigaset_probe,
118 .disconnect = gigaset_disconnect, 123 .disconnect = gigaset_disconnect,
119 .id_table = gigaset_table, 124 .id_table = gigaset_table,
125 .suspend = gigaset_suspend,
126 .resume = gigaset_resume,
127 .reset_resume = gigaset_resume,
128 .pre_reset = gigaset_pre_reset,
129 .post_reset = gigaset_resume,
120}; 130};
121 131
122struct usb_cardstate { 132struct usb_cardstate {
123 struct usb_device *udev; /* usb device pointer */ 133 struct usb_device *udev; /* usb device pointer */
124 struct usb_interface *interface; /* interface for this device */ 134 struct usb_interface *interface; /* interface for this device */
125 atomic_t busy; /* bulk output in progress */ 135 int busy; /* bulk output in progress */
126 136
127 /* Output buffer */ 137 /* Output buffer */
128 unsigned char *bulk_out_buffer; 138 unsigned char *bulk_out_buffer;
@@ -314,7 +324,7 @@ static void gigaset_modem_fill(unsigned long data)
314 324
315 gig_dbg(DEBUG_OUTPUT, "modem_fill"); 325 gig_dbg(DEBUG_OUTPUT, "modem_fill");
316 326
317 if (atomic_read(&cs->hw.usb->busy)) { 327 if (cs->hw.usb->busy) {
318 gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); 328 gig_dbg(DEBUG_OUTPUT, "modem_fill: busy");
319 return; 329 return;
320 } 330 }
@@ -361,18 +371,13 @@ static void gigaset_read_int_callback(struct urb *urb)
361{ 371{
362 struct inbuf_t *inbuf = urb->context; 372 struct inbuf_t *inbuf = urb->context;
363 struct cardstate *cs = inbuf->cs; 373 struct cardstate *cs = inbuf->cs;
364 int resubmit = 0; 374 int status = urb->status;
365 int r; 375 int r;
366 unsigned numbytes; 376 unsigned numbytes;
367 unsigned char *src; 377 unsigned char *src;
368 unsigned long flags; 378 unsigned long flags;
369 379
370 if (!urb->status) { 380 if (!status) {
371 if (!cs->connected) {
372 err("%s: disconnected", __func__); /* should never happen */
373 return;
374 }
375
376 numbytes = urb->actual_length; 381 numbytes = urb->actual_length;
377 382
378 if (numbytes) { 383 if (numbytes) {
@@ -389,28 +394,26 @@ static void gigaset_read_int_callback(struct urb *urb)
389 } 394 }
390 } else 395 } else
391 gig_dbg(DEBUG_INTR, "Received zero block length"); 396 gig_dbg(DEBUG_INTR, "Received zero block length");
392 resubmit = 1;
393 } else { 397 } else {
394 /* The urb might have been killed. */ 398 /* The urb might have been killed. */
395 gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", 399 gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",
396 __func__, urb->status); 400 __func__, status);
397 if (urb->status != -ENOENT) { /* not killed */ 401 if (status == -ENOENT || status == -ESHUTDOWN)
398 if (!cs->connected) { 402 /* killed or endpoint shutdown: don't resubmit */
399 err("%s: disconnected", __func__); /* should never happen */ 403 return;
400 return;
401 }
402 resubmit = 1;
403 }
404 } 404 }
405 405
406 if (resubmit) { 406 /* resubmit URB */
407 spin_lock_irqsave(&cs->lock, flags); 407 spin_lock_irqsave(&cs->lock, flags);
408 r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV; 408 if (!cs->connected) {
409 spin_unlock_irqrestore(&cs->lock, flags); 409 spin_unlock_irqrestore(&cs->lock, flags);
410 if (r) 410 err("%s: disconnected", __func__);
411 dev_err(cs->dev, "error %d when resubmitting urb.\n", 411 return;
412 -r);
413 } 412 }
413 r = usb_submit_urb(urb, GFP_ATOMIC);
414 spin_unlock_irqrestore(&cs->lock, flags);
415 if (r)
416 dev_err(cs->dev, "error %d resubmitting URB\n", -r);
414} 417}
415 418
416 419
@@ -418,19 +421,28 @@ static void gigaset_read_int_callback(struct urb *urb)
418static void gigaset_write_bulk_callback(struct urb *urb) 421static void gigaset_write_bulk_callback(struct urb *urb)
419{ 422{
420 struct cardstate *cs = urb->context; 423 struct cardstate *cs = urb->context;
424 int status = urb->status;
421 unsigned long flags; 425 unsigned long flags;
422 426
423 if (urb->status) 427 switch (status) {
428 case 0: /* normal completion */
429 break;
430 case -ENOENT: /* killed */
431 gig_dbg(DEBUG_ANY, "%s: killed", __func__);
432 cs->hw.usb->busy = 0;
433 return;
434 default:
424 dev_err(cs->dev, "bulk transfer failed (status %d)\n", 435 dev_err(cs->dev, "bulk transfer failed (status %d)\n",
425 -urb->status); 436 -status);
426 /* That's all we can do. Communication problems 437 /* That's all we can do. Communication problems
427 are handled by timeouts or network protocols. */ 438 are handled by timeouts or network protocols. */
439 }
428 440
429 spin_lock_irqsave(&cs->lock, flags); 441 spin_lock_irqsave(&cs->lock, flags);
430 if (!cs->connected) { 442 if (!cs->connected) {
431 err("%s: not connected", __func__); 443 err("%s: not connected", __func__);
432 } else { 444 } else {
433 atomic_set(&cs->hw.usb->busy, 0); 445 cs->hw.usb->busy = 0;
434 tasklet_schedule(&cs->write_tasklet); 446 tasklet_schedule(&cs->write_tasklet);
435 } 447 }
436 spin_unlock_irqrestore(&cs->lock, flags); 448 spin_unlock_irqrestore(&cs->lock, flags);
@@ -478,14 +490,14 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
478 490
479 cb->offset += count; 491 cb->offset += count;
480 cb->len -= count; 492 cb->len -= count;
481 atomic_set(&ucs->busy, 1); 493 ucs->busy = 1;
482 494
483 spin_lock_irqsave(&cs->lock, flags); 495 spin_lock_irqsave(&cs->lock, flags);
484 status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; 496 status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV;
485 spin_unlock_irqrestore(&cs->lock, flags); 497 spin_unlock_irqrestore(&cs->lock, flags);
486 498
487 if (status) { 499 if (status) {
488 atomic_set(&ucs->busy, 0); 500 ucs->busy = 0;
489 err("could not submit urb (error %d)\n", 501 err("could not submit urb (error %d)\n",
490 -status); 502 -status);
491 cb->len = 0; /* skip urb => remove cb+wakeup 503 cb->len = 0; /* skip urb => remove cb+wakeup
@@ -504,7 +516,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
504 struct cmdbuf_t *cb; 516 struct cmdbuf_t *cb;
505 unsigned long flags; 517 unsigned long flags;
506 518
507 gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? 519 gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
508 DEBUG_TRANSCMD : DEBUG_LOCKCMD, 520 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
509 "CMD Transmit", len, buf); 521 "CMD Transmit", len, buf);
510 522
@@ -641,7 +653,7 @@ static int write_modem(struct cardstate *cs)
641 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); 653 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
642 skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count); 654 skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);
643 skb_pull(bcs->tx_skb, count); 655 skb_pull(bcs->tx_skb, count);
644 atomic_set(&ucs->busy, 1); 656 ucs->busy = 1;
645 gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); 657 gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count);
646 658
647 spin_lock_irqsave(&cs->lock, flags); 659 spin_lock_irqsave(&cs->lock, flags);
@@ -659,7 +671,7 @@ static int write_modem(struct cardstate *cs)
659 671
660 if (ret) { 672 if (ret) {
661 err("could not submit urb (error %d)\n", -ret); 673 err("could not submit urb (error %d)\n", -ret);
662 atomic_set(&ucs->busy, 0); 674 ucs->busy = 0;
663 } 675 }
664 676
665 if (!bcs->tx_skb->len) { 677 if (!bcs->tx_skb->len) {
@@ -680,53 +692,44 @@ static int gigaset_probe(struct usb_interface *interface,
680{ 692{
681 int retval; 693 int retval;
682 struct usb_device *udev = interface_to_usbdev(interface); 694 struct usb_device *udev = interface_to_usbdev(interface);
683 unsigned int ifnum; 695 struct usb_host_interface *hostif = interface->cur_altsetting;
684 struct usb_host_interface *hostif;
685 struct cardstate *cs = NULL; 696 struct cardstate *cs = NULL;
686 struct usb_cardstate *ucs = NULL; 697 struct usb_cardstate *ucs = NULL;
687 struct usb_endpoint_descriptor *endpoint; 698 struct usb_endpoint_descriptor *endpoint;
688 int buffer_size; 699 int buffer_size;
689 int alt;
690 700
691 gig_dbg(DEBUG_ANY, 701 gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__);
692 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
693 __func__, le16_to_cpu(udev->descriptor.idVendor),
694 le16_to_cpu(udev->descriptor.idProduct));
695
696 retval = -ENODEV; //FIXME
697 702
698 /* See if the device offered us matches what we can accept */ 703 /* See if the device offered us matches what we can accept */
699 if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || 704 if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) ||
700 (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) 705 (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) {
706 gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip",
707 le16_to_cpu(udev->descriptor.idVendor),
708 le16_to_cpu(udev->descriptor.idProduct));
701 return -ENODEV; 709 return -ENODEV;
702 710 }
703 /* this starts to become ascii art... */ 711 if (hostif->desc.bInterfaceNumber != 0) {
704 hostif = interface->cur_altsetting; 712 gig_dbg(DEBUG_ANY, "interface %d not for me - skip",
705 alt = hostif->desc.bAlternateSetting; 713 hostif->desc.bInterfaceNumber);
706 ifnum = hostif->desc.bInterfaceNumber; // FIXME ? 714 return -ENODEV;
707 715 }
708 if (alt != 0 || ifnum != 0) { 716 if (hostif->desc.bAlternateSetting != 0) {
709 dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); 717 dev_notice(&udev->dev, "unsupported altsetting %d - skip",
718 hostif->desc.bAlternateSetting);
710 return -ENODEV; 719 return -ENODEV;
711 } 720 }
712
713 /* Reject application specific intefaces
714 *
715 */
716 if (hostif->desc.bInterfaceClass != 255) { 721 if (hostif->desc.bInterfaceClass != 255) {
717 dev_info(&udev->dev, 722 dev_notice(&udev->dev, "unsupported interface class %d - skip",
718 "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", 723 hostif->desc.bInterfaceClass);
719 __func__, ifnum, hostif->desc.bInterfaceClass);
720 return -ENODEV; 724 return -ENODEV;
721 } 725 }
722 726
723 dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); 727 dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
724 728
725 cs = gigaset_getunassignedcs(driver); 729 /* allocate memory for our device state and intialize it */
726 if (!cs) { 730 cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
727 dev_warn(&udev->dev, "no free cardstate\n"); 731 if (!cs)
728 return -ENODEV; 732 return -ENODEV;
729 }
730 ucs = cs->hw.usb; 733 ucs = cs->hw.usb;
731 734
732 /* save off device structure ptrs for later use */ 735 /* save off device structure ptrs for later use */
@@ -759,7 +762,7 @@ static int gigaset_probe(struct usb_interface *interface,
759 762
760 endpoint = &hostif->endpoint[1].desc; 763 endpoint = &hostif->endpoint[1].desc;
761 764
762 atomic_set(&ucs->busy, 0); 765 ucs->busy = 0;
763 766
764 ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); 767 ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);
765 if (!ucs->read_urb) { 768 if (!ucs->read_urb) {
@@ -792,7 +795,7 @@ static int gigaset_probe(struct usb_interface *interface,
792 795
793 /* tell common part that the device is ready */ 796 /* tell common part that the device is ready */
794 if (startmode == SM_LOCKED) 797 if (startmode == SM_LOCKED)
795 atomic_set(&cs->mstate, MS_LOCKED); 798 cs->mstate = MS_LOCKED;
796 799
797 if (!gigaset_start(cs)) { 800 if (!gigaset_start(cs)) {
798 tasklet_kill(&cs->write_tasklet); 801 tasklet_kill(&cs->write_tasklet);
@@ -813,7 +816,7 @@ error:
813 usb_put_dev(ucs->udev); 816 usb_put_dev(ucs->udev);
814 ucs->udev = NULL; 817 ucs->udev = NULL;
815 ucs->interface = NULL; 818 ucs->interface = NULL;
816 gigaset_unassign(cs); 819 gigaset_freecs(cs);
817 return retval; 820 return retval;
818} 821}
819 822
@@ -824,6 +827,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
824 827
825 cs = usb_get_intfdata(interface); 828 cs = usb_get_intfdata(interface);
826 ucs = cs->hw.usb; 829 ucs = cs->hw.usb;
830
831 dev_info(cs->dev, "disconnecting Gigaset USB adapter\n");
832
827 usb_kill_urb(ucs->read_urb); 833 usb_kill_urb(ucs->read_urb);
828 834
829 gigaset_stop(cs); 835 gigaset_stop(cs);
@@ -831,7 +837,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
831 usb_set_intfdata(interface, NULL); 837 usb_set_intfdata(interface, NULL);
832 tasklet_kill(&cs->write_tasklet); 838 tasklet_kill(&cs->write_tasklet);
833 839
834 usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ 840 usb_kill_urb(ucs->bulk_out_urb);
835 841
836 kfree(ucs->bulk_out_buffer); 842 kfree(ucs->bulk_out_buffer);
837 usb_free_urb(ucs->bulk_out_urb); 843 usb_free_urb(ucs->bulk_out_urb);
@@ -844,7 +850,53 @@ static void gigaset_disconnect(struct usb_interface *interface)
844 ucs->interface = NULL; 850 ucs->interface = NULL;
845 ucs->udev = NULL; 851 ucs->udev = NULL;
846 cs->dev = NULL; 852 cs->dev = NULL;
847 gigaset_unassign(cs); 853 gigaset_freecs(cs);
854}
855
856/* gigaset_suspend
857 * This function is called before the USB connection is suspended or reset.
858 */
859static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
860{
861 struct cardstate *cs = usb_get_intfdata(intf);
862
863 /* stop activity */
864 cs->connected = 0; /* prevent rescheduling */
865 usb_kill_urb(cs->hw.usb->read_urb);
866 tasklet_kill(&cs->write_tasklet);
867 usb_kill_urb(cs->hw.usb->bulk_out_urb);
868
869 gig_dbg(DEBUG_SUSPEND, "suspend complete");
870 return 0;
871}
872
873/* gigaset_resume
874 * This function is called after the USB connection has been resumed or reset.
875 */
876static int gigaset_resume(struct usb_interface *intf)
877{
878 struct cardstate *cs = usb_get_intfdata(intf);
879 int rc;
880
881 /* resubmit interrupt URB */
882 cs->connected = 1;
883 rc = usb_submit_urb(cs->hw.usb->read_urb, GFP_KERNEL);
884 if (rc) {
885 dev_err(cs->dev, "Could not submit read URB (error %d)\n", -rc);
886 return rc;
887 }
888
889 gig_dbg(DEBUG_SUSPEND, "resume complete");
890 return 0;
891}
892
893/* gigaset_pre_reset
894 * This function is called before the USB connection is reset.
895 */
896static int gigaset_pre_reset(struct usb_interface *intf)
897{
898 /* same as suspend */
899 return gigaset_suspend(intf, PMSG_ON);
848} 900}
849 901
850static const struct gigaset_ops ops = { 902static const struct gigaset_ops ops = {
@@ -880,11 +932,6 @@ static int __init usb_gigaset_init(void)
880 &ops, THIS_MODULE)) == NULL) 932 &ops, THIS_MODULE)) == NULL)
881 goto error; 933 goto error;
882 934
883 /* allocate memory for our device state and intialize it */
884 cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
885 if (!cardstate)
886 goto error;
887
888 /* register this driver with the USB subsystem */ 935 /* register this driver with the USB subsystem */
889 result = usb_register(&gigaset_usb_driver); 936 result = usb_register(&gigaset_usb_driver);
890 if (result < 0) { 937 if (result < 0) {
@@ -897,9 +944,7 @@ static int __init usb_gigaset_init(void)
897 info(DRIVER_DESC); 944 info(DRIVER_DESC);
898 return 0; 945 return 0;
899 946
900error: if (cardstate) 947error:
901 gigaset_freecs(cardstate);
902 cardstate = NULL;
903 if (driver) 948 if (driver)
904 gigaset_freedriver(driver); 949 gigaset_freedriver(driver);
905 driver = NULL; 950 driver = NULL;
@@ -913,11 +958,16 @@ error: if (cardstate)
913 */ 958 */
914static void __exit usb_gigaset_exit(void) 959static void __exit usb_gigaset_exit(void)
915{ 960{
961 int i;
962
916 gigaset_blockdriver(driver); /* => probe will fail 963 gigaset_blockdriver(driver); /* => probe will fail
917 * => no gigaset_start any more 964 * => no gigaset_start any more
918 */ 965 */
919 966
920 gigaset_shutdown(cardstate); 967 /* stop all connected devices */
968 for (i = 0; i < driver->minors; i++)
969 gigaset_shutdown(driver->cs + i);
970
921 /* from now on, no isdn callback should be possible */ 971 /* from now on, no isdn callback should be possible */
922 972
923 /* deregister this driver with the USB subsystem */ 973 /* deregister this driver with the USB subsystem */
@@ -925,8 +975,6 @@ static void __exit usb_gigaset_exit(void)
925 /* this will call the disconnect-callback */ 975 /* this will call the disconnect-callback */
926 /* from now on, no disconnect/probe callback should be running */ 976 /* from now on, no disconnect/probe callback should be running */
927 977
928 gigaset_freecs(cardstate);
929 cardstate = NULL;
930 gigaset_freedriver(driver); 978 gigaset_freedriver(driver);
931 driver = NULL; 979 driver = NULL;
932} 980}