Commit d6c59c13 authored by Martin Bachem's avatar Martin Bachem Committed by Linus Torvalds

hisax: update hfc_usb driver

This fixes handling of USB ISO completion error -EXDEV and includes
several other changes to current CVS version at isdn4linux.de (changes
in debug flags, style of code remarks, etc)
Signed-off-by: default avatarMartin Bachem <info@colognechip.com>
Acked-by: default avatarKarsten Keil <kkeil@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 36ce1514
/* /*
* hfc_usb.c * hfc_usb.c
* *
* $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $
* *
* modular HiSax ISDN driver for Colognechip HFC-S USB chip * modular HiSax ISDN driver for Colognechip HFC-S USB chip
* *
* Authors : Peter Sprenger (sprenger@moving-bytes.de) * Authors : Peter Sprenger (sprenger@moving-bytes.de)
* Martin Bachem (info@colognechip.com) * Martin Bachem (m.bachem@gmx.de, info@colognechip.com)
* *
* based on the first hfc_usb driver of * based on the first hfc_usb driver of
* Werner Cornelius (werner@isdn-development.de) * Werner Cornelius (werner@isdn-development.de)
...@@ -37,24 +37,25 @@ ...@@ -37,24 +37,25 @@
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include "hisax.h" #include "hisax.h"
#include "hisax_if.h" #include "hisax_if.h"
#include "hfc_usb.h" #include "hfc_usb.h"
static const char *hfcusb_revision = static const char *hfcusb_revision =
"$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ ";
/* Hisax debug support /* Hisax debug support
* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG * debug flags defined in hfc_usb.h as HFCUSB_DBG_[*]
*/ */
#ifdef CONFIG_HISAX_DEBUG
#include <linux/moduleparam.h>
#define __debug_variable hfc_debug #define __debug_variable hfc_debug
#include "hisax_debug.h" #include "hisax_debug.h"
static u_int debug; static u_int debug;
module_param(debug, uint, 0); module_param(debug, uint, 0);
static int hfc_debug; static int hfc_debug;
#endif
/* private vendor specific data */ /* private vendor specific data */
typedef struct { typedef struct {
...@@ -63,9 +64,7 @@ typedef struct { ...@@ -63,9 +64,7 @@ typedef struct {
char *vend_name; // device name char *vend_name; // device name
} hfcsusb_vdata; } hfcsusb_vdata;
/****************************************/ /* VID/PID device list */
/* data defining the devices to be used */
/****************************************/
static struct usb_device_id hfcusb_idtab[] = { static struct usb_device_id hfcusb_idtab[] = {
{ {
USB_DEVICE(0x0959, 0x2bd0), USB_DEVICE(0x0959, 0x2bd0),
...@@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = { ...@@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = {
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1}, {LED_SCHEME1, {4, 0, 2, 1},
"Stollmann USB TA"}), "Stollmann USB TA"}),
}, },
{ {
USB_DEVICE(0x0742, 0x2009), USB_DEVICE(0x0742, 0x2009),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1}, {LED_SCHEME1, {4, 0, 2, 1},
"Aceex USB ISDN TA"}), "Aceex USB ISDN TA"}),
}, },
{ {
USB_DEVICE(0x0742, 0x200A), USB_DEVICE(0x0742, 0x200A),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1}, {LED_SCHEME1, {4, 0, 2, 1},
"OEM USB ISDN TA"}), "OEM USB ISDN TA"}),
}, },
{ {
USB_DEVICE(0x08e3, 0x0301), USB_DEVICE(0x08e3, 0x0301),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {2, 0, 1, 4}, {LED_SCHEME1, {2, 0, 1, 4},
"Olitec USB RNIS"}), "Olitec USB RNIS"}),
}, },
{ {
USB_DEVICE(0x07fa, 0x0846), USB_DEVICE(0x07fa, 0x0846),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16}, {LED_SCHEME1, {0x80, -64, -32, -16},
"Bewan Modem RNIS USB"}), "Bewan Modem RNIS USB"}),
}, },
{ {
USB_DEVICE(0x07fa, 0x0847), USB_DEVICE(0x07fa, 0x0847),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16}, {LED_SCHEME1, {0x80, -64, -32, -16},
"Djinn Numeris USB"}), "Djinn Numeris USB"}),
}, },
{ {
USB_DEVICE(0x07b0, 0x0006), USB_DEVICE(0x07b0, 0x0006),
.driver_info = (unsigned long) &((hfcsusb_vdata) .driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16}, {LED_SCHEME1, {0x80, -64, -32, -16},
"Twister ISDN TA"}), "Twister ISDN TA"}),
}, },
{ } { }
}; };
/***************************************************************/
/* structure defining input+output fifos (interrupt/bulk mode) */ /* structure defining input+output fifos (interrupt/bulk mode) */
/***************************************************************/
struct usb_fifo; /* forward definition */ struct usb_fifo; /* forward definition */
typedef struct iso_urb_struct { typedef struct iso_urb_struct {
struct urb *purb; struct urb *purb;
...@@ -140,8 +137,8 @@ typedef struct iso_urb_struct { ...@@ -140,8 +137,8 @@ typedef struct iso_urb_struct {
struct usb_fifo *owner_fifo; /* pointer to owner fifo */ struct usb_fifo *owner_fifo; /* pointer to owner fifo */
} iso_urb_struct; } iso_urb_struct;
struct hfcusb_data; /* forward definition */ struct hfcusb_data; /* forward definition */
typedef struct usb_fifo { typedef struct usb_fifo {
int fifonum; /* fifo index attached to this structure */ int fifonum; /* fifo index attached to this structure */
int active; /* fifo is currently active */ int active; /* fifo is currently active */
...@@ -160,15 +157,12 @@ typedef struct usb_fifo { ...@@ -160,15 +157,12 @@ typedef struct usb_fifo {
struct hisax_if *hif; /* hisax interface */ struct hisax_if *hif; /* hisax interface */
int delete_flg; /* only delete skbuff once */ int delete_flg; /* only delete skbuff once */
int last_urblen; /* remember length of last packet */ int last_urblen; /* remember length of last packet */
} usb_fifo; } usb_fifo;
/*********************************************/
/* structure holding all data for one device */ /* structure holding all data for one device */
/*********************************************/
typedef struct hfcusb_data { typedef struct hfcusb_data {
/* HiSax Interface for loadable Layer1 drivers */ /* HiSax Interface for loadable Layer1 drivers */
struct hisax_d_if d_if; /* see hisax_if.h */ struct hisax_d_if d_if; /* see hisax_if.h */
struct hisax_b_if b_if[2]; /* see hisax_if.h */ struct hisax_b_if b_if[2]; /* see hisax_if.h */
int protocol; int protocol;
...@@ -176,12 +170,13 @@ typedef struct hfcusb_data { ...@@ -176,12 +170,13 @@ typedef struct hfcusb_data {
int if_used; /* used interface number */ int if_used; /* used interface number */
int alt_used; /* used alternate config */ int alt_used; /* used alternate config */
int ctrl_paksize; /* control pipe packet size */ int ctrl_paksize; /* control pipe packet size */
int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ int ctrl_in_pipe, /* handles for control pipe */
ctrl_out_pipe;
int cfg_used; /* configuration index used */ int cfg_used; /* configuration index used */
int vend_idx; /* vendor found */ int vend_idx; /* vendor found */
int b_mode[2]; /* B-channel mode */ int b_mode[2]; /* B-channel mode */
int l1_activated; /* layer 1 activated */ int l1_activated; /* layer 1 activated */
int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */
int packet_size, iso_packet_size; int packet_size, iso_packet_size;
/* control pipe background handling */ /* control pipe background handling */
...@@ -208,7 +203,6 @@ typedef struct hfcusb_data { ...@@ -208,7 +203,6 @@ typedef struct hfcusb_data {
static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len,
int finish); int finish);
static inline const char * static inline const char *
symbolic(struct hfcusb_symbolic_list list[], const int num) symbolic(struct hfcusb_symbolic_list list[], const int num)
{ {
...@@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) ...@@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
return "<unknown ERROR>"; return "<unknown ERROR>";
} }
/******************************************************/
/* start next background transfer for control channel */
/******************************************************/
static void static void
ctrl_start_transfer(hfcusb_data * hfc) ctrl_start_transfer(hfcusb_data * hfc)
{ {
...@@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc) ...@@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc)
} }
} /* ctrl_start_transfer */ } /* ctrl_start_transfer */
/************************************/
/* queue a control transfer request */
/* return 0 on success. */
/************************************/
static int static int
queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action)
{ {
...@@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) ...@@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action)
if (++hfc->ctrl_cnt == 1) if (++hfc->ctrl_cnt == 1)
ctrl_start_transfer(hfc); ctrl_start_transfer(hfc);
return (0); return (0);
} /* queue_control_request */
static int
control_action_handler(hfcusb_data * hfc, int reg, int val, int action)
{
if (!action)
return (1); /* no action defined */
return (0);
} }
/***************************************************************/
/* control completion routine handling background control cmds */
/***************************************************************/
static void static void
ctrl_complete(struct urb *urb) ctrl_complete(struct urb *urb)
{ {
...@@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb) ...@@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb)
urb->dev = hfc->dev; urb->dev = hfc->dev;
if (hfc->ctrl_cnt) { if (hfc->ctrl_cnt) {
buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; 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 */ hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */ hfc->ctrl_out_idx = 0; /* pointer wrap */
...@@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb) ...@@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb)
} }
} /* ctrl_complete */ } /* ctrl_complete */
/***************************************************/
/* write led data to auxport & invert if necessary */ /* write led data to auxport & invert if necessary */
/***************************************************/
static void static void
write_led(hfcusb_data * hfc, __u8 led_state) write_led(hfcusb_data * hfc, __u8 led_state)
{ {
...@@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state) ...@@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state)
} }
} }
/**************************/
/* handle LED bits */
/**************************/
static void static void
set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
{ {
...@@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) ...@@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
} }
} }
/**************************/ /* handle LED requests */
/* handle LED requests */
/**************************/
static void static void
handle_led(hfcusb_data * hfc, int event) handle_led(hfcusb_data * hfc, int event)
{ {
...@@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event) ...@@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event)
switch (event) { switch (event) {
case LED_POWER_ON: case LED_POWER_ON:
set_led_bit(hfc, driver_info->led_bits[0], set_led_bit(hfc, driver_info->led_bits[0], 0);
0); set_led_bit(hfc, driver_info->led_bits[1], 1);
set_led_bit(hfc, driver_info->led_bits[1], set_led_bit(hfc, driver_info->led_bits[2], 1);
1); set_led_bit(hfc, driver_info->led_bits[3], 1);
set_led_bit(hfc, driver_info->led_bits[2],
1);
set_led_bit(hfc, driver_info->led_bits[3],
1);
break; break;
case LED_POWER_OFF: /* no Power off handling */ case LED_POWER_OFF:
set_led_bit(hfc, driver_info->led_bits[0], 1);
set_led_bit(hfc, driver_info->led_bits[1], 1);
set_led_bit(hfc, driver_info->led_bits[2], 1);
set_led_bit(hfc, driver_info->led_bits[3], 1);
break; break;
case LED_S0_ON: case LED_S0_ON:
set_led_bit(hfc, driver_info->led_bits[1], set_led_bit(hfc, driver_info->led_bits[1], 0);
0);
break; break;
case LED_S0_OFF: case LED_S0_OFF:
set_led_bit(hfc, driver_info->led_bits[1], set_led_bit(hfc, driver_info->led_bits[1], 1);
1);
break; break;
case LED_B1_ON: case LED_B1_ON:
set_led_bit(hfc, driver_info->led_bits[2], set_led_bit(hfc, driver_info->led_bits[2], 0);
0);
break; break;
case LED_B1_OFF: case LED_B1_OFF:
set_led_bit(hfc, driver_info->led_bits[2], set_led_bit(hfc, driver_info->led_bits[2], 1);
1);
break; break;
case LED_B2_ON: case LED_B2_ON:
set_led_bit(hfc, driver_info->led_bits[3], set_led_bit(hfc, driver_info->led_bits[3], 0);
0);
break; break;
case LED_B2_OFF: case LED_B2_OFF:
set_led_bit(hfc, driver_info->led_bits[3], set_led_bit(hfc, driver_info->led_bits[3], 1);
1);
break; break;
} }
write_led(hfc, hfc->led_state); write_led(hfc, hfc->led_state);
} }
/********************************/ /* ISDN l1 timer T3 expires */
/* called when timer t3 expires */
/********************************/
static void static void
l1_timer_expire_t3(hfcusb_data * hfc) l1_timer_expire_t3(hfcusb_data * hfc)
{ {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL); NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG, DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)");
#endif
hfc->l1_activated = false; hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF); handle_led(hfc, LED_S0_OFF);
/* deactivate : */ /* deactivate : */
queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); queue_control_request(hfc, HFCUSB_STATES, 0x10, 1);
queue_control_request(hfc, HFCUSB_STATES, 3, 1); queue_control_request(hfc, HFCUSB_STATES, 3, 1);
} }
/********************************/ /* ISDN l1 timer T4 expires */
/* called when timer t4 expires */
/********************************/
static void static void
l1_timer_expire_t4(hfcusb_data * hfc) l1_timer_expire_t4(hfcusb_data * hfc)
{ {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL); NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG, DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)");
#endif
hfc->l1_activated = false; hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF); handle_led(hfc, LED_S0_OFF);
} }
/*****************************/ /* S0 state changed */
/* handle S0 state changes */
/*****************************/
static void static void
state_handler(hfcusb_data * hfc, __u8 state) s0_state_handler(hfcusb_data * hfc, __u8 state)
{ {
__u8 old_state; __u8 old_state;
...@@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state) ...@@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state)
if (state == old_state || state < 1 || state > 8) if (state == old_state || state < 1 || state > 8)
return; return;
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)",
DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, old_state, state);
old_state);
#endif
if (state < 4 || state == 7 || state == 8) { if (state < 4 || state == 7 || state == 8) {
if (timer_pending(&hfc->t3_timer)) if (timer_pending(&hfc->t3_timer))
del_timer(&hfc->t3_timer); del_timer(&hfc->t3_timer);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated");
DBG(ISDN_DBG, "HFC-S USB: T3 deactivated");
#endif
} }
if (state >= 7) { if (state >= 7) {
if (timer_pending(&hfc->t4_timer)) if (timer_pending(&hfc->t4_timer))
del_timer(&hfc->t4_timer); del_timer(&hfc->t4_timer);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated");
DBG(ISDN_DBG, "HFC-S USB: T4 deactivated");
#endif
} }
if (state == 7 && !hfc->l1_activated) { if (state == 7 && !hfc->l1_activated) {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_ACTIVATE | INDICATION, NULL); PH_ACTIVATE | INDICATION, NULL);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); hfc->l1_activated = 1;
#endif
hfc->l1_activated = true;
handle_led(hfc, LED_S0_ON); handle_led(hfc, LED_S0_ON);
} else if (state <= 3 /* && activated */ ) { } else if (state <= 3 /* && activated */ ) {
if (old_state == 7 || old_state == 8) { if (old_state == 7 || old_state == 8) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated");
DBG(ISDN_DBG, "HFC-S USB: T4 activated");
#endif
if (!timer_pending(&hfc->t4_timer)) { if (!timer_pending(&hfc->t4_timer)) {
hfc->t4_timer.expires = hfc->t4_timer.expires =
jiffies + (HFC_TIMER_T4 * HZ) / 1000; jiffies + (HFC_TIMER_T4 * HZ) / 1000;
...@@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state) ...@@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state)
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_DEACTIVATE | INDICATION, PH_DEACTIVATE | INDICATION,
NULL); NULL);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent"); "HFC-S USB: PH_DEACTIVATE | INDICATION sent");
#endif hfc->l1_activated = 0;
hfc->l1_activated = false;
handle_led(hfc, LED_S0_OFF); handle_led(hfc, LED_S0_OFF);
} }
} }
hfc->l1_state = state; hfc->l1_state = state;
} }
/* prepare iso urb */
static void static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
void *buf, int num_packets, int packet_size, int interval, void *buf, int num_packets, int packet_size, int interval,
...@@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, ...@@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
} }
/* allocs urbs and start isoc transfer with two pending urbs to avoid /* allocs urbs and start isoc transfer with two pending urbs to avoid
gaps in the transfer chain */ * gaps in the transfer chain
*/
static int static int
start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
usb_complete_t complete, int packet_size) usb_complete_t complete, int packet_size)
{ {
int i, k, errcode; int i, k, errcode;
printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n",
fifo->fifonum); fifo->fifonum);
/* allocate Memory for Iso out Urbs */ /* allocate Memory for Iso out Urbs */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
...@@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, ...@@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL);
fifo->active = (errcode >= 0) ? 1 : 0; fifo->active = (errcode >= 0) ? 1 : 0;
if (errcode < 0) { if (errcode < 0)
printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n",
symbolic(urb_errlist, errcode), i); i, errcode, symbolic(urb_errlist, errcode));
};
} }
return (fifo->active); return (fifo->active);
} }
...@@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo) ...@@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (fifo->iso[i].purb) { if (fifo->iso[i].purb) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_INIT,
DBG(USB_DBG,
"HFC-S USB: Stopping iso chain for fifo %i.%i", "HFC-S USB: Stopping iso chain for fifo %i.%i",
fifo->fifonum, i); fifo->fifonum, i);
#endif
usb_kill_urb(fifo->iso[i].purb); usb_kill_urb(fifo->iso[i].purb);
usb_free_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb);
fifo->iso[i].purb = NULL; fifo->iso[i].purb = NULL;
} }
} }
usb_kill_urb(fifo->urb); usb_kill_urb(fifo->urb);
usb_free_urb(fifo->urb); usb_free_urb(fifo->urb);
fifo->urb = NULL; fifo->urb = NULL;
...@@ -594,9 +534,6 @@ static int iso_packets[8] = ...@@ -594,9 +534,6 @@ static int iso_packets[8] =
ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
}; };
/*****************************************************/
/* transmit completion routine for all ISO tx fifos */
/*****************************************************/
static void static void
tx_iso_complete(struct urb *urb) tx_iso_complete(struct urb *urb)
{ {
...@@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb) ...@@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb)
errcode; errcode;
int frame_complete, transp_mode, fifon, status; int frame_complete, transp_mode, fifon, status;
__u8 threshbit; __u8 threshbit;
__u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
fifon = fifo->fifonum; fifon = fifo->fifonum;
status = urb->status; status = urb->status;
tx_offset = 0; tx_offset = 0;
/* ISO transfer only partially completed,
look at individual frame status for details */
if (status == -EXDEV) {
DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV"
", urb->status %d, fifonum %d\n",
status, fifon);
for (k = 0; k < iso_packets[fifon]; ++k) {
errcode = urb->iso_frame_desc[k].status;
if (errcode)
DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete "
"packet %i, status: %i\n",
k, errcode);
}
// clear status, so go on with ISO transfers
status = 0;
}
if (fifo->active && !status) { if (fifo->active && !status) {
transp_mode = 0; transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
transp_mode = true; transp_mode = 1;
/* is FifoFull-threshold set for our channel? */ /* is FifoFull-threshold set for our channel? */
threshbit = threshtable[fifon] & hfc->threshold_mask; threshbit = (hfc->threshold_mask & (1 << fifon));
num_isoc_packets = iso_packets[fifon]; num_isoc_packets = iso_packets[fifon];
/* predict dataflow to avoid fifo overflow */ /* predict dataflow to avoid fifo overflow */
...@@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb) ...@@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb)
tx_iso_complete, urb->context); tx_iso_complete, urb->context);
memset(context_iso_urb->buffer, 0, memset(context_iso_urb->buffer, 0,
sizeof(context_iso_urb->buffer)); sizeof(context_iso_urb->buffer));
frame_complete = false; frame_complete = 0;
/* Generate next Iso Packets */
/* Generate next ISO Packets */
for (k = 0; k < num_isoc_packets; ++k) { for (k = 0; k < num_isoc_packets; ++k) {
if (fifo->skbuff) { if (fifo->skbuff) {
len = fifo->skbuff->len; len = fifo->skbuff->len;
...@@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb) ...@@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb)
/* add 2 byte flags and 16bit CRC at end of ISDN frame */ /* add 2 byte flags and 16bit CRC at end of ISDN frame */
fifo->bit_line += 32; fifo->bit_line += 32;
} }
frame_complete = true; frame_complete = 1;
} }
memcpy(context_iso_urb->buffer + memcpy(context_iso_urb->buffer +
...@@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb) ...@@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb)
} }
if (frame_complete) { if (frame_complete) {
fifo->delete_flg = true; fifo->delete_flg = 1;
fifo->hif->l1l2(fifo->hif, fifo->hif->l1l2(fifo->hif,
PH_DATA | CONFIRM, PH_DATA | CONFIRM,
(void *) (unsigned long) fifo->skbuff-> (void *) (unsigned long) fifo->skbuff->
...@@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb) ...@@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb)
if (fifo->skbuff && fifo->delete_flg) { if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff); dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL; fifo->skbuff = NULL;
fifo->delete_flg = false; fifo->delete_flg = 0;
} }
frame_complete = false; frame_complete = 0;
} }
} }
errcode = usb_submit_urb(urb, GFP_ATOMIC); errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) { if (errcode < 0) {
printk(KERN_INFO printk(KERN_INFO
"HFC-S USB: error submitting ISO URB: %d \n", "HFC-S USB: error submitting ISO URB: %d\n",
errcode); errcode);
} }
} else { } else {
if (status && !hfc->disc_flag) { if (status && !hfc->disc_flag) {
printk(KERN_INFO printk(KERN_INFO
"HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n",
symbolic(urb_errlist, status), status, status, symbolic(urb_errlist, status), fifon);
fifon);
} }
} }
} /* tx_iso_complete */ }
/*****************************************************/
/* receive completion routine for all ISO tx fifos */
/*****************************************************/
static void static void
rx_iso_complete(struct urb *urb) rx_iso_complete(struct urb *urb)
{ {
...@@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb) ...@@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb)
unsigned int iso_status; unsigned int iso_status;
__u8 *buf; __u8 *buf;
static __u8 eof[8]; static __u8 eof[8];
#ifdef CONFIG_HISAX_DEBUG
__u8 i;
#endif
fifon = fifo->fifonum; fifon = fifo->fifonum;
status = urb->status; status = urb->status;
if (urb->status == -EOVERFLOW) { if (urb->status == -EOVERFLOW) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_VERBOSE_USB,
DBG(USB_DBG, "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon);
"HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", status = 0;
fifon); }
#endif
/* ISO transfer only partially completed,
look at individual frame status for details */
if (status == -EXDEV) {
DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV "
"urb->status %d, fifonum %d\n",
status, fifon);
status = 0; status = 0;
} }
if (fifo->active && !status) { if (fifo->active && !status) {
num_isoc_packets = iso_packets[fifon]; num_isoc_packets = iso_packets[fifon];
maxlen = fifo->usb_packet_maxlen; maxlen = fifo->usb_packet_maxlen;
...@@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb) ...@@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb)
offset = urb->iso_frame_desc[k].offset; offset = urb->iso_frame_desc[k].offset;
buf = context_iso_urb->buffer + offset; buf = context_iso_urb->buffer + offset;
iso_status = urb->iso_frame_desc[k].status; iso_status = urb->iso_frame_desc[k].status;
#ifdef CONFIG_HISAX_DEBUG
if (iso_status && !hfc->disc_flag) if (iso_status && !hfc->disc_flag)
DBG(USB_DBG, DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: ISO packet failure - status:%x", "HFC-S USB: rx_iso_complete "
iso_status); "ISO packet %i, status: %i\n",
k, iso_status);
if ((fifon == 5) && (debug > 1)) { if (fifon == HFCUSB_D_RX) {
printk(KERN_INFO DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: ISO-D-RX lst_urblen:%2d " "HFC-S USB: ISO-D-RX lst_urblen:%2d "
"act_urblen:%2d max-urblen:%2d " "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
"EOF:0x%0x DATA: ",
fifo->last_urblen, len, maxlen, fifo->last_urblen, len, maxlen,
eof[5]); eof[5]);
for (i = 0; i < len; i++)
printk("%.2x ", buf[i]); DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
printk("\n");
} }
#endif
if (fifo->last_urblen != maxlen) { if (fifo->last_urblen != maxlen) {
/* the threshold mask is in the 2nd status byte */ /* the threshold mask is in the 2nd status byte */
hfc->threshold_mask = buf[1]; hfc->threshold_mask = buf[1];
/* care for L1 state only for D-Channel /* care for L1 state only for D-Channel
to avoid overlapped iso completions */ to avoid overlapped iso completions */
if (fifon == 5) { if (fifon == HFCUSB_D_RX) {
/* the S0 state is in the upper half /* the S0 state is in the upper half
of the 1st status byte */ of the 1st status byte */
state_handler(hfc, buf[0] >> 4); s0_state_handler(hfc, buf[0] >> 4);
} }
eof[fifon] = buf[0] & 1; eof[fifon] = buf[0] & 1;
if (len > 2) if (len > 2)
collect_rx_frame(fifo, buf + 2, collect_rx_frame(fifo, buf + 2,
len - 2, len - 2,
(len < (len < maxlen) ?
maxlen) ?
eof[fifon] : 0); eof[fifon] : 0);
} else { } else {
collect_rx_frame(fifo, buf, len, collect_rx_frame(fifo, buf, len,
...@@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb) ...@@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb)
rx_iso_complete, urb->context); rx_iso_complete, urb->context);
errcode = usb_submit_urb(urb, GFP_ATOMIC); errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) { if (errcode < 0) {
printk(KERN_INFO printk(KERN_ERR
"HFC-S USB: error submitting ISO URB: %d \n", "HFC-S USB: error submitting ISO URB: %d\n",
errcode); errcode);
} }
} else { } else {
if (status && !hfc->disc_flag) { if (status && !hfc->disc_flag) {
printk(KERN_INFO printk(KERN_ERR
"HFC-S USB: rx_iso_complete : " "HFC-S USB: rx_iso_complete : "
"urb->status %d, fifonum %d\n", "urb->status %d, fifonum %d\n",
status, fifon); status, fifon);
} }
} }
} /* rx_iso_complete */ }
/*****************************************************/ /* collect rx data from INT- and ISO-URBs */
/* collect data from interrupt or isochron in */
/*****************************************************/
static void static void
collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
{ {
hfcusb_data *hfc = fifo->hfc; hfcusb_data *hfc = fifo->hfc;
int transp_mode, fifon; int transp_mode, fifon;
#ifdef CONFIG_HISAX_DEBUG
int i;
#endif
fifon = fifo->fifonum; fifon = fifo->fifonum;
transp_mode = 0; transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
transp_mode = true; transp_mode = 1;
if (!fifo->skbuff) { if (!fifo->skbuff) {
fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); fifo->skbuff = dev_alloc_skb(fifo->max_size + 3);
if (!fifo->skbuff) { if (!fifo->skbuff) {
printk(KERN_INFO printk(KERN_ERR
"HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", "HFC-S USB: cannot allocate buffer for fifo(%d)\n",
fifon); fifon);
return; return;
} }
...@@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) ...@@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
if (fifo->skbuff->len + len < fifo->max_size) { if (fifo->skbuff->len + len < fifo->max_size) {
memcpy(skb_put(fifo->skbuff, len), data, len); memcpy(skb_put(fifo->skbuff, len), data, len);
} else { } else {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_FIFO_ERR,
printk(KERN_INFO "HFC-S USB: "); "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)",
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); fifo->max_size, fifon);
DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
skb_trim(fifo->skbuff, 0);
} }
} }
if (transp_mode && fifo->skbuff->len >= 128) { if (transp_mode && fifo->skbuff->len >= 128) {
...@@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) ...@@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
if (finish) { if (finish) {
if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
&& (fifo->skbuff->len > 3)) { && (fifo->skbuff->len > 3)) {
if (fifon == HFCUSB_D_RX) {
DBG(HFCUSB_DBG_DCHANNEL,
"HFC-S USB: D-RX len(%d)", fifo->skbuff->len);
DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff);
}
/* remove CRC & status */ /* remove CRC & status */
skb_trim(fifo->skbuff, fifo->skbuff->len - 3); skb_trim(fifo->skbuff, fifo->skbuff->len - 3);
if (fifon == HFCUSB_PCM_RX) { if (fifon == HFCUSB_PCM_RX) {
...@@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) ...@@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
fifo->skbuff); fifo->skbuff);
fifo->skbuff = NULL; /* buffer was freed from upper layer */ fifo->skbuff = NULL; /* buffer was freed from upper layer */
} else { } else {
if (fifo->skbuff->len > 3) { DBG(HFCUSB_DBG_FIFO_ERR,
printk(KERN_INFO "HFC-S USB: ERROR frame len(%d) fifo(%d)",
"HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", fifo->skbuff->len, fifon);
fifo->skbuff->len, fifon); DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
#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); skb_trim(fifo->skbuff, 0);
} }
} }
} }
/***********************************************/
/* receive completion routine for all rx fifos */
/***********************************************/
static void static void
rx_complete(struct urb *urb) rx_int_complete(struct urb *urb)
{ {
int len; int len;
int status; int status;
...@@ -922,18 +851,14 @@ rx_complete(struct urb *urb) ...@@ -922,18 +851,14 @@ rx_complete(struct urb *urb)
usb_fifo *fifo = (usb_fifo *) urb->context; usb_fifo *fifo = (usb_fifo *) urb->context;
hfcusb_data *hfc = fifo->hfc; hfcusb_data *hfc = fifo->hfc;
static __u8 eof[8]; static __u8 eof[8];
#ifdef CONFIG_HISAX_DEBUG
__u8 i;
#endif
urb->dev = hfc->dev; /* security init */ urb->dev = hfc->dev; /* security init */
fifon = fifo->fifonum; fifon = fifo->fifonum;
if ((!fifo->active) || (urb->status)) { if ((!fifo->active) || (urb->status)) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)",
DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)",
fifon, urb->status); fifon, urb->status);
#endif
fifo->urb->interval = 0; /* cancel automatic rescheduling */ fifo->urb->interval = 0; /* cancel automatic rescheduling */
if (fifo->skbuff) { if (fifo->skbuff) {
dev_kfree_skb_any(fifo->skbuff); dev_kfree_skb_any(fifo->skbuff);
...@@ -945,22 +870,20 @@ rx_complete(struct urb *urb) ...@@ -945,22 +870,20 @@ rx_complete(struct urb *urb)
buf = fifo->buffer; buf = fifo->buffer;
maxlen = fifo->usb_packet_maxlen; maxlen = fifo->usb_packet_maxlen;
#ifdef CONFIG_HISAX_DEBUG if (fifon == HFCUSB_D_RX) {
if ((fifon == 5) && (debug > 1)) { DBG(HFCUSB_DBG_VERBOSE_USB,
printk(KERN_INFO "HFC-S USB: INT-D-RX lst_urblen:%2d "
"HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
fifo->last_urblen, len, maxlen, eof[5]); fifo->last_urblen, len, maxlen,
for (i = 0; i < len; i++) eof[5]);
printk("%.2x ", buf[i]); DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
printk("\n");
} }
#endif
if (fifo->last_urblen != fifo->usb_packet_maxlen) { if (fifo->last_urblen != fifo->usb_packet_maxlen) {
/* the threshold mask is in the 2nd status byte */ /* the threshold mask is in the 2nd status byte */
hfc->threshold_mask = buf[1]; hfc->threshold_mask = buf[1];
/* the S0 state is in the upper half of the 1st status byte */ /* the S0 state is in the upper half of the 1st status byte */
state_handler(hfc, buf[0] >> 4); s0_state_handler(hfc, buf[0] >> 4);
eof[fifon] = buf[0] & 1; eof[fifon] = buf[0] & 1;
/* if we have more than the 2 status bytes -> collect data */ /* if we have more than the 2 status bytes -> collect data */
if (len > 2) if (len > 2)
...@@ -975,20 +898,19 @@ rx_complete(struct urb *urb) ...@@ -975,20 +898,19 @@ rx_complete(struct urb *urb)
status = usb_submit_urb(urb, GFP_ATOMIC); status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) { if (status) {
printk(KERN_INFO printk(KERN_INFO
"HFC-S USB: error resubmitting URN at rx_complete...\n"); "HFC-S USB: %s error resubmitting URB fifo(%d)\n",
__FUNCTION__, fifon);
} }
} /* rx_complete */ }
/***************************************************/ /* start initial INT-URB for certain fifo */
/* start the interrupt transfer for the given fifo */
/***************************************************/
static void static void
start_int_fifo(usb_fifo * fifo) start_int_fifo(usb_fifo * fifo)
{ {
int errcode; int errcode;
printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n",
fifo->fifonum); fifo->fifonum);
if (!fifo->urb) { if (!fifo->urb) {
fifo->urb = usb_alloc_urb(0, GFP_KERNEL); fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
...@@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo) ...@@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo)
} }
usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe,
fifo->buffer, fifo->usb_packet_maxlen, fifo->buffer, fifo->usb_packet_maxlen,
rx_complete, fifo, fifo->intervall); rx_int_complete, fifo, fifo->intervall);
fifo->active = 1; /* must be marked active */ fifo->active = 1; /* must be marked active */
errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
if (errcode) { if (errcode) {
printk(KERN_INFO printk(KERN_ERR
"HFC-S USB: submit URB error(start_int_info): status:%i\n", "HFC-S USB: submit URB error(start_int_info): status:%i\n",
errcode); errcode);
fifo->active = 0; fifo->active = 0;
fifo->skbuff = NULL; fifo->skbuff = NULL;
} }
} /* start_int_fifo */ }
/*****************************/
/* set the B-channel mode */
/*****************************/
static void static void
set_hfcmode(hfcusb_data * hfc, int channel, int mode) setup_bchannel(hfcusb_data * hfc, int channel, int mode)
{ {
__u8 val, idx_table[2] = { 0, 2 }; __u8 val, idx_table[2] = { 0, 2 };
if (hfc->disc_flag) { if (hfc->disc_flag) {
return; return;
} }
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d",
DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, channel, mode);
mode);
#endif
hfc->b_mode[channel] = mode; hfc->b_mode[channel] = mode;
/* setup CON_HDLC */ /* setup CON_HDLC */
...@@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) ...@@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
switch (pr) { switch (pr) {
case PH_ACTIVATE | REQUEST: case PH_ACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) { if (fifo->fifonum == HFCUSB_D_TX) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST");
#endif
if (hfc->l1_state != 3 if (hfc->l1_state != 3
&& hfc->l1_state != 7) { && hfc->l1_state != 7) {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_DEACTIVATE | PH_DEACTIVATE |
INDICATION, INDICATION,
NULL); NULL);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)");
#endif
} else { } else {
if (hfc->l1_state == 7) { /* l1 already active */ if (hfc->l1_state == 7) { /* l1 already active */
hfc->d_if.ifc.l1l2(&hfc-> hfc->d_if.ifc.l1l2(&hfc->
...@@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) ...@@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
| |
INDICATION, INDICATION,
NULL); NULL);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
#endif
} else { } else {
/* force sending sending INFO1 */ /* force sending sending INFO1 */
queue_control_request(hfc, queue_control_request(hfc,
...@@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) ...@@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
} }
} }
} else { } else {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG, "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST");
"HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); setup_bchannel(hfc,
#endif
set_hfcmode(hfc,
(fifo->fifonum == (fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1, HFCUSB_B1_TX) ? 0 : 1,
(long) arg); (long) arg);
...@@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) ...@@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
break; break;
case PH_DEACTIVATE | REQUEST: case PH_DEACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) { if (fifo->fifonum == HFCUSB_D_TX) {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); "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 { } else {
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_STATES,
DBG(ISDN_DBG,
"HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
#endif setup_bchannel(hfc,
set_hfcmode(hfc,
(fifo->fifonum == (fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1, HFCUSB_B1_TX) ? 0 : 1,
(int) L1_MODE_NULL); (int) L1_MODE_NULL);
...@@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) ...@@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
if (fifo->skbuff && fifo->delete_flg) { if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff); dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL; fifo->skbuff = NULL;
fifo->delete_flg = false; fifo->delete_flg = 0;
} }
fifo->skbuff = arg; /* we have a new buffer */ fifo->skbuff = arg; /* we have a new buffer */
break; break;
default: default:
printk(KERN_INFO DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr);
pr);
break; break;
} }
} }
/***************************************************************************/ /* initial init HFC-S USB chip registers, HiSax interface, USB URBs */
/* 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. */
/* on success 0 is returned. */
/***************************************************************************/
static int static int
usb_init(hfcusb_data * hfc) hfc_usb_init(hfcusb_data * hfc)
{ {
usb_fifo *fifo; usb_fifo *fifo;
int i, err; int i, err;
...@@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc) ...@@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc)
/* aux = output, reset off */ /* aux = output, reset off */
write_usb(hfc, HFCUSB_CIRM, 0x10); write_usb(hfc, HFCUSB_CIRM, 0x10);
/* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */
write_usb(hfc, HFCUSB_USB_SIZE, write_usb(hfc, HFCUSB_USB_SIZE,
(hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4));
/* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */
write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size);
/* enable PCM/GCI master mode */ /* enable PCM/GCI master mode */
...@@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc) ...@@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc)
hfc->b_mode[0] = L1_MODE_NULL; hfc->b_mode[0] = L1_MODE_NULL;
hfc->b_mode[1] = L1_MODE_NULL; hfc->b_mode[1] = L1_MODE_NULL;
hfc->l1_activated = false; hfc->l1_activated = 0;
hfc->disc_flag = false; hfc->disc_flag = 0;
hfc->led_state = 0; hfc->led_state = 0;
hfc->led_new_data = 0; hfc->led_new_data = 0;
hfc->old_led_state = 0; hfc->old_led_state = 0;
...@@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc) ...@@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc)
handle_led(hfc, LED_POWER_ON); handle_led(hfc, LED_POWER_ON);
return (0); return (0);
} /* usb_init */ }
/*************************************************/ /* initial callback for each plugged USB device */
/* function called to probe a new plugged device */
/*************************************************/
static int static int
hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
...@@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
} }
} }
#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 printk(KERN_INFO
"HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n",
ifnum, iface->desc.bAlternateSetting, intf->minor); ifnum, iface->desc.bAlternateSetting, intf->minor);
...@@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* check for config EOL element */ /* check for config EOL element */
while (validconf[cfg_used][0]) { while (validconf[cfg_used][0]) {
cfg_found = true; cfg_found = 1;
vcf = validconf[cfg_used]; vcf = validconf[cfg_used];
/* first endpoint descriptor */ /* first endpoint descriptor */
ep = iface->endpoint; 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)); memcpy(cmptbl, vcf, 16 * sizeof(int));
/* check for all endpoints in this alternate setting */ /* check for all endpoints in this alternate setting */
...@@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
idx++; idx++;
attr = ep->desc.bmAttributes; attr = ep->desc.bmAttributes;
if (cmptbl[idx] == EP_NUL) { if (cmptbl[idx] == EP_NUL) {
cfg_found = false; cfg_found = 0;
} }
if (attr == USB_ENDPOINT_XFER_INT if (attr == USB_ENDPOINT_XFER_INT
&& cmptbl[idx] == EP_INT) && cmptbl[idx] == EP_INT)
...@@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
cmptbl[idx] = EP_NUL; cmptbl[idx] = EP_NUL;
/* check if all INT endpoints match minimum interval */ /* check if all INT endpoints match minimum interval */
if (attr == USB_ENDPOINT_XFER_INT if ((attr == USB_ENDPOINT_XFER_INT)
&& ep->desc.bInterval < && (ep->desc.bInterval < vcf[17])) {
vcf[17]) { cfg_found = 0;
#ifdef CONFIG_HISAX_DEBUG
if (cfg_found)
DBG(USB_DBG,
"HFC-S USB: Interrupt Endpoint interval < %d found - skipping config",
vcf[17]);
#endif
cfg_found = false;
} }
ep++; ep++;
} }
...@@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* all entries must be EP_NOP or EP_NUL for a valid config */ /* all entries must be EP_NOP or EP_NUL for a valid config */
if (cmptbl[i] != EP_NOP if (cmptbl[i] != EP_NOP
&& cmptbl[i] != EP_NUL) && cmptbl[i] != EP_NUL)
cfg_found = false; cfg_found = 0;
} }
if (cfg_found) { if (cfg_found) {
if (cfg_used < small_match) { if (cfg_used < small_match) {
...@@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
probe_alt_setting; probe_alt_setting;
iface_used = iface; iface_used = iface;
} }
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-USB: small_match=%x %x\n",
small_match, alt_used);
#endif
} }
cfg_used++; cfg_used++;
} }
alt_idx++; alt_idx++;
} /* (alt_idx < intf->num_altsetting) */ } /* (alt_idx < intf->num_altsetting) */
/* found a valid USB Ta Endpint config */ /* found a valid USB Ta Endpint config */
if (small_match != 0xffff) { if (small_match != 0xffff) {
iface = iface_used; iface = iface_used;
if (! if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
(context =
kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
return (-ENOMEM); /* got no mem */ return (-ENOMEM); /* got no mem */
ep = iface->endpoint; ep = iface->endpoint;
...@@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
driver_info; driver_info;
printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
driver_info->vend_name); driver_info->vend_name);
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG, DBG(HFCUSB_DBG_INIT,
"HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)",
conf_str[small_match], context->if_used, conf_str[small_match], context->if_used,
context->alt_used); context->alt_used,
printk(KERN_INFO validconf[small_match][18]);
"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 */ /* init the chip and register the driver */
if (usb_init(context)) { if (hfc_usb_init(context)) {
usb_kill_urb(context->ctrl_urb); usb_kill_urb(context->ctrl_urb);
usb_free_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb);
context->ctrl_urb = NULL; context->ctrl_urb = NULL;
...@@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return (-EIO); return (-EIO);
} }
/****************************************************/ /* callback for unplugged USB device */
/* function called when an active device is removed */
/****************************************************/
static void static void
hfc_usb_disconnect(struct usb_interface hfc_usb_disconnect(struct usb_interface
*intf) *intf)
{ {
hfcusb_data *context = usb_get_intfdata(intf); hfcusb_data *context = usb_get_intfdata(intf);
int i; int i;
handle_led(context, LED_POWER_OFF);
schedule_timeout((10 * HZ) / 1000);
printk(KERN_INFO "HFC-S USB: device disconnect\n"); printk(KERN_INFO "HFC-S USB: device disconnect\n");
context->disc_flag = true; context->disc_flag = 1;
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (!context) if (!context)
return; return;
...@@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface ...@@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface
del_timer(&context->t3_timer); del_timer(&context->t3_timer);
if (timer_pending(&context->t4_timer)) if (timer_pending(&context->t4_timer))
del_timer(&context->t4_timer); del_timer(&context->t4_timer);
/* tell all fifos to terminate */ /* tell all fifos to terminate */
for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
if (context->fifos[i].usb_transfer_mode == USB_ISOC) { if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
if (context->fifos[i].active > 0) { if (context->fifos[i].active > 0) {
stop_isoc_chain(&context->fifos[i]); stop_isoc_chain(&context->fifos[i]);
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_INIT,
DBG(USB_DBG, "HFC-S USB: %s stopping ISOC chain Fifo(%i)",
"HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", __FUNCTION__, i);
i);
#endif
} }
} else { } else {
if (context->fifos[i].active > 0) { if (context->fifos[i].active > 0) {
context->fifos[i].active = 0; context->fifos[i].active = 0;
#ifdef CONFIG_HISAX_DEBUG DBG(HFCUSB_DBG_INIT,
DBG(USB_DBG, "HFC-S USB: %s unlinking URB for Fifo(%i)",
"HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", __FUNCTION__, i);
i);
#endif
} }
usb_kill_urb(context->fifos[i].urb); usb_kill_urb(context->fifos[i].urb);
usb_free_urb(context->fifos[i].urb); usb_free_urb(context->fifos[i].urb);
...@@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface ...@@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface
context->ctrl_urb = NULL; context->ctrl_urb = NULL;
hisax_unregister(&context->d_if); hisax_unregister(&context->d_if);
kfree(context); /* free our structure again */ kfree(context); /* free our structure again */
} /* hfc_usb_disconnect */ }
/************************************/
/* our driver information structure */
/************************************/
static struct usb_driver hfc_drv = { static struct usb_driver hfc_drv = {
.name = "hfc_usb", .name = "hfc_usb",
.id_table = hfcusb_idtab, .id_table = hfcusb_idtab,
.probe = hfc_usb_probe, .probe = hfc_usb_probe,
.disconnect = hfc_usb_disconnect, .disconnect = hfc_usb_disconnect,
}; };
static void __exit static void __exit
hfc_usb_exit(void) hfc_usb_mod_exit(void)
{ {
#ifdef CONFIG_HISAX_DEBUG usb_deregister(&hfc_drv); /* release our driver */
DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ...");
#endif
usb_deregister(&hfc_drv); /* release our driver */
printk(KERN_INFO "HFC-S USB: module removed\n"); printk(KERN_INFO "HFC-S USB: module removed\n");
} }
static int __init static int __init
hfc_usb_init(void) hfc_usb_mod_init(void)
{ {
char revstr[30], datestr[30], dummy[30];
#ifndef CONFIG_HISAX_DEBUG #ifndef CONFIG_HISAX_DEBUG
unsigned int debug = -1; hfc_debug = debug;
#endif #endif
char revstr[30], datestr[30], dummy[30];
sscanf(hfcusb_revision, sscanf(hfcusb_revision,
"%s %s $ %s %s %s $ ", dummy, revstr, "%s %s $ %s %s %s $ ", dummy, revstr,
dummy, datestr, dummy); dummy, datestr, dummy);
...@@ -1734,8 +1597,8 @@ hfc_usb_init(void) ...@@ -1734,8 +1597,8 @@ hfc_usb_init(void)
return (0); return (0);
} }
module_init(hfc_usb_init); module_init(hfc_usb_mod_init);
module_exit(hfc_usb_exit); module_exit(hfc_usb_mod_exit);
MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC); MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
/* /*
* hfc_usb.h * hfc_usb.h
* *
* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $
*/ */
#ifndef __HFC_USB_H__ #ifndef __HFC_USB_H__
#define __HFC_USB_H__ #define __HFC_USB_H__
...@@ -10,25 +10,20 @@ ...@@ -10,25 +10,20 @@
#define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)"
#define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver"
#define VERBOSE_USB_DEBUG
#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 */
/* defines */ #define HFCUSB_L1_DRX 1 /* D-frame received */
/***********/ #define HFCUSB_L1_ERX 2 /* E-frame received */
#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ #define HFCUSB_L1_DTX 4 /* D-frames completed */
#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 MAX_BCH_SIZE 2048 /* allowed B-channel packet size */
#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_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_CHIP_ID 0x16 /* Chip ID register index */
#define HFCUSB_CIRM 0x00 /* cirm register index */ #define HFCUSB_CIRM 0x00 /* cirm register index */
...@@ -52,9 +47,8 @@ ...@@ -52,9 +47,8 @@
#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */
/******************/
/* fifo registers */ /* fifo registers */
/******************/
#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */
#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */
#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */
...@@ -66,9 +60,9 @@ ...@@ -66,9 +60,9 @@
#define HFCUSB_PCM_RX 7 #define HFCUSB_PCM_RX 7
/* /*
* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just * 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 * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out
*/ */
#define USB_INT 0 #define USB_INT 0
#define USB_BULK 1 #define USB_BULK 1
#define USB_ISOC 2 #define USB_ISOC 2
...@@ -77,49 +71,36 @@ ...@@ -77,49 +71,36 @@
#define ISOC_PACKETS_B 8 #define ISOC_PACKETS_B 8
#define ISO_BUFFER_SIZE 128 #define ISO_BUFFER_SIZE 128
// ISO send definitions /* Fifo flow Control for TX ISO */
#define SINK_MAX 68 #define SINK_MAX 68
#define SINK_MIN 48 #define SINK_MIN 48
#define SINK_DMIN 12 #define SINK_DMIN 12
#define SINK_DMAX 18 #define SINK_DMAX 18
#define BITLINE_INF (-64*8) #define BITLINE_INF (-64*8)
/* HFC-S USB register access by Control-URSs */
/**********/
/* 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 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) #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 #define HFC_CTRL_BUFSIZE 32
/*************************************************/
/* entry and size of output/input control buffer */ /* entry and size of output/input control buffer */
/*************************************************/
typedef struct { typedef struct {
__u8 hfc_reg; /* register number */ __u8 hfc_reg; /* register number */
__u8 reg_val; /* value to be written (or read) */ __u8 reg_val; /* value to be written (or read) */
int action; /* data for action handler */ int action; /* data for action handler */
} ctrl_buft; } ctrl_buft;
/* Debugging Flags */
#define HFCUSB_DBG_INIT 0x0001
#define HFCUSB_DBG_STATES 0x0002
#define HFCUSB_DBG_DCHANNEL 0x0080
#define HFCUSB_DBG_FIFO_ERR 0x4000
#define HFCUSB_DBG_VERBOSE_USB 0x8000
/********************/ /*
/* URB error codes: */ * URB error codes:
/********************/ * Used to represent a list of values and their respective symbolic names
/* Used to represent a list of values and their respective symbolic names */ */
struct hfcusb_symbolic_list { struct hfcusb_symbolic_list {
const int num; const int num;
const char *name; const char *name;
...@@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { ...@@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
{-ENXIO, "URB already queued"}, {-ENXIO, "URB already queued"},
{-EFBIG, "Too much ISO frames requested"}, {-EFBIG, "Too much ISO frames requested"},
{-ENOSR, "Buffer error (overrun)"}, {-ENOSR, "Buffer error (overrun)"},
{-EPIPE, "Specified endpoint is stalled"}, {-EPIPE, "Specified endpoint is stalled (device not responding)"},
{-EOVERFLOW, "Babble (bad cable?)"}, {-EOVERFLOW, "Babble (bad cable?)"},
{-EPROTO, "Bit-stuff error (bad cable?)"}, {-EPROTO, "Bit-stuff error (bad cable?)"},
{-EILSEQ, "CRC or missing token"}, {-EILSEQ, "CRC/Timeout"},
{-ETIME, "Device did not respond"}, {-ETIMEDOUT, "NAK (device does not respond)"},
{-ESHUTDOWN, "Device unplugged"}, {-ESHUTDOWN, "Device unplugged"},
{-1, NULL} {-1, NULL}
}; };
/*****************************************************/ /*
/* device dependant information to support different */ * device dependant information to support different
/* ISDN Ta's using the HFC-S USB chip */ * ISDN Ta's using the HFC-S USB chip
/*****************************************************/ */
/* USB descriptor need to contain one of the following EndPoint combination: */ /* USB descriptor need to contain one of the following EndPoint combination: */
#define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT
...@@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = { ...@@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
#define CNF_4ISO3ISO 3 // 4 ISO 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 CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT
#define EP_NUL 1 // Endpoint at this position not allowed #define EP_NUL 1 // Endpoint at this position not allowed
#define EP_NOP 2 // all type of endpoints allowed at this position #define EP_NOP 2 // all type of endpoints allowed at this position
#define EP_ISO 3 // Isochron endpoint mandatory 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_BLK 4 // Bulk endpoint mandatory at this position
#define EP_INT 5 // Interrupt 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 * List of all supported endpoint configuration sets, used to find the
* Interrupt endpoints & boolean if E-channel logging possible * best matching endpoint configuration within a devices' USB descriptor.
*/ * We need at least 3 RX endpoints, and 3 TX endpoints, either
* INT-in and ISO-out, or ISO-in and ISO-out)
* with 4 RX endpoints even E-Channel logging is possible
*/
static int validconf[][19] = { static int validconf[][19] = {
// INT in, ISO out config // INT in, ISO out config
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
...@@ -193,7 +177,6 @@ static char *conf_str[] = { ...@@ -193,7 +177,6 @@ static char *conf_str[] = {
}; };
#endif #endif
typedef struct { typedef struct {
int vendor; // vendor id int vendor; // vendor id
int prod_id; // product id int prod_id; // product id
...@@ -202,9 +185,9 @@ typedef struct { ...@@ -202,9 +185,9 @@ typedef struct {
signed short led_bits[8]; // array of 8 possible LED bitmask settings signed short led_bits[8]; // array of 8 possible LED bitmask settings
} vendor_data; } vendor_data;
#define LED_OFF 0 // no LED support #define LED_OFF 0 // no LED support
#define LED_SCHEME1 1 // LED standard scheme #define LED_SCHEME1 1 // LED standard scheme
#define LED_SCHEME2 2 // not used yet... #define LED_SCHEME2 2 // not used yet...
#define LED_POWER_ON 1 #define LED_POWER_ON 1
#define LED_POWER_OFF 2 #define LED_POWER_OFF 2
...@@ -217,11 +200,8 @@ typedef struct { ...@@ -217,11 +200,8 @@ typedef struct {
#define LED_B2_OFF 9 #define LED_B2_OFF 9
#define LED_B2_DATA 10 #define LED_B2_DATA 10
#define LED_NORMAL 0 // LEDs are normal #define LED_NORMAL 0 // LEDs are normal
#define LED_INVERTED 1 // LEDs are inverted #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__ #endif // __HFC_USB_H__
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment