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
*
* $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
*
* 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
* Werner Cornelius (werner@isdn-development.de)
......@@ -37,24 +37,25 @@
#include <linux/kernel_stat.h>
#include <linux/usb.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include "hisax.h"
#include "hisax_if.h"
#include "hfc_usb.h"
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
* 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
#include "hisax_debug.h"
static u_int debug;
module_param(debug, uint, 0);
static int hfc_debug;
#endif
/* private vendor specific data */
typedef struct {
......@@ -63,9 +64,7 @@ typedef struct {
char *vend_name; // device name
} hfcsusb_vdata;
/****************************************/
/* data defining the devices to be used */
/****************************************/
/* VID/PID device list */
static struct usb_device_id hfcusb_idtab[] = {
{
USB_DEVICE(0x0959, 0x2bd0),
......@@ -130,9 +129,7 @@ static struct usb_device_id hfcusb_idtab[] = {
{ }
};
/***************************************************************/
/* structure defining input+output fifos (interrupt/bulk mode) */
/***************************************************************/
struct usb_fifo; /* forward definition */
typedef struct iso_urb_struct {
struct urb *purb;
......@@ -140,8 +137,8 @@ typedef struct iso_urb_struct {
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 */
......@@ -160,12 +157,9 @@ typedef struct usb_fifo {
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 */
......@@ -176,12 +170,13 @@ typedef struct hfcusb_data {
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 ctrl_in_pipe, /* handles for control pipe */
ctrl_out_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 disc_flag; /* TRUE if device was disonnected to avoid some USB actions */
int packet_size, iso_packet_size;
/* control pipe background handling */
......@@ -208,7 +203,6 @@ typedef struct hfcusb_data {
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)
{
......@@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
return "<unknown ERROR>";
}
/******************************************************/
/* start next background transfer for control channel */
/******************************************************/
static void
ctrl_start_transfer(hfcusb_data * hfc)
{
......@@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc)
}
} /* ctrl_start_transfer */
/************************************/
/* queue a control transfer request */
/* return 0 on success. */
/************************************/
static int
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)
ctrl_start_transfer(hfc);
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
ctrl_complete(struct urb *urb)
{
......@@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb)
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);
hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */
......@@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb)
}
} /* ctrl_complete */
/***************************************************/
/* write led data to auxport & invert if necessary */
/***************************************************/
static void
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
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 */
/**************************/
static void
handle_led(hfcusb_data * hfc, int event)
{
......@@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event)
switch (event) {
case LED_POWER_ON:
set_led_bit(hfc, driver_info->led_bits[0],
0);
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);
set_led_bit(hfc, driver_info->led_bits[0], 0);
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;
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;
case LED_S0_ON:
set_led_bit(hfc, driver_info->led_bits[1],
0);
set_led_bit(hfc, driver_info->led_bits[1], 0);
break;
case LED_S0_OFF:
set_led_bit(hfc, driver_info->led_bits[1],
1);
set_led_bit(hfc, driver_info->led_bits[1], 1);
break;
case LED_B1_ON:
set_led_bit(hfc, driver_info->led_bits[2],
0);
set_led_bit(hfc, driver_info->led_bits[2], 0);
break;
case LED_B1_OFF:
set_led_bit(hfc, driver_info->led_bits[2],
1);
set_led_bit(hfc, driver_info->led_bits[2], 1);
break;
case LED_B2_ON:
set_led_bit(hfc, driver_info->led_bits[3],
0);
set_led_bit(hfc, driver_info->led_bits[3], 0);
break;
case LED_B2_OFF:
set_led_bit(hfc, driver_info->led_bits[3],
1);
set_led_bit(hfc, driver_info->led_bits[3], 1);
break;
}
write_led(hfc, hfc->led_state);
}
/********************************/
/* called when timer t3 expires */
/********************************/
/* ISDN l1 timer T3 expires */
static void
l1_timer_expire_t3(hfcusb_data * hfc)
{
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)");
#endif
hfc->l1_activated = false;
hfc->l1_activated = 0;
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 */
/********************************/
/* ISDN l1 timer T4 expires */
static void
l1_timer_expire_t4(hfcusb_data * hfc)
{
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"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 S0 state changes */
/*****************************/
/* S0 state changed */
static void
state_handler(hfcusb_data * hfc, __u8 state)
s0_state_handler(hfcusb_data * hfc, __u8 state)
{
__u8 old_state;
......@@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state)
if (state == old_state || state < 1 || state > 8)
return;
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state,
old_state);
#endif
DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)",
old_state, state);
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
DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated");
}
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
DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated");
}
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;
DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
hfc->l1_activated = 1;
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
DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated");
if (!timer_pending(&hfc->t4_timer)) {
hfc->t4_timer.expires =
jiffies + (HFC_TIMER_T4 * HZ) / 1000;
......@@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state)
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_DEACTIVATE | INDICATION,
NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent");
#endif
hfc->l1_activated = false;
hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF);
}
}
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,
......@@ -503,14 +444,15 @@ 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
gaps in the transfer chain */
* 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;
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);
/* allocate Memory for Iso out Urbs */
......@@ -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);
fifo->active = (errcode >= 0) ? 1 : 0;
if (errcode < 0) {
printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n",
symbolic(urb_errlist, errcode), i);
};
if (errcode < 0)
printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n",
i, errcode, symbolic(urb_errlist, errcode));
}
return (fifo->active);
}
......@@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo)
for (i = 0; i < 2; i++) {
if (fifo->iso[i].purb) {
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
DBG(HFCUSB_DBG_INIT,
"HFC-S USB: Stopping iso chain for fifo %i.%i",
fifo->fifonum, i);
#endif
usb_kill_urb(fifo->iso[i].purb);
usb_free_urb(fifo->iso[i].purb);
fifo->iso[i].purb = NULL;
}
}
usb_kill_urb(fifo->urb);
usb_free_urb(fifo->urb);
fifo->urb = NULL;
......@@ -594,9 +534,6 @@ static int iso_packets[8] =
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)
{
......@@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb)
errcode;
int frame_complete, transp_mode, fifon, status;
__u8 threshbit;
__u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
fifon = fifo->fifonum;
status = urb->status;
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) {
transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
transp_mode = true;
transp_mode = 1;
/* 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];
/* predict dataflow to avoid fifo overflow */
......@@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb)
tx_iso_complete, urb->context);
memset(context_iso_urb->buffer, 0,
sizeof(context_iso_urb->buffer));
frame_complete = false;
/* Generate next Iso Packets */
frame_complete = 0;
/* Generate next ISO Packets */
for (k = 0; k < num_isoc_packets; ++k) {
if (fifo->skbuff) {
len = fifo->skbuff->len;
......@@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb)
/* add 2 byte flags and 16bit CRC at end of ISDN frame */
fifo->bit_line += 32;
}
frame_complete = true;
frame_complete = 1;
}
memcpy(context_iso_urb->buffer +
......@@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb)
}
if (frame_complete) {
fifo->delete_flg = true;
fifo->delete_flg = 1;
fifo->hif->l1l2(fifo->hif,
PH_DATA | CONFIRM,
(void *) (unsigned long) fifo->skbuff->
......@@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb)
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
fifo->delete_flg = false;
fifo->delete_flg = 0;
}
frame_complete = false;
frame_complete = 0;
}
}
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) {
printk(KERN_INFO
"HFC-S USB: error submitting ISO URB: %d \n",
"HFC-S USB: error submitting ISO URB: %d\n",
errcode);
}
} 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);
"HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n",
status, symbolic(urb_errlist, status), fifon);
}
}
} /* tx_iso_complete */
}
/*****************************************************/
/* receive completion routine for all ISO tx fifos */
/*****************************************************/
static void
rx_iso_complete(struct urb *urb)
{
......@@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb)
unsigned int iso_status;
__u8 *buf;
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
DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon);
status = 0;
}
/* 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;
}
if (fifo->active && !status) {
num_isoc_packets = iso_packets[fifon];
maxlen = fifo->usb_packet_maxlen;
......@@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb)
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);
DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: rx_iso_complete "
"ISO packet %i, status: %i\n",
k, iso_status);
if ((fifon == 5) && (debug > 1)) {
printk(KERN_INFO
if (fifon == HFCUSB_D_RX) {
DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: ISO-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]);
for (i = 0; i < len; i++)
printk("%.2x ", buf[i]);
printk("\n");
DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
}
#endif
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) {
if (fifon == HFCUSB_D_RX) {
/* 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;
if (len > 2)
collect_rx_frame(fifo, buf + 2,
len - 2,
(len <
maxlen) ?
(len < maxlen) ?
eof[fifon] : 0);
} else {
collect_rx_frame(fifo, buf, len,
......@@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb)
rx_iso_complete, urb->context);
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) {
printk(KERN_INFO
"HFC-S USB: error submitting ISO URB: %d \n",
printk(KERN_ERR
"HFC-S USB: error submitting ISO URB: %d\n",
errcode);
}
} else {
if (status && !hfc->disc_flag) {
printk(KERN_INFO
printk(KERN_ERR
"HFC-S USB: rx_iso_complete : "
"urb->status %d, fifonum %d\n",
status, fifon);
}
}
} /* rx_iso_complete */
}
/*****************************************************/
/* collect data from interrupt or isochron in */
/*****************************************************/
/* collect rx data from INT- and ISO-URBs */
static void
collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
{
hfcusb_data *hfc = fifo->hfc;
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;
transp_mode = 1;
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",
printk(KERN_ERR
"HFC-S USB: cannot allocate buffer for fifo(%d)\n",
fifon);
return;
}
......@@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
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",
DBG(HFCUSB_DBG_FIFO_ERR,
"HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)",
fifo->max_size, fifon);
DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
skb_trim(fifo->skbuff, 0);
}
}
if (transp_mode && fifo->skbuff->len >= 128) {
......@@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
if (finish) {
if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
&& (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 */
skb_trim(fifo->skbuff, fifo->skbuff->len - 3);
if (fifon == HFCUSB_PCM_RX) {
......@@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
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",
DBG(HFCUSB_DBG_FIFO_ERR,
"HFC-S USB: ERROR frame len(%d) fifo(%d)",
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
DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
skb_trim(fifo->skbuff, 0);
}
}
}
/***********************************************/
/* receive completion routine for all rx fifos */
/***********************************************/
static void
rx_complete(struct urb *urb)
rx_int_complete(struct urb *urb)
{
int len;
int status;
......@@ -922,18 +851,14 @@ rx_complete(struct urb *urb)
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 */
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)",
DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)",
fifon, urb->status);
#endif
fifo->urb->interval = 0; /* cancel automatic rescheduling */
if (fifo->skbuff) {
dev_kfree_skb_any(fifo->skbuff);
......@@ -945,22 +870,20 @@ rx_complete(struct urb *urb)
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");
if (fifon == HFCUSB_D_RX) {
DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: INT-D-RX lst_urblen:%2d "
"act_urblen:%2d max-urblen:%2d EOF:0x%0x",
fifo->last_urblen, len, maxlen,
eof[5]);
DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
}
#endif
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);
s0_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)
......@@ -975,19 +898,18 @@ rx_complete(struct urb *urb)
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
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 the interrupt transfer for the given fifo */
/***************************************************/
/* start initial INT-URB for certain fifo */
static void
start_int_fifo(usb_fifo * fifo)
{
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);
if (!fifo->urb) {
......@@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo)
}
usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe,
fifo->buffer, fifo->usb_packet_maxlen,
rx_complete, fifo, fifo->intervall);
rx_int_complete, fifo, fifo->intervall);
fifo->active = 1; /* must be marked active */
errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
if (errcode) {
printk(KERN_INFO
printk(KERN_ERR
"HFC-S USB: submit URB error(start_int_info): status:%i\n",
errcode);
fifo->active = 0;
fifo->skbuff = NULL;
}
} /* start_int_fifo */
}
/*****************************/
/* set the B-channel mode */
/*****************************/
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 };
if (hfc->disc_flag) {
return;
}
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel,
mode);
#endif
DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d",
channel, mode);
hfc->b_mode[channel] = mode;
/* setup CON_HDLC */
......@@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
switch (pr) {
case PH_ACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) {
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"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,
DBG(HFCUSB_DBG_STATES,
"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->
......@@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
|
INDICATION,
NULL);
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
#endif
} else {
/* force sending sending INFO1 */
queue_control_request(hfc,
......@@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
}
}
} else {
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
"HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST");
#endif
set_hfcmode(hfc,
DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST");
setup_bchannel(hfc,
(fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1,
(long) arg);
......@@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
break;
case PH_DEACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) {
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG,
DBG(HFCUSB_DBG_STATES,
"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,
DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
#endif
set_hfcmode(hfc,
setup_bchannel(hfc,
(fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1,
(int) L1_MODE_NULL);
......@@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
fifo->delete_flg = false;
fifo->delete_flg = 0;
}
fifo->skbuff = arg; /* we have a new buffer */
break;
default:
printk(KERN_INFO
"HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n",
pr);
DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr);
break;
}
}
/***************************************************************************/
/* 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. */
/***************************************************************************/
/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */
static int
usb_init(hfcusb_data * hfc)
hfc_usb_init(hfcusb_data * hfc)
{
usb_fifo *fifo;
int i, err;
......@@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc)
/* aux = output, reset off */
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,
(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);
/* enable PCM/GCI master mode */
......@@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc)
hfc->b_mode[0] = L1_MODE_NULL;
hfc->b_mode[1] = L1_MODE_NULL;
hfc->l1_activated = false;
hfc->disc_flag = false;
hfc->l1_activated = 0;
hfc->disc_flag = 0;
hfc->led_state = 0;
hfc->led_new_data = 0;
hfc->old_led_state = 0;
......@@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc)
handle_led(hfc, LED_POWER_ON);
return (0);
} /* usb_init */
}
/*************************************************/
/* function called to probe a new plugged device */
/*************************************************/
/* initial callback for each plugged USB device */
static int
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
"HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n",
ifnum, iface->desc.bAlternateSetting, intf->minor);
......@@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* check for config EOL element */
while (validconf[cfg_used][0]) {
cfg_found = true;
cfg_found = 1;
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 */
......@@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
idx++;
attr = ep->desc.bmAttributes;
if (cmptbl[idx] == EP_NUL) {
cfg_found = false;
cfg_found = 0;
}
if (attr == USB_ENDPOINT_XFER_INT
&& cmptbl[idx] == EP_INT)
......@@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
cmptbl[idx] = EP_NUL;
/* 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)
DBG(USB_DBG,
"HFC-S USB: Interrupt Endpoint interval < %d found - skipping config",
vcf[17]);
#endif
cfg_found = false;
if ((attr == USB_ENDPOINT_XFER_INT)
&& (ep->desc.bInterval < vcf[17])) {
cfg_found = 0;
}
ep++;
}
......@@ -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 */
if (cmptbl[i] != EP_NOP
&& cmptbl[i] != EP_NUL)
cfg_found = false;
cfg_found = 0;
}
if (cfg_found) {
if (cfg_used < small_match) {
......@@ -1464,11 +1345,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
probe_alt_setting;
iface_used = iface;
}
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-USB: small_match=%x %x\n",
small_match, alt_used);
#endif
}
cfg_used++;
}
......@@ -1478,9 +1354,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* found a valid USB Ta Endpint config */
if (small_match != 0xffff) {
iface = iface_used;
if (!
(context =
kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
return (-ENOMEM); /* got no mem */
ep = iface->endpoint;
......@@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
driver_info;
printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
driver_info->vend_name);
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
DBG(HFCUSB_DBG_INIT,
"HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)",
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
context->alt_used,
validconf[small_match][18]);
/* init the chip and register the driver */
if (usb_init(context)) {
if (hfc_usb_init(context)) {
usb_kill_urb(context->ctrl_urb);
usb_free_urb(context->ctrl_urb);
context->ctrl_urb = NULL;
......@@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return (-EIO);
}
/****************************************************/
/* function called when an active device is removed */
/****************************************************/
/* callback for unplugged USB device */
static void
hfc_usb_disconnect(struct usb_interface
*intf)
{
hfcusb_data *context = usb_get_intfdata(intf);
int i;
handle_led(context, LED_POWER_OFF);
schedule_timeout((10 * HZ) / 1000);
printk(KERN_INFO "HFC-S USB: device disconnect\n");
context->disc_flag = true;
context->disc_flag = 1;
usb_set_intfdata(intf, NULL);
if (!context)
return;
......@@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface
del_timer(&context->t3_timer);
if (timer_pending(&context->t4_timer))
del_timer(&context->t4_timer);
/* 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 CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i",
i);
#endif
DBG(HFCUSB_DBG_INIT,
"HFC-S USB: %s stopping ISOC chain Fifo(%i)",
__FUNCTION__, i);
}
} else {
if (context->fifos[i].active > 0) {
context->fifos[i].active = 0;
#ifdef CONFIG_HISAX_DEBUG
DBG(USB_DBG,
"HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i",
i);
#endif
DBG(HFCUSB_DBG_INIT,
"HFC-S USB: %s unlinking URB for Fifo(%i)",
__FUNCTION__, i);
}
usb_kill_urb(context->fifos[i].urb);
usb_free_urb(context->fifos[i].urb);
......@@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface
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 = {
.name = "hfc_usb",
.id_table = hfcusb_idtab,
.probe = hfc_usb_probe,
.disconnect = hfc_usb_disconnect,
};
static void __exit
hfc_usb_exit(void)
hfc_usb_mod_exit(void)
{
#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-S USB: module removed\n");
}
static int __init
hfc_usb_init(void)
hfc_usb_mod_init(void)
{
char revstr[30], datestr[30], dummy[30];
#ifndef CONFIG_HISAX_DEBUG
unsigned int debug = -1;
hfc_debug = debug;
#endif
char revstr[30], datestr[30], dummy[30];
sscanf(hfcusb_revision,
"%s %s $ %s %s %s $ ", dummy, revstr,
dummy, datestr, dummy);
......@@ -1734,8 +1597,8 @@ hfc_usb_init(void)
return (0);
}
module_init(hfc_usb_init);
module_exit(hfc_usb_exit);
module_init(hfc_usb_mod_init);
module_exit(hfc_usb_mod_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
......
/*
* hfc_usb.h
*
* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
*/
* hfc_usb.h
*
* $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $
*/
#ifndef __HFC_USB_H__
#define __HFC_USB_H__
......@@ -10,12 +10,7 @@
#define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)"
#define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver"
#define VERBOSE_USB_DEBUG
/***********/
/* 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 */
......@@ -52,9 +47,8 @@
#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 */
......@@ -66,9 +60,9 @@
#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
*/
* 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
......@@ -77,49 +71,36 @@
#define ISOC_PACKETS_B 8
#define ISO_BUFFER_SIZE 128
// ISO send definitions
/* Fifo flow Control for TX ISO */
#define SINK_MAX 68
#define SINK_MIN 48
#define SINK_DMIN 12
#define SINK_DMAX 18
#define BITLINE_INF (-64*8)
/**********/
/* macros */
/**********/
/* HFC-S USB register access by Control-URSs */
#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)
/*******************/
/* 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;
/* 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: */
/********************/
/* Used to represent a list of values and their respective symbolic names */
/*
* 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;
......@@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
{-ENXIO, "URB already queued"},
{-EFBIG, "Too much ISO frames requested"},
{-ENOSR, "Buffer error (overrun)"},
{-EPIPE, "Specified endpoint is stalled"},
{-EPIPE, "Specified endpoint is stalled (device not responding)"},
{-EOVERFLOW, "Babble (bad cable?)"},
{-EPROTO, "Bit-stuff error (bad cable?)"},
{-EILSEQ, "CRC or missing token"},
{-ETIME, "Device did not respond"},
{-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 */
/*****************************************************/
/*
* 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
......@@ -161,10 +142,13 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
#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
*/
/*
* List of all supported endpoint configuration sets, used to find the
* 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] = {
// INT in, ISO out config
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
......@@ -193,7 +177,6 @@ static char *conf_str[] = {
};
#endif
typedef struct {
int vendor; // vendor id
int prod_id; // product id
......@@ -220,8 +203,5 @@ typedef struct {
#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__
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