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