From: Karsten Keil This is an update of the HFC USB ISDN driver, the current one has some bugs and support not all HW. It was already tested as standalone patch for some time, so including it should be safe. Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton --- 25-akpm/drivers/isdn/hisax/hfc_usb.c | 2323 ++++++++++++++++++----------------- 25-akpm/drivers/isdn/hisax/hfc_usb.h | 228 +++ 2 files changed, 1468 insertions(+), 1083 deletions(-) diff -puN drivers/isdn/hisax/hfc_usb.c~i4l-new-hfc_usb-driver-version drivers/isdn/hisax/hfc_usb.c --- 25/drivers/isdn/hisax/hfc_usb.c~i4l-new-hfc_usb-driver-version 2005-02-02 18:24:09.937311728 -0800 +++ 25-akpm/drivers/isdn/hisax/hfc_usb.c 2005-02-02 18:24:09.955308992 -0800 @@ -1,11 +1,15 @@ /* * hfc_usb.c * - * modular HiSax ISDN driver for Colognechip HFC-USB chip + * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $ * - * Authors : Peter Sprenger (sprenger@moving-byters.de) + * modular HiSax ISDN driver for Colognechip HFC-S USB chip + * + * Authors : Peter Sprenger (sprenger@moving-bytes.de) * Martin Bachem (info@colognechip.com) - * based on the first hfc_usb driver of Werner Cornelius (werner@isdn-development.de) + * + * based on the first hfc_usb driver of + * Werner Cornelius (werner@isdn-development.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,249 +25,229 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * + * See Version Histroy at the bottom of this file + * */ - #include #include #include #include #include -#include "hisax.h" #include #include #include #include #include #include +#include "hisax.h" #include "hisax_if.h" - -static const char *hfcusb_revision = "4.0"; +#include "hfc_usb.h" /* - to enable much mire debug messages in this driver, define - VERBOSE_USB_DEBUG and VERBOSE_ISDN_DEBUG - below +* 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 $ "; -#define VERBOSE_USB_DEBUG -#define VERBOSE_ISDN_DEBUG - -#define INCLUDE_INLINE_FUNCS - -#define TRUE 1 -#define FALSE 0 - - -/***********/ -/* defines */ -/***********/ -#define HFC_CTRL_TIMEOUT 20 //(HZ * USB_CTRL_GET_TIMEOUT) -/* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ - -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ - -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ - -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ - -#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ -#define HFCUSB_CIRM 0x00 /* cirm register index */ -#define HFCUSB_USB_SIZE 0x07 /* int length register */ -#define HFCUSB_USB_SIZE_I 0x06 /* iso length register */ -#define HFCUSB_F_CROSS 0x0b /* bit order register */ -#define HFCUSB_CLKDEL 0x37 /* bit delay register */ -#define HFCUSB_CON_HDLC 0xfa /* channel connect register */ -#define HFCUSB_HDLC_PAR 0xfb -#define HFCUSB_SCTRL 0x31 /* S-bus control register (tx) */ -#define HFCUSB_SCTRL_E 0x32 /* same for E and special funcs */ -#define HFCUSB_SCTRL_R 0x33 /* S-bus control register (rx) */ -#define HFCUSB_F_THRES 0x0c /* threshold register */ -#define HFCUSB_FIFO 0x0f /* fifo select register */ -#define HFCUSB_F_USAGE 0x1a /* fifo usage register */ -#define HFCUSB_MST_MODE0 0x14 -#define HFCUSB_MST_MODE1 0x15 -#define HFCUSB_P_DATA 0x1f -#define HFCUSB_INC_RES_F 0x0e -#define HFCUSB_STATES 0x30 - -#define HFCUSB_CHIPID 0x40 /* ID value of HFC-USB */ - -/******************/ -/* fifo registers */ -/******************/ -#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ -#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ -#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ -#define HFCUSB_B2_TX 2 -#define HFCUSB_B2_RX 3 -#define HFCUSB_D_TX 4 -#define HFCUSB_D_RX 5 -#define HFCUSB_PCM_TX 6 -#define HFCUSB_PCM_RX 7 - -/* -* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just -* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out +/* Hisax debug support +* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG */ -#define USB_INT 0 -#define USB_BULK 1 -#define USB_ISOC 2 - -#define ISOC_PACKETS_D 8 -#define ISOC_PACKETS_B 8 -#define ISO_BUFFER_SIZE 128 - -// ISO send definitions -#define SINK_MAX 68 -#define SINK_MIN 48 -#define SINK_DMIN 12 -#define SINK_DMAX 18 -#define BITLINE_INF (-64*8) - - - - -/**********/ -/* macros */ -/**********/ -#define write_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) -#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) - -/*************************************************/ -/* entry and size of output/input control buffer */ -/*************************************************/ -#define HFC_CTRL_BUFSIZE 32 -typedef struct -{ - __u8 hfc_reg; /* register number */ - __u8 reg_val; /* value to be written (or read) */ - int action; /* data for action handler */ +#ifdef CONFIG_HISAX_DEBUG +#include +#define __debug_variable hfc_debug +#include "hisax_debug.h" +static u_int debug; +module_param(debug, uint, 0); +int hfc_debug; +#endif -} ctrl_buft; -typedef struct -{ - int vendor; // vendor id - int prod_id; // product id - char *vend_name; // vendor string - __u8 led_scheme; // led display scheme - __u8 led_invert; // invert led aux port settings - __u8 led_bits[8]; // array of 8 possible LED bitmask settings +/****************************************/ +/* 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 */ +}; -} vendor_data; +/* 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 */ +}; /***************************************************************/ /* structure defining input+output fifos (interrupt/bulk mode) */ /***************************************************************/ - -struct usb_fifo; /* forward definition */ -typedef struct iso_urb_struct -{ +struct usb_fifo; /* forward definition */ +typedef struct iso_urb_struct { struct urb *purb; __u8 buffer[ISO_BUFFER_SIZE]; /* buffer incoming/outgoing data */ - struct usb_fifo *owner_fifo; // pointer to owner fifo + struct usb_fifo *owner_fifo; /* pointer to owner fifo */ } iso_urb_struct; -struct hfcusb_data; /* forward definition */ -typedef struct usb_fifo -{ - int fifonum; /* fifo index attached to this structure */ - int active; /* fifo is currently active */ +struct hfcusb_data; /* forward definition */ +typedef struct usb_fifo { + int fifonum; /* fifo index attached to this structure */ + int active; /* fifo is currently active */ struct hfcusb_data *hfc; /* pointer to main structure */ - int pipe; /* address of endpoint */ - __u8 usb_packet_maxlen; /* maximum length for usb transfer */ - unsigned int max_size; /* maximum size of receive/send packet */ - __u8 intervall; /* interrupt interval */ - struct sk_buff *skbuff; /* actual used buffer */ - struct urb *urb; /* transfer structure for usb routines */ - __u8 buffer[128]; /* buffer incoming/outgoing data */ - int bit_line; /* how much bits are in the fifo? */ - - volatile __u8 usb_transfer_mode;/* switched between ISO and INT */ - iso_urb_struct iso[2]; /* need two urbs to have one always for pending */ - struct hisax_if *hif; /* hisax interface */ - int delete_flg; /* only delete skbuff once */ - int last_urblen; /* remember length of last packet */ + int pipe; /* address of endpoint */ + __u8 usb_packet_maxlen; /* maximum length for usb transfer */ + unsigned int max_size; /* maximum size of receive/send packet */ + __u8 intervall; /* interrupt interval */ + struct sk_buff *skbuff; /* actual used buffer */ + struct urb *urb; /* transfer structure for usb routines */ + __u8 buffer[128]; /* buffer incoming/outgoing data */ + int bit_line; /* how much bits are in the fifo? */ + + volatile __u8 usb_transfer_mode; /* switched between ISO and INT */ + iso_urb_struct iso[2]; /* need two urbs to have one always for pending */ + struct hisax_if *hif; /* hisax interface */ + int delete_flg; /* only delete skbuff once */ + int last_urblen; /* remember length of last packet */ } usb_fifo; - /*********************************************/ /* structure holding all data for one device */ /*********************************************/ -typedef struct hfcusb_data -{ - // HiSax Interface for loadable Layer1 drivers - struct hisax_d_if d_if; /* see hisax_if.h */ - struct hisax_b_if b_if[2]; /* see hisax_if.h */ +typedef struct hfcusb_data { + /* HiSax Interface for loadable Layer1 drivers */ + struct hisax_d_if d_if; /* see hisax_if.h */ + struct hisax_b_if b_if[2]; /* see hisax_if.h */ int protocol; - - struct usb_device *dev; /* our device */ - int if_used; /* used interface number */ - int alt_used; /* used alternate config */ - int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ - int cfg_used; /* configuration index used */ - int vend_idx; // vendor found - - int b_mode[2]; // B-channel mode - - int l1_activated; // layer 1 activated - int packet_size,iso_packet_size; + struct usb_device *dev; /* our device */ + int if_used; /* used interface number */ + int alt_used; /* used alternate config */ + int ctrl_paksize; /* control pipe packet size */ + int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ + int cfg_used; /* configuration index used */ + int vend_idx; /* vendor found */ + int b_mode[2]; /* B-channel mode */ + int l1_activated; /* layer 1 activated */ + int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ + int packet_size, iso_packet_size; /* control pipe background handling */ ctrl_buft ctrl_buff[HFC_CTRL_BUFSIZE]; /* buffer holding queued data */ - volatile int ctrl_in_idx, ctrl_out_idx, - ctrl_cnt; /* input/output pointer + count */ - struct urb *ctrl_urb; /* transfer structure for control channel */ + volatile int ctrl_in_idx, ctrl_out_idx, ctrl_cnt; /* input/output pointer + count */ + struct urb *ctrl_urb; /* transfer structure for control channel */ struct usb_ctrlrequest ctrl_write; /* buffer for control write request */ struct usb_ctrlrequest ctrl_read; /* same for read request */ - __u8 led_state,led_new_data,led_b_active; + __u8 old_led_state, led_state, led_new_data, led_b_active; - volatile __u8 threshold_mask; /* threshold actually reported */ - volatile __u8 bch_enables; /* or mask for sctrl_r and sctrl register values */ + volatile __u8 threshold_mask; /* threshold actually reported */ + volatile __u8 bch_enables; /* or mask for sctrl_r and sctrl register values */ usb_fifo fifos[HFCUSB_NUM_FIFOS]; /* structure holding all fifo 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 */ + 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; -static void collect_rx_frame(usb_fifo *fifo,__u8 *data,int len,int finish); +static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, + int finish); + +static inline const char * +symbolic(struct hfcusb_symbolic_list list[], const int num) +{ + int i; + for (i = 0; list[i].name != NULL; i++) + if (list[i].num == num) + return (list[i].name); + return ""; +} /******************************************************/ /* start next background transfer for control channel */ /******************************************************/ -static void ctrl_start_transfer(hfcusb_data * hfc) +static void +ctrl_start_transfer(hfcusb_data * hfc) { - int err; - if(hfc->ctrl_cnt) - { + if (hfc->ctrl_cnt) { hfc->ctrl_urb->pipe = hfc->ctrl_out_pipe; hfc->ctrl_urb->setup_packet = (u_char *) & hfc->ctrl_write; 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; - hfc->ctrl_write.wValue = hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val; - err = usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ - printk(KERN_DEBUG "ctrl_start_transfer: submit %d\n", err); + hfc->ctrl_write.wIndex = + hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg; + hfc->ctrl_write.wValue = + hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val; + + usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ } } /* ctrl_start_transfer */ @@ -271,271 +255,284 @@ static void ctrl_start_transfer(hfcusb_d /* queue a control transfer request */ /* return 0 on success. */ /************************************/ -static int queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val,int action) +static int +queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) { ctrl_buft *buf; -#ifdef VERBOSE_USB_DEBUG - printk ("HFC_USB: queue_control_request reg: %x, val: %x\n", reg, val); -#endif - - if(hfc->ctrl_cnt >= HFC_CTRL_BUFSIZE) return(1); /* no space left */ + if (hfc->ctrl_cnt >= HFC_CTRL_BUFSIZE) + return (1); /* no space left */ buf = &hfc->ctrl_buff[hfc->ctrl_in_idx]; /* pointer to new index */ buf->hfc_reg = reg; buf->reg_val = val; - buf->action=action; + buf->action = action; if (++hfc->ctrl_in_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_in_idx = 0; /* pointer wrap */ if (++hfc->ctrl_cnt == 1) ctrl_start_transfer(hfc); - return(0); -} /* queue_control_request */ + return (0); +} /* queue_control_request */ - -static int control_action_handler(hfcusb_data *hfc,int reg,int val,int action) +static int +control_action_handler(hfcusb_data * hfc, int reg, int val, int action) { - if(!action) return(1); // no action defined - - return(0); + if (!action) + return (1); /* no action defined */ + return (0); } - /***************************************************************/ /* control completion routine handling background control cmds */ /***************************************************************/ -static void ctrl_complete(struct urb *urb, struct pt_regs *regs) +static void +ctrl_complete(struct urb *urb, struct pt_regs *regs) { hfcusb_data *hfc = (hfcusb_data *) urb->context; ctrl_buft *buf; - printk(KERN_DEBUG "ctrl_complete cnt %d\n", hfc->ctrl_cnt); urb->dev = hfc->dev; - if(hfc->ctrl_cnt) - { - buf=&hfc->ctrl_buff[hfc->ctrl_out_idx]; - control_action_handler(hfc,buf->hfc_reg,buf->reg_val,buf->action); + if (hfc->ctrl_cnt) { + buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; + control_action_handler(hfc, buf->hfc_reg, buf->reg_val, + buf->action); hfc->ctrl_cnt--; /* decrement actual count */ - if(++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ + if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) + hfc->ctrl_out_idx = 0; /* pointer wrap */ ctrl_start_transfer(hfc); /* start next transfer */ } } /* ctrl_complete */ - - -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... - -#define LED_POWER_ON 1 -#define LED_POWER_OFF 2 -#define LED_S0_ON 3 -#define LED_S0_OFF 4 -#define LED_B1_ON 5 -#define LED_B1_OFF 6 -#define LED_B1_DATA 7 -#define LED_B2_ON 8 -#define LED_B2_OFF 9 -#define LED_B2_DATA 10 - -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted - -// time for LED flashing -#define LED_TIME 250 - -vendor_data vdata[]= -{ - {0x959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)", LED_OFF,LED_NORMAL,{4,0,2,1}}, /* CologneChip Eval TA */ - {0x7b0, 0x0007, "Billion tiny USB ISDN TA 128", LED_SCHEME1, LED_INVERTED, {8,0x40,0x20,0x10}}, /* Billion TA */ - {0x742, 0x2008, "Stollmann USB TA", LED_SCHEME1, LED_NORMAL, {4,0,2,1}}, /* Stollmann TA */ - {0x8e3, 0x0301, "Olitec USB RNIS", LED_SCHEME1, LED_NORMAL, {2,0,1,4}}, /* Olitec TA */ - {0x675, 0x1688, "DrayTec USB ISDN TA", LED_SCHEME1, LED_NORMAL, {4,0,2,1}}, /* Draytec TA */ - {0x7fa, 0x0846, "Bewan Modem RNIS USB", LED_SCHEME1, LED_INVERTED, {8,0x40,0x20,0x10}}, /* Bewan TA */ - {0} // EOL element -}; - /***************************************************/ /* write led data to auxport & invert if necessary */ /***************************************************/ -static void write_led(hfcusb_data * hfc,__u8 led_state) +static void +write_led(hfcusb_data * hfc, __u8 led_state) { - if(led_state!=hfc->led_state) - { - hfc->led_state=led_state; - queue_control_request(hfc, HFCUSB_P_DATA,(vdata[hfc->vend_idx].led_invert) ? ~led_state : led_state,1); + if (led_state != hfc->old_led_state) { + hfc->old_led_state = led_state; + queue_control_request(hfc, HFCUSB_P_DATA, led_state, 1); + } +} + +/**************************/ +/* handle LED bits */ +/**************************/ +static void +set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) +{ + if (unset) { + if (led_bits < 0) + hfc->led_state |= abs(led_bits); + else + hfc->led_state &= ~led_bits; + } else { + if (led_bits < 0) + hfc->led_state &= ~abs(led_bits); + else + hfc->led_state |= led_bits; } } /******************************************/ /* invert B-channel LEDs if data is sent */ /******************************************/ -static void led_timer(hfcusb_data * hfc) +static void +led_timer(hfcusb_data * hfc) { - static int cnt=0; - __u8 led_state=hfc->led_state; + static int cnt = 0; - if(cnt) - { - if(hfc->led_b_active&1) led_state|=vdata[hfc->vend_idx].led_bits[2]; - if(hfc->led_b_active&2) led_state|=vdata[hfc->vend_idx].led_bits[3]; - } - else - { - if(!(hfc->led_b_active&1) || hfc->led_new_data&1) led_state&=~vdata[hfc->vend_idx].led_bits[2]; - if(!(hfc->led_b_active&2) || hfc->led_new_data&2) led_state&=~vdata[hfc->vend_idx].led_bits[3]; + 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; } - - write_led(hfc,led_state); - hfc->led_new_data=0; - - cnt=!cnt; - // restart 4 hz timer - hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000; - if(!timer_pending(&hfc->led_timer)) add_timer(&hfc->led_timer); } /**************************/ /* handle LED requests */ /**************************/ -static void handle_led(hfcusb_data * hfc,int event) +static void +handle_led(hfcusb_data * hfc, int event) { - __u8 led_state=hfc->led_state; - - // if no scheme -> no LED action - if(vdata[hfc->vend_idx].led_scheme==LED_OFF) return; + /* if no scheme -> no LED action */ + if (vdata[hfc->vend_idx].led_scheme == LED_OFF) + return; - switch(event) - { + switch (event) { case LED_POWER_ON: - led_state|=vdata[hfc->vend_idx].led_bits[0]; - break; - case LED_POWER_OFF: // no Power off handling - break; + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0], + 0); + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], + 1); + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2], + 1); + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3], + 1); + break; + case LED_POWER_OFF: /* no Power off handling */ + break; case LED_S0_ON: - led_state|=vdata[hfc->vend_idx].led_bits[1]; - break; + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], + 0); + break; case LED_S0_OFF: - led_state&=~vdata[hfc->vend_idx].led_bits[1]; - break; + set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], + 1); + break; case LED_B1_ON: - hfc->led_b_active|=1; - break; + hfc->led_b_active |= 1; + break; case LED_B1_OFF: - hfc->led_b_active&=~1; - break; + hfc->led_b_active &= ~1; + break; case LED_B1_DATA: - hfc->led_new_data|=1; - break; + hfc->led_new_data |= 1; + break; case LED_B2_ON: - hfc->led_b_active|=2; - break; + hfc->led_b_active |= 2; + break; case LED_B2_OFF: - hfc->led_b_active&=~2; - break; + hfc->led_b_active &= ~2; + break; case LED_B2_DATA: - hfc->led_new_data|=2; - break; + hfc->led_new_data |= 2; + break; } - - write_led(hfc,led_state); + + write_led(hfc, hfc->led_state); } /********************************/ /* called when timer t3 expires */ /********************************/ -static void l1_timer_expire_t3(hfcusb_data * hfc) +static void +l1_timer_expire_t3(hfcusb_data * hfc) { - //printk (KERN_INFO "HFC-USB: l1_timer_expire_t3\n"); - - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,PH_DEACTIVATE | INDICATION,NULL); -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "PH_DEACTIVATE | INDICATION sent\n"); -#endif - hfc->l1_activated=FALSE; - handle_led(hfc,LED_S0_OFF); + hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, + NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); +#endif + hfc->l1_activated = FALSE; + handle_led(hfc, LED_S0_OFF); + /* deactivate : */ + queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); + queue_control_request(hfc, HFCUSB_STATES, 3, 1); } /********************************/ /* called when timer t4 expires */ /********************************/ -static void l1_timer_expire_t4(hfcusb_data * hfc) +static void +l1_timer_expire_t4(hfcusb_data * hfc) { - //printk (KERN_INFO "HFC-USB: l1_timer_expire_t4\n"); - - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,PH_DEACTIVATE | INDICATION,NULL); -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "PH_DEACTIVATE | INDICATION sent\n"); + hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, + NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); #endif - hfc->l1_activated=FALSE; - handle_led(hfc,LED_S0_OFF); + hfc->l1_activated = FALSE; + handle_led(hfc, LED_S0_OFF); } /*****************************/ /* handle S0 state changes */ /*****************************/ -static void state_handler(hfcusb_data * hfc,__u8 state) +static void +state_handler(hfcusb_data * hfc, __u8 state) { __u8 old_state; - old_state=hfc->l1_state; - - // range check - if(state==old_state || state<1 || state>8) return; + old_state = hfc->l1_state; + if (state == old_state || state < 1 || state > 8) + return; -#ifdef VERBOSE_ISDN_DEBUG - printk(KERN_INFO "HFC-USB: new S0 state:%d old_state:%d\n",state,old_state); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, + old_state); +#endif + if (state < 4 || state == 7 || state == 8) { + if (timer_pending(&hfc->t3_timer)) + del_timer(&hfc->t3_timer); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); +#endif + } + if (state >= 7) { + if (timer_pending(&hfc->t4_timer)) + del_timer(&hfc->t4_timer); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); #endif + } - if(state<4 || state==7 || state==8) - { - if(timer_pending(&hfc->t3_timer)) del_timer(&hfc->t3_timer); - //printk(KERN_INFO "HFC-USB: T3 deactivated\n"); - } - - if(state>=7) - { - if(timer_pending(&hfc->t4_timer)) del_timer(&hfc->t4_timer); - //printk(KERN_INFO "HFC-USB: T4 deactivated\n"); - } - - if(state==7 && !hfc->l1_activated) - { - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,PH_ACTIVATE | INDICATION,NULL); - //printk(KERN_INFO "HFC-USB: PH_ACTIVATE | INDICATION sent\n"); - hfc->l1_activated=TRUE; - handle_led(hfc,LED_S0_ON); - } - else - if(state<=3 /* && activated*/) - { - if(old_state==7 || old_state==8) - { - //printk(KERN_INFO "HFC-USB: T4 activated\n"); - hfc->t4_timer.expires = jiffies + (HFC_TIMER_T4 * HZ) / 1000; - if(!timer_pending(&hfc->t4_timer)) add_timer(&hfc->t4_timer); - } - else - { - hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,PH_DEACTIVATE | INDICATION,NULL); - //printk(KERN_INFO "HFC-USB: PH_DEACTIVATE | INDICATION sent\n"); - hfc->l1_activated=FALSE; - handle_led(hfc,LED_S0_OFF); + if (state == 7 && !hfc->l1_activated) { + hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, + PH_ACTIVATE | INDICATION, NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); +#endif + hfc->l1_activated = TRUE; + handle_led(hfc, LED_S0_ON); + } else if (state <= 3 /* && activated */ ) { + if (old_state == 7 || old_state == 8) { +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T4 activated"); +#endif + if (!timer_pending(&hfc->t4_timer)) { + hfc->t4_timer.expires = + jiffies + (HFC_TIMER_T4 * HZ) / 1000; + add_timer(&hfc->t4_timer); + } + } else { + hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, + PH_DEACTIVATE | INDICATION, + NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); +#endif + hfc->l1_activated = FALSE; + handle_led(hfc, LED_S0_OFF); } } - - hfc->l1_state=state; + hfc->l1_state = state; } - /* prepare iso urb */ -static void fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *buf, - int num_packets, int packet_size, int interval, usb_complete_t complete, void *context) +static void +fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, + void *buf, int num_packets, int packet_size, int interval, + usb_complete_t complete, void *context) { int k; - spin_lock_init(&urb->lock); // do we really need spin_lock_init ? + spin_lock_init(&urb->lock); urb->dev = dev; urb->pipe = pipe; urb->complete = complete; @@ -543,7 +540,6 @@ static void fill_isoc_urb(struct urb *ur urb->transfer_buffer_length = packet_size * num_packets; urb->context = context; urb->transfer_buffer = buf; - urb->transfer_flags = 0; urb->transfer_flags = URB_ISO_ASAP; urb->actual_length = 0; urb->interval = interval; @@ -554,67 +550,80 @@ static void fill_isoc_urb(struct urb *ur } } -/* allocs urbs and start isoc transfer with two pending urbs to avoid gaps in the transfer chain */ -static int start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,usb_complete_t complete,int packet_size) +/* allocs urbs and start isoc transfer with two pending urbs to avoid + gaps in the transfer chain */ +static int +start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, + usb_complete_t complete, int packet_size) { int i, k, errcode; -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: starting ISO-chain for Fifo %i\n", fifo->fifonum); -#endif - + printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", + fifo->fifonum); - // allocate Memory for Iso out Urbs + /* allocate Memory for Iso out Urbs */ for (i = 0; i < 2; i++) { if (!(fifo->iso[i].purb)) { - fifo->iso[i].purb = usb_alloc_urb(num_packets_per_urb, GFP_KERNEL); + fifo->iso[i].purb = + usb_alloc_urb(num_packets_per_urb, GFP_KERNEL); + if (!(fifo->iso[i].purb)) { + printk(KERN_INFO + "alloc urb for fifo %i failed!!!", + fifo->fifonum); + } fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo; - // Init the first iso - if (ISO_BUFFER_SIZE >= (fifo->usb_packet_maxlen * num_packets_per_urb)) - { - - fill_isoc_urb(fifo->iso[i].purb, fifo->hfc->dev, fifo->pipe, fifo->iso[i].buffer, - num_packets_per_urb, fifo->usb_packet_maxlen, fifo->intervall, - complete, &fifo->iso[i]); - - memset(fifo->iso[i].buffer, 0, sizeof(fifo->iso[i].buffer)); - - // defining packet delimeters in fifo->buffer - for(k = 0; k < num_packets_per_urb; k++) - { - fifo->iso[i].purb->iso_frame_desc[k].offset = k*packet_size; - fifo->iso[i].purb->iso_frame_desc[k].length = packet_size; + /* Init the first iso */ + if (ISO_BUFFER_SIZE >= + (fifo->usb_packet_maxlen * + num_packets_per_urb)) { + fill_isoc_urb(fifo->iso[i].purb, + fifo->hfc->dev, fifo->pipe, + fifo->iso[i].buffer, + num_packets_per_urb, + fifo->usb_packet_maxlen, + fifo->intervall, complete, + &fifo->iso[i]); + memset(fifo->iso[i].buffer, 0, + sizeof(fifo->iso[i].buffer)); + /* defining packet delimeters in fifo->buffer */ + for (k = 0; k < num_packets_per_urb; k++) { + fifo->iso[i].purb-> + iso_frame_desc[k].offset = + k * packet_size; + fifo->iso[i].purb-> + iso_frame_desc[k].length = + packet_size; } + } else { + printk(KERN_INFO + "HFC-S USB: ISO Buffer size to small!\n"); } } - fifo->bit_line = BITLINE_INF; errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); fifo->active = (errcode >= 0) ? 1 : 0; - if(errcode < 0) - { - printk(KERN_INFO "HFC-USB: error submitting ISO URB: %i.%i \n", errcode, i); + if (errcode < 0) { + printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", + symbolic(urb_errlist, errcode), i); }; - } - - // errcode = (usb_submit_urb(fifo->iso[0].purb, GFP_KERNEL)); - return(fifo->active); + return (fifo->active); } /* stops running iso chain and frees their pending urbs */ -static void stop_isoc_chain(usb_fifo * fifo) +static void +stop_isoc_chain(usb_fifo * fifo) { int i; - for(i = 0; i < 2; i++) - { - if(fifo->iso[i].purb) - { -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: Stopping iso chain for fifo %i.%i\n", fifo->fifonum, i); + for (i = 0; i < 2; i++) { + if (fifo->iso[i].purb) { +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: Stopping iso chain for fifo %i.%i", + fifo->fifonum, i); #endif usb_unlink_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); @@ -629,554 +638,653 @@ static void stop_isoc_chain(usb_fifo * f fifo->active = 0; } -// defines how much ISO packets are handled in one URB -static int iso_packets[8]={ISOC_PACKETS_B,ISOC_PACKETS_B,ISOC_PACKETS_B,ISOC_PACKETS_B, - ISOC_PACKETS_D,ISOC_PACKETS_D,ISOC_PACKETS_D,ISOC_PACKETS_D}; +/* defines how much ISO packets are handled in one URB */ +static int iso_packets[8] = + { ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, + ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D +}; /*****************************************************/ /* transmit completion routine for all ISO tx fifos */ /*****************************************************/ -static void tx_iso_complete(struct urb *urb, struct pt_regs *regs) +static void +tx_iso_complete(struct urb *urb, struct pt_regs *regs) { iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; usb_fifo *fifo = context_iso_urb->owner_fifo; hfcusb_data *hfc = fifo->hfc; - int k, tx_offset, num_isoc_packets, sink, len, current_len,errcode,frame_complete,transp_mode,fifon; + int k, tx_offset, num_isoc_packets, sink, len, current_len, + errcode; + int frame_complete, transp_mode, fifon, status; __u8 threshbit; - __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; + __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; - fifon=fifo->fifonum; - tx_offset=0; - // very weird error code when using ohci drivers, for now : ignore this error ... (MB) - if(urb->status == -EOVERFLOW) - { - urb->status = 0; -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n",fifon); -#endif - } + fifon = fifo->fifonum; + status = urb->status; - if(fifo->active && !urb->status) - { - transp_mode=0; - if(fifon<4 && hfc->b_mode[fifon/2]==L1_MODE_TRANS) transp_mode=TRUE; - - threshbit = threshtable[fifon] & hfc->threshold_mask; // is threshold set for our channel? - num_isoc_packets=iso_packets[fifon]; - - if(fifon >= HFCUSB_D_TX) - { - sink = (threshbit) ? SINK_DMIN : SINK_DMAX; // how much bit go to the sink for D-channel? - } - else - { - sink = (threshbit) ? SINK_MIN : SINK_MAX; // how much bit go to the sink for B-channel? - } + tx_offset = 0; + + if (fifo->active && !status) { + transp_mode = 0; + if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) + transp_mode = TRUE; - // prepare ISO Urb - fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe,context_iso_urb->buffer, num_isoc_packets, - fifo->usb_packet_maxlen, fifo->intervall, tx_iso_complete, urb->context); - memset(context_iso_urb->buffer, 0, sizeof(context_iso_urb->buffer)); - - frame_complete=FALSE; - - // Generate Iso Packets - for(k = 0; k < num_isoc_packets; ++k) - { - if(fifo->skbuff) - { - len = fifo->skbuff->len; // remaining length + /* is FifoFull-threshold set for our channel? */ + threshbit = threshtable[fifon] & hfc->threshold_mask; + num_isoc_packets = iso_packets[fifon]; - fifo->bit_line -= sink; // we lower data margin every msec + /* predict dataflow to avoid fifo overflow */ + if (fifon >= HFCUSB_D_TX) { + sink = (threshbit) ? SINK_DMIN : SINK_DMAX; + } else { + sink = (threshbit) ? SINK_MIN : SINK_MAX; + } + fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe, + context_iso_urb->buffer, num_isoc_packets, + fifo->usb_packet_maxlen, fifo->intervall, + tx_iso_complete, urb->context); + memset(context_iso_urb->buffer, 0, + sizeof(context_iso_urb->buffer)); + frame_complete = FALSE; + /* Generate next Iso Packets */ + for (k = 0; k < num_isoc_packets; ++k) { + if (fifo->skbuff) { + len = fifo->skbuff->len; + /* we lower data margin every msec */ + fifo->bit_line -= sink; current_len = (0 - fifo->bit_line) / 8; - if(current_len > 14) current_len = 14; // maximum 15 byte for every ISO packet makes our life easier - current_len = (len <= current_len) ? len : current_len; - fifo->bit_line += current_len * 8; // how much bit do we put on the line? + /* maximum 15 byte for every ISO packet makes our life easier */ + if (current_len > 14) + current_len = 14; + current_len = + (len <= + current_len) ? len : current_len; + /* how much bit do we put on the line? */ + fifo->bit_line += current_len * 8; context_iso_urb->buffer[tx_offset] = 0; - if(current_len == len) - { - if(!transp_mode) - { - context_iso_urb->buffer[tx_offset] = 1; // here frame completion - fifo->bit_line += 32; // add 2 byte flags and 16bit CRC at end of ISDN frame + if (current_len == len) { + if (!transp_mode) { + /* here frame completion */ + context_iso_urb-> + buffer[tx_offset] = 1; + /* add 2 byte flags and 16bit CRC at end of ISDN frame */ + fifo->bit_line += 32; } frame_complete = TRUE; } - // copy bytes from buffer into ISO_URB - memcpy(context_iso_urb->buffer+tx_offset+1,fifo->skbuff->data,current_len); - skb_pull(fifo->skbuff,current_len); + memcpy(context_iso_urb->buffer + + tx_offset + 1, fifo->skbuff->data, + current_len); + skb_pull(fifo->skbuff, current_len); - // define packet delimeters within the URB buffer + /* define packet delimeters within the URB buffer */ urb->iso_frame_desc[k].offset = tx_offset; - urb->iso_frame_desc[k].length = current_len + 1; + urb->iso_frame_desc[k].length = + current_len + 1; tx_offset += (current_len + 1); - // printk(KERN_INFO "HFC-USB: fifonum:%d,%d bytes to send, %d bytes ISO packet,bitline:%d,sink:%d,threshbit:%d,threshmask:%x\n",fifon,len,current_len,fifo->bit_line,sink,threshbit,hfc->threshold_mask); - 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); + 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 - { - // we have no more data - generate 1 byte ISO packets - urb->iso_frame_desc[k].offset = tx_offset++; + } else { + urb->iso_frame_desc[k].offset = + tx_offset++; urb->iso_frame_desc[k].length = 1; - fifo->bit_line -= sink; // we lower data margin every msec + fifo->bit_line -= sink; /* we lower data margin every msec */ - if(fifo->bit_line < BITLINE_INF) - { + if (fifo->bit_line < BITLINE_INF) { fifo->bit_line = BITLINE_INF; - //printk (KERN_INFO "HFC-USB: BITLINE_INF underrun\n"); } } - if(frame_complete) - { - // delete the buffer only once, here or in hfc_usb_l2l1() in a PH_DATA|REQUEST - fifo->delete_flg=TRUE; - - fifo->hif->l1l2(fifo->hif,PH_DATA|CONFIRM,(void*)fifo->skbuff->truesize); - - if(fifo->skbuff && fifo->delete_flg) - { + if (frame_complete) { + fifo->delete_flg = TRUE; + fifo->hif->l1l2(fifo->hif, + PH_DATA | CONFIRM, + (void *) fifo->skbuff-> + truesize); + if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); - //printk(KERN_INFO "HFC-USB: skbuff=NULL on fifo:%d\n",fifo->fifonum); fifo->skbuff = NULL; - fifo->delete_flg=FALSE; + fifo->delete_flg = FALSE; } - - frame_complete=FALSE; + frame_complete = FALSE; } - } - + } errcode = usb_submit_urb(urb, GFP_ATOMIC); - if(errcode < 0) - { - printk(KERN_INFO "HFC-USB: error submitting ISO URB: %i \n", errcode); + if (errcode < 0) { + printk(KERN_INFO + "HFC-S USB: error submitting ISO URB: %d \n", + errcode); } - } - else - { - if(urb->status) - { - printk(KERN_INFO "HFC-USB: tx_iso_complete : urb->status %i, fifonum %i\n", urb->status,fifon); + } else { + if (status && !hfc->disc_flag) { + printk(KERN_INFO + "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", + symbolic(urb_errlist, status), status, + fifon); } } - } /* tx_iso_complete */ /*****************************************************/ /* receive completion routine for all ISO tx fifos */ /*****************************************************/ -static void rx_iso_complete(struct urb *urb, struct pt_regs *regs) +static void +rx_iso_complete(struct urb *urb, struct pt_regs *regs) { iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; usb_fifo *fifo = context_iso_urb->owner_fifo; hfcusb_data *hfc = fifo->hfc; - int k, len, errcode, offset, num_isoc_packets,fifon; + int k, len, errcode, offset, num_isoc_packets, fifon, maxlen, + status; + unsigned int iso_status; __u8 *buf; - - fifon=fifo->fifonum; - // very weird error code when using ohci drivers, for now : ignore this error ... (MB) - if(urb->status == -EOVERFLOW) - { - urb->status = 0; -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n",fifon); + static __u8 eof[8]; +#ifdef CONFIG_HISAX_DEBUG + __u8 i; +#endif + + fifon = fifo->fifonum; + status = urb->status; + + if (urb->status == -EOVERFLOW) { +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", + fifon); +#endif + status = 0; + } + if (fifo->active && !status) { + num_isoc_packets = iso_packets[fifon]; + maxlen = fifo->usb_packet_maxlen; + for (k = 0; k < num_isoc_packets; ++k) { + len = urb->iso_frame_desc[k].actual_length; + offset = urb->iso_frame_desc[k].offset; + buf = context_iso_urb->buffer + offset; + iso_status = urb->iso_frame_desc[k].status; +#ifdef CONFIG_HISAX_DEBUG + if (iso_status && !hfc->disc_flag) + DBG(USB_DBG, + "HFC-S USB: ISO packet failure - status:%x", + iso_status); + + if ((fifon == 5) && (debug > 1)) { + printk(KERN_INFO + "HFC-S USB: ISO-D-RX lst_urblen:%2d " + "act_urblen:%2d max-urblen:%2d " + "EOF:0x%0x DATA: ", + fifo->last_urblen, len, maxlen, + eof[5]); + for (i = 0; i < len; i++) + printk("%.2x ", buf[i]); + printk("\n"); + } #endif - } - - if(fifo->active && !urb->status) - { - num_isoc_packets=iso_packets[fifon]; - - // Generate D-Channel Iso Packets - for(k = 0; k < num_isoc_packets; ++k) - { - len=urb->iso_frame_desc[k].actual_length; - offset=urb->iso_frame_desc[k].offset; - buf=context_iso_urb->buffer+offset; - - if(fifo->last_urblen!=fifo->usb_packet_maxlen) - { - // the threshold mask is in the 2nd status byte - hfc->threshold_mask=buf[1]; - // the S0 state is in the upper half of the 1st status byte - state_handler(hfc,buf[0] >> 4); - // if we have more than the 2 status bytes -> collect data - if(len>2) collect_rx_frame(fifo,buf+2,len-2,buf[0]&1); + if (fifo->last_urblen != maxlen) { + /* the threshold mask is in the 2nd status byte */ + hfc->threshold_mask = buf[1]; + /* care for L1 state only for D-Channel + to avoid overlapped iso completions */ + if (fifon == 5) { + /* the S0 state is in the upper half + of the 1st status byte */ + state_handler(hfc, buf[0] >> 4); + } + eof[fifon] = buf[0] & 1; + if (len > 2) + collect_rx_frame(fifo, buf + 2, + len - 2, + (len < + maxlen) ? + eof[fifon] : 0); + } else { + collect_rx_frame(fifo, buf, len, + (len < + maxlen) ? eof[fifon] : + 0); } - else collect_rx_frame(fifo,buf,len,0); - - fifo->last_urblen=len; - - } - - // prepare ISO Urb - fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe,context_iso_urb->buffer, num_isoc_packets, - fifo->usb_packet_maxlen, fifo->intervall, rx_iso_complete, urb->context); + fifo->last_urblen = len; + } + fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe, + context_iso_urb->buffer, num_isoc_packets, + fifo->usb_packet_maxlen, fifo->intervall, + rx_iso_complete, urb->context); errcode = usb_submit_urb(urb, GFP_ATOMIC); - if(errcode < 0) - { - printk(KERN_INFO "HFC-USB: error submitting ISO URB: %i \n", errcode); + if (errcode < 0) { + printk(KERN_INFO + "HFC-S USB: error submitting ISO URB: %d \n", + errcode); } - } - else - { - if(urb->status) - { - printk(KERN_INFO "HFC-USB: rx_iso_complete : urb->status %i, fifonum %i\n", urb->status,fifon); + } else { + if (status && !hfc->disc_flag) { + printk(KERN_INFO + "HFC-S USB: rx_iso_complete : " + "urb->status %d, fifonum %d\n", + status, fifon); } } } /* rx_iso_complete */ - /*****************************************************/ /* collect data from interrupt or isochron in */ /*****************************************************/ -static void collect_rx_frame(usb_fifo *fifo,__u8 *data,int len,int finish) +static void +collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) { hfcusb_data *hfc = fifo->hfc; - int transp_mode,fifon; - - fifon=fifo->fifonum; - transp_mode=0; - if(fifon<4 && hfc->b_mode[fifon/2]==L1_MODE_TRANS) transp_mode=TRUE; - - //printk(KERN_INFO "HFC-USB: got %d bytes finish:%d max_size:%d fifo:%d\n",len,finish,fifo->max_size,fifon); - if(!fifo->skbuff) - { - // allocate sk buffer - fifo->skbuff=dev_alloc_skb(fifo->max_size + 3); - if(!fifo->skbuff) - { - printk(KERN_INFO "HFC-USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n",fifon); + int transp_mode, fifon; +#ifdef CONFIG_HISAX_DEBUG + int i; +#endif + fifon = fifo->fifonum; + transp_mode = 0; + if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) + transp_mode = TRUE; + + if (!fifo->skbuff) { + fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); + if (!fifo->skbuff) { + printk(KERN_INFO + "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", + fifon); return; } - } - - if(len && fifo->skbuff->len+lenmax_size) - { - memcpy(skb_put(fifo->skbuff,len),data,len); + if (len) { + if (fifo->skbuff->len + len < fifo->max_size) { + memcpy(skb_put(fifo->skbuff, len), data, len); + } else { +#ifdef CONFIG_HISAX_DEBUG + printk(KERN_INFO "HFC-S USB: "); + for (i = 0; i < 15; i++) + printk("%.2x ", + fifo->skbuff->data[fifo->skbuff-> + len - 15 + i]); + printk("\n"); +#endif + printk(KERN_INFO + "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", + fifo->max_size, fifon); + } } - else printk(KERN_INFO "HCF-USB: got frame exceeded fifo->max_size:%d\n",fifo->max_size); - - // give transparent data up, when 128 byte are available - if(transp_mode && fifo->skbuff->len>=128) - { - fifo->hif->l1l2(fifo->hif,PH_DATA | INDICATION,fifo->skbuff); - fifo->skbuff = NULL; // buffer was freed from upper layer + if (transp_mode && fifo->skbuff->len >= 128) { + fifo->hif->l1l2(fifo->hif, PH_DATA | INDICATION, + fifo->skbuff); + fifo->skbuff = NULL; return; } - - // we have a complete hdlc packet - if(finish) - { - if(!fifo->skbuff->data[fifo->skbuff->len-1]) - { - skb_trim(fifo->skbuff,fifo->skbuff->len-3); // remove CRC & status - - //printk(KERN_INFO "HFC-USB: got frame %d bytes on fifo:%d\n",fifo->skbuff->len,fifon); - - if(fifon==HFCUSB_PCM_RX) fifo->hif->l1l2(fifo->hif,PH_DATA_E | INDICATION,fifo->skbuff); - else fifo->hif->l1l2(fifo->hif,PH_DATA | INDICATION,fifo->skbuff); - - fifo->skbuff = NULL; // buffer was freed from upper layer - } - else - { - printk(KERN_INFO "HFC-USB: got frame %d bytes but CRC ERROR!!!\n",fifo->skbuff->len); - - skb_trim(fifo->skbuff,0); // clear whole buffer + /* we have a complete hdlc packet */ + if (finish) { + if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) + && (fifo->skbuff->len > 3)) { + /* remove CRC & status */ + skb_trim(fifo->skbuff, fifo->skbuff->len - 3); + if (fifon == HFCUSB_PCM_RX) { + fifo->hif->l1l2(fifo->hif, + PH_DATA_E | INDICATION, + fifo->skbuff); + } else + fifo->hif->l1l2(fifo->hif, + PH_DATA | INDICATION, + fifo->skbuff); + fifo->skbuff = NULL; /* buffer was freed from upper layer */ + } else { + if (fifo->skbuff->len > 3) { + printk(KERN_INFO + "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", + fifo->skbuff->len, fifon); +#ifdef CONFIG_HISAX_DEBUG + if (debug > 1) { + printk(KERN_INFO "HFC-S USB: "); + for (i = 0; i < 15; i++) + printk("%.2x ", + fifo->skbuff-> + data[fifo->skbuff-> + len - 15 + i]); + printk("\n"); + } +#endif + } +#ifdef CONFIG_HISAX_DEBUG + else { + printk(KERN_INFO + "HFC-S USB: frame to small (%d bytes)!!!\n", + fifo->skbuff->len); + } +#endif + 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); + /* 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); } } /***********************************************/ /* receive completion routine for all rx fifos */ /***********************************************/ -static void rx_complete(struct urb *urb, struct pt_regs *regs) +static void +rx_complete(struct urb *urb, struct pt_regs *regs) { int len; - __u8 *buf; - usb_fifo *fifo = (usb_fifo *) urb->context; /* pointer to our fifo */ + int status; + __u8 *buf, maxlen, fifon; + usb_fifo *fifo = (usb_fifo *) urb->context; hfcusb_data *hfc = fifo->hfc; + static __u8 eof[8]; +#ifdef CONFIG_HISAX_DEBUG + __u8 i; +#endif urb->dev = hfc->dev; /* security init */ - if((!fifo->active) || (urb->status)) { -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: RX-Fifo %i is going down (%i)\n", fifo->fifonum, urb->status); + fifon = fifo->fifonum; + if ((!fifo->active) || (urb->status)) { +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", + fifon, urb->status); #endif fifo->urb->interval = 0; /* cancel automatic rescheduling */ - if(fifo->skbuff) { + if (fifo->skbuff) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; } return; } + len = urb->actual_length; + buf = fifo->buffer; + maxlen = fifo->usb_packet_maxlen; + +#ifdef CONFIG_HISAX_DEBUG + if ((fifon == 5) && (debug > 1)) { + printk(KERN_INFO + "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", + fifo->last_urblen, len, maxlen, eof[5]); + for (i = 0; i < len; i++) + printk("%.2x ", buf[i]); + printk("\n"); + } +#endif - len=urb->actual_length; - buf=fifo->buffer; - - if(fifo->last_urblen!=fifo->usb_packet_maxlen) { - // the threshold mask is in the 2nd status byte - hfc->threshold_mask=buf[1]; - // the S0 state is in the upper half of the 1st status byte - state_handler(hfc,buf[0] >> 4); - // if we have more than the 2 status bytes -> collect data - if(len>2) collect_rx_frame(fifo,buf+2,urb->actual_length-2,buf[0]&1); - } else - collect_rx_frame(fifo,buf,urb->actual_length,0); - - fifo->last_urblen=urb->actual_length; - - -} /* rx_complete */ - - + if (fifo->last_urblen != fifo->usb_packet_maxlen) { + /* the threshold mask is in the 2nd status byte */ + hfc->threshold_mask = buf[1]; + /* the S0 state is in the upper half of the 1st status byte */ + state_handler(hfc, buf[0] >> 4); + eof[fifon] = buf[0] & 1; + /* if we have more than the 2 status bytes -> collect data */ + if (len > 2) + collect_rx_frame(fifo, buf + 2, + urb->actual_length - 2, + (len < maxlen) ? eof[fifon] : 0); + } else { + collect_rx_frame(fifo, buf, urb->actual_length, + (len < maxlen) ? eof[fifon] : 0); + } + fifo->last_urblen = urb->actual_length; + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) { + printk(KERN_INFO + "HFC-S USB: error resubmitting URN at rx_complete...\n"); + } +} /* rx_complete */ /***************************************************/ /* start the interrupt transfer for the given fifo */ /***************************************************/ -static void start_int_fifo(usb_fifo * fifo) +static void +start_int_fifo(usb_fifo * fifo) { int errcode; -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: starting intr IN fifo:%d\n", fifo->fifonum); -#endif + printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", + fifo->fifonum); + if (!fifo->urb) { fifo->urb = usb_alloc_urb(0, GFP_KERNEL); if (!fifo->urb) return; } - usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer, - fifo->usb_packet_maxlen, rx_complete, fifo, fifo->intervall); - fifo->active = 1; /* must be marked active */ + usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, + fifo->buffer, fifo->usb_packet_maxlen, + rx_complete, fifo, fifo->intervall); + fifo->active = 1; /* must be marked active */ errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); - - if(errcode) - { - printk(KERN_INFO "HFC-USB: submit URB error(start_int_info): status:%i\n", errcode); + if (errcode) { + printk(KERN_INFO + "HFC-S USB: submit URB error(start_int_info): status:%i\n", + errcode); fifo->active = 0; fifo->skbuff = NULL; } -} /* start_int_fifo */ +} /* start_int_fifo */ /*****************************/ /* set the B-channel mode */ /*****************************/ -static void set_hfcmode(hfcusb_data *hfc,int channel,int mode) +static void +set_hfcmode(hfcusb_data * hfc, int channel, int mode) { - __u8 val,idx_table[2]={0,2}; - -#ifdef VERBOSE_ISDN_DEBUG - printk (KERN_INFO "HFC-USB: setting channel %d to mode %d\n",channel,mode); -#endif - - hfc->b_mode[channel]=mode; - - // setup CON_HDLC - val=0; - if(mode!=L1_MODE_NULL) val=8; // enable fifo? - if(mode==L1_MODE_TRANS) val|=2; // set transparent bit - - queue_control_request(hfc,HFCUSB_FIFO,idx_table[channel],1); // set FIFO to transmit register - queue_control_request(hfc,HFCUSB_CON_HDLC,val,1); - queue_control_request(hfc,HFCUSB_INC_RES_F,2,1); // reset fifo - - queue_control_request(hfc,HFCUSB_FIFO,idx_table[channel]+1,1); // set FIFO to receive register - queue_control_request(hfc,HFCUSB_CON_HDLC,val,1); - queue_control_request(hfc,HFCUSB_INC_RES_F,2,1); // reset fifo + __u8 val, idx_table[2] = { 0, 2 }; - val=0x40; - if(hfc->b_mode[0]) val|=1; - if(hfc->b_mode[1]) val|=2; - queue_control_request(hfc,HFCUSB_SCTRL,val,1); - - val=0; - if(hfc->b_mode[0]) val|=1; - if(hfc->b_mode[1]) val|=2; - queue_control_request(hfc,HFCUSB_SCTRL_R,val,1); - - if(mode==L1_MODE_NULL) - { - if(channel) handle_led(hfc,LED_B2_OFF); - else handle_led(hfc,LED_B1_OFF); + if (hfc->disc_flag) { + return; } - else - { - if(channel) handle_led(hfc,LED_B2_ON); - else handle_led(hfc,LED_B1_ON); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, + mode); +#endif + hfc->b_mode[channel] = mode; + + /* setup CON_HDLC */ + val = 0; + if (mode != L1_MODE_NULL) + val = 8; /* enable fifo? */ + if (mode == L1_MODE_TRANS) + val |= 2; /* set transparent bit */ + + /* set FIFO to transmit register */ + queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel], 1); + queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1); + /* reset fifo */ + queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1); + /* set FIFO to receive register */ + queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel] + 1, 1); + queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1); + /* reset fifo */ + queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1); + + val = 0x40; + if (hfc->b_mode[0]) + val |= 1; + if (hfc->b_mode[1]) + val |= 2; + queue_control_request(hfc, HFCUSB_SCTRL, val, 1); + + val = 0; + if (hfc->b_mode[0]) + val |= 1; + if (hfc->b_mode[1]) + val |= 2; + queue_control_request(hfc, HFCUSB_SCTRL_R, val, 1); + + if (mode == L1_MODE_NULL) { + if (channel) + handle_led(hfc, LED_B2_OFF); + else + handle_led(hfc, LED_B1_OFF); + } else { + if (channel) + handle_led(hfc, LED_B2_ON); + else + handle_led(hfc, LED_B1_ON); } } -/* - -------------------------------------------------------------------------------------- - from here : hisax_if callback routines : - - void hfc_usb_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) { - - l1 to l2 routines : - - static void hfc_usb_l1l2(hfcusb_data * hfc) - -*/ - -void hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) +void +hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) { - usb_fifo *fifo = my_hisax_if->priv; + usb_fifo *fifo = my_hisax_if->priv; hfcusb_data *hfc = fifo->hfc; - switch (pr) { + switch (pr) { case PH_ACTIVATE | REQUEST: - if(fifo->fifonum==HFCUSB_D_TX) - { -#ifdef VERBOSE_ISDN_DEBUG - printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST\n"); -#endif - queue_control_request(hfc, HFCUSB_STATES,0x60,1); /* make activation */ - hfc->t3_timer.expires = jiffies + (HFC_TIMER_T3 * HZ) / 1000; - if(!timer_pending(&hfc->t3_timer)) add_timer(&hfc->t3_timer); - } - else - { -#ifdef VERBOSE_ISDN_DEBUG - printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST\n"); -#endif - set_hfcmode(hfc,(fifo->fifonum==HFCUSB_B1_TX) ? 0 : 1 ,(int)arg); - fifo->hif->l1l2(fifo->hif,PH_ACTIVATE | INDICATION, NULL); - } - break; - case PH_DEACTIVATE | REQUEST: - if(fifo->fifonum==HFCUSB_D_TX) - { -#ifdef VERBOSE_ISDN_DEBUG - printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST\n"); -#endif - printk (KERN_INFO "HFC-USB: ISDN TE device should not deativate...\n"); - } - else - { -#ifdef VERBOSE_ISDN_DEBUG - printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST\n"); -#endif - set_hfcmode(hfc,(fifo->fifonum==HFCUSB_B1_TX) ? 0 : 1 ,(int)L1_MODE_NULL); - fifo->hif->l1l2(fifo->hif,PH_DEACTIVATE | INDICATION, NULL); + if (fifo->fifonum == HFCUSB_D_TX) { +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); +#endif + if (hfc->l1_state != 3 + && hfc->l1_state != 7) { + hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, + PH_DEACTIVATE | + INDICATION, + NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); +#endif + } else { + if (hfc->l1_state == 7) { /* l1 already active */ + hfc->d_if.ifc.l1l2(&hfc-> + d_if. + ifc, + PH_ACTIVATE + | + INDICATION, + NULL); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); +#endif + } else { + /* force sending sending INFO1 */ + queue_control_request(hfc, + HFCUSB_STATES, + 0x14, + 1); + mdelay(1); + /* start l1 activation */ + queue_control_request(hfc, + HFCUSB_STATES, + 0x04, + 1); + if (!timer_pending + (&hfc->t3_timer)) { + hfc->t3_timer. + expires = + jiffies + + (HFC_TIMER_T3 * + HZ) / 1000; + add_timer(&hfc-> + t3_timer); + } + } } - break; + } else { +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); +#endif + set_hfcmode(hfc, + (fifo->fifonum == + HFCUSB_B1_TX) ? 0 : 1, + (int) arg); + fifo->hif->l1l2(fifo->hif, + PH_ACTIVATE | INDICATION, + NULL); + } + break; + case PH_DEACTIVATE | REQUEST: + if (fifo->fifonum == HFCUSB_D_TX) { +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); +#endif + printk(KERN_INFO + "HFC-S USB: ISDN TE device should not deativate...\n"); + } else { +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); +#endif + set_hfcmode(hfc, + (fifo->fifonum == + HFCUSB_B1_TX) ? 0 : 1, + (int) L1_MODE_NULL); + fifo->hif->l1l2(fifo->hif, + PH_DEACTIVATE | INDICATION, + NULL); + } + break; case PH_DATA | REQUEST: - if(fifo->skbuff && fifo->delete_flg) - { - dev_kfree_skb_any(fifo->skbuff); - //printk(KERN_INFO "skbuff=NULL on fifo:%d\n",fifo->fifonum); - fifo->skbuff = NULL; - fifo->delete_flg=FALSE; - } - - fifo->skbuff=arg; // we have a new buffer - - //if(fifo->fifonum==HFCUSB_D_TX) printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DATA | REQUEST\n"); - //else printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DATA | REQUEST\n"); - break; - default: - printk (KERN_INFO "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", pr); - break; - } + if (fifo->skbuff && fifo->delete_flg) { + dev_kfree_skb_any(fifo->skbuff); + fifo->skbuff = NULL; + fifo->delete_flg = FALSE; + } + fifo->skbuff = arg; /* we have a new buffer */ + break; + default: + printk(KERN_INFO + "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", + pr); + break; + } } -// valid configurations -#define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT -#define CNF_3INT3ISO 2 // 3 INT IN, 3 ISO OUT -#define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT -#define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT - - -/* - -------------------------------------------------------------------------------------- - From here on USB initialization and deactivation related routines are implemented : - - - hfc_usb_init : - is the main Entry Point for the USB Subsystem when the device get plugged - in. This function calls usb_register with usb_driver as parameter. - Here, further entry points for probing (hfc_usb_probe) and disconnecting - the device (hfc_usb_disconnect) are published, as the id_table - - - hfc_usb_probe - this function is called by the usb subsystem, and steps through the alternate - settings of the currently plugged in device to detect all Endpoints needed to - run an ISDN TA. - Needed EndPoints are - 3 (+1) IntIn EndPoints (D-in, E-in, B1-in, B2-in, (E-in)) or - 3 (+1) Isochron In Endpoints (D-out, B1-out, B2-out) and 3 IsoOut Endpoints - The currently used transfer mode of on the Out-Endpoints will be stored in - hfc->usb_transfer_mode and is either USB_INT or USB_ISO - When a valid alternate setting could be found, the usb_init (see blow) - function is called - - - usb_init - Here, the HFC_USB Chip itself gets initialized and the USB framework to send/receive - Data to/from the several EndPoints are initialized: - The E- and D-Channel Int-In chain gets started - The IsoChain for the Iso-Out traffic get started - - - hfc_usb_disconnect - this function is called by the usb subsystem and has to free all resources - and stop all usb traffic to allow a proper hotplugging disconnect. - -*/ - /***************************************************************************/ /* usb_init is called once when a new matching device is detected to setup */ -/* main parameters. It registers the driver at the main hisax module. */ +/* main parameters. It registers the driver at the main hisax module. */ /* on success 0 is returned. */ /***************************************************************************/ -static int usb_init(hfcusb_data * hfc) +static int +usb_init(hfcusb_data * hfc) { usb_fifo *fifo; int i, err; u_char b; struct hisax_b_if *p_b_if[2]; - + /* check the chip id */ - printk(KERN_INFO "HFCUSB_CHIP_ID begin\n"); if (read_usb(hfc, HFCUSB_CHIP_ID, &b) != 1) { printk(KERN_INFO "HFC-USB: cannot read chip id\n"); - return(1); + return (1); } - printk(KERN_INFO "HFCUSB_CHIP_ID %x\n", b); if (b != HFCUSB_CHIPID) { - printk(KERN_INFO "HFC-USB: Invalid chip id 0x%02x\n", b); - return(1); + printk(KERN_INFO "HFC-S USB: Invalid chip id 0x%02x\n", b); + return (1); } /* first set the needed config, interface and alternate */ - printk(KERN_INFO "usb_init 1\n"); -// usb_set_configuration(hfc->dev, 1); - printk(KERN_INFO "usb_init 2\n"); err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used); - printk(KERN_INFO "usb_init usb_set_interface return %d\n", err); - /* now we initialize the chip */ - write_usb(hfc, HFCUSB_CIRM, 8); // do reset - write_usb(hfc, HFCUSB_CIRM, 0x10); // aux = output, reset off - // set USB_SIZE to match the the wMaxPacketSize for INT or BULK transfers - write_usb(hfc, HFCUSB_USB_SIZE,(hfc->packet_size/8) | ((hfc->packet_size/8) << 4)); + /* do Chip reset */ + write_usb(hfc, HFCUSB_CIRM, 8); + /* aux = output, reset off */ + write_usb(hfc, HFCUSB_CIRM, 0x10); + + /* set USB_SIZE to match the the wMaxPacketSize for INT or BULK transfers */ + write_usb(hfc, HFCUSB_USB_SIZE, + (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - // set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers + /* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */ write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); /* enable PCM/GCI master mode */ @@ -1184,412 +1292,447 @@ static int usb_init(hfcusb_data * hfc) write_usb(hfc, HFCUSB_MST_MODE0, 1); /* enable master mode */ /* init the fifos */ - write_usb(hfc, HFCUSB_F_THRES, (HFCUSB_TX_THRESHOLD/8) |((HFCUSB_RX_THRESHOLD/8) << 4)); + write_usb(hfc, HFCUSB_F_THRES, + (HFCUSB_TX_THRESHOLD / + 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4)); fifo = hfc->fifos; - for(i = 0; i < HFCUSB_NUM_FIFOS; i++) - { + for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { write_usb(hfc, HFCUSB_FIFO, i); /* select the desired fifo */ fifo[i].skbuff = NULL; /* init buffer pointer */ - fifo[i].max_size = (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN; - fifo[i].last_urblen=0; - write_usb(hfc, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2)); // set 2 bit for D- & E-channel - write_usb(hfc, HFCUSB_CON_HDLC, ((i==HFCUSB_D_TX) ? 0x09 : 0x08)); // rx hdlc, enable IFF for D-channel + fifo[i].max_size = + (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN; + fifo[i].last_urblen = 0; + /* set 2 bit for D- & E-channel */ + write_usb(hfc, HFCUSB_HDLC_PAR, + ((i <= HFCUSB_B2_RX) ? 0 : 2)); + /* rx hdlc, enable IFF for D-channel */ + write_usb(hfc, HFCUSB_CON_HDLC, + ((i == HFCUSB_D_TX) ? 0x09 : 0x08)); write_usb(hfc, HFCUSB_INC_RES_F, 2); /* reset the fifo */ } - write_usb(hfc, HFCUSB_CLKDEL, 0x0f); /* clock delay value */ - write_usb(hfc, HFCUSB_STATES, 3 | 0x10); /* set deactivated mode */ - write_usb(hfc, HFCUSB_STATES, 3); /* enable state machine */ - - write_usb(hfc, HFCUSB_SCTRL_R, 0); /* disable both B receivers */ - write_usb(hfc, HFCUSB_SCTRL, 0x40); /* disable B transmitters + capacitive mode */ - - // set both B-channel to not connected - hfc->b_mode[0]=L1_MODE_NULL; - hfc->b_mode[1]=L1_MODE_NULL; - - hfc->l1_activated=FALSE; - hfc->led_state=0; - hfc->led_new_data=0; + write_usb(hfc, HFCUSB_CLKDEL, 0x0f); /* clock delay value */ + write_usb(hfc, HFCUSB_STATES, 3 | 0x10); /* set deactivated mode */ + write_usb(hfc, HFCUSB_STATES, 3); /* enable state machine */ + + write_usb(hfc, HFCUSB_SCTRL_R, 0); /* disable both B receivers */ + write_usb(hfc, HFCUSB_SCTRL, 0x40); /* disable B transmitters + capacitive mode */ + + /* set both B-channel to not connected */ + hfc->b_mode[0] = L1_MODE_NULL; + hfc->b_mode[1] = L1_MODE_NULL; + + hfc->l1_activated = FALSE; + hfc->disc_flag = FALSE; + hfc->led_state = 0; + hfc->led_new_data = 0; + hfc->old_led_state = 0; /* init the t3 timer */ init_timer(&hfc->t3_timer); hfc->t3_timer.data = (long) hfc; hfc->t3_timer.function = (void *) l1_timer_expire_t3; + /* init the t4 timer */ init_timer(&hfc->t4_timer); 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 - hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000; - if(!timer_pending(&hfc->led_timer)) add_timer(&hfc->led_timer); - // init the background machinery for control requests + /* 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_write.bRequestType = 0x40; hfc->ctrl_write.bRequest = 0; hfc->ctrl_write.wLength = 0; - usb_fill_control_urb(hfc->ctrl_urb, hfc->dev, hfc->ctrl_out_pipe,(u_char *) & hfc->ctrl_write, NULL, 0, ctrl_complete, hfc); - + usb_fill_control_urb(hfc->ctrl_urb, + hfc->dev, + hfc->ctrl_out_pipe, + (u_char *) & hfc->ctrl_write, + NULL, 0, ctrl_complete, hfc); /* Init All Fifos */ - for(i = 0; i < HFCUSB_NUM_FIFOS; i++) - { + for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { hfc->fifos[i].iso[0].purb = NULL; hfc->fifos[i].iso[1].purb = NULL; hfc->fifos[i].active = 0; } - - // register like Germaschewski : + /* register Modul to upper Hisax Layers */ hfc->d_if.owner = THIS_MODULE; hfc->d_if.ifc.priv = &hfc->fifos[HFCUSB_D_TX]; hfc->d_if.ifc.l2l1 = hfc_usb_l2l1; - - for (i=0; i<2; i++) - { - hfc->b_if[i].ifc.priv = &hfc->fifos[HFCUSB_B1_TX+i*2]; + for (i = 0; i < 2; i++) { + hfc->b_if[i].ifc.priv = &hfc->fifos[HFCUSB_B1_TX + i * 2]; hfc->b_if[i].ifc.l2l1 = hfc_usb_l2l1; p_b_if[i] = &hfc->b_if[i]; } - - hfc->protocol = 2; /* default EURO ISDN, should be a module_param */ + /* default Prot: EURO ISDN, should be a module_param */ + hfc->protocol = 2; hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol); - - for (i=0; i<4; i++) - hfc->fifos[i].hif=&p_b_if[i/2]->ifc; - for (i=4; i<8; i++) - hfc->fifos[i].hif=&hfc->d_if.ifc; - - // 3 (+1) INT IN + 3 ISO OUT - if(hfc->cfg_used == CNF_3INT3ISO || hfc->cfg_used == CNF_4INT3ISO) - { - start_int_fifo(hfc->fifos + HFCUSB_D_RX); // Int IN D-fifo - if(hfc->fifos[HFCUSB_PCM_RX].pipe) start_int_fifo(hfc->fifos + HFCUSB_PCM_RX); // E-fifo - start_int_fifo(hfc->fifos + HFCUSB_B1_RX); // Int IN B1-fifo - start_int_fifo(hfc->fifos + HFCUSB_B2_RX); // Int IN B2-fifo - } - - // 3 (+1) ISO IN + 3 ISO OUT - if(hfc->cfg_used==CNF_3ISO3ISO || hfc->cfg_used==CNF_4ISO3ISO) - { - start_isoc_chain(hfc->fifos + HFCUSB_D_RX, ISOC_PACKETS_D, rx_iso_complete,16); - if(hfc->fifos[HFCUSB_PCM_RX].pipe) start_isoc_chain(hfc->fifos + HFCUSB_PCM_RX, ISOC_PACKETS_D, rx_iso_complete,16); - start_isoc_chain(hfc->fifos + HFCUSB_B1_RX, ISOC_PACKETS_B, rx_iso_complete,16); - start_isoc_chain(hfc->fifos + HFCUSB_B2_RX, ISOC_PACKETS_B, rx_iso_complete,16); - } - - start_isoc_chain(hfc->fifos + HFCUSB_D_TX, ISOC_PACKETS_D, tx_iso_complete,1); - start_isoc_chain(hfc->fifos + HFCUSB_B1_TX, ISOC_PACKETS_B, tx_iso_complete,1); - start_isoc_chain(hfc->fifos + HFCUSB_B2_TX, ISOC_PACKETS_B, tx_iso_complete,1); - - handle_led(hfc,LED_POWER_ON); - - return(0); -} /* usb_init */ - - -/****************************************/ -/* data defining the devices to be used */ -/****************************************/ -// static __devinitdata const struct usb_device_id hfc_usb_idtab[3] = { -static struct usb_device_id hfc_usb_idtab[] = { - {USB_DEVICE(0x7b0, 0x0007)}, /* Billion USB TA 2 */ - {USB_DEVICE(0x742, 0x2008)}, /* Stollmann USB TA */ - {USB_DEVICE(0x959, 0x2bd0)}, /* Colognechip USB eval TA */ - {USB_DEVICE(0x8e3, 0x0301)}, /* OliTec ISDN USB */ - {USB_DEVICE(0x675, 0x1688)}, /* DrayTec ISDN USB */ - {USB_DEVICE(0x7fa, 0x0846)}, /* Bewan ISDN USB TA */ - {} /* end with an all-zeroes entry */ -}; -MODULE_AUTHOR("Peter Sprenger (sprenger@moving-byters.de)/Martin Bachem (info@colognechip.com)"); -MODULE_DESCRIPTION("HFC I4L USB driver"); -MODULE_DEVICE_TABLE(usb, hfc_usb_idtab); -MODULE_LICENSE("GPL"); +#ifdef CONFIG_HISAX_DEBUG + hfc_debug = debug; +#endif -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position - -// this array represents all endpoints possible in the HCF-USB -// the last 2 entries are the configuration number and the minimum interval for Interrupt endpoints -int validconf[][18]= -{ - // INT in, ISO out config - {EP_NUL,EP_INT,EP_NUL,EP_INT,EP_NUL,EP_INT,EP_NOP,EP_INT,EP_ISO,EP_NUL,EP_ISO,EP_NUL,EP_ISO,EP_NUL,EP_NUL,EP_NUL,CNF_4INT3ISO,2}, - {EP_NUL,EP_INT,EP_NUL,EP_INT,EP_NUL,EP_INT,EP_NUL,EP_NUL,EP_ISO,EP_NUL,EP_ISO,EP_NUL,EP_ISO,EP_NUL,EP_NUL,EP_NUL,CNF_3INT3ISO,2}, - // ISO in, ISO out config - {EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_NOP,EP_ISO,CNF_4ISO3ISO,2}, - {EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_NUL,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_ISO,EP_NUL,EP_NUL,CNF_3ISO3ISO,2}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // EOL element -}; + for (i = 0; i < 4; i++) + hfc->fifos[i].hif = &p_b_if[i / 2]->ifc; + for (i = 4; i < 8; i++) + hfc->fifos[i].hif = &hfc->d_if.ifc; + + /* 3 (+1) INT IN + 3 ISO OUT */ + if (hfc->cfg_used == CNF_3INT3ISO || hfc->cfg_used == CNF_4INT3ISO) { + start_int_fifo(hfc->fifos + HFCUSB_D_RX); + if (hfc->fifos[HFCUSB_PCM_RX].pipe) + start_int_fifo(hfc->fifos + HFCUSB_PCM_RX); + start_int_fifo(hfc->fifos + HFCUSB_B1_RX); + start_int_fifo(hfc->fifos + HFCUSB_B2_RX); + } + /* 3 (+1) ISO IN + 3 ISO OUT */ + if (hfc->cfg_used == CNF_3ISO3ISO || hfc->cfg_used == CNF_4ISO3ISO) { + start_isoc_chain(hfc->fifos + HFCUSB_D_RX, ISOC_PACKETS_D, + rx_iso_complete, 16); + if (hfc->fifos[HFCUSB_PCM_RX].pipe) + start_isoc_chain(hfc->fifos + HFCUSB_PCM_RX, + ISOC_PACKETS_D, rx_iso_complete, + 16); + start_isoc_chain(hfc->fifos + HFCUSB_B1_RX, ISOC_PACKETS_B, + rx_iso_complete, 16); + start_isoc_chain(hfc->fifos + HFCUSB_B2_RX, ISOC_PACKETS_B, + rx_iso_complete, 16); + } + + start_isoc_chain(hfc->fifos + HFCUSB_D_TX, ISOC_PACKETS_D, + tx_iso_complete, 1); + start_isoc_chain(hfc->fifos + HFCUSB_B1_TX, ISOC_PACKETS_B, + tx_iso_complete, 1); + start_isoc_chain(hfc->fifos + HFCUSB_B2_TX, ISOC_PACKETS_B, + tx_iso_complete, 1); -// string description of chosen config -char *conf_str[]= -{ - "4 Interrupt IN + 3 Isochron OUT", - "3 Interrupt IN + 3 Isochron OUT", - "4 Isochron IN + 3 Isochron OUT", - "3 Isochron IN + 3 Isochron OUT" -}; + handle_led(hfc, LED_POWER_ON); + return (0); +} /* usb_init */ /*************************************************/ /* function called to probe a new plugged device */ /*************************************************/ -static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int +hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev= interface_to_usbdev(intf); + struct usb_device *dev = interface_to_usbdev(intf); hfcusb_data *context; struct usb_host_interface *iface = intf->cur_altsetting; struct usb_host_interface *iface_used = NULL; struct usb_host_endpoint *ep; int ifnum = iface->desc.bInterfaceNumber; - int i, idx, alt_idx, probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found, cidx, ep_addr; - int cmptbl[16],small_match,iso_packet_size,packet_size,alt_used=0; - -// usb_show_device(dev); -// usb_show_device_descriptor(&dev->descriptor); -// usb_show_interface_descriptor(&iface->desc); - vend_idx=0xffff; - for(i=0;vdata[i].vendor;i++) { - if (le16_to_cpu(dev->descriptor.idVendor) == vdata[i].vendor && - le16_to_cpu(dev->descriptor.idProduct) == vdata[i].prod_id) + int i, idx, alt_idx, probe_alt_setting, vend_idx, cfg_used, *vcf, + attr, cfg_found, cidx, ep_addr; + int cmptbl[16], small_match, iso_packet_size, packet_size, + alt_used = 0; + + vend_idx = 0xffff; + for (i = 0; vdata[i].vendor; i++) { + if (dev->descriptor.idVendor == vdata[i].vendor + && dev->descriptor.idProduct == vdata[i].prod_id) vend_idx = i; } - - -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", - ifnum, iface->desc.bAlternateSetting, intf->minor); -#endif +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, + iface->desc.bAlternateSetting, intf->minor); +#endif + printk(KERN_INFO + "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", + ifnum, iface->desc.bAlternateSetting, intf->minor); if (vend_idx != 0xffff) { -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: found vendor idx:%d name:%s\n",vend_idx,vdata[vend_idx].vend_name); +#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 a matching alternate setting ... */ + /* if vendor and product ID is OK, start probing alternate settings */ alt_idx = 0; - small_match=0xffff; - // default settings - iso_packet_size=16; - packet_size=64; + small_match = 0xffff; + + /* default settings */ + iso_packet_size = 16; + packet_size = 64; while (alt_idx < intf->num_altsetting) { iface = intf->altsetting + alt_idx; probe_alt_setting = iface->desc.bAlternateSetting; - cfg_used=0; + cfg_used = 0; -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: test alt_setting %d\n", probe_alt_setting); -#endif - // check for config EOL element + /* check for config EOL element */ while (validconf[cfg_used][0]) { - cfg_found=TRUE; - vcf=validconf[cfg_used]; - ep = iface->endpoint; /* first endpoint descriptor */ - -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: (if=%d alt=%d cfg_used=%d)\n", - ifnum, probe_alt_setting, cfg_used); -#endif - // copy table - memcpy(cmptbl,vcf,16*sizeof(int)); - - // check for all endpoints in this alternate setting - for (i=0; i < iface->desc.bNumEndpoints; i++) { - ep_addr = ep->desc.bEndpointAddress; - idx = ((ep_addr & 0x7f)-1)*2; /* get endpoint base */ + cfg_found = TRUE; + vcf = validconf[cfg_used]; + /* first endpoint descriptor */ + ep = iface->endpoint; +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", + ifnum, probe_alt_setting, cfg_used); +#endif + memcpy(cmptbl, vcf, 16 * sizeof(int)); + + /* check for all endpoints in this alternate setting */ + for (i = 0; i < iface->desc.bNumEndpoints; + i++) { + ep_addr = + ep->desc.bEndpointAddress; + /* get endpoint base */ + idx = ((ep_addr & 0x7f) - 1) * 2; if (ep_addr & 0x80) idx++; attr = ep->desc.bmAttributes; - if (cmptbl[idx] == EP_NUL) { - printk(KERN_INFO "HFC-USB: cfg_found=FALSE in idx:%d attr:%d cmptbl[%d]:%d\n", - idx, attr, idx, cmptbl[idx]); cfg_found = FALSE; } - - if (attr == USB_ENDPOINT_XFER_INT && cmptbl[idx] == EP_INT) + if (attr == USB_ENDPOINT_XFER_INT + && cmptbl[idx] == EP_INT) cmptbl[idx] = EP_NUL; - if (attr == USB_ENDPOINT_XFER_BULK && cmptbl[idx] == EP_BLK) + if (attr == USB_ENDPOINT_XFER_BULK + && cmptbl[idx] == EP_BLK) cmptbl[idx] = EP_NUL; - if (attr == USB_ENDPOINT_XFER_ISOC && cmptbl[idx] == EP_ISO) + if (attr == USB_ENDPOINT_XFER_ISOC + && cmptbl[idx] == EP_ISO) cmptbl[idx] = EP_NUL; - // check if all INT endpoints match minimum interval - if (attr == USB_ENDPOINT_XFER_INT && ep->desc.bInterval < vcf[17]) { -#ifdef VERBOSE_USB_DEBUG + /* check if all INT endpoints match minimum interval */ + if (attr == USB_ENDPOINT_XFER_INT + && ep->desc.bInterval < + vcf[17]) { +#ifdef CONFIG_HISAX_DEBUG if (cfg_found) - printk(KERN_INFO "HFC-USB: Interrupt Endpoint interval < %d found - skipping config\n", - vcf[17]); + DBG(USB_DBG, + "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", + vcf[17]); #endif cfg_found = FALSE; } - ep++; } - for (i = 0; i < 16; i++) { - // printk(KERN_INFO "HFC-USB: cmptbl[%d]:%d\n", i, cmptbl[i]); - - // all entries must be EP_NOP or EP_NUL for a valid config - if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) + /* all entries must be EP_NOP or EP_NUL for a valid config */ + if (cmptbl[i] != EP_NOP + && cmptbl[i] != EP_NUL) cfg_found = FALSE; } - - // we check for smallest match, to provide configuration priority - // configurations with smaller index have higher priority if (cfg_found) { if (cfg_used < small_match) { small_match = cfg_used; - alt_used = probe_alt_setting; + alt_used = + probe_alt_setting; iface_used = iface; } -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: small_match=%x %x\n", small_match, alt_used); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: small_match=%x %x\n", + small_match, alt_used); #endif } - cfg_used++; } - alt_idx++; } /* (alt_idx < intf->num_altsetting) */ -#ifdef VERBOSE_USB_DEBUG - printk(KERN_INFO "HFC-USB: final small_match=%x alt_used=%x\n",small_match, alt_used); -#endif - // yiipiee, we found a valid config + + /* found a valid USB Ta Endpint config */ if (small_match != 0xffff) { iface = iface_used; + if (! + (context = + kmalloc(sizeof(hfcusb_data), GFP_KERNEL))) + return (-ENOMEM); /* got no mem */ + memset(context, 0, sizeof(hfcusb_data)); - if (!(context = kmalloc(sizeof(hfcusb_data), GFP_KERNEL))) - return(-ENOMEM); /* got no mem */ - memset(context, 0, sizeof(hfcusb_data)); /* clear the structure */ - - ep = iface->endpoint; /* first endpoint descriptor */ + ep = iface->endpoint; vcf = validconf[small_match]; for (i = 0; i < iface->desc.bNumEndpoints; i++) { ep_addr = ep->desc.bEndpointAddress; - idx = ((ep_addr & 0x7f)-1)*2; /* get endpoint base */ + /* get endpoint base */ + idx = ((ep_addr & 0x7f) - 1) * 2; if (ep_addr & 0x80) idx++; cidx = idx & 7; attr = ep->desc.bmAttributes; - // only initialize used endpoints - if (vcf[idx] != EP_NOP && vcf[idx] != EP_NUL) { + /* init Endpoints */ + if (vcf[idx] != EP_NOP + && vcf[idx] != EP_NUL) { switch (attr) { case USB_ENDPOINT_XFER_INT: - context->fifos[cidx].pipe = usb_rcvintpipe(dev, ep->desc.bEndpointAddress); - context->fifos[cidx].usb_transfer_mode = USB_INT; - packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: Interrupt-In Endpoint found %d ms(idx:%d cidx:%d)!\n", - ep->desc.bInterval, idx, cidx); -#endif + context-> + fifos[cidx]. + pipe = + usb_rcvintpipe + (dev, + ep->desc. + bEndpointAddress); + context-> + fifos[cidx]. + usb_transfer_mode + = USB_INT; + packet_size = + ep->desc. + wMaxPacketSize; break; case USB_ENDPOINT_XFER_BULK: if (ep_addr & 0x80) - context->fifos[cidx].pipe = usb_rcvbulkpipe(dev, ep->desc.bEndpointAddress); + context-> + fifos + [cidx]. + pipe = + usb_rcvbulkpipe + (dev, + ep-> + desc. + bEndpointAddress); else - context->fifos[cidx].pipe = usb_sndbulkpipe(dev, ep->desc.bEndpointAddress); - context->fifos[cidx].usb_transfer_mode = USB_BULK; - packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: Bulk Endpoint found (idx:%d cidx:%d)!\n", - idx, cidx); -#endif + context-> + fifos + [cidx]. + pipe = + usb_sndbulkpipe + (dev, + ep-> + desc. + bEndpointAddress); + context-> + fifos[cidx]. + usb_transfer_mode + = USB_BULK; + packet_size = + ep->desc. + wMaxPacketSize; break; case USB_ENDPOINT_XFER_ISOC: if (ep_addr & 0x80) - context->fifos[cidx].pipe = usb_rcvisocpipe(dev, ep->desc.bEndpointAddress); + context-> + fifos + [cidx]. + pipe = + usb_rcvisocpipe + (dev, + ep-> + desc. + bEndpointAddress); else - context->fifos[cidx].pipe = usb_sndisocpipe(dev, ep->desc.bEndpointAddress); - context->fifos[cidx].usb_transfer_mode = USB_ISOC; - iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: ISO Endpoint found (idx:%d cidx:%d)!\n", - idx, cidx); -#endif + context-> + fifos + [cidx]. + pipe = + usb_sndisocpipe + (dev, + ep-> + desc. + bEndpointAddress); + context-> + fifos[cidx]. + usb_transfer_mode + = USB_ISOC; + iso_packet_size = + ep->desc. + wMaxPacketSize; break; default: - context->fifos[cidx].pipe = 0; /* reset data */ + context-> + fifos[cidx]. + pipe = 0; } /* switch attribute */ if (context->fifos[cidx].pipe) { - context->fifos[cidx].fifonum = cidx; - context->fifos[cidx].hfc = context; - context->fifos[cidx].usb_packet_maxlen = le16_to_cpu(ep->desc.wMaxPacketSize); - context->fifos[cidx].intervall = ep->desc.bInterval; - context->fifos[cidx].skbuff = NULL; -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: fifo%d pktlen %d interval %d\n", - context->fifos[cidx].fifonum, - context->fifos[cidx].usb_packet_maxlen, - context->fifos[cidx].intervall); -#endif + context->fifos[cidx]. + fifonum = cidx; + context->fifos[cidx].hfc = + context; + context->fifos[cidx]. + usb_packet_maxlen = + ep->desc. + wMaxPacketSize; + context->fifos[cidx]. + intervall = + ep->desc.bInterval; + context->fifos[cidx]. + skbuff = NULL; } } - ep++; } - - // now share our luck - context->dev = dev; /* save device */ - context->if_used = ifnum; /* save used interface */ - context->alt_used = alt_used; /* and alternate config */ + context->dev = dev; /* save device */ + context->if_used = ifnum; /* save used interface */ + context->alt_used = alt_used; /* and alternate config */ context->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */ - context->cfg_used=vcf[16]; // store used config - context->vend_idx=vend_idx; // store found vendor - context->packet_size=packet_size; - context->iso_packet_size=iso_packet_size; + context->cfg_used = vcf[16]; /* store used config */ + context->vend_idx = vend_idx; /* store found vendor */ + context->packet_size = packet_size; + context->iso_packet_size = iso_packet_size; /* create the control pipes needed for register access */ - context->ctrl_in_pipe = usb_rcvctrlpipe(context->dev, 0); - context->ctrl_out_pipe = usb_sndctrlpipe(context->dev, 0); + context->ctrl_in_pipe = + usb_rcvctrlpipe(context->dev, 0); + context->ctrl_out_pipe = + usb_sndctrlpipe(context->dev, 0); context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); - printk(KERN_INFO "HFC-USB: detected \"%s\" configuration: %s (if=%d alt=%d)\n", - vdata[vend_idx].vend_name, conf_str[small_match], context->if_used, context->alt_used); - + printk(KERN_INFO + "HFC-S USB: detected \"%s\"\n", + vdata[vend_idx].vend_name); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", + conf_str[small_match], context->if_used, + context->alt_used); + printk(KERN_INFO + "HFC-S USB: E-channel (\"ECHO:\") logging "); + if (validconf[small_match][18]) + printk(" possible\n"); + else + printk("NOT possible\n"); +#endif /* init the chip and register the driver */ - if (usb_init(context)) - { + if (usb_init(context)) { if (context->ctrl_urb) { usb_unlink_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; } kfree(context); - return(-EIO); + return (-EIO); } usb_set_intfdata(intf, context); - return(0); - } + return (0); + } + } else { + printk(KERN_INFO + "HFC-S USB: no valid vendor found in USB descriptor\n"); } - return(-EIO); + return (-EIO); } /****************************************************/ /* function called when an active device is removed */ /****************************************************/ -static void hfc_usb_disconnect(struct usb_interface *intf) +static void +hfc_usb_disconnect(struct usb_interface + *intf) { hfcusb_data *context = usb_get_intfdata(intf); int i; - - printk(KERN_INFO "HFC-USB: device disconnect\n"); - + printk(KERN_INFO "HFC-S USB: device disconnect\n"); + context->disc_flag = TRUE; usb_set_intfdata(intf, NULL); if (!context) return; @@ -1599,23 +1742,24 @@ static void hfc_usb_disconnect(struct us del_timer(&context->t4_timer); if (timer_pending(&context->led_timer)) del_timer(&context->led_timer); - - hisax_unregister(&context->d_if); - /* tell all fifos to terminate */ - for(i = 0; i < HFCUSB_NUM_FIFOS; i++) { - if(context->fifos[i].usb_transfer_mode == USB_ISOC) { - if(context->fifos[i].active > 0) { - stop_isoc_chain(&context->fifos[i]); -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i\n", i); + for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { + if (context->fifos[i].usb_transfer_mode == USB_ISOC) { + if (context->fifos[i].active > 0) { + stop_isoc_chain(&context->fifos[i]); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", + i); #endif - } + } } else { - if(context->fifos[i].active > 0) { + if (context->fifos[i].active > 0) { context->fifos[i].active = 0; -#ifdef VERBOSE_USB_DEBUG - printk (KERN_INFO "HFC-USB: hfc_usb_disconnect: unlinking URB for Fifo no %i\n", i); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", + i); #endif } if (context->fifos[i].urb) { @@ -1626,46 +1770,59 @@ static void hfc_usb_disconnect(struct us } context->fifos[i].active = 0; } + /* wait for all URBS to terminate */ + mdelay(10); if (context->ctrl_urb) { usb_unlink_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; } + hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ } /* hfc_usb_disconnect */ - /************************************/ /* 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, + .owner = THIS_MODULE,.name = + "hfc_usb",.id_table = hfc_usb_idtab,.probe = + hfc_usb_probe,.disconnect = hfc_usb_disconnect, }; - -static void __exit hfc_usb_exit(void) +static void __exit +hfc_usb_exit(void) { -#ifdef VERBOSE_USB_DEBUG - printk ("HFC-USB: calling \"hfc_usb_exit\" ...\n"); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); #endif usb_deregister(&hfc_drv); /* release our driver */ - printk(KERN_INFO "HFC-USB module removed\n"); + printk(KERN_INFO "HFC-S USB: module removed\n"); } -static int __init hfc_usb_init(void) +static int __init +hfc_usb_init(void) { - printk ("HFC-USB: driver module revision %s loaded\n", hfcusb_revision); - - if(usb_register(&hfc_drv)) - { - printk(KERN_INFO "HFC-USB: Unable to register HFC-USB module at usb stack\n"); - return(-1); /* unable to register */ +#ifndef CONFIG_HISAX_DEBUG + unsigned int debug = -1; +#endif + char revstr[30], datestr[30], dummy[30]; + sscanf(hfcusb_revision, + "%s %s $ %s %s %s $ ", dummy, revstr, + dummy, datestr, dummy); + printk(KERN_INFO + "HFC-S USB: driver module revision %s date %s loaded, (debug=%i)\n", + revstr, datestr, debug); + if (usb_register(&hfc_drv)) { + printk(KERN_INFO + "HFC-S USB: Unable to register HFC-S USB module at usb stack\n"); + return (-1); /* unable to register */ } - return(0); + return (0); } module_init(hfc_usb_init); module_exit(hfc_usb_exit); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, hfc_usb_idtab); diff -puN /dev/null drivers/isdn/hisax/hfc_usb.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/drivers/isdn/hisax/hfc_usb.h 2005-02-02 18:24:09.957308688 -0800 @@ -0,0 +1,228 @@ +/* +* hfc_usb.h +* +* $Id: hfc_usb.h,v 4.1 2005/01/26 17:25:53 martinb1 Exp $ +*/ + +#ifndef __HFC_USB_H__ +#define __HFC_USB_H__ + +#define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" +#define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" + +#define VERBOSE_USB_DEBUG + +#define TRUE 1 +#define FALSE 0 + + +/***********/ +/* defines */ +/***********/ +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ +#define HFC_TIMER_T4 500 /* time for state change interval */ + +#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ +#define HFCUSB_L1_DRX 1 /* D-frame received */ +#define HFCUSB_L1_ERX 2 /* E-frame received */ +#define HFCUSB_L1_DTX 4 /* D-frames completed */ + +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ + +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ + +#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ +#define HFCUSB_CIRM 0x00 /* cirm register index */ +#define HFCUSB_USB_SIZE 0x07 /* int length register */ +#define HFCUSB_USB_SIZE_I 0x06 /* iso length register */ +#define HFCUSB_F_CROSS 0x0b /* bit order register */ +#define HFCUSB_CLKDEL 0x37 /* bit delay register */ +#define HFCUSB_CON_HDLC 0xfa /* channel connect register */ +#define HFCUSB_HDLC_PAR 0xfb +#define HFCUSB_SCTRL 0x31 /* S-bus control register (tx) */ +#define HFCUSB_SCTRL_E 0x32 /* same for E and special funcs */ +#define HFCUSB_SCTRL_R 0x33 /* S-bus control register (rx) */ +#define HFCUSB_F_THRES 0x0c /* threshold register */ +#define HFCUSB_FIFO 0x0f /* fifo select register */ +#define HFCUSB_F_USAGE 0x1a /* fifo usage register */ +#define HFCUSB_MST_MODE0 0x14 +#define HFCUSB_MST_MODE1 0x15 +#define HFCUSB_P_DATA 0x1f +#define HFCUSB_INC_RES_F 0x0e +#define HFCUSB_STATES 0x30 + +#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ + +/******************/ +/* fifo registers */ +/******************/ +#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ +#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ +#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ +#define HFCUSB_B2_TX 2 +#define HFCUSB_B2_RX 3 +#define HFCUSB_D_TX 4 +#define HFCUSB_D_RX 5 +#define HFCUSB_PCM_TX 6 +#define HFCUSB_PCM_RX 7 + +/* +* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just +* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out +*/ +#define USB_INT 0 +#define USB_BULK 1 +#define USB_ISOC 2 + +#define ISOC_PACKETS_D 8 +#define ISOC_PACKETS_B 8 +#define ISO_BUFFER_SIZE 128 + +// ISO send definitions +#define SINK_MAX 68 +#define SINK_MIN 48 +#define SINK_DMIN 12 +#define SINK_DMAX 18 +#define BITLINE_INF (-64*8) + + +/**********/ +/* macros */ +/**********/ +#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT) +#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) + + +/*******************/ +/* Debugging Flags */ +/*******************/ +#define USB_DBG 1 +#define ISDN_DBG 2 + + +/* *********************/ +/* USB related defines */ +/***********************/ +#define HFC_CTRL_BUFSIZE 32 + + + +/*************************************************/ +/* entry and size of output/input control buffer */ +/*************************************************/ +typedef struct { + __u8 hfc_reg; /* register number */ + __u8 reg_val; /* value to be written (or read) */ + int action; /* data for action handler */ +} ctrl_buft; + + +/********************/ +/* URB error codes: */ +/********************/ +/* Used to represent a list of values and their respective symbolic names */ +struct hfcusb_symbolic_list { + const int num; + const char *name; +}; + +static struct hfcusb_symbolic_list urb_errlist[] = { + {-ENOMEM, "No memory for allocation of internal structures"}, + {-ENOSPC, "The host controller's bandwidth is already consumed"}, + {-ENOENT, "URB was canceled by unlink_urb"}, + {-EXDEV, "ISO transfer only partially completed"}, + {-EAGAIN, "Too match scheduled for the future"}, + {-ENXIO, "URB already queued"}, + {-EFBIG, "Too much ISO frames requested"}, + {-ENOSR, "Buffer error (overrun)"}, + {-EPIPE, "Specified endpoint is stalled (device not responding)"}, + {-EOVERFLOW, "Babble (bad cable?)"}, + {-EPROTO, "Bit-stuff error (bad cable?)"}, + {-EILSEQ, "CRC/Timeout"}, + {-ETIMEDOUT, "NAK (device does not respond)"}, + {-ESHUTDOWN, "Device unplugged"}, + {-1, NULL} +}; + + +/*****************************************************/ +/* device dependant information to support different */ +/* ISDN Ta's using the HFC-S USB chip */ +/*****************************************************/ + +/* USB descriptor need to contain one of the following EndPoint combination: */ +#define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT +#define CNF_3INT3ISO 2 // 3 INT IN, 3 ISO OUT +#define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT +#define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT + +#define EP_NUL 1 // Endpoint at this position not allowed +#define EP_NOP 2 // all type of endpoints allowed at this position +#define EP_ISO 3 // Isochron endpoint mandatory at this position +#define EP_BLK 4 // Bulk endpoint mandatory at this position +#define EP_INT 5 // Interrupt endpoint mandatory at this position + +/* this array represents all endpoints possible in the HCF-USB the last +* 3 entries are the configuration number, the minimum interval for +* Interrupt endpoints & boolean if E-channel logging possible +*/ +int validconf[][19] = { + // INT in, ISO out config + {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, + EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, + CNF_4INT3ISO, 2, 1}, + {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_NUL, + EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, + CNF_3INT3ISO, 2, 0}, + // ISO in, ISO out config + {EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, + EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NOP, EP_ISO, + CNF_4ISO3ISO, 2, 1}, + {EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, + EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NUL, EP_NUL, + CNF_3ISO3ISO, 2, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // EOL element +}; + +// string description of chosen config +char *conf_str[] = { + "4 Interrupt IN + 3 Isochron OUT", + "3 Interrupt IN + 3 Isochron OUT", + "4 Isochron IN + 3 Isochron OUT", + "3 Isochron IN + 3 Isochron OUT" +}; + + +typedef struct { + int vendor; // vendor id + int prod_id; // product id + char *vend_name; // vendor string + __u8 led_scheme; // led display scheme + signed short led_bits[8]; // array of 8 possible LED bitmask settings +} vendor_data; + +#define LED_OFF 0 // no LED support +#define LED_SCHEME1 1 // LED standard scheme +#define LED_SCHEME2 2 // not used yet... + +#define LED_POWER_ON 1 +#define LED_POWER_OFF 2 +#define LED_S0_ON 3 +#define LED_S0_OFF 4 +#define LED_B1_ON 5 +#define LED_B1_OFF 6 +#define LED_B1_DATA 7 +#define LED_B2_ON 8 +#define LED_B2_OFF 9 +#define LED_B2_DATA 10 + +#define LED_NORMAL 0 // LEDs are normal +#define LED_INVERTED 1 // LEDs are inverted + +/* time in ms to perform a Flashing LED when B-Channel has traffic */ +#define LED_TIME 250 + + +#endif // __HFC_USB_H__ _