st5481_init.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Driver for ST5481 USB ISDN modem
  3. *
  4. * Author Frode Isaksen
  5. * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com>
  6. * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
  7. *
  8. * This software may be used and distributed according to the terms
  9. * of the GNU General Public License, incorporated herein by reference.
  10. *
  11. */
  12. /*
  13. * TODO:
  14. *
  15. * b layer1 delay?
  16. * hotplug / unregister issues
  17. * mod_inc/dec_use_count
  18. * unify parts of d/b channel usb handling
  19. * file header
  20. * avoid copy to isoc buffer?
  21. * improve usb delay?
  22. * merge l1 state machines?
  23. * clean up debug
  24. */
  25. #include <linux/module.h>
  26. #include <linux/init.h>
  27. #include <linux/usb.h>
  28. #include <linux/slab.h>
  29. #include "st5481.h"
  30. MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter");
  31. MODULE_AUTHOR("Frode Isaksen");
  32. MODULE_LICENSE("GPL");
  33. static int protocol = 2; /* EURO-ISDN Default */
  34. module_param(protocol, int, 0);
  35. static int number_of_leds = 2; /* 2 LEDs on the adpater default */
  36. module_param(number_of_leds, int, 0);
  37. #ifdef CONFIG_HISAX_DEBUG
  38. static int debug = 0;
  39. module_param(debug, int, 0);
  40. #endif
  41. int st5481_debug;
  42. /* ======================================================================
  43. * registration/deregistration with the USB layer
  44. */
  45. /*
  46. * This function will be called when the adapter is plugged
  47. * into the USB bus.
  48. */
  49. static int probe_st5481(struct usb_interface *intf,
  50. const struct usb_device_id *id)
  51. {
  52. struct usb_device *dev = interface_to_usbdev(intf);
  53. struct st5481_adapter *adapter;
  54. struct hisax_b_if *b_if[2];
  55. int retval, i;
  56. printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
  57. le16_to_cpu(dev->descriptor.idVendor),
  58. le16_to_cpu(dev->descriptor.idProduct),
  59. number_of_leds);
  60. adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
  61. if (!adapter)
  62. return -ENOMEM;
  63. adapter->number_of_leds = number_of_leds;
  64. adapter->usb_dev = dev;
  65. adapter->hisax_d_if.owner = THIS_MODULE;
  66. adapter->hisax_d_if.ifc.priv = adapter;
  67. adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1;
  68. for (i = 0; i < 2; i++) {
  69. adapter->bcs[i].adapter = adapter;
  70. adapter->bcs[i].channel = i;
  71. adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
  72. adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
  73. }
  74. retval = st5481_setup_usb(adapter);
  75. if (retval < 0)
  76. goto err;
  77. retval = st5481_setup_d(adapter);
  78. if (retval < 0)
  79. goto err_usb;
  80. retval = st5481_setup_b(&adapter->bcs[0]);
  81. if (retval < 0)
  82. goto err_d;
  83. retval = st5481_setup_b(&adapter->bcs[1]);
  84. if (retval < 0)
  85. goto err_b;
  86. for (i = 0; i < 2; i++)
  87. b_if[i] = &adapter->bcs[i].b_if;
  88. if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
  89. protocol) != 0)
  90. goto err_b1;
  91. st5481_start(adapter);
  92. usb_set_intfdata(intf, adapter);
  93. return 0;
  94. err_b1:
  95. st5481_release_b(&adapter->bcs[1]);
  96. err_b:
  97. st5481_release_b(&adapter->bcs[0]);
  98. err_d:
  99. st5481_release_d(adapter);
  100. err_usb:
  101. st5481_release_usb(adapter);
  102. err:
  103. kfree(adapter);
  104. return -EIO;
  105. }
  106. /*
  107. * This function will be called when the adapter is removed
  108. * from the USB bus.
  109. */
  110. static void disconnect_st5481(struct usb_interface *intf)
  111. {
  112. struct st5481_adapter *adapter = usb_get_intfdata(intf);
  113. DBG(1, "");
  114. usb_set_intfdata(intf, NULL);
  115. if (!adapter)
  116. return;
  117. st5481_stop(adapter);
  118. st5481_release_b(&adapter->bcs[1]);
  119. st5481_release_b(&adapter->bcs[0]);
  120. st5481_release_d(adapter);
  121. // we would actually better wait for completion of outstanding urbs
  122. mdelay(2);
  123. st5481_release_usb(adapter);
  124. hisax_unregister(&adapter->hisax_d_if);
  125. kfree(adapter);
  126. }
  127. /*
  128. * The last 4 bits in the Product Id is set with 4 pins on the chip.
  129. */
  130. static struct usb_device_id st5481_ids[] = {
  131. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x0) },
  132. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x1) },
  133. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x2) },
  134. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x3) },
  135. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x4) },
  136. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x5) },
  137. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x6) },
  138. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x7) },
  139. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x8) },
  140. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x9) },
  141. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xA) },
  142. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xB) },
  143. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xC) },
  144. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xD) },
  145. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xE) },
  146. { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xF) },
  147. { }
  148. };
  149. MODULE_DEVICE_TABLE(usb, st5481_ids);
  150. static struct usb_driver st5481_usb_driver = {
  151. .name = "st5481_usb",
  152. .probe = probe_st5481,
  153. .disconnect = disconnect_st5481,
  154. .id_table = st5481_ids,
  155. .disable_hub_initiated_lpm = 1,
  156. };
  157. static int __init st5481_usb_init(void)
  158. {
  159. int retval;
  160. #ifdef CONFIG_HISAX_DEBUG
  161. st5481_debug = debug;
  162. #endif
  163. printk(KERN_INFO "hisax_st5481: ST5481 USB ISDN driver $Revision: 2.4.2.3 $\n");
  164. retval = st5481_d_init();
  165. if (retval < 0)
  166. goto out;
  167. retval = usb_register(&st5481_usb_driver);
  168. if (retval < 0)
  169. goto out_d_exit;
  170. return 0;
  171. out_d_exit:
  172. st5481_d_exit();
  173. out:
  174. return retval;
  175. }
  176. static void __exit st5481_usb_exit(void)
  177. {
  178. usb_deregister(&st5481_usb_driver);
  179. st5481_d_exit();
  180. }
  181. module_init(st5481_usb_init);
  182. module_exit(st5481_usb_exit);