Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / isdn / hisax / hfc_usb.c
index ffd74b8..262c441 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * hfc_usb.c
  *
- * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $
+ * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $
  *
  * modular HiSax ISDN driver for Colognechip HFC-S USB chip
  *
 #include "hisax_if.h"
 #include "hfc_usb.h"
 
-/*
-* Version Information
-* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
-*/
 static const char *hfcusb_revision =
-    "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ ";
+    "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ ";
 
 /* Hisax debug support
 * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -60,83 +56,81 @@ static const char *hfcusb_revision =
 #include "hisax_debug.h"
 static u_int debug;
 module_param(debug, uint, 0);
-int hfc_debug;
+static int hfc_debug;
 #endif
 
+/* private vendor specific data */
+typedef struct {
+       __u8 led_scheme;        // led display scheme
+       signed short led_bits[8];       // array of 8 possible LED bitmask settings
+       char *vend_name;        // device name
+} hfcsusb_vdata;
 
 /****************************************/
 /* data defining the devices to be used */
 /****************************************/
-static struct usb_device_id hfc_usb_idtab[] = {
-       {USB_DEVICE(0x0959, 0x2bd0)},   /* Colognechip USB eval TA */
-       {USB_DEVICE(0x0675, 0x1688)},   /* DrayTek miniVigor 128 USB ISDN TA */
-       {USB_DEVICE(0x07b0, 0x0007)},   /* Billion USB TA 2 */
-       {USB_DEVICE(0x0742, 0x2008)},   /* Stollmann USB TA */
-       {USB_DEVICE(0x0742, 0x2009)},   /* Aceex USB ISDN TA */
-       {USB_DEVICE(0x0742, 0x200A)},   /* OEM USB ISDN TA */
-       {USB_DEVICE(0x08e3, 0x0301)},   /* OliTec ISDN USB */
-       {USB_DEVICE(0x07fa, 0x0846)},   /* Bewan ISDN USB TA */
-       {USB_DEVICE(0x07fa, 0x0847)},   /* Djinn Numeris USB */
-       {USB_DEVICE(0x07b0, 0x0006)},   /* Twister ISDN USB TA */
-       {}                      /* end with an all-zeroes entry */
-};
-
-/* driver internal device specific data:
-*   VendorID, ProductID, Devicename, LED_SCHEME,
-*   LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
-*/
-vendor_data vdata[] = {
-       /* CologneChip Eval TA */
-       {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
-        LED_OFF, {4, 0, 2, 1}
-        }
-       ,
-       /* DrayTek miniVigor 128 USB ISDN TA */
-       {0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
-        LED_SCHEME1, {1, 2, 0, 0}
-        }
-       ,
-       /* Billion TA */
-       {0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Stollmann TA */
-       {0x0742, 0x2008, "Stollmann USB TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* Aceex USB ISDN TA */
-       {0x0742, 0x2009, "Aceex USB ISDN TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* OEM USB ISDN TA */
-       {0x0742, 0x200A, "OEM USB ISDN TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* Olitec TA  */
-       {0x08e3, 0x0301, "Olitec USB RNIS",
-        LED_SCHEME1, {2, 0, 1, 4}
-        }
-       ,
-       /* Bewan TA   */
-       {0x07fa, 0x0846, "Bewan Modem RNIS USB",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Bewan TA   */
-       {0x07fa, 0x0847, "Djinn Numeris USB",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Twister ISDN TA   */
-       {0x07b0, 0x0006, "Twister ISDN TA",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       {0, 0, 0}               /* EOL element */
+static struct usb_device_id hfcusb_idtab[] = {
+       {
+        USB_DEVICE(0x0959, 0x2bd0),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_OFF, {4, 0, 2, 1},
+                          "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+       },
+       {
+        USB_DEVICE(0x0675, 0x1688),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {1, 2, 0, 0},
+                          "DrayTek miniVigor 128 USB ISDN TA"}),
+       },
+       {
+        USB_DEVICE(0x07b0, 0x0007),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Billion tiny USB ISDN TA 128"}),
+       },
+       {
+        USB_DEVICE(0x0742, 0x2008),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "Stollmann USB TA"}),
+        },
+       {
+        USB_DEVICE(0x0742, 0x2009),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "Aceex USB ISDN TA"}),
+        },
+       {
+        USB_DEVICE(0x0742, 0x200A),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "OEM USB ISDN TA"}),
+        },
+       {
+        USB_DEVICE(0x08e3, 0x0301),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {2, 0, 1, 4},
+                          "Olitec USB RNIS"}),
+        },
+       {
+        USB_DEVICE(0x07fa, 0x0846),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Bewan Modem RNIS USB"}),
+        },
+       {
+        USB_DEVICE(0x07fa, 0x0847),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Djinn Numeris USB"}),
+        },
+       {
+        USB_DEVICE(0x07b0, 0x0006),
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Twister ISDN TA"}),
+        },
+       { }
 };
 
 /***************************************************************/
@@ -211,8 +205,6 @@ typedef struct hfcusb_data {
        volatile __u8 l1_state; /* actual l1 state */
        struct timer_list t3_timer;     /* timer 3 for activation/deactivation */
        struct timer_list t4_timer;     /* timer 4 for activation/deactivation */
-       struct timer_list led_timer;    /* timer flashing leds */
-
 } hfcusb_data;
 
 
@@ -227,7 +219,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
        for (i = 0; list[i].name != NULL; i++)
                if (list[i].num == num)
                        return (list[i].name);
-       return "<unkown>";
+       return "<unknown ERROR>";
 }
 
 
@@ -243,9 +235,9 @@ ctrl_start_transfer(hfcusb_data * hfc)
                hfc->ctrl_urb->transfer_buffer = NULL;
                hfc->ctrl_urb->transfer_buffer_length = 0;
                hfc->ctrl_write.wIndex =
-                   hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg;
+                   cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg);
                hfc->ctrl_write.wValue =
-                   hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val;
+                   cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val);
 
                usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC);      /* start transfer */
        }
@@ -335,93 +327,57 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
        }
 }
 
-/******************************************/
-/* invert B-channel LEDs if data is sent  */
-/******************************************/
-static void
-led_timer(hfcusb_data * hfc)
-{
-       static int cnt = 0;
-
-       if (cnt) {
-               if (hfc->led_b_active & 1)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-                                   0);
-               if (hfc->led_b_active & 2)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-                                   0);
-       } else {
-               if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-                                   1);
-               if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-                                   1);
-       }
-
-       write_led(hfc, hfc->led_state);
-       hfc->led_new_data = 0;
-
-       cnt = !cnt;
-
-       /* restart 4 hz timer */
-       if (!timer_pending(&hfc->led_timer)) {
-               add_timer(&hfc->led_timer);
-               hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-       }
-}
-
 /**************************/
 /* handle LED requests    */
 /**************************/
 static void
 handle_led(hfcusb_data * hfc, int event)
 {
+       hfcsusb_vdata *driver_info =
+           (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
+
        /* if no scheme -> no LED action */
-       if (vdata[hfc->vend_idx].led_scheme == LED_OFF)
+       if (driver_info->led_scheme == LED_OFF)
                return;
 
        switch (event) {
                case LED_POWER_ON:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0],
+                       set_led_bit(hfc, driver_info->led_bits[0],
                                    0);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    1);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
+                       set_led_bit(hfc, driver_info->led_bits[2],
                                    1);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
+                       set_led_bit(hfc, driver_info->led_bits[3],
                                    1);
                        break;
                case LED_POWER_OFF:     /* no Power off handling */
                        break;
                case LED_S0_ON:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    0);
                        break;
                case LED_S0_OFF:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    1);
                        break;
                case LED_B1_ON:
