linux/drivers/isdn/hisax/st5481_init.c
<<
>>
Prefs
   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/* 
  14 * TODO:
  15 *
  16 * b layer1 delay?
  17 * hotplug / unregister issues
  18 * mod_inc/dec_use_count
  19 * unify parts of d/b channel usb handling
  20 * file header
  21 * avoid copy to isoc buffer?
  22 * improve usb delay?
  23 * merge l1 state machines?
  24 * clean up debug
  25 */
  26
  27#include <linux/module.h>
  28#include <linux/init.h>
  29#include <linux/usb.h>
  30#include <linux/slab.h>
  31#include "st5481.h"
  32
  33MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter");
  34MODULE_AUTHOR("Frode Isaksen");
  35MODULE_LICENSE("GPL");
  36
  37static int protocol = 2;       /* EURO-ISDN Default */
  38module_param(protocol, int, 0);
  39
  40static int number_of_leds = 2;       /* 2 LEDs on the adpater default */
  41module_param(number_of_leds, int, 0);
  42
  43#ifdef CONFIG_HISAX_DEBUG
  44static int debug = 0;
  45module_param(debug, int, 0);
  46#endif
  47int st5481_debug;
  48
  49static LIST_HEAD(adapter_list);
  50
  51/* ======================================================================
  52 * registration/deregistration with the USB layer
  53 */
  54
  55/*
  56 * This function will be called when the adapter is plugged
  57 * into the USB bus.
  58 */
  59static int probe_st5481(struct usb_interface *intf,
  60                        const struct usb_device_id *id)
  61{
  62        struct usb_device *dev = interface_to_usbdev(intf);
  63        struct st5481_adapter *adapter;
  64        struct hisax_b_if *b_if[2];
  65        int retval, i;
  66
  67        printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
  68             le16_to_cpu(dev->descriptor.idVendor),
  69             le16_to_cpu(dev->descriptor.idProduct),
  70             number_of_leds);
  71
  72        adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
  73        if (!adapter)
  74                return -ENOMEM;
  75
  76        adapter->number_of_leds = number_of_leds;
  77        adapter->usb_dev = dev;
  78
  79        adapter->hisax_d_if.owner = THIS_MODULE;
  80        adapter->hisax_d_if.ifc.priv = adapter;
  81        adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1;
  82
  83        for (i = 0; i < 2; i++) {
  84                adapter->bcs[i].adapter = adapter;
  85                adapter->bcs[i].channel = i;
  86                adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
  87                adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
  88        }
  89        list_add(&adapter->list, &adapter_list);
  90
  91        retval = st5481_setup_usb(adapter);
  92        if (retval < 0)
  93                goto err;
  94
  95        retval = st5481_setup_d(adapter);
  96        if (retval < 0)
  97                goto err_usb;
  98
  99        retval = st5481_setup_b(&adapter->bcs[0]);
 100        if (retval < 0)
 101                goto err_d;
 102
 103        retval = st5481_setup_b(&adapter->bcs[1]);
 104        if (retval < 0)
 105                goto err_b;
 106
 107        for (i = 0; i < 2; i++)
 108                b_if[i] = &adapter->bcs[i].b_if;
 109
 110        if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
 111                        protocol) != 0)
 112                goto err_b1;
 113
 114        st5481_start(adapter);
 115
 116        usb_set_intfdata(intf, adapter);
 117        return 0;
 118
 119 err_b1:
 120        st5481_release_b(&adapter->bcs[1]);
 121 err_b:
 122        st5481_release_b(&adapter->bcs[0]);
 123 err_d:
 124        st5481_release_d(adapter);
 125 err_usb:
 126        st5481_release_usb(adapter);
 127 err:
 128        return -EIO;
 129}
 130
 131/*
 132 * This function will be called when the adapter is removed
 133 * from the USB bus.
 134 */
 135static void disconnect_st5481(struct usb_interface *intf)
 136{
 137        struct st5481_adapter *adapter = usb_get_intfdata(intf);
 138
 139        DBG(1,"");
 140
 141        usb_set_intfdata(intf, NULL);
 142        if (!adapter)
 143                return;
 144        
 145        list_del(&adapter->list);
 146
 147        st5481_stop(adapter);
 148        st5481_release_b(&adapter->bcs[1]);
 149        st5481_release_b(&adapter->bcs[0]);
 150        st5481_release_d(adapter);
 151        // we would actually better wait for completion of outstanding urbs
 152        mdelay(2);
 153        st5481_release_usb(adapter);
 154
 155        hisax_unregister(&adapter->hisax_d_if);
 156
 157        kfree(adapter);
 158}
 159
 160/*
 161 * The last 4 bits in the Product Id is set with 4 pins on the chip.
 162 */
 163static struct usb_device_id st5481_ids[] = {
 164        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x0) },
 165        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x1) },
 166        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x2) },
 167        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x3) },
 168        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x4) },
 169        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x5) },
 170        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x6) },
 171        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x7) },
 172        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x8) },
 173        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x9) },
 174        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xA) },
 175        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xB) },
 176        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xC) },
 177        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xD) },
 178        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xE) },
 179        { USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xF) },
 180        { }
 181};
 182MODULE_DEVICE_TABLE (usb, st5481_ids);
 183
 184static struct usb_driver st5481_usb_driver = {
 185        .name =         "st5481_usb",
 186        .probe =        probe_st5481,
 187        .disconnect =   disconnect_st5481,
 188        .id_table =     st5481_ids,
 189};
 190
 191static int __init st5481_usb_init(void)
 192{
 193        int retval;
 194
 195#ifdef CONFIG_HISAX_DEBUG
 196        st5481_debug = debug;
 197#endif
 198
 199        printk(KERN_INFO "hisax_st5481: ST5481 USB ISDN driver $Revision: 2.4.2.3 $\n");
 200
 201        retval = st5481_d_init();
 202        if (retval < 0)
 203                goto out;
 204
 205        retval = usb_register(&st5481_usb_driver);
 206        if (retval < 0)
 207                goto out_d_exit;
 208
 209        return 0;
 210
 211 out_d_exit:
 212        st5481_d_exit();
 213 out:
 214        return retval;
 215}
 216
 217static void __exit st5481_usb_exit(void)
 218{
 219        usb_deregister(&st5481_usb_driver);
 220        st5481_d_exit();
 221}
 222
 223module_init(st5481_usb_init);
 224module_exit(st5481_usb_exit);
 225
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.