/* hfcsusb.c
 * mISDN driver for Colognechip HFC-S USB chip
 *
 * Copyright 2001 by Peter Sprenger (sprenger@moving-bytes.de)
 * Copyright 2008 by Martin Bachem (info@bachem-it.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * module params
 *   debug=<n>, default=0, with n=0xHHHHGGGG
 *      H - l1 driver flags described in hfcsusb.h
 *      G - common mISDN debug flags described at mISDNhw.h
 *
 *   poll=<n>, default 128
 *     n : burst size of PH_DATA_IND at transparent rx data
 *
 * Revision: 0.3.3 (socket), 2008-11-05
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/usb.h>
#include <linux/mISDNhw.h>
#include <linux/slab.h>
#include "hfcsusb.h"

static unsigned int debug;
static int poll = DEFAULT_TRANSP_BURST_SZ;

static LIST_HEAD(HFClist);
static DEFINE_RWLOCK(HFClock);


MODULE_AUTHOR("Martin Bachem");
MODULE_LICENSE("GPL");
module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(poll, int, 0);

static int hfcsusb_cnt;

/* some function prototypes */
static void hfcsusb_ph_command(struct hfcsusb *hw, u_char command);
static void release_hw(struct hfcsusb *hw);
static void reset_hfcsusb(struct hfcsusb *hw);
static void setPortMode(struct hfcsusb *hw);
static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel);
static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);
static int  hfcsusb_setup_bch(struct bchannel *bch, int protocol);
static void deactivate_bchannel(struct bchannel *bch);
static void hfcsusb_ph_info(struct hfcsusb *hw);

/* start next background transfer for control channel */
static void
ctrl_start_transfer(struct hfcsusb *hw)
{
	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	if (hw->ctrl_cnt) {
		hw->ctrl_urb->pipe = hw->ctrl_out_pipe;
		hw->ctrl_urb->setup_packet = (u_char *)&hw->ctrl_write;
		hw->ctrl_urb->transfer_buffer = NULL;
		hw->ctrl_urb->transfer_buffer_length = 0;
		hw->ctrl_write.wIndex =
			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);
		hw->ctrl_write.wValue =
			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);

		usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC);
	}
}

/*
 * queue a control transfer request to write HFC-S USB
 * chip register using CTRL resuest queue
 */
static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
{
	struct ctrl_buf *buf;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n",
		       hw->name, __func__, reg, val);

	spin_lock(&hw->ctrl_lock);
	if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
		spin_unlock(&hw->ctrl_lock);
		return 1;
	}
	buf = &hw->ctrl_buff[hw->ctrl_in_idx];
	buf->hfcs_reg = reg;
	buf->reg_val = val;
	if (++hw->ctrl_in_idx >= HFC_CTRL_BUFSIZE)
		hw->ctrl_in_idx = 0;
	if (++hw->ctrl_cnt == 1)
		ctrl_start_transfer(hw);
	spin_unlock(&hw->ctrl_lock);

	return 0;
}

/* control completion routine handling background control cmds */
static void
ctrl_complete(struct urb *urb)
{
	struct hfcsusb *hw = (struct hfcsusb *) urb->context;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	urb->dev = hw->dev;
	if (hw->ctrl_cnt) {
		hw->ctrl_cnt--;	/* decrement actual count */
		if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
			hw->ctrl_out_idx = 0;	/* pointer wrap */

		ctrl_start_transfer(hw); /* start next transfer */
	}
}

/* handle LED bits   */
static void
set_led_bit(struct hfcsusb *hw, signed short led_bits, int set_on)
{
	if (set_on) {
		if (led_bits < 0)
			hw->led_state &= ~abs(led_bits);
		else
			hw->led_state |= led_bits;
	} else {
		if (led_bits < 0)
			hw->led_state |= abs(led_bits);
		else
			hw->led_state &= ~led_bits;
	}
}

/* handle LED requests  */
static void
handle_led(struct hfcsusb *hw, int event)
{
	struct hfcsusb_vdata *driver_info = (struct hfcsusb_vdata *)
		hfcsusb_idtab[hw->vend_idx].driver_info;
	__u8 tmpled;

	if (driver_info->led_scheme == LED_OFF)
		return;
	tmpled = hw->led_state;

	switch (event) {
	case LED_POWER_ON:
		set_led_bit(hw, driver_info->led_bits[0], 1);
		set_led_bit(hw, driver_info->led_bits[1], 0);
		set_led_bit(hw, driver_info->led_bits[2], 0);
		set_led_bit(hw, driver_info->led_bits[3], 0);
		break;
	case LED_POWER_OFF:
		set_led_bit(hw, driver_info->led_bits[0], 0);
		set_led_bit(hw, driver_info->led_bits[1], 0);
		set_led_bit(hw, driver_info->led_bits[2], 0);
		set_led_bit(hw, driver_info->led_bits[3], 0);
		break;
	case LED_S0_ON:
		set_led_bit(hw, driver_info->led_bits[1], 1);
		break;
	case LED_S0_OFF:
		set_led_bit(hw, driver_info->led_bits[1], 0);
		break;
	case LED_B1_ON:
		set_led_bit(hw, driver_info->led_bits[2], 1);
		break;
	case LED_B1_OFF:
		set_led_bit(hw, driver_info->led_bits[2], 0);
		break;
	case LED_B2_ON:
		set_led_bit(hw, driver_info->led_bits[3], 1);
		break;
	case LED_B2_OFF:
		set_led_bit(hw, driver_info->led_bits[3], 0);
		break;
	}

	if (hw->led_state != tmpled) {
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n",
			       hw->name, __func__,
			       HFCUSB_P_DATA, hw->led_state);

		write_reg(hw, HFCUSB_P_DATA, hw->led_state);
	}
}

/*
 * Layer2 -> Layer 1 Bchannel data
 */
static int
hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct bchannel		*bch = container_of(ch, struct bchannel, ch);
	struct hfcsusb		*hw = bch->hw;
	int			ret = -EINVAL;
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	u_long			flags;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	switch (hh->prim) {
	case PH_DATA_REQ:
		spin_lock_irqsave(&hw->lock, flags);
		ret = bchannel_senddata(bch, skb);
		spin_unlock_irqrestore(&hw->lock, flags);
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",
			       hw->name, __func__, ret);
		if (ret > 0)
			ret = 0;
		return ret;
	case PH_ACTIVATE_REQ:
		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
			hfcsusb_start_endpoint(hw, bch->nr - 1);
			ret = hfcsusb_setup_bch(bch, ch->protocol);
		} else
			ret = 0;
		if (!ret)
			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
				    0, NULL, GFP_KERNEL);
		break;
	case PH_DEACTIVATE_REQ:
		deactivate_bchannel(bch);
		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,
			    0, NULL, GFP_KERNEL);
		ret = 0;
		break;
	}
	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}

/*
 * send full D/B channel status information
 * as MPH_INFORMATION_IND
 */
static void
hfcsusb_ph_info(struct hfcsusb *hw)
{
	struct ph_info *phi;
	struct dchannel *dch = &hw->dch;
	int i;

	phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC);
	if (!phi)
		return;

	phi->dch.ch.protocol = hw->protocol;
	phi->dch.ch.Flags = dch->Flags;
	phi->dch.state = dch->state;
	phi->dch.num_bch = dch->dev.nrbchan;
	for (i = 0; i < dch->dev.nrbchan; i++) {
		phi->bch[i].protocol = hw->bch[i].ch.protocol;
		phi->bch[i].Flags = hw->bch[i].Flags;
	}
	_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
		    sizeof(struct ph_info_dch) + dch->dev.nrbchan *
		    sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
	kfree(phi);
}

/*
 * Layer2 -> Layer 1 Dchannel data
 */
static int
hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
	struct hfcsusb		*hw = dch->hw;
	int			ret = -EINVAL;
	u_long			flags;

	switch (hh->prim) {
	case PH_DATA_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
			       hw->name, __func__);

		spin_lock_irqsave(&hw->lock, flags);
		ret = dchannel_senddata(dch, skb);
		spin_unlock_irqrestore(&hw->lock, flags);
		if (ret > 0) {
			ret = 0;
			queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);
		}
		break;

	case PH_ACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
			       hw->name, __func__,
			       (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");

		if (hw->protocol == ISDN_P_NT_S0) {
			ret = 0;
			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
				_queue_data(&dch->dev.D,
					    PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
					    NULL, GFP_ATOMIC);
			} else {
				hfcsusb_ph_command(hw,
						   HFC_L1_ACTIVATE_NT);
				test_and_set_bit(FLG_L2_ACTIVATED,
						 &dch->Flags);
			}
		} else {
			hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
			ret = l1_event(dch->l1, hh->prim);
		}
		break;

	case PH_DEACTIVATE_REQ:
		if (debug & DBG_HFC_CALL_TRACE)
			printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
			       hw->name, __func__);
		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);

		if (hw->protocol == ISDN_P_NT_S0) {
			hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
			spin_lock_irqsave(&hw->lock, flags);
			skb_queue_purge(&dch->squeue);
			if (dch->tx_skb) {
				dev_kfree_skb(dch->tx_skb);
				dch->tx_skb = NULL;
			}
			dch->tx_idx = 0;
			if (dch->rx_skb) {
				dev_kfree_skb(dch->rx_skb);
				dch->rx_skb = NULL;
			}
			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
			spin_unlock_irqrestore(&hw->lock, flags);
#ifdef FIXME
			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
#endif
			ret = 0;
		} else
			ret = l1_event(dch->l1, hh->prim);
		break;
	case MPH_INFORMATION_REQ:
		hfcsusb_ph_info(hw);
		ret = 0;
		break;
	}

	return ret;
}

/*
 * Layer 1 callback function
 */
static int
hfc_l1callback(struct dchannel *dch, u_int cmd)
{
	struct hfcsusb *hw = dch->hw;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s cmd 0x%x\n",
		       hw->name, __func__, cmd);

	switch (cmd) {
	case INFO3_P8:
	case INFO3_P10:
	case HW_RESET_REQ:
	case HW_POWERUP_REQ:
		break;

	case HW_DEACT_REQ:
		skb_queue_purge(&dch->squeue);
		if (dch->tx_skb) {
			dev_kfree_skb(dch->tx_skb);
			dch->tx_skb = NULL;
		}
		dch->tx_idx = 0;
		if (dch->rx_skb) {
			dev_kfree_skb(dch->rx_skb);
			dch->rx_skb = NULL;
		}
		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
		break;
	case PH_ACTIVATE_IND:
		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
			    GFP_ATOMIC);
		break;
	case PH_DEACTIVATE_IND:
		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
			    GFP_ATOMIC);
		break;
	default:
		if (dch->debug & DEBUG_HW)
			printk(KERN_DEBUG "%s: %s: unknown cmd %x\n",
			       hw->name, __func__, cmd);
		return -1;
	}
	hfcsusb_ph_info(hw);
	return 0;
}

static int
open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
	      struct channel_req *rq)
{
	int err = 0;

	if (debug & DEBUG_HW_OPEN)
		printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",
		       hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
		       __builtin_return_address(0));
	if (rq->protocol == ISDN_P_NONE)
		return -EINVAL;

	test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags);
	test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags);
	hfcsusb_start_endpoint(hw, HFC_CHAN_D);

	/* E-Channel logging */
	if (rq->adr.channel == 1) {
		if (hw->fifos[HFCUSB_PCM_RX].pipe) {
			hfcsusb_start_endpoint(hw, HFC_CHAN_E);
			set_bit(FLG_ACTIVE, &hw->ech.Flags);
			_queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,
				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
		} else
			return -EINVAL;
	}

	if (!hw->initdone) {
		hw->protocol = rq->protocol;
		if (rq->protocol == ISDN_P_TE_S0) {
			err = create_l1(&hw->dch, hfc_l1callback);
			if (err)
				return err;
		}
		setPortMode(hw);
		ch->protocol = rq->protocol;
		hw->initdone = 1;
	} else {
		if (rq->protocol != ch->protocol)
			return -EPROTONOSUPPORT;
	}

	if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||
	    ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))
		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
			    0, NULL, GFP_KERNEL);
	rq->ch = ch;
	if (!try_module_get(THIS_MODULE))
		printk(KERN_WARNING "%s: %s: cannot get module\n",
		       hw->name, __func__);
	return 0;
}

static int
open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
{
	struct bchannel		*bch;

	if (rq->adr.channel == 0 || rq->adr.channel > 2)
		return -EINVAL;
	if (rq->protocol == ISDN_P_NONE)
		return -EINVAL;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s B%i\n",
		       hw->name, __func__, rq->adr.channel);

	bch = &hw->bch[rq->adr.channel - 1];
	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
		return -EBUSY; /* b-channel can be only open once */
	bch->ch.protocol = rq->protocol;
	rq->ch = &bch->ch;

	if (!try_module_get(THIS_MODULE))
		printk(KERN_WARNING "%s: %s:cannot get module\n",
		       hw->name, __func__);
	return 0;
}

static int
channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq)
{
	int ret = 0;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n",
		       hw->name, __func__, (cq->op), (cq->channel));

	switch (cq->op) {
	case MISDN_CTRL_GETOP:
		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
			MISDN_CTRL_DISCONNECT;
		break;
	default:
		printk(KERN_WARNING "%s: %s: unknown Op %x\n",
		       hw->name, __func__, cq->op);
		ret = -EINVAL;
		break;
	}
	return ret;
}

/*
 * device control function
 */
static int
hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
	struct hfcsusb		*hw = dch->hw;
	struct channel_req	*rq;
	int			err = 0;

	if (dch->debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s: cmd:%x %p\n",
		       hw->name, __func__, cmd, arg);
	switch (cmd) {
	case OPEN_CHANNEL:
		rq = arg;
		if ((rq->protocol == ISDN_P_TE_S0) ||
		    (rq->protocol == ISDN_P_NT_S0))
			err = open_dchannel(hw, ch, rq);
		else
			err = open_bchannel(hw, rq);
		if (!err)
			hw->open++;
		break;
	case CLOSE_CHANNEL:
		hw->open--;
		if (debug & DEBUG_HW_OPEN)
			printk(KERN_DEBUG
			       "%s: %s: dev(%d) close from %p (open %d)\n",
			       hw->name, __func__, hw->dch.dev.id,
			       __builtin_return_address(0), hw->open);
		if (!hw->open) {
			hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
			if (hw->fifos[HFCUSB_PCM_RX].pipe)
				hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
			handle_led(hw, LED_POWER_ON);
		}
		module_put(THIS_MODULE);
		break;
	case CONTROL_CHANNEL:
		err = channel_ctrl(hw, arg);
		break;
	default:
		if (dch->debug & DEBUG_HW)
			printk(KERN_DEBUG "%s: %s: unknown command %x\n",
			       hw->name, __func__, cmd);
		return -EINVAL;
	}
	return err;
}

/*
 * S0 TE state change event handler
 */
static void
ph_state_te(struct dchannel *dch)
{
	struct hfcsusb *hw = dch->hw;

	if (debug & DEBUG_HW) {
		if (dch->state <= HFC_MAX_TE_LAYER1_STATE)
			printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,
			       HFC_TE_LAYER1_STATES[dch->state]);
		else
			printk(KERN_DEBUG "%s: %s: TE F%d\n",
			       hw->name, __func__, dch->state);
	}

	switch (dch->state) {
	case 0:
		l1_event(dch->l1, HW_RESET_IND);
		break;
	case 3:
		l1_event(dch->l1, HW_DEACT_IND);
		break;
	case 5:
	case 8:
		l1_event(dch->l1, ANYSIGNAL);
		break;
	case 6:
		l1_event(dch->l1, INFO2);
		break;
	case 7:
		l1_event(dch->l1, INFO4_P8);
		break;
	}
	if (dch->state == 7)
		handle_led(hw, LED_S0_ON);
	else
		handle_led(hw, LED_S0_OFF);
}

/*
 * S0 NT state change event handler
 */
static void
ph_state_nt(struct dchannel *dch)
{
	struct hfcsusb *hw = dch->hw;

	if (debug & DEBUG_HW) {
		if (dch->state <= HFC_MAX_NT_LAYER1_STATE)
			printk(KERN_DEBUG "%s: %s: %s\n",
			       hw->name, __func__,
			       HFC_NT_LAYER1_STATES[dch->state]);

		else
			printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n",
			       hw->name, __func__, dch->state);
	}

	switch (dch->state) {
	case (1):
		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
		hw->nt_timer = 0;
		hw->timers &= ~NT_ACTIVATION_TIMER;
		handle_led(hw, LED_S0_OFF);
		break;

	case (2):
		if (hw->nt_timer < 0) {
			hw->nt_timer = 0;
			hw->timers &= ~NT_ACTIVATION_TIMER;
			hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
		} else {
			hw->timers |= NT_ACTIVATION_TIMER;
			hw->nt_timer = NT_T1_COUNT;
			/* allow G2 -> G3 transition */
			write_reg(hw, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
		}
		break;
	case (3):
		hw->nt_timer = 0;
		hw->timers &= ~NT_ACTIVATION_TIMER;
		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
		_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
		handle_led(hw, LED_S0_ON);
		break;
	case (4):
		hw->nt_timer = 0;
		hw->timers &= ~NT_ACTIVATION_TIMER;
		break;
	default:
		break;
	}
	hfcsusb_ph_info(hw);
}

static void
ph_state(struct dchannel *dch)
{
	struct hfcsusb *hw = dch->hw;

	if (hw->protocol == ISDN_P_NT_S0)
		ph_state_nt(dch);
	else if (hw->protocol == ISDN_P_TE_S0)
		ph_state_te(dch);
}

/*
 * disable/enable BChannel for desired protocoll
 */
static int
hfcsusb_setup_bch(struct bchannel *bch, int protocol)
{
	struct hfcsusb *hw = bch->hw;
	__u8 conhdlc, sctrl, sctrl_r;

	if (debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n",
		       hw->name, __func__, bch->state, protocol,
		       bch->nr);

	/* setup val for CON_HDLC */
	conhdlc = 0;
	if (protocol > ISDN_P_NONE)
		conhdlc = 8;	/* enable FIFO */

	switch (protocol) {
	case (-1):	/* used for init */
		bch->state = -1;
		/* fall through */
	case (ISDN_P_NONE):
		if (bch->state == ISDN_P_NONE)
			return 0; /* already in idle state */
		bch->state = ISDN_P_NONE;
		clear_bit(FLG_HDLC, &bch->Flags);
		clear_bit(FLG_TRANSPARENT, &bch->Flags);
		break;
	case (ISDN_P_B_RAW):
		conhdlc |= 2;
		bch->state = protocol;
		set_bit(FLG_TRANSPARENT, &bch->Flags);
		break;
	case (ISDN_P_B_HDLC):
		bch->state = protocol;
		set_bit(FLG_HDLC, &bch->Flags);
		break;
	default:
		if (debug & DEBUG_HW)
			printk(KERN_DEBUG "%s: %s: prot not known %x\n",
			       hw->name, __func__, protocol);
		return -ENOPROTOOPT;
	}

	if (protocol >= ISDN_P_NONE) {
		write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 0 : 2);
		write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
		write_reg(hw, HFCUSB_INC_RES_F, 2);
		write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 1 : 3);
		write_reg(hw, HFCUSB_CON_HDLC, conhdlc);
		write_reg(hw, HFCUSB_INC_RES_F, 2);

		sctrl = 0x40 + ((hw->protocol == ISDN_P_TE_S0) ? 0x00 : 0x04);
		sctrl_r = 0x0;
		if (test_bit(FLG_ACTIVE, &hw->bch[0].Flags)) {
			sctrl |= 1;
			sctrl_r |= 1;
		}
		if (test_bit(FLG_ACTIVE, &hw->bch[1].Flags)) {
			sctrl |= 2;
			sctrl_r |= 2;
		}
		write_reg(hw, HFCUSB_SCTRL, sctrl);
		write_reg(hw, HFCUSB_SCTRL_R, sctrl_r);

		if (protocol > ISDN_P_NONE)
			handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON);
		else
			handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
				   LED_B2_OFF);
	}
	hfcsusb_ph_info(hw);
	return 0;
}

static void
hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
{
	if (debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s: %x\n",
		       hw->name, __func__, command);

	switch (command) {
	case HFC_L1_ACTIVATE_TE:
		/* force sending sending INFO1 */
		write_reg(hw, HFCUSB_STATES, 0x14);
		/* start l1 activation */
		write_reg(hw, HFCUSB_STATES, 0x04);
		break;

	case HFC_L1_FORCE_DEACTIVATE_TE:
		write_reg(hw, HFCUSB_STATES, 0x10);
		write_reg(hw, HFCUSB_STATES, 0x03);
		break;

	case HFC_L1_ACTIVATE_NT:
		if (hw->dch.state == 3)
			_queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND,
				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
		else
			write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE |
				  HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);
		break;

	case HFC_L1_DEACTIVATE_NT:
		write_reg(hw, HFCUSB_STATES,
			  HFCUSB_DO_ACTION);
		break;
	}
}

/*
 * Layer 1 B-channel hardware access
 */
static int
channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
{
	return mISDN_ctrl_bchannel(bch, cq);
}

/* collect data from incoming interrupt or isochron USB data */
static void
hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
		 int finish)
{
	struct hfcsusb	*hw = fifo->hw;
	struct sk_buff	*rx_skb = NULL;
	int		maxlen = 0;
	int		fifon = fifo->fifonum;
	int		i;
	int		hdlc = 0;
	unsigned long	flags;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
		       "dch(%p) bch(%p) ech(%p)\n",
		       hw->name, __func__, fifon, len,
		       fifo->dch, fifo->bch, fifo->ech);

	if (!len)
		return;

	if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) {
		printk(KERN_DEBUG "%s: %s: undefined channel\n",
		       hw->name, __func__);
		return;
	}

	spin_lock_irqsave(&hw->lock, flags);
	if (fifo->dch) {
		rx_skb = fifo->dch->rx_skb;
		maxlen = fifo->dch->maxlen;
		hdlc = 1;
	}
	if (fifo->bch) {
		if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
			fifo->bch->dropcnt += len;
			spin_unlock_irqrestore(&hw->lock, flags);
			return;
		}
		maxlen = bchannel_get_rxbuf(fifo->bch, len);
		rx_skb = fifo->bch->rx_skb;
		if (maxlen < 0) {
			if (rx_skb)
				skb_trim(rx_skb, 0);
			pr_warning("%s.B%d: No bufferspace for %d bytes\n",
				   hw->name, fifo->bch->nr, len);
			spin_unlock_irqrestore(&hw->lock, flags);
			return;
		}
		maxlen = fifo->bch->maxlen;
		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
	}
	if (fifo->ech) {
		rx_skb = fifo->ech->rx_skb;
		maxlen = fifo->ech->maxlen;
		hdlc = 1;
	}

	if (fifo->dch || fifo->ech) {
		if (!rx_skb) {
			rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC);
			if (rx_skb) {
				if (fifo->dch)
					fifo->dch->rx_skb = rx_skb;
				if (fifo->ech)
					fifo->ech->rx_skb = rx_skb;
				skb_trim(rx_skb, 0);
			} else {
				printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
				       hw->name, __func__);
				spin_unlock_irqrestore(&hw->lock, flags);
				return;
			}
		}
		/* D/E-Channel SKB range check */
		if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {
			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
			       "for fifo(%d) HFCUSB_D_RX\n",
			       hw->name, __func__, fifon);
			skb_trim(rx_skb, 0);
			spin_unlock_irqrestore(&hw->lock, flags);
			return;
		}
	}

	skb_put_data(rx_skb, data, len);

	if (hdlc) {
		/* we have a complete hdlc packet */
		if (finish) {
			if ((rx_skb->len > 3) &&
			    (!(rx_skb->data[rx_skb->len - 1]))) {
				if (debug & DBG_HFC_FIFO_VERBOSE) {
					printk(KERN_DEBUG "%s: %s: fifon(%i)"
					       " new RX len(%i): ",
					       hw->name, __func__, fifon,
					       rx_skb->len);
					i = 0;
					while (i < rx_skb->len)
						printk("%02x ",
						       rx_skb->data[i++]);
					printk("\n");
				}

				/* remove CRC & status */
				skb_trim(rx_skb, rx_skb->len - 3);

				if (fifo->dch)
					recv_Dchannel(fifo->dch);
				if (fifo->bch)
					recv_Bchannel(fifo->bch, MISDN_ID_ANY,
						      0);
				if (fifo->ech)
					recv_Echannel(fifo->ech,
						      &hw->dch);
			} else {
				if (debug & DBG_HFC_FIFO_VERBOSE) {
					printk(KERN_DEBUG
					       "%s: CRC or minlen ERROR fifon(%i) "
					       "RX len(%i): ",
					       hw->name, fifon, rx_skb->len);
					i = 0;
					while (i < rx_skb->len)
						printk("%02x ",
						       rx_skb->data[i++]);
					printk("\n");
				}
				skb_trim(rx_skb, 0);
			}
		}
	} else {
		/* deliver transparent data to layer2 */
		recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
	}
	spin_unlock_irqrestore(&hw->lock, flags);
}

static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
	      void *buf, int num_packets, int packet_size, int interval,
	      usb_complete_t complete, void *context)
{
	int k;

	usb_fill_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets,
			  complete, context);

	urb->number_of_packets = num_packets;
	urb->transfer_flags = URB_ISO_ASAP;
	urb->actual_length = 0;
	urb->interval = interval;

	for (k = 0; k < num_packets; k++) {
		urb->iso_frame_desc[k].offset = packet_size * k;
		urb->iso_frame_desc[k].length = packet_size;
		urb->iso_frame_desc[k].actual_length = 0;
	}
}

/* receive completion routine for all ISO tx fifos   */
static void
rx_iso_complete(struct urb *urb)
{
	struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
	struct usb_fifo *fifo = context_iso_urb->owner_fifo;
	struct hfcsusb *hw = fifo->hw;
	int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
		status, iso_status, i;
	__u8 *buf;
	static __u8 eof[8];
	__u8 s0_state;
	unsigned long flags;

	fifon = fifo->fifonum;
	status = urb->status;

	spin_lock_irqsave(&hw->lock, flags);
	if (fifo->stop_gracefull) {
		fifo->stop_gracefull = 0;
		fifo->active = 0;
		spin_unlock_irqrestore(&hw->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&hw->lock, flags);

	/*
	 * ISO transfer only partially completed,
	 * look at individual frame status for details
	 */
	if (status == -EXDEV) {
		if (debug & DEBUG_HW)
			printk(KERN_DEBUG "%s: %s: with -EXDEV "
			       "urb->status %d, fifonum %d\n",
			       hw->name, __func__,  status, fifon);

		/* clear status, so go on with ISO transfers */
		status = 0;
	}

	s0_state = 0;
	if (fifo->active && !status) {
		num_isoc_packets = iso_packets[fifon];
		maxlen = fifo->usb_packet_maxlen;

		for (k = 0; k < num_isoc_packets; ++k) {
			len = urb->iso_frame_desc[k].actual_length;
			offset = urb->iso_frame_desc[k].offset;
			buf = context_iso_urb->buffer + offset;
			iso_status = urb->iso_frame_desc[k].status;

			if (iso_status && (debug & DBG_HFC_FIFO_VERBOSE)) {
				printk(KERN_DEBUG "%s: %s: "
				       "ISO packet %i, status: %i\n",
				       hw->name, __func__, k, iso_status);
			}

			/* USB data log for every D ISO in */
			if ((fifon == HFCUSB_D_RX) &&
			    (debug & DBG_HFC_USB_VERBOSE)) {
				printk(KERN_DEBUG
				       "%s: %s: %d (%d/%d) len(%d) ",
				       hw->name, __func__, urb->start_frame,
				       k, num_isoc_packets - 1,
				       len);
				for (i = 0; i < len; i++)
					printk("%x ", buf[i]);
				printk("\n");
			}

			if (!iso_status) {
				if (fifo->last_urblen != maxlen) {
					/*
					 * save fifo fill-level threshold bits
					 * to use them later in TX ISO URB
					 * completions
					 */
					hw->threshold_mask = buf[1];

					if (fifon == HFCUSB_D_RX)
						s0_state = (buf[0] >> 4);

					eof[fifon] = buf[0] & 1;
					if (len > 2)
						hfcsusb_rx_frame(fifo, buf + 2,
								 len - 2, (len < maxlen)
								 ? eof[fifon] : 0);
				} else
					hfcsusb_rx_frame(fifo, buf, len,
							 (len < maxlen) ?
							 eof[fifon] : 0);
				fifo->last_urblen = len;
			}
		}

		/* signal S0 layer1 state change */
		if ((s0_state) && (hw->initdone) &&
		    (s0_state != hw->dch.state)) {
			hw->dch.state = s0_state;
			schedule_event(&hw->dch, FLG_PHCHANGE);
		}

		fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,
			      context_iso_urb->buffer, num_isoc_packets,
			      fifo->usb_packet_maxlen, fifo->intervall,
			      (usb_complete_t)rx_iso_complete, urb->context);
		errcode = usb_submit_urb(urb, GFP_ATOMIC);
		if (errcode < 0) {
			if (debug & DEBUG_HW)
				printk(KERN_DEBUG "%s: %s: error submitting "
				       "ISO URB: %d\n",
				       hw->name, __func__, errcode);
		}
	} else {
		if (status && (debug & DBG_HFC_URB_INFO))
			printk(KERN_DEBUG "%s: %s: rx_iso_complete : "
			       "urb->status %d, fifonum %d\n",
			       hw->name, __func__, status, fifon);
	}
}

/* receive completion routine for all interrupt rx fifos */
static void
rx_int_complete(struct urb *urb)
{
	int len, status, i;
	__u8 *buf, maxlen, fifon;
	struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
	struct hfcsusb *hw = fifo->hw;
	static __u8 eof[8];
	unsigned long flags;

	spin_lock_irqsave(&hw->lock, flags);
	if (fifo->stop_gracefull) {
		fifo->stop_gracefull = 0;
		fifo->active = 0;
		spin_unlock_irqrestore(&hw->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&hw->lock, flags);

	fifon = fifo->fifonum;
	if ((!fifo->active) || (urb->status)) {
		if (debug & DBG_HFC_URB_ERROR)
			printk(KERN_DEBUG
			       "%s: %s: RX-Fifo %i is going down (%i)\n",
			       hw->name, __func__, fifon, urb->status);

		fifo->urb->interval = 0; /* cancel automatic rescheduling */
		return;
	}
	len = urb->actual_length;
	buf = fifo->buffer;
	maxlen = fifo->usb_packet_maxlen;

	/* USB data log for every D INT in */
	if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) {
		printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ",
		       hw->name, __func__, len);
		for (i = 0; i < len; i++)
			printk("%02x ", buf[i]);
		printk("\n");
	}

	if (fifo->last_urblen != fifo->usb_packet_maxlen) {
		/* the threshold mask is in the 2nd status byte */
		hw->threshold_mask = buf[1];

		/* signal S0 layer1 state change */
		if (hw->initdone && ((buf[0] >> 4) != hw->dch.state)) {
			hw->dch.state = (buf[0] >> 4);
			schedule_event(&hw->dch, FLG_PHCHANGE);
		}

		eof[fifon] = buf[0] & 1;
		/* if we have more than the 2 status bytes -> collect data */
		if (len > 2)
			hfcsusb_rx_frame(fifo, buf + 2,
					 urb->actual_length - 2,
					 (len < maxlen) ? eof[fifon] : 0);
	} else {
		hfcsusb_rx_frame(fifo, buf, urb->actual_length,
				 (len < maxlen) ? eof[fifon] : 0);
	}
	fifo->last_urblen = urb->actual_length;

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		if (debug & DEBUG_HW)
			printk(KERN_DEBUG "%s: %s: error resubmitting USB\n",
			       hw->name, __func__);
	}
}

/* transmit completion routine for all ISO tx fifos */
static void
tx_iso_complete(struct urb *urb)
{
	struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;
	struct usb_fifo *fifo = context_iso_urb->owner_fifo;
	struct hfcsusb *hw = fifo->hw;
	struct sk_buff *tx_skb;
	int k, tx_offset, num_isoc_packets, sink, remain, current_len,
		errcode, hdlc, i;
	int *tx_idx;
	int frame_complete, fifon, status, fillempty = 0;
	__u8 threshbit, *p;
	unsigned long flags;

	spin_lock_irqsave(&hw->lock, flags);
	if (fifo->stop_gracefull) {
		fifo->stop_gracefull = 0;
		fifo->active = 0;
		spin_unlock_irqrestore(&hw->lock, flags);
		return;
	}

	if (fifo->dch) {
		tx_skb = fifo->dch->tx_skb;
		tx_idx = &fifo->dch->tx_idx;
		hdlc = 1;
	} else if (fifo->bch) {
		tx_skb = fifo->bch->tx_skb;
		tx_idx = &fifo->bch->tx_idx;
		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
		if (!tx_skb && !hdlc &&
		    test_bit(FLG_FILLEMPTY, &fifo->bch->Flags))
			fillempty = 1;
	} else {
		printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
		       hw->name, __func__);
		spin_unlock_irqrestore(&hw->lock, flags);
		return;
	}

	fifon = fifo->fifonum;
	status = urb->status;

	tx_offset = 0;

	/*
	 * ISO transfer only partially completed,
	 * look at individual frame status for details
	 */
	if (status == -EXDEV) {
		if (debug & DBG_HFC_URB_ERROR)
			printk(KERN_DEBUG "%s: %s: "
			       "-EXDEV (%i) fifon (%d)\n",
			       hw->name, __func__, status, fifon);

		/* clear status, so go on with ISO transfers */
		status = 0;
	}

	if (fifo->active && !status) {
		/* is FifoFull-threshold set for our channel? */
		threshbit = (hw->threshold_mask & (1 << fifon));
		num_isoc_packets = iso_packets[fifon];

		/* predict dataflow to avoid fifo overflow */
		if (fifon >= HFCUSB_D_TX)
			sink = (threshbit) ? SINK_DMIN : SINK_DMAX;
		else
			sink = (threshbit) ? SINK_MIN : SINK_MAX;
		fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,
			      context_iso_urb->buffer, num_isoc_packets,
			      fifo->usb_packet_maxlen, fifo->intervall,
			      (usb_complete_t)tx_iso_complete, urb->context);
		memset(context_iso_urb->buffer, 0,
		       sizeof(context_iso_urb->buffer));
		frame_complete = 0;

		for (k = 0; k < num_isoc_packets; ++k) {
			/* analyze tx success of previous ISO packets */
			if (debug & DBG_HFC_URB_ERROR) {
				errcode = urb->iso_frame_desc[k].status;
				if (errcode) {
					printk(KERN_DEBUG "%s: %s: "
					       "ISO packet %i, status: %i\n",
					       hw->name, __func__, k, errcode);
				}
			}

			/* Generate next ISO Packets */
			if (tx_skb)
				remain = tx_skb->len - *tx_idx;
			else if (fillempty)
				remain = 15; /* > not complete */
			else
				remain = 0;

			if (remain > 0) {
				fifo->bit_line -= sink;
				current_len = (0 - fifo->bit_line) / 8;
				if (current_len > 14)
					current_len = 14;
				if (current_len < 0)
					current_len = 0;
				if (remain < current_len)
					current_len = remain;

				/* how much bit do we put on the line? */
				fifo->bit_line += current_len * 8;

				context_iso_urb->buffer[tx_offset] = 0;
				if (current_len == remain) {
					if (hdlc) {
						/* signal frame completion */
						context_iso_urb->
							buffer[tx_offset] = 1;
						/* add 2 byte flags and 16bit
						 * CRC at end of ISDN frame */
						fifo->bit_line += 32;
					}
					frame_complete = 1;
				}

				/* copy tx data to iso-urb buffer */
				p = context_iso_urb->buffer + tx_offset + 1;
				if (fillempty) {
					memset(p, fifo->bch->fill[0],
					       current_len);
				} else {
					memcpy(p, (tx_skb->data + *tx_idx),
					       current_len);
					*tx_idx += current_len;
				}
				urb->iso_frame_desc[k].offset = tx_offset;
				urb->iso_frame_desc[k].length = current_len + 1;

				/* USB data log for every D ISO out */
				if ((fifon == HFCUSB_D_RX) && !fillempty &&
				    (debug & DBG_HFC_USB_VERBOSE)) {
					printk(KERN_DEBUG
					       "%s: %s (%d/%d) offs(%d) len(%d) ",
					       hw->name, __func__,
					       k, num_isoc_packets - 1,
					       urb->iso_frame_desc[k].offset,
					       urb->iso_frame_desc[k].length);

					for (i = urb->iso_frame_desc[k].offset;
					     i < (urb->iso_frame_desc[k].offset
						  + urb->iso_frame_desc[k].length);
					     i++)
						printk("%x ",
						       context_iso_urb->buffer[i]);

					printk(" skb->len(%i) tx-idx(%d)\n",
					       tx_skb->len, *tx_idx);
				}

				tx_offset += (current_len + 1);
			} else {
				urb->iso_frame_desc[k].offset = tx_offset++;
				urb->iso_frame_desc[k].length = 1;
				/* we lower data margin every msec */
				fifo->bit_line -= sink;
				if (fifo->bit_line < BITLINE_INF)
					fifo->bit_line = BITLINE_INF;
			}

			if (frame_complete) {
				frame_complete = 0;

				if (debug & DBG_HFC_FIFO_VERBOSE) {
					printk(KERN_DEBUG  "%s: %s: "
					       "fifon(%i) new TX len(%i): ",
					       hw->name, __func__,
					       fifon, tx_skb->len);
					i = 0;
					while (i < tx_skb->len)
						printk("%02x ",
						       tx_skb->data[i++]);
					printk("\n");
				}

				dev_kfree_skb(tx_skb);
				tx_skb = NULL;
				if (fifo->dch && get_next_dframe(fifo->dch))
					tx_skb = fifo->dch->tx_skb;
				else if (fifo->bch &&
					 get_next_bframe(fifo->bch))
					tx_skb = fifo->bch->tx_skb;
			}
		}
		errcode = usb_submit_urb(urb, GFP_ATOMIC);
		if (errcode < 0) {
			if (debug & DEBUG_HW)
				printk(KERN_DEBUG
				       "%s: %s: error submitting ISO URB: %d \n",
				       hw->name, __func__, errcode);
		}

		/*
		 * abuse DChannel tx iso completion to trigger NT mode state
		 * changes tx_iso_complete is assumed to be called every
		 * fifo->intervall (ms)
		 */
		if ((fifon == HFCUSB_D_TX) && (hw->protocol == ISDN_P_NT_S0)
		    && (hw->timers & NT_ACTIVATION_TIMER)) {
			if ((--hw->nt_timer) < 0)
				schedule_event(&hw->dch, FLG_PHCHANGE);
		}

	} else {
		if (status && (debug & DBG_HFC_URB_ERROR))
			printk(KERN_DEBUG  "%s: %s: urb->status %s (%i)"
			       "fifonum=%d\n",
			       hw->name, __func__,
			       symbolic(urb_errlist, status), status, fifon);
	}
	spin_unlock_irqrestore(&hw->lock, flags);
}

/*
 * allocs urbs and start isoc transfer with two pending urbs to avoid
 * gaps in the transfer chain
 */
static int
start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
		 usb_complete_t complete, int packet_size)
{
	struct hfcsusb *hw = fifo->hw;
	int i, k, errcode;

	if (debug)
		printk(KERN_DEBUG "%s: %s: fifo %i\n",
		       hw->name, __func__, fifo->fifonum);

	/* allocate Memory for Iso out Urbs */
	for (i = 0; i < 2; i++) {
		if (!(fifo->iso[i].urb)) {
			fifo->iso[i].urb =
				usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
			if (!(fifo->iso[i].urb)) {
				printk(KERN_DEBUG
				       "%s: %s: alloc urb for fifo %i failed",
				       hw->name, __func__, fifo->fifonum);
			}
			fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;
			fifo->iso[i].indx = i;

			/* Init the first iso */
			if (ISO_BUFFER_SIZE >=
			    (fifo->usb_packet_maxlen *
			     num_packets_per_urb)) {
				fill_isoc_urb(fifo->iso[i].urb,
					      fifo->hw->dev, fifo->pipe,
					      fifo->iso[i].buffer,
					      num_packets_per_urb,
					      fifo->usb_packet_maxlen,
					      fifo->intervall, complete,
					      &fifo->iso[i]);
				memset(fifo->iso[i].buffer, 0,
				       sizeof(fifo->iso[i].buffer));

				for (k = 0; k < num_packets_per_urb; k++) {
					fifo->iso[i].urb->
						iso_frame_desc[k].offset =
						k * packet_size;
					fifo->iso[i].urb->
						iso_frame_desc[k].length =
						packet_size;
				}
			} else {
				printk(KERN_DEBUG
				       "%s: %s: ISO Buffer size to small!\n",
				       hw->name, __func__);
			}
		}
		fifo->bit_line = BITLINE_INF;

		errcode = usb_submit_urb(fifo->iso[i].urb, GFP_KERNEL);
		fifo->active = (errcode >= 0) ? 1 : 0;
		fifo->stop_gracefull = 0;
		if (errcode < 0) {
			printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n",
			       hw->name, __func__,
			       symbolic(urb_errlist, errcode), i);
		}
	}
	return fifo->active;
}

static void
stop_iso_gracefull(struct usb_fifo *fifo)
{
	struct hfcsusb *hw = fifo->hw;
	int i, timeout;
	u_long flags;

	for (i = 0; i < 2; i++) {
		spin_lock_irqsave(&hw->lock, flags);
		if (debug)
			printk(KERN_DEBUG "%s: %s for fifo %i.%i\n",
			       hw->name, __func__, fifo->fifonum, i);
		fifo->stop_gracefull = 1;
		spin_unlock_irqrestore(&hw->lock, flags);
	}

	for (i = 0; i < 2; i++) {
		timeout = 3;
		while (fifo->stop_gracefull && timeout--)
			schedule_timeout_interruptible((HZ / 1000) * 16);
		if (debug && fifo->stop_gracefull)
			printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n",
			       hw->name, __func__, fifo->fifonum, i);
	}
}

static void
stop_int_gracefull(struct usb_fifo *fifo)
{
	struct hfcsusb *hw = fifo->hw;
	int timeout;
	u_long flags;

	spin_lock_irqsave(&hw->lock, flags);
	if (debug)
		printk(KERN_DEBUG "%s: %s for fifo %i\n",
		       hw->name, __func__, fifo->fifonum);
	fifo->stop_gracefull = 1;
	spin_unlock_irqrestore(&hw->lock, flags);

	timeout = 3;
	while (fifo->stop_gracefull && timeout--)
		schedule_timeout_interruptible((HZ / 1000) * 3);
	if (debug && fifo->stop_gracefull)
		printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n",
		       hw->name, __func__, fifo->fifonum);
}

/* start the interrupt transfer for the given fifo */
static void
start_int_fifo(struct usb_fifo *fifo)
{
	struct hfcsusb *hw = fifo->hw;
	int errcode;

	if (debug)
		printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n",
		       hw->name, __func__, fifo->fifonum);

	if (!fifo->urb) {
		fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!fifo->urb)
			return;
	}
	usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe,
			 fifo->buffer, fifo->usb_packet_maxlen,
			 (usb_complete_t)rx_int_complete, fifo, fifo->intervall);
	fifo->active = 1;
	fifo->stop_gracefull = 0;
	errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
	if (errcode) {
		printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n",
		       hw->name, __func__, errcode);
		fifo->active = 0;
	}
}

static void
setPortMode(struct hfcsusb *hw)
{
	if (debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__,
		       (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");

	if (hw->protocol == ISDN_P_TE_S0) {
		write_reg(hw, HFCUSB_SCTRL, 0x40);
		write_reg(hw, HFCUSB_SCTRL_E, 0x00);
		write_reg(hw, HFCUSB_CLKDEL, CLKDEL_TE);
		write_reg(hw, HFCUSB_STATES, 3 | 0x10);
		write_reg(hw, HFCUSB_STATES, 3);
	} else {
		write_reg(hw, HFCUSB_SCTRL, 0x44);
		write_reg(hw, HFCUSB_SCTRL_E, 0x09);
		write_reg(hw, HFCUSB_CLKDEL, CLKDEL_NT);
		write_reg(hw, HFCUSB_STATES, 1 | 0x10);
		write_reg(hw, HFCUSB_STATES, 1);
	}
}

static void
reset_hfcsusb(struct hfcsusb *hw)
{
	struct usb_fifo *fifo;
	int i;

	if (debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	/* do Chip reset */
	write_reg(hw, HFCUSB_CIRM, 8);

	/* aux = output, reset off */
	write_reg(hw, HFCUSB_CIRM, 0x10);

	/* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */
	write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) |
		  ((hw->packet_size / 8) << 4));

	/* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */
	write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size);

	/* enable PCM/GCI master mode */
	write_reg(hw, HFCUSB_MST_MODE1, 0);	/* set default values */
	write_reg(hw, HFCUSB_MST_MODE0, 1);	/* enable master mode */

	/* init the fifos */
	write_reg(hw, HFCUSB_F_THRES,
		  (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));

	fifo = hw->fifos;
	for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
		write_reg(hw, HFCUSB_FIFO, i);	/* select the desired fifo */
		fifo[i].max_size =
			(i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
		fifo[i].last_urblen = 0;

		/* set 2 bit for D- & E-channel */
		write_reg(hw, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2));

		/* enable all fifos */
		if (i == HFCUSB_D_TX)
			write_reg(hw, HFCUSB_CON_HDLC,
				  (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);
		else
			write_reg(hw, HFCUSB_CON_HDLC, 0x08);
		write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */
	}

	write_reg(hw, HFCUSB_SCTRL_R, 0); /* disable both B receivers */
	handle_led(hw, LED_POWER_ON);
}

/* start USB data pipes dependand on device's endpoint configuration */
static void
hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)
{
	/* quick check if endpoint already running */
	if ((channel == HFC_CHAN_D) && (hw->fifos[HFCUSB_D_RX].active))
		return;
	if ((channel == HFC_CHAN_B1) && (hw->fifos[HFCUSB_B1_RX].active))
		return;
	if ((channel == HFC_CHAN_B2) && (hw->fifos[HFCUSB_B2_RX].active))
		return;
	if ((channel == HFC_CHAN_E) && (hw->fifos[HFCUSB_PCM_RX].active))
		return;

	/* start rx endpoints using USB INT IN method */
	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
		start_int_fifo(hw->fifos + channel * 2 + 1);

	/* start rx endpoints using USB ISO IN method */
	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) {
		switch (channel) {
		case HFC_CHAN_D:
			start_isoc_chain(hw->fifos + HFCUSB_D_RX,
					 ISOC_PACKETS_D,
					 (usb_complete_t)rx_iso_complete,
					 16);
			break;
		case HFC_CHAN_E:
			start_isoc_chain(hw->fifos + HFCUSB_PCM_RX,
					 ISOC_PACKETS_D,
					 (usb_complete_t)rx_iso_complete,
					 16);
			break;
		case HFC_CHAN_B1:
			start_isoc_chain(hw->fifos + HFCUSB_B1_RX,
					 ISOC_PACKETS_B,
					 (usb_complete_t)rx_iso_complete,
					 16);
			break;
		case HFC_CHAN_B2:
			start_isoc_chain(hw->fifos + HFCUSB_B2_RX,
					 ISOC_PACKETS_B,
					 (usb_complete_t)rx_iso_complete,
					 16);
			break;
		}
	}

	/* start tx endpoints using USB ISO OUT method */
	switch (channel) {
	case HFC_CHAN_D:
		start_isoc_chain(hw->fifos + HFCUSB_D_TX,
				 ISOC_PACKETS_B,
				 (usb_complete_t)tx_iso_complete, 1);
		break;
	case HFC_CHAN_B1:
		start_isoc_chain(hw->fifos + HFCUSB_B1_TX,
				 ISOC_PACKETS_D,
				 (usb_complete_t)tx_iso_complete, 1);
		break;
	case HFC_CHAN_B2:
		start_isoc_chain(hw->fifos + HFCUSB_B2_TX,
				 ISOC_PACKETS_B,
				 (usb_complete_t)tx_iso_complete, 1);
		break;
	}
}

/* stop USB data pipes dependand on device's endpoint configuration */
static void
hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
{
	/* quick check if endpoint currently running */
	if ((channel == HFC_CHAN_D) && (!hw->fifos[HFCUSB_D_RX].active))
		return;
	if ((channel == HFC_CHAN_B1) && (!hw->fifos[HFCUSB_B1_RX].active))
		return;
	if ((channel == HFC_CHAN_B2) && (!hw->fifos[HFCUSB_B2_RX].active))
		return;
	if ((channel == HFC_CHAN_E) && (!hw->fifos[HFCUSB_PCM_RX].active))
		return;

	/* rx endpoints using USB INT IN method */
	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
		stop_int_gracefull(hw->fifos + channel * 2 + 1);

	/* rx endpoints using USB ISO IN method */
	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO)
		stop_iso_gracefull(hw->fifos + channel * 2 + 1);

	/* tx endpoints using USB ISO OUT method */
	if (channel != HFC_CHAN_E)
		stop_iso_gracefull(hw->fifos + channel * 2);
}


/* Hardware Initialization */
static int
setup_hfcsusb(struct hfcsusb *hw)
{
	u_char b;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	/* check the chip id */
	if (read_reg_atomic(hw, HFCUSB_CHIP_ID, &b) != 1) {
		printk(KERN_DEBUG "%s: %s: cannot read chip id\n",
		       hw->name, __func__);
		return 1;
	}
	if (b != HFCUSB_CHIPID) {
		printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n",
		       hw->name, __func__, b);
		return 1;
	}

	/* first set the needed config, interface and alternate */
	(void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);

	hw->led_state = 0;

	/* init the background machinery for control requests */
	hw->ctrl_read.bRequestType = 0xc0;
	hw->ctrl_read.bRequest = 1;
	hw->ctrl_read.wLength = cpu_to_le16(1);
	hw->ctrl_write.bRequestType = 0x40;
	hw->ctrl_write.bRequest = 0;
	hw->ctrl_write.wLength = 0;
	usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe,
			     (u_char *)&hw->ctrl_write, NULL, 0,
			     (usb_complete_t)ctrl_complete, hw);

	reset_hfcsusb(hw);
	return 0;
}

static void
release_hw(struct hfcsusb *hw)
{
	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	/*
	 * stop all endpoints gracefully
	 * TODO: mISDN_core should generate CLOSE_CHANNEL
	 *       signals after calling mISDN_unregister_device()
	 */
	hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
	hfcsusb_stop_endpoint(hw, HFC_CHAN_B1);
	hfcsusb_stop_endpoint(hw, HFC_CHAN_B2);
	if (hw->fifos[HFCUSB_PCM_RX].pipe)
		hfcsusb_stop_endpoint(hw, HFC_CHAN_E);
	if (hw->protocol == ISDN_P_TE_S0)
		l1_event(hw->dch.l1, CLOSE_CHANNEL);

	mISDN_unregister_device(&hw->dch.dev);
	mISDN_freebchannel(&hw->bch[1]);
	mISDN_freebchannel(&hw->bch[0]);
	mISDN_freedchannel(&hw->dch);

	if (hw->ctrl_urb) {
		usb_kill_urb(hw->ctrl_urb);
		usb_free_urb(hw->ctrl_urb);
		hw->ctrl_urb = NULL;
	}

	if (hw->intf)
		usb_set_intfdata(hw->intf, NULL);
	list_del(&hw->list);
	kfree(hw);
	hw = NULL;
}

static void
deactivate_bchannel(struct bchannel *bch)
{
	struct hfcsusb *hw = bch->hw;
	u_long flags;

	if (bch->debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n",
		       hw->name, __func__, bch->nr);

	spin_lock_irqsave(&hw->lock, flags);
	mISDN_clear_bchannel(bch);
	spin_unlock_irqrestore(&hw->lock, flags);
	hfcsusb_setup_bch(bch, ISDN_P_NONE);
	hfcsusb_stop_endpoint(hw, bch->nr - 1);
}

/*
 * Layer 1 B-channel hardware access
 */
static int
hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
	struct bchannel	*bch = container_of(ch, struct bchannel, ch);
	int		ret = -EINVAL;

	if (bch->debug & DEBUG_HW)
		printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);

	switch (cmd) {
	case HW_TESTRX_RAW:
	case HW_TESTRX_HDLC:
	case HW_TESTRX_OFF:
		ret = -EINVAL;
		break;

	case CLOSE_CHANNEL:
		test_and_clear_bit(FLG_OPEN, &bch->Flags);
		deactivate_bchannel(bch);
		ch->protocol = ISDN_P_NONE;
		ch->peer = NULL;
		module_put(THIS_MODULE);
		ret = 0;
		break;
	case CONTROL_CHANNEL:
		ret = channel_bctrl(bch, arg);
		break;
	default:
		printk(KERN_WARNING "%s: unknown prim(%x)\n",
		       __func__, cmd);
	}
	return ret;
}

static int
setup_instance(struct hfcsusb *hw, struct device *parent)
{
	u_long	flags;
	int	err, i;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);

	spin_lock_init(&hw->ctrl_lock);
	spin_lock_init(&hw->lock);

	mISDN_initdchannel(&hw->dch, MAX_DFRAME_LEN_L1, ph_state);
	hw->dch.debug = debug & 0xFFFF;
	hw->dch.hw = hw;
	hw->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
	hw->dch.dev.D.send = hfcusb_l2l1D;
	hw->dch.dev.D.ctrl = hfc_dctrl;

	/* enable E-Channel logging */
	if (hw->fifos[HFCUSB_PCM_RX].pipe)
		mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL);

	hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
	hw->dch.dev.nrbchan = 2;
	for (i = 0; i < 2; i++) {
		hw->bch[i].nr = i + 1;
		set_channelmap(i + 1, hw->dch.dev.channelmap);
		hw->bch[i].debug = debug;
		mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1);
		hw->bch[i].hw = hw;
		hw->bch[i].ch.send = hfcusb_l2l1B;
		hw->bch[i].ch.ctrl = hfc_bctrl;
		hw->bch[i].ch.nr = i + 1;
		list_add(&hw->bch[i].ch.list, &hw->dch.dev.bchannels);
	}

	hw->fifos[HFCUSB_B1_TX].bch = &hw->bch[0];
	hw->fifos[HFCUSB_B1_RX].bch = &hw->bch[0];
	hw->fifos[HFCUSB_B2_TX].bch = &hw->bch[1];
	hw->fifos[HFCUSB_B2_RX].bch = &hw->bch[1];
	hw->fifos[HFCUSB_D_TX].dch = &hw->dch;
	hw->fifos[HFCUSB_D_RX].dch = &hw->dch;
	hw->fifos[HFCUSB_PCM_RX].ech = &hw->ech;
	hw->fifos[HFCUSB_PCM_TX].ech = &hw->ech;

	err = setup_hfcsusb(hw);
	if (err)
		goto out;

	snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME,
		 hfcsusb_cnt + 1);
	printk(KERN_INFO "%s: registered as '%s'\n",
	       DRIVER_NAME, hw->name);

	err = mISDN_register_device(&hw->dch.dev, parent, hw->name);
	if (err)
		goto out;

	hfcsusb_cnt++;
	write_lock_irqsave(&HFClock, flags);
	list_add_tail(&hw->list, &HFClist);
	write_unlock_irqrestore(&HFClock, flags);
	return 0;