-                       hfc->led_b_active |= 1;
+                       set_led_bit(hfc, driver_info->led_bits[2],
+                                   0);
                        break;
                case LED_B1_OFF:
-                       hfc->led_b_active &= ~1;
-                       break;
-               case LED_B1_DATA:
-                       hfc->led_new_data |= 1;
+                       set_led_bit(hfc, driver_info->led_bits[2],
+                                   1);
                        break;
                case LED_B2_ON:
-                       hfc->led_b_active |= 2;
+                       set_led_bit(hfc, driver_info->led_bits[3],
+                                   0);
                        break;
                case LED_B2_OFF:
-                       hfc->led_b_active &= ~2;
-                       break;
-               case LED_B2_DATA:
-                       hfc->led_new_data |= 2;
+                       set_led_bit(hfc, driver_info->led_bits[3],
+                                   1);
                        break;
        }
-
        write_led(hfc, hfc->led_state);
 }
 
@@ -725,14 +681,6 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
                                    current_len + 1;
 
                                tx_offset += (current_len + 1);
-                               if (!transp_mode) {
-                                       if (fifon == HFCUSB_B1_TX)
-                                               handle_led(hfc,
-                                                          LED_B1_DATA);
-                                       if (fifon == HFCUSB_B2_TX)
-                                               handle_led(hfc,
-                                                          LED_B2_DATA);
-                               }
                        } else {
                                urb->iso_frame_desc[k].offset =
                                    tx_offset++;
@@ -966,14 +914,6 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
                        skb_trim(fifo->skbuff, 0);
                }
        }
-
-       /* LED flashing only in HDLC mode */
-       if (!transp_mode) {
-               if (fifon == HFCUSB_B1_RX)
-                       handle_led(hfc, LED_B1_DATA);
-               if (fifon == HFCUSB_B2_RX)
-                       handle_led(hfc, LED_B2_DATA);
-       }
 }
 
 /***********************************************/
@@ -1137,7 +1077,7 @@ set_hfcmode(hfcusb_data * hfc, int channel, int mode)
        }
 }
 
-void
+static void
 hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
 {
        usb_fifo *fifo = my_hisax_if->priv;
@@ -1339,21 +1279,10 @@ usb_init(hfcusb_data * hfc)
        hfc->t4_timer.data = (long) hfc;
        hfc->t4_timer.function = (void *) l1_timer_expire_t4;
 
-       /* init the led timer */
-       init_timer(&hfc->led_timer);
-       hfc->led_timer.data = (long) hfc;
-       hfc->led_timer.function = (void *) led_timer;
-
-       /* trigger 4 hz led timer */
-       if (!timer_pending(&hfc->led_timer)) {
-               hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-               add_timer(&hfc->led_timer);
-       }
-
        /* init the background machinery for control requests */
        hfc->ctrl_read.bRequestType = 0xc0;
        hfc->ctrl_read.bRequest = 1;
-       hfc->ctrl_read.wLength = 1;
+       hfc->ctrl_read.wLength = cpu_to_le16(1);
        hfc->ctrl_write.bRequestType = 0x40;
        hfc->ctrl_write.bRequest = 0;
        hfc->ctrl_write.wLength = 0;
@@ -1440,13 +1369,17 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
            attr, cfg_found, cidx, ep_addr;
        int cmptbl[16], small_match, iso_packet_size, packet_size,
            alt_used = 0;
+       hfcsusb_vdata *driver_info;
 
        vend_idx = 0xffff;
-       for (i = 0; vdata[i].vendor; i++) {
-               if (dev->descriptor.idVendor == vdata[i].vendor
-                   && dev->descriptor.idProduct == vdata[i].prod_id)
+       for (i = 0; hfcusb_idtab[i].idVendor; i++) {
+               if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor)
+                   && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) {
                        vend_idx = i;
+                       continue;
+               }
        }