out:
	mISDN_freebchannel(&hw->bch[1]);
	mISDN_freebchannel(&hw->bch[0]);
	mISDN_freedchannel(&hw->dch);
	kfree(hw);
	return err;
}

static int
hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct hfcsusb			*hw;
	struct usb_device		*dev = interface_to_usbdev(intf);
	struct usb_host_interface	*iface = intf->cur_altsetting;
	struct usb_host_interface	*iface_used = NULL;
	struct usb_host_endpoint	*ep;
	struct hfcsusb_vdata		*driver_info;
	int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx,
		probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,
		ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,
		alt_used = 0;

	vend_idx = 0xffff;
	for (i = 0; hfcsusb_idtab[i].idVendor; i++) {
		if ((le16_to_cpu(dev->descriptor.idVendor)
		     == hfcsusb_idtab[i].idVendor) &&
		    (le16_to_cpu(dev->descriptor.idProduct)
		     == hfcsusb_idtab[i].idProduct)) {
			vend_idx = i;
			continue;
		}
	}

	printk(KERN_DEBUG
	       "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",
	       __func__, ifnum, iface->desc.bAlternateSetting,
	       intf->minor, vend_idx);

	if (vend_idx == 0xffff) {
		printk(KERN_WARNING
		       "%s: no valid vendor found in USB descriptor\n",
		       __func__);
		return -EIO;
	}
	/* if vendor and product ID is OK, start probing alternate settings */
	alt_idx = 0;
	small_match = -1;

	/* default settings */
	iso_packet_size = 16;
	packet_size = 64;

	while (alt_idx < intf->num_altsetting) {
		iface = intf->altsetting + alt_idx;
		probe_alt_setting = iface->desc.bAlternateSetting;
		cfg_used = 0;

		while (validconf[cfg_used][0]) {
			cfg_found = 1;
			vcf = validconf[cfg_used];
			ep = iface->endpoint;
			memcpy(cmptbl, vcf, 16 * sizeof(int));

			/* check for all endpoints in this alternate setting */
			for (i = 0; i < iface->desc.bNumEndpoints; i++) {
				ep_addr = ep->desc.bEndpointAddress;

				/* get endpoint base */
				idx = ((ep_addr & 0x7f) - 1) * 2;
				if (ep_addr & 0x80)
					idx++;
				attr = ep->desc.bmAttributes;

				if (cmptbl[idx] != EP_NOP) {
					if (cmptbl[idx] == EP_NUL)
						cfg_found = 0;
					if (attr == USB_ENDPOINT_XFER_INT
					    && cmptbl[idx] == EP_INT)
						cmptbl[idx] = EP_NUL;
					if (attr == USB_ENDPOINT_XFER_BULK
					    && cmptbl[idx] == EP_BLK)
						cmptbl[idx] = EP_NUL;
					if (attr == USB_ENDPOINT_XFER_ISOC
					    && cmptbl[idx] == EP_ISO)
						cmptbl[idx] = EP_NUL;

					if (attr == USB_ENDPOINT_XFER_INT &&
					    ep->desc.bInterval < vcf[17]) {
						cfg_found = 0;
					}
				}
				ep++;
			}

			for (i = 0; i < 16; i++)
				if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL)
					cfg_found = 0;

			if (cfg_found) {
				if (small_match < cfg_used) {
					small_match = cfg_used;
					alt_used = probe_alt_setting;
					iface_used = iface;
				}
			}
			cfg_used++;
		}
		alt_idx++;
	}	/* (alt_idx < intf->num_altsetting) */

	/* not found a valid USB Ta Endpoint config */
	if (small_match == -1)
		return -EIO;

	iface = iface_used;
	hw = kzalloc(sizeof(struct hfcsusb), GFP_KERNEL);
	if (!hw)
		return -ENOMEM;	/* got no mem */
	snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME);

	ep = iface->endpoint;
	vcf = validconf[small_match];

	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
		struct usb_fifo *f;

		ep_addr = ep->desc.bEndpointAddress;
		/* get endpoint base */
		idx = ((ep_addr & 0x7f) - 1) * 2;
		if (ep_addr & 0x80)
			idx++;
		f = &hw->fifos[idx & 7];

		/* init Endpoints */
		if (vcf[idx] == EP_NOP || vcf[idx] == EP_NUL) {
			ep++;
			continue;
		}
		switch (ep->desc.bmAttributes) {
		case USB_ENDPOINT_XFER_INT:
			f->pipe = usb_rcvintpipe(dev,
						 ep->desc.bEndpointAddress);
			f->usb_transfer_mode = USB_INT;
			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
			break;
		case USB_ENDPOINT_XFER_BULK:
			if (ep_addr & 0x80)
				f->pipe = usb_rcvbulkpipe(dev,
							  ep->desc.bEndpointAddress);
			else
				f->pipe = usb_sndbulkpipe(dev,
							  ep->desc.bEndpointAddress);
			f->usb_transfer_mode = USB_BULK;
			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
			break;
		case USB_ENDPOINT_XFER_ISOC:
			if (ep_addr & 0x80)
				f->pipe = usb_rcvisocpipe(dev,
							  ep->desc.bEndpointAddress);
			else
				f->pipe = usb_sndisocpipe(dev,
							  ep->desc.bEndpointAddress);
			f->usb_transfer_mode = USB_ISOC;
			iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
			break;
		default:
			f->pipe = 0;
		}

		if (f->pipe) {
			f->fifonum = idx & 7;
			f->hw = hw;
			f->usb_packet_maxlen =
				le16_to_cpu(ep->desc.wMaxPacketSize);
			f->intervall = ep->desc.bInterval;
		}
		ep++;
	}
	hw->dev = dev; /* save device */
	hw->if_used = ifnum; /* save used interface */
	hw->alt_used = alt_used; /* and alternate config */
	hw->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */
	hw->cfg_used = vcf[16];	/* store used config */
	hw->vend_idx = vend_idx; /* store found vendor */
	hw->packet_size = packet_size;
	hw->iso_packet_size = iso_packet_size;

	/* create the control pipes needed for register access */
	hw->ctrl_in_pipe = usb_rcvctrlpipe(hw->dev, 0);
	hw->ctrl_out_pipe = usb_sndctrlpipe(hw->dev, 0);

	driver_info = (struct hfcsusb_vdata *)
		      hfcsusb_idtab[vend_idx].driver_info;

	hw->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!hw->ctrl_urb) {
		pr_warn("%s: No memory for control urb\n",
			driver_info->vend_name);
		kfree(hw);
		return -ENOMEM;
	}

	pr_info("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n",
		hw->name, __func__, driver_info->vend_name,
		conf_str[small_match], ifnum, alt_used);

	if (setup_instance(hw, dev->dev.parent))
		return -EIO;

	hw->intf = intf;
	usb_set_intfdata(hw->intf, hw);
	return 0;
}

/* function called when an active device is removed */
static void
hfcsusb_disconnect(struct usb_interface *intf)
{
	struct hfcsusb *hw = usb_get_intfdata(intf);
	struct hfcsusb *next;
	int cnt = 0;

	printk(KERN_INFO "%s: device disconnected\n", hw->name);

	handle_led(hw, LED_POWER_OFF);
	release_hw(hw);

	list_for_each_entry_safe(hw, next, &HFClist, list)
		cnt++;
	if (!cnt)
		hfcsusb_cnt = 0;

	usb_set_intfdata(intf, NULL);
}

static struct usb_driver hfcsusb_drv = {
	.name = DRIVER_NAME,
	.id_table = hfcsusb_idtab,
	.probe = hfcsusb_probe,
	.disconnect = hfcsusb_disconnect,
	.disable_hub_initiated_lpm = 1,
};

module_usb_driver(hfcsusb_drv);