+
 #ifdef CONFIG_HISAX_DEBUG
        DBG(USB_DBG,
            "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
@@ -1457,10 +1390,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
               ifnum, iface->desc.bAlternateSetting, intf->minor);
 
        if (vend_idx != 0xffff) {
-#ifdef CONFIG_HISAX_DEBUG
-               DBG(USB_DBG, "HFC-S USB: found vendor idx:%d  name:%s",
-                   vend_idx, vdata[vend_idx].vend_name);
-#endif
                /* if vendor and product ID is OK, start probing alternate settings */
                alt_idx = 0;
                small_match = 0xffff;
@@ -1586,8 +1515,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                                                            usb_transfer_mode
                                                            = USB_INT;
                                                        packet_size =
-                                                           ep->desc.
-                                                           wMaxPacketSize;
+                                                           le16_to_cpu(ep->desc.wMaxPacketSize);
                                                        break;
                                                case USB_ENDPOINT_XFER_BULK:
                                                        if (ep_addr & 0x80)
@@ -1615,8 +1543,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                                                            usb_transfer_mode
                                                            = USB_BULK;
                                                        packet_size =
-                                                           ep->desc.
-                                                           wMaxPacketSize;
+                                                           le16_to_cpu(ep->desc.wMaxPacketSize);
                                                        break;
                                                case USB_ENDPOINT_XFER_ISOC:
                                                        if (ep_addr & 0x80)
@@ -1644,8 +1571,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                                                            usb_transfer_mode
                                                            = USB_ISOC;
                                                        iso_packet_size =
-                                                           ep->desc.
-                                                           wMaxPacketSize;
+                                                           le16_to_cpu(ep->desc.wMaxPacketSize);
                                                        break;
                                                default:
                                                        context->
@@ -1658,10 +1584,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                                                    fifonum = cidx;
                                                context->fifos[cidx].hfc =
                                                    context;
-                                               context->fifos[cidx].
-                                                   usb_packet_maxlen =
-                                                   ep->desc.
-                                                   wMaxPacketSize;
+                                               context->fifos[cidx].usb_packet_maxlen =
+                                                   le16_to_cpu(ep->desc.wMaxPacketSize);
                                                context->fifos[cidx].
                                                    intervall =
                                                    ep->desc.bInterval;
@@ -1687,9 +1611,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                            usb_sndctrlpipe(context->dev, 0);
                        context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
 
-                       printk(KERN_INFO
-                              "HFC-S USB: detected \"%s\"\n",
-                              vdata[vend_idx].vend_name);
+                       driver_info =
+                           (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
+                           driver_info;
+                       printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
+                              driver_info->vend_name);
 #ifdef CONFIG_HISAX_DEBUG
                        DBG(USB_DBG,
                            "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
@@ -1740,8 +1666,6 @@ hfc_usb_disconnect(struct usb_interface
                del_timer(&context->t3_timer);
        if (timer_pending(&context->t4_timer))
                del_timer(&context->t4_timer);
-       if (timer_pending(&context->led_timer))
-               del_timer(&context->led_timer);
        /* tell all fifos to terminate */
        for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
                if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
@@ -1785,9 +1709,10 @@ hfc_usb_disconnect(struct usb_interface
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-       .owner = THIS_MODULE,.name =
-           "hfc_usb",.id_table = hfc_usb_idtab,.probe =
-           hfc_usb_probe,.disconnect = hfc_usb_disconnect,
+       .name  = "hfc_usb",
+       .id_table = hfcusb_idtab,
+       .probe = hfc_usb_probe,
+       .disconnect = hfc_usb_disconnect,
 };
 static void __exit
 hfc_usb_exit(void)
@@ -1825,4 +1750,4 @@ module_exit(hfc_usb_exit);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, hfc_usb_idtab);
+MODULE_DEVICE_TABLE(usb, hfcusb_idtab);