Path: blob/master/drivers/isdn/hardware/mISDN/hfcsusb.c
15111 views
/* hfcsusb.c1* mISDN driver for Colognechip HFC-S USB chip2*3* Copyright 2001 by Peter Sprenger ([email protected])4* Copyright 2008 by Martin Bachem ([email protected])5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2, or (at your option)9* any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19*20*21* module params22* debug=<n>, default=0, with n=0xHHHHGGGG23* H - l1 driver flags described in hfcsusb.h24* G - common mISDN debug flags described at mISDNhw.h25*26* poll=<n>, default 12827* n : burst size of PH_DATA_IND at transparent rx data28*29*/3031#include <linux/module.h>32#include <linux/delay.h>33#include <linux/usb.h>34#include <linux/mISDNhw.h>35#include <linux/slab.h>36#include "hfcsusb.h"3738static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";3940static unsigned int debug;41static int poll = DEFAULT_TRANSP_BURST_SZ;4243static LIST_HEAD(HFClist);44static DEFINE_RWLOCK(HFClock);454647MODULE_AUTHOR("Martin Bachem");48MODULE_LICENSE("GPL");49module_param(debug, uint, S_IRUGO | S_IWUSR);50module_param(poll, int, 0);5152static int hfcsusb_cnt;5354/* some function prototypes */55static void hfcsusb_ph_command(struct hfcsusb *hw, u_char command);56static void release_hw(struct hfcsusb *hw);57static void reset_hfcsusb(struct hfcsusb *hw);58static void setPortMode(struct hfcsusb *hw);59static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel);60static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);61static int hfcsusb_setup_bch(struct bchannel *bch, int protocol);62static void deactivate_bchannel(struct bchannel *bch);63static void hfcsusb_ph_info(struct hfcsusb *hw);6465/* start next background transfer for control channel */66static void67ctrl_start_transfer(struct hfcsusb *hw)68{69if (debug & DBG_HFC_CALL_TRACE)70printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);7172if (hw->ctrl_cnt) {73hw->ctrl_urb->pipe = hw->ctrl_out_pipe;74hw->ctrl_urb->setup_packet = (u_char *)&hw->ctrl_write;75hw->ctrl_urb->transfer_buffer = NULL;76hw->ctrl_urb->transfer_buffer_length = 0;77hw->ctrl_write.wIndex =78cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);79hw->ctrl_write.wValue =80cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);8182usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC);83}84}8586/*87* queue a control transfer request to write HFC-S USB88* chip register using CTRL resuest queue89*/90static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)91{92struct ctrl_buf *buf;9394if (debug & DBG_HFC_CALL_TRACE)95printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n",96hw->name, __func__, reg, val);9798spin_lock(&hw->ctrl_lock);99if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {100spin_unlock(&hw->ctrl_lock);101return 1;102}103buf = &hw->ctrl_buff[hw->ctrl_in_idx];104buf->hfcs_reg = reg;105buf->reg_val = val;106if (++hw->ctrl_in_idx >= HFC_CTRL_BUFSIZE)107hw->ctrl_in_idx = 0;108if (++hw->ctrl_cnt == 1)109ctrl_start_transfer(hw);110spin_unlock(&hw->ctrl_lock);111112return 0;113}114115/* control completion routine handling background control cmds */116static void117ctrl_complete(struct urb *urb)118{119struct hfcsusb *hw = (struct hfcsusb *) urb->context;120121if (debug & DBG_HFC_CALL_TRACE)122printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);123124urb->dev = hw->dev;125if (hw->ctrl_cnt) {126hw->ctrl_cnt--; /* decrement actual count */127if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)128hw->ctrl_out_idx = 0; /* pointer wrap */129130ctrl_start_transfer(hw); /* start next transfer */131}132}133134/* handle LED bits */135static void136set_led_bit(struct hfcsusb *hw, signed short led_bits, int set_on)137{138if (set_on) {139if (led_bits < 0)140hw->led_state &= ~abs(led_bits);141else142hw->led_state |= led_bits;143} else {144if (led_bits < 0)145hw->led_state |= abs(led_bits);146else147hw->led_state &= ~led_bits;148}149}150151/* handle LED requests */152static void153handle_led(struct hfcsusb *hw, int event)154{155struct hfcsusb_vdata *driver_info = (struct hfcsusb_vdata *)156hfcsusb_idtab[hw->vend_idx].driver_info;157__u8 tmpled;158159if (driver_info->led_scheme == LED_OFF)160return;161tmpled = hw->led_state;162163switch (event) {164case LED_POWER_ON:165set_led_bit(hw, driver_info->led_bits[0], 1);166set_led_bit(hw, driver_info->led_bits[1], 0);167set_led_bit(hw, driver_info->led_bits[2], 0);168set_led_bit(hw, driver_info->led_bits[3], 0);169break;170case LED_POWER_OFF:171set_led_bit(hw, driver_info->led_bits[0], 0);172set_led_bit(hw, driver_info->led_bits[1], 0);173set_led_bit(hw, driver_info->led_bits[2], 0);174set_led_bit(hw, driver_info->led_bits[3], 0);175break;176case LED_S0_ON:177set_led_bit(hw, driver_info->led_bits[1], 1);178break;179case LED_S0_OFF:180set_led_bit(hw, driver_info->led_bits[1], 0);181break;182case LED_B1_ON:183set_led_bit(hw, driver_info->led_bits[2], 1);184break;185case LED_B1_OFF:186set_led_bit(hw, driver_info->led_bits[2], 0);187break;188case LED_B2_ON:189set_led_bit(hw, driver_info->led_bits[3], 1);190break;191case LED_B2_OFF:192set_led_bit(hw, driver_info->led_bits[3], 0);193break;194}195196if (hw->led_state != tmpled) {197if (debug & DBG_HFC_CALL_TRACE)198printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n",199hw->name, __func__,200HFCUSB_P_DATA, hw->led_state);201202write_reg(hw, HFCUSB_P_DATA, hw->led_state);203}204}205206/*207* Layer2 -> Layer 1 Bchannel data208*/209static int210hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)211{212struct bchannel *bch = container_of(ch, struct bchannel, ch);213struct hfcsusb *hw = bch->hw;214int ret = -EINVAL;215struct mISDNhead *hh = mISDN_HEAD_P(skb);216u_long flags;217218if (debug & DBG_HFC_CALL_TRACE)219printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);220221switch (hh->prim) {222case PH_DATA_REQ:223spin_lock_irqsave(&hw->lock, flags);224ret = bchannel_senddata(bch, skb);225spin_unlock_irqrestore(&hw->lock, flags);226if (debug & DBG_HFC_CALL_TRACE)227printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",228hw->name, __func__, ret);229if (ret > 0) {230/*231* other l1 drivers don't send early confirms on232* transp data, but hfcsusb does because tx_next233* skb is needed in tx_iso_complete()234*/235queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);236ret = 0;237}238return ret;239case PH_ACTIVATE_REQ:240if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {241hfcsusb_start_endpoint(hw, bch->nr);242ret = hfcsusb_setup_bch(bch, ch->protocol);243} else244ret = 0;245if (!ret)246_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,2470, NULL, GFP_KERNEL);248break;249case PH_DEACTIVATE_REQ:250deactivate_bchannel(bch);251_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,2520, NULL, GFP_KERNEL);253ret = 0;254break;255}256if (!ret)257dev_kfree_skb(skb);258return ret;259}260261/*262* send full D/B channel status information263* as MPH_INFORMATION_IND264*/265static void266hfcsusb_ph_info(struct hfcsusb *hw)267{268struct ph_info *phi;269struct dchannel *dch = &hw->dch;270int i;271272phi = kzalloc(sizeof(struct ph_info) +273dch->dev.nrbchan * sizeof(struct ph_info_ch), GFP_ATOMIC);274phi->dch.ch.protocol = hw->protocol;275phi->dch.ch.Flags = dch->Flags;276phi->dch.state = dch->state;277phi->dch.num_bch = dch->dev.nrbchan;278for (i = 0; i < dch->dev.nrbchan; i++) {279phi->bch[i].protocol = hw->bch[i].ch.protocol;280phi->bch[i].Flags = hw->bch[i].Flags;281}282_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,283sizeof(struct ph_info_dch) + dch->dev.nrbchan *284sizeof(struct ph_info_ch), phi, GFP_ATOMIC);285kfree(phi);286}287288/*289* Layer2 -> Layer 1 Dchannel data290*/291static int292hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)293{294struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);295struct dchannel *dch = container_of(dev, struct dchannel, dev);296struct mISDNhead *hh = mISDN_HEAD_P(skb);297struct hfcsusb *hw = dch->hw;298int ret = -EINVAL;299u_long flags;300301switch (hh->prim) {302case PH_DATA_REQ:303if (debug & DBG_HFC_CALL_TRACE)304printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",305hw->name, __func__);306307spin_lock_irqsave(&hw->lock, flags);308ret = dchannel_senddata(dch, skb);309spin_unlock_irqrestore(&hw->lock, flags);310if (ret > 0) {311ret = 0;312queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL);313}314break;315316case PH_ACTIVATE_REQ:317if (debug & DBG_HFC_CALL_TRACE)318printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",319hw->name, __func__,320(hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");321322if (hw->protocol == ISDN_P_NT_S0) {323ret = 0;324if (test_bit(FLG_ACTIVE, &dch->Flags)) {325_queue_data(&dch->dev.D,326PH_ACTIVATE_IND, MISDN_ID_ANY, 0,327NULL, GFP_ATOMIC);328} else {329hfcsusb_ph_command(hw,330HFC_L1_ACTIVATE_NT);331test_and_set_bit(FLG_L2_ACTIVATED,332&dch->Flags);333}334} else {335hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);336ret = l1_event(dch->l1, hh->prim);337}338break;339340case PH_DEACTIVATE_REQ:341if (debug & DBG_HFC_CALL_TRACE)342printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",343hw->name, __func__);344test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);345346if (hw->protocol == ISDN_P_NT_S0) {347hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);348spin_lock_irqsave(&hw->lock, flags);349skb_queue_purge(&dch->squeue);350if (dch->tx_skb) {351dev_kfree_skb(dch->tx_skb);352dch->tx_skb = NULL;353}354dch->tx_idx = 0;355if (dch->rx_skb) {356dev_kfree_skb(dch->rx_skb);357dch->rx_skb = NULL;358}359test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);360spin_unlock_irqrestore(&hw->lock, flags);361#ifdef FIXME362if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))363dchannel_sched_event(&hc->dch, D_CLEARBUSY);364#endif365ret = 0;366} else367ret = l1_event(dch->l1, hh->prim);368break;369case MPH_INFORMATION_REQ:370hfcsusb_ph_info(hw);371ret = 0;372break;373}374375return ret;376}377378/*379* Layer 1 callback function380*/381static int382hfc_l1callback(struct dchannel *dch, u_int cmd)383{384struct hfcsusb *hw = dch->hw;385386if (debug & DBG_HFC_CALL_TRACE)387printk(KERN_DEBUG "%s: %s cmd 0x%x\n",388hw->name, __func__, cmd);389390switch (cmd) {391case INFO3_P8:392case INFO3_P10:393case HW_RESET_REQ:394case HW_POWERUP_REQ:395break;396397case HW_DEACT_REQ:398skb_queue_purge(&dch->squeue);399if (dch->tx_skb) {400dev_kfree_skb(dch->tx_skb);401dch->tx_skb = NULL;402}403dch->tx_idx = 0;404if (dch->rx_skb) {405dev_kfree_skb(dch->rx_skb);406dch->rx_skb = NULL;407}408test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);409break;410case PH_ACTIVATE_IND:411test_and_set_bit(FLG_ACTIVE, &dch->Flags);412_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,413GFP_ATOMIC);414break;415case PH_DEACTIVATE_IND:416test_and_clear_bit(FLG_ACTIVE, &dch->Flags);417_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,418GFP_ATOMIC);419break;420default:421if (dch->debug & DEBUG_HW)422printk(KERN_DEBUG "%s: %s: unknown cmd %x\n",423hw->name, __func__, cmd);424return -1;425}426hfcsusb_ph_info(hw);427return 0;428}429430static int431open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,432struct channel_req *rq)433{434int err = 0;435436if (debug & DEBUG_HW_OPEN)437printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",438hw->name, __func__, hw->dch.dev.id, rq->adr.channel,439__builtin_return_address(0));440if (rq->protocol == ISDN_P_NONE)441return -EINVAL;442443test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags);444test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags);445hfcsusb_start_endpoint(hw, HFC_CHAN_D);446447/* E-Channel logging */448if (rq->adr.channel == 1) {449if (hw->fifos[HFCUSB_PCM_RX].pipe) {450hfcsusb_start_endpoint(hw, HFC_CHAN_E);451set_bit(FLG_ACTIVE, &hw->ech.Flags);452_queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,453MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);454} else455return -EINVAL;456}457458if (!hw->initdone) {459hw->protocol = rq->protocol;460if (rq->protocol == ISDN_P_TE_S0) {461err = create_l1(&hw->dch, hfc_l1callback);462if (err)463return err;464}465setPortMode(hw);466ch->protocol = rq->protocol;467hw->initdone = 1;468} else {469if (rq->protocol != ch->protocol)470return -EPROTONOSUPPORT;471}472473if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||474((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))475_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,4760, NULL, GFP_KERNEL);477rq->ch = ch;478if (!try_module_get(THIS_MODULE))479printk(KERN_WARNING "%s: %s: cannot get module\n",480hw->name, __func__);481return 0;482}483484static int485open_bchannel(struct hfcsusb *hw, struct channel_req *rq)486{487struct bchannel *bch;488489if (rq->adr.channel > 2)490return -EINVAL;491if (rq->protocol == ISDN_P_NONE)492return -EINVAL;493494if (debug & DBG_HFC_CALL_TRACE)495printk(KERN_DEBUG "%s: %s B%i\n",496hw->name, __func__, rq->adr.channel);497498bch = &hw->bch[rq->adr.channel - 1];499if (test_and_set_bit(FLG_OPEN, &bch->Flags))500return -EBUSY; /* b-channel can be only open once */501test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);502bch->ch.protocol = rq->protocol;503rq->ch = &bch->ch;504505/* start USB endpoint for bchannel */506if (rq->adr.channel == 1)507hfcsusb_start_endpoint(hw, HFC_CHAN_B1);508else509hfcsusb_start_endpoint(hw, HFC_CHAN_B2);510511if (!try_module_get(THIS_MODULE))512printk(KERN_WARNING "%s: %s:cannot get module\n",513hw->name, __func__);514return 0;515}516517static int518channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq)519{520int ret = 0;521522if (debug & DBG_HFC_CALL_TRACE)523printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n",524hw->name, __func__, (cq->op), (cq->channel));525526switch (cq->op) {527case MISDN_CTRL_GETOP:528cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |529MISDN_CTRL_DISCONNECT;530break;531default:532printk(KERN_WARNING "%s: %s: unknown Op %x\n",533hw->name, __func__, cq->op);534ret = -EINVAL;535break;536}537return ret;538}539540/*541* device control function542*/543static int544hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)545{546struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);547struct dchannel *dch = container_of(dev, struct dchannel, dev);548struct hfcsusb *hw = dch->hw;549struct channel_req *rq;550int err = 0;551552if (dch->debug & DEBUG_HW)553printk(KERN_DEBUG "%s: %s: cmd:%x %p\n",554hw->name, __func__, cmd, arg);555switch (cmd) {556case OPEN_CHANNEL:557rq = arg;558if ((rq->protocol == ISDN_P_TE_S0) ||559(rq->protocol == ISDN_P_NT_S0))560err = open_dchannel(hw, ch, rq);561else562err = open_bchannel(hw, rq);563if (!err)564hw->open++;565break;566case CLOSE_CHANNEL:567hw->open--;568if (debug & DEBUG_HW_OPEN)569printk(KERN_DEBUG570"%s: %s: dev(%d) close from %p (open %d)\n",571hw->name, __func__, hw->dch.dev.id,572__builtin_return_address(0), hw->open);573if (!hw->open) {574hfcsusb_stop_endpoint(hw, HFC_CHAN_D);575if (hw->fifos[HFCUSB_PCM_RX].pipe)576hfcsusb_stop_endpoint(hw, HFC_CHAN_E);577handle_led(hw, LED_POWER_ON);578}579module_put(THIS_MODULE);580break;581case CONTROL_CHANNEL:582err = channel_ctrl(hw, arg);583break;584default:585if (dch->debug & DEBUG_HW)586printk(KERN_DEBUG "%s: %s: unknown command %x\n",587hw->name, __func__, cmd);588return -EINVAL;589}590return err;591}592593/*594* S0 TE state change event handler595*/596static void597ph_state_te(struct dchannel *dch)598{599struct hfcsusb *hw = dch->hw;600601if (debug & DEBUG_HW) {602if (dch->state <= HFC_MAX_TE_LAYER1_STATE)603printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,604HFC_TE_LAYER1_STATES[dch->state]);605else606printk(KERN_DEBUG "%s: %s: TE F%d\n",607hw->name, __func__, dch->state);608}609610switch (dch->state) {611case 0:612l1_event(dch->l1, HW_RESET_IND);613break;614case 3:615l1_event(dch->l1, HW_DEACT_IND);616break;617case 5:618case 8:619l1_event(dch->l1, ANYSIGNAL);620break;621case 6:622l1_event(dch->l1, INFO2);623break;624case 7:625l1_event(dch->l1, INFO4_P8);626break;627}628if (dch->state == 7)629handle_led(hw, LED_S0_ON);630else631handle_led(hw, LED_S0_OFF);632}633634/*635* S0 NT state change event handler636*/637static void638ph_state_nt(struct dchannel *dch)639{640struct hfcsusb *hw = dch->hw;641642if (debug & DEBUG_HW) {643if (dch->state <= HFC_MAX_NT_LAYER1_STATE)644printk(KERN_DEBUG "%s: %s: %s\n",645hw->name, __func__,646HFC_NT_LAYER1_STATES[dch->state]);647648else649printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n",650hw->name, __func__, dch->state);651}652653switch (dch->state) {654case (1):655test_and_clear_bit(FLG_ACTIVE, &dch->Flags);656test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);657hw->nt_timer = 0;658hw->timers &= ~NT_ACTIVATION_TIMER;659handle_led(hw, LED_S0_OFF);660break;661662case (2):663if (hw->nt_timer < 0) {664hw->nt_timer = 0;665hw->timers &= ~NT_ACTIVATION_TIMER;666hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);667} else {668hw->timers |= NT_ACTIVATION_TIMER;669hw->nt_timer = NT_T1_COUNT;670/* allow G2 -> G3 transition */671write_reg(hw, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);672}673break;674case (3):675hw->nt_timer = 0;676hw->timers &= ~NT_ACTIVATION_TIMER;677test_and_set_bit(FLG_ACTIVE, &dch->Flags);678_queue_data(&dch->dev.D, PH_ACTIVATE_IND,679MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);680handle_led(hw, LED_S0_ON);681break;682case (4):683hw->nt_timer = 0;684hw->timers &= ~NT_ACTIVATION_TIMER;685break;686default:687break;688}689hfcsusb_ph_info(hw);690}691692static void693ph_state(struct dchannel *dch)694{695struct hfcsusb *hw = dch->hw;696697if (hw->protocol == ISDN_P_NT_S0)698ph_state_nt(dch);699else if (hw->protocol == ISDN_P_TE_S0)700ph_state_te(dch);701}702703/*704* disable/enable BChannel for desired protocoll705*/706static int707hfcsusb_setup_bch(struct bchannel *bch, int protocol)708{709struct hfcsusb *hw = bch->hw;710__u8 conhdlc, sctrl, sctrl_r;711712if (debug & DEBUG_HW)713printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n",714hw->name, __func__, bch->state, protocol,715bch->nr);716717/* setup val for CON_HDLC */718conhdlc = 0;719if (protocol > ISDN_P_NONE)720conhdlc = 8; /* enable FIFO */721722switch (protocol) {723case (-1): /* used for init */724bch->state = -1;725/* fall through */726case (ISDN_P_NONE):727if (bch->state == ISDN_P_NONE)728return 0; /* already in idle state */729bch->state = ISDN_P_NONE;730clear_bit(FLG_HDLC, &bch->Flags);731clear_bit(FLG_TRANSPARENT, &bch->Flags);732break;733case (ISDN_P_B_RAW):734conhdlc |= 2;735bch->state = protocol;736set_bit(FLG_TRANSPARENT, &bch->Flags);737break;738case (ISDN_P_B_HDLC):739bch->state = protocol;740set_bit(FLG_HDLC, &bch->Flags);741break;742default:743if (debug & DEBUG_HW)744printk(KERN_DEBUG "%s: %s: prot not known %x\n",745hw->name, __func__, protocol);746return -ENOPROTOOPT;747}748749if (protocol >= ISDN_P_NONE) {750write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 0 : 2);751write_reg(hw, HFCUSB_CON_HDLC, conhdlc);752write_reg(hw, HFCUSB_INC_RES_F, 2);753write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 1 : 3);754write_reg(hw, HFCUSB_CON_HDLC, conhdlc);755write_reg(hw, HFCUSB_INC_RES_F, 2);756757sctrl = 0x40 + ((hw->protocol == ISDN_P_TE_S0) ? 0x00 : 0x04);758sctrl_r = 0x0;759if (test_bit(FLG_ACTIVE, &hw->bch[0].Flags)) {760sctrl |= 1;761sctrl_r |= 1;762}763if (test_bit(FLG_ACTIVE, &hw->bch[1].Flags)) {764sctrl |= 2;765sctrl_r |= 2;766}767write_reg(hw, HFCUSB_SCTRL, sctrl);768write_reg(hw, HFCUSB_SCTRL_R, sctrl_r);769770if (protocol > ISDN_P_NONE)771handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON);772else773handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :774LED_B2_OFF);775}776hfcsusb_ph_info(hw);777return 0;778}779780static void781hfcsusb_ph_command(struct hfcsusb *hw, u_char command)782{783if (debug & DEBUG_HW)784printk(KERN_DEBUG "%s: %s: %x\n",785hw->name, __func__, command);786787switch (command) {788case HFC_L1_ACTIVATE_TE:789/* force sending sending INFO1 */790write_reg(hw, HFCUSB_STATES, 0x14);791/* start l1 activation */792write_reg(hw, HFCUSB_STATES, 0x04);793break;794795case HFC_L1_FORCE_DEACTIVATE_TE:796write_reg(hw, HFCUSB_STATES, 0x10);797write_reg(hw, HFCUSB_STATES, 0x03);798break;799800case HFC_L1_ACTIVATE_NT:801if (hw->dch.state == 3)802_queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND,803MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);804else805write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE |806HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);807break;808809case HFC_L1_DEACTIVATE_NT:810write_reg(hw, HFCUSB_STATES,811HFCUSB_DO_ACTION);812break;813}814}815816/*817* Layer 1 B-channel hardware access818*/819static int820channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)821{822int ret = 0;823824switch (cq->op) {825case MISDN_CTRL_GETOP:826cq->op = MISDN_CTRL_FILL_EMPTY;827break;828case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */829test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);830if (debug & DEBUG_HW_OPEN)831printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "832"off=%d)\n", __func__, bch->nr, !!cq->p1);833break;834default:835printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);836ret = -EINVAL;837break;838}839return ret;840}841842/* collect data from incoming interrupt or isochron USB data */843static void844hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,845int finish)846{847struct hfcsusb *hw = fifo->hw;848struct sk_buff *rx_skb = NULL;849int maxlen = 0;850int fifon = fifo->fifonum;851int i;852int hdlc = 0;853854if (debug & DBG_HFC_CALL_TRACE)855printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "856"dch(%p) bch(%p) ech(%p)\n",857hw->name, __func__, fifon, len,858fifo->dch, fifo->bch, fifo->ech);859860if (!len)861return;862863if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) {864printk(KERN_DEBUG "%s: %s: undefined channel\n",865hw->name, __func__);866return;867}868869spin_lock(&hw->lock);870if (fifo->dch) {871rx_skb = fifo->dch->rx_skb;872maxlen = fifo->dch->maxlen;873hdlc = 1;874}875if (fifo->bch) {876rx_skb = fifo->bch->rx_skb;877maxlen = fifo->bch->maxlen;878hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);879}880if (fifo->ech) {881rx_skb = fifo->ech->rx_skb;882maxlen = fifo->ech->maxlen;883hdlc = 1;884}885886if (!rx_skb) {887rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC);888if (rx_skb) {889if (fifo->dch)890fifo->dch->rx_skb = rx_skb;891if (fifo->bch)892fifo->bch->rx_skb = rx_skb;893if (fifo->ech)894fifo->ech->rx_skb = rx_skb;895skb_trim(rx_skb, 0);896} else {897printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",898hw->name, __func__);899spin_unlock(&hw->lock);900return;901}902}903904if (fifo->dch || fifo->ech) {905/* D/E-Channel SKB range check */906if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {907printk(KERN_DEBUG "%s: %s: sbk mem exceeded "908"for fifo(%d) HFCUSB_D_RX\n",909hw->name, __func__, fifon);910skb_trim(rx_skb, 0);911spin_unlock(&hw->lock);912return;913}914} else if (fifo->bch) {915/* B-Channel SKB range check */916if ((rx_skb->len + len) >= (MAX_BCH_SIZE + 3)) {917printk(KERN_DEBUG "%s: %s: sbk mem exceeded "918"for fifo(%d) HFCUSB_B_RX\n",919hw->name, __func__, fifon);920skb_trim(rx_skb, 0);921spin_unlock(&hw->lock);922return;923}924}925926memcpy(skb_put(rx_skb, len), data, len);927928if (hdlc) {929/* we have a complete hdlc packet */930if (finish) {931if ((rx_skb->len > 3) &&932(!(rx_skb->data[rx_skb->len - 1]))) {933if (debug & DBG_HFC_FIFO_VERBOSE) {934printk(KERN_DEBUG "%s: %s: fifon(%i)"935" new RX len(%i): ",936hw->name, __func__, fifon,937rx_skb->len);938i = 0;939while (i < rx_skb->len)940printk("%02x ",941rx_skb->data[i++]);942printk("\n");943}944945/* remove CRC & status */946skb_trim(rx_skb, rx_skb->len - 3);947948if (fifo->dch)949recv_Dchannel(fifo->dch);950if (fifo->bch)951recv_Bchannel(fifo->bch, MISDN_ID_ANY);952if (fifo->ech)953recv_Echannel(fifo->ech,954&hw->dch);955} else {956if (debug & DBG_HFC_FIFO_VERBOSE) {957printk(KERN_DEBUG958"%s: CRC or minlen ERROR fifon(%i) "959"RX len(%i): ",960hw->name, fifon, rx_skb->len);961i = 0;962while (i < rx_skb->len)963printk("%02x ",964rx_skb->data[i++]);965printk("\n");966}967skb_trim(rx_skb, 0);968}969}970} else {971/* deliver transparent data to layer2 */972if (rx_skb->len >= poll)973recv_Bchannel(fifo->bch, MISDN_ID_ANY);974}975spin_unlock(&hw->lock);976}977978static void979fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,980void *buf, int num_packets, int packet_size, int interval,981usb_complete_t complete, void *context)982{983int k;984985usb_fill_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets,986complete, context);987988urb->number_of_packets = num_packets;989urb->transfer_flags = URB_ISO_ASAP;990urb->actual_length = 0;991urb->interval = interval;992993for (k = 0; k < num_packets; k++) {994urb->iso_frame_desc[k].offset = packet_size * k;995urb->iso_frame_desc[k].length = packet_size;996urb->iso_frame_desc[k].actual_length = 0;997}998}9991000/* receive completion routine for all ISO tx fifos */1001static void1002rx_iso_complete(struct urb *urb)1003{1004struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;1005struct usb_fifo *fifo = context_iso_urb->owner_fifo;1006struct hfcsusb *hw = fifo->hw;1007int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,1008status, iso_status, i;1009__u8 *buf;1010static __u8 eof[8];1011__u8 s0_state;10121013fifon = fifo->fifonum;1014status = urb->status;10151016spin_lock(&hw->lock);1017if (fifo->stop_gracefull) {1018fifo->stop_gracefull = 0;1019fifo->active = 0;1020spin_unlock(&hw->lock);1021return;1022}1023spin_unlock(&hw->lock);10241025/*1026* ISO transfer only partially completed,1027* look at individual frame status for details1028*/1029if (status == -EXDEV) {1030if (debug & DEBUG_HW)1031printk(KERN_DEBUG "%s: %s: with -EXDEV "1032"urb->status %d, fifonum %d\n",1033hw->name, __func__, status, fifon);10341035/* clear status, so go on with ISO transfers */1036status = 0;1037}10381039s0_state = 0;1040if (fifo->active && !status) {1041num_isoc_packets = iso_packets[fifon];1042maxlen = fifo->usb_packet_maxlen;10431044for (k = 0; k < num_isoc_packets; ++k) {1045len = urb->iso_frame_desc[k].actual_length;1046offset = urb->iso_frame_desc[k].offset;1047buf = context_iso_urb->buffer + offset;1048iso_status = urb->iso_frame_desc[k].status;10491050if (iso_status && (debug & DBG_HFC_FIFO_VERBOSE)) {1051printk(KERN_DEBUG "%s: %s: "1052"ISO packet %i, status: %i\n",1053hw->name, __func__, k, iso_status);1054}10551056/* USB data log for every D ISO in */1057if ((fifon == HFCUSB_D_RX) &&1058(debug & DBG_HFC_USB_VERBOSE)) {1059printk(KERN_DEBUG1060"%s: %s: %d (%d/%d) len(%d) ",1061hw->name, __func__, urb->start_frame,1062k, num_isoc_packets-1,1063len);1064for (i = 0; i < len; i++)1065printk("%x ", buf[i]);1066printk("\n");1067}10681069if (!iso_status) {1070if (fifo->last_urblen != maxlen) {1071/*1072* save fifo fill-level threshold bits1073* to use them later in TX ISO URB1074* completions1075*/1076hw->threshold_mask = buf[1];10771078if (fifon == HFCUSB_D_RX)1079s0_state = (buf[0] >> 4);10801081eof[fifon] = buf[0] & 1;1082if (len > 2)1083hfcsusb_rx_frame(fifo, buf + 2,1084len - 2, (len < maxlen)1085? eof[fifon] : 0);1086} else1087hfcsusb_rx_frame(fifo, buf, len,1088(len < maxlen) ?1089eof[fifon] : 0);1090fifo->last_urblen = len;1091}1092}10931094/* signal S0 layer1 state change */1095if ((s0_state) && (hw->initdone) &&1096(s0_state != hw->dch.state)) {1097hw->dch.state = s0_state;1098schedule_event(&hw->dch, FLG_PHCHANGE);1099}11001101fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,1102context_iso_urb->buffer, num_isoc_packets,1103fifo->usb_packet_maxlen, fifo->intervall,1104(usb_complete_t)rx_iso_complete, urb->context);1105errcode = usb_submit_urb(urb, GFP_ATOMIC);1106if (errcode < 0) {1107if (debug & DEBUG_HW)1108printk(KERN_DEBUG "%s: %s: error submitting "1109"ISO URB: %d\n",1110hw->name, __func__, errcode);1111}1112} else {1113if (status && (debug & DBG_HFC_URB_INFO))1114printk(KERN_DEBUG "%s: %s: rx_iso_complete : "1115"urb->status %d, fifonum %d\n",1116hw->name, __func__, status, fifon);1117}1118}11191120/* receive completion routine for all interrupt rx fifos */1121static void1122rx_int_complete(struct urb *urb)1123{1124int len, status, i;1125__u8 *buf, maxlen, fifon;1126struct usb_fifo *fifo = (struct usb_fifo *) urb->context;1127struct hfcsusb *hw = fifo->hw;1128static __u8 eof[8];11291130spin_lock(&hw->lock);1131if (fifo->stop_gracefull) {1132fifo->stop_gracefull = 0;1133fifo->active = 0;1134spin_unlock(&hw->lock);1135return;1136}1137spin_unlock(&hw->lock);11381139fifon = fifo->fifonum;1140if ((!fifo->active) || (urb->status)) {1141if (debug & DBG_HFC_URB_ERROR)1142printk(KERN_DEBUG1143"%s: %s: RX-Fifo %i is going down (%i)\n",1144hw->name, __func__, fifon, urb->status);11451146fifo->urb->interval = 0; /* cancel automatic rescheduling */1147return;1148}1149len = urb->actual_length;1150buf = fifo->buffer;1151maxlen = fifo->usb_packet_maxlen;11521153/* USB data log for every D INT in */1154if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) {1155printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ",1156hw->name, __func__, len);1157for (i = 0; i < len; i++)1158printk("%02x ", buf[i]);1159printk("\n");1160}11611162if (fifo->last_urblen != fifo->usb_packet_maxlen) {1163/* the threshold mask is in the 2nd status byte */1164hw->threshold_mask = buf[1];11651166/* signal S0 layer1 state change */1167if (hw->initdone && ((buf[0] >> 4) != hw->dch.state)) {1168hw->dch.state = (buf[0] >> 4);1169schedule_event(&hw->dch, FLG_PHCHANGE);1170}11711172eof[fifon] = buf[0] & 1;1173/* if we have more than the 2 status bytes -> collect data */1174if (len > 2)1175hfcsusb_rx_frame(fifo, buf + 2,1176urb->actual_length - 2,1177(len < maxlen) ? eof[fifon] : 0);1178} else {1179hfcsusb_rx_frame(fifo, buf, urb->actual_length,1180(len < maxlen) ? eof[fifon] : 0);1181}1182fifo->last_urblen = urb->actual_length;11831184status = usb_submit_urb(urb, GFP_ATOMIC);1185if (status) {1186if (debug & DEBUG_HW)1187printk(KERN_DEBUG "%s: %s: error resubmitting USB\n",1188hw->name, __func__);1189}1190}11911192/* transmit completion routine for all ISO tx fifos */1193static void1194tx_iso_complete(struct urb *urb)1195{1196struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context;1197struct usb_fifo *fifo = context_iso_urb->owner_fifo;1198struct hfcsusb *hw = fifo->hw;1199struct sk_buff *tx_skb;1200int k, tx_offset, num_isoc_packets, sink, remain, current_len,1201errcode, hdlc, i;1202int *tx_idx;1203int frame_complete, fifon, status;1204__u8 threshbit;12051206spin_lock(&hw->lock);1207if (fifo->stop_gracefull) {1208fifo->stop_gracefull = 0;1209fifo->active = 0;1210spin_unlock(&hw->lock);1211return;1212}12131214if (fifo->dch) {1215tx_skb = fifo->dch->tx_skb;1216tx_idx = &fifo->dch->tx_idx;1217hdlc = 1;1218} else if (fifo->bch) {1219tx_skb = fifo->bch->tx_skb;1220tx_idx = &fifo->bch->tx_idx;1221hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);1222} else {1223printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",1224hw->name, __func__);1225spin_unlock(&hw->lock);1226return;1227}12281229fifon = fifo->fifonum;1230status = urb->status;12311232tx_offset = 0;12331234/*1235* ISO transfer only partially completed,1236* look at individual frame status for details1237*/1238if (status == -EXDEV) {1239if (debug & DBG_HFC_URB_ERROR)1240printk(KERN_DEBUG "%s: %s: "1241"-EXDEV (%i) fifon (%d)\n",1242hw->name, __func__, status, fifon);12431244/* clear status, so go on with ISO transfers */1245status = 0;1246}12471248if (fifo->active && !status) {1249/* is FifoFull-threshold set for our channel? */1250threshbit = (hw->threshold_mask & (1 << fifon));1251num_isoc_packets = iso_packets[fifon];12521253/* predict dataflow to avoid fifo overflow */1254if (fifon >= HFCUSB_D_TX)1255sink = (threshbit) ? SINK_DMIN : SINK_DMAX;1256else1257sink = (threshbit) ? SINK_MIN : SINK_MAX;1258fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe,1259context_iso_urb->buffer, num_isoc_packets,1260fifo->usb_packet_maxlen, fifo->intervall,1261(usb_complete_t)tx_iso_complete, urb->context);1262memset(context_iso_urb->buffer, 0,1263sizeof(context_iso_urb->buffer));1264frame_complete = 0;12651266for (k = 0; k < num_isoc_packets; ++k) {1267/* analyze tx success of previous ISO packets */1268if (debug & DBG_HFC_URB_ERROR) {1269errcode = urb->iso_frame_desc[k].status;1270if (errcode) {1271printk(KERN_DEBUG "%s: %s: "1272"ISO packet %i, status: %i\n",1273hw->name, __func__, k, errcode);1274}1275}12761277/* Generate next ISO Packets */1278if (tx_skb)1279remain = tx_skb->len - *tx_idx;1280else1281remain = 0;12821283if (remain > 0) {1284fifo->bit_line -= sink;1285current_len = (0 - fifo->bit_line) / 8;1286if (current_len > 14)1287current_len = 14;1288if (current_len < 0)1289current_len = 0;1290if (remain < current_len)1291current_len = remain;12921293/* how much bit do we put on the line? */1294fifo->bit_line += current_len * 8;12951296context_iso_urb->buffer[tx_offset] = 0;1297if (current_len == remain) {1298if (hdlc) {1299/* signal frame completion */1300context_iso_urb->1301buffer[tx_offset] = 1;1302/* add 2 byte flags and 16bit1303* CRC at end of ISDN frame */1304fifo->bit_line += 32;1305}1306frame_complete = 1;1307}13081309/* copy tx data to iso-urb buffer */1310memcpy(context_iso_urb->buffer + tx_offset + 1,1311(tx_skb->data + *tx_idx), current_len);1312*tx_idx += current_len;13131314urb->iso_frame_desc[k].offset = tx_offset;1315urb->iso_frame_desc[k].length = current_len + 1;13161317/* USB data log for every D ISO out */1318if ((fifon == HFCUSB_D_RX) &&1319(debug & DBG_HFC_USB_VERBOSE)) {1320printk(KERN_DEBUG1321"%s: %s (%d/%d) offs(%d) len(%d) ",1322hw->name, __func__,1323k, num_isoc_packets-1,1324urb->iso_frame_desc[k].offset,1325urb->iso_frame_desc[k].length);13261327for (i = urb->iso_frame_desc[k].offset;1328i < (urb->iso_frame_desc[k].offset1329+ urb->iso_frame_desc[k].length);1330i++)1331printk("%x ",1332context_iso_urb->buffer[i]);13331334printk(" skb->len(%i) tx-idx(%d)\n",1335tx_skb->len, *tx_idx);1336}13371338tx_offset += (current_len + 1);1339} else {1340urb->iso_frame_desc[k].offset = tx_offset++;1341urb->iso_frame_desc[k].length = 1;1342/* we lower data margin every msec */1343fifo->bit_line -= sink;1344if (fifo->bit_line < BITLINE_INF)1345fifo->bit_line = BITLINE_INF;1346}13471348if (frame_complete) {1349frame_complete = 0;13501351if (debug & DBG_HFC_FIFO_VERBOSE) {1352printk(KERN_DEBUG "%s: %s: "1353"fifon(%i) new TX len(%i): ",1354hw->name, __func__,1355fifon, tx_skb->len);1356i = 0;1357while (i < tx_skb->len)1358printk("%02x ",1359tx_skb->data[i++]);1360printk("\n");1361}13621363dev_kfree_skb(tx_skb);1364tx_skb = NULL;1365if (fifo->dch && get_next_dframe(fifo->dch))1366tx_skb = fifo->dch->tx_skb;1367else if (fifo->bch &&1368get_next_bframe(fifo->bch)) {1369if (test_bit(FLG_TRANSPARENT,1370&fifo->bch->Flags))1371confirm_Bsend(fifo->bch);1372tx_skb = fifo->bch->tx_skb;1373}1374}1375}1376errcode = usb_submit_urb(urb, GFP_ATOMIC);1377if (errcode < 0) {1378if (debug & DEBUG_HW)1379printk(KERN_DEBUG1380"%s: %s: error submitting ISO URB: %d \n",1381hw->name, __func__, errcode);1382}13831384/*1385* abuse DChannel tx iso completion to trigger NT mode state1386* changes tx_iso_complete is assumed to be called every1387* fifo->intervall (ms)1388*/1389if ((fifon == HFCUSB_D_TX) && (hw->protocol == ISDN_P_NT_S0)1390&& (hw->timers & NT_ACTIVATION_TIMER)) {1391if ((--hw->nt_timer) < 0)1392schedule_event(&hw->dch, FLG_PHCHANGE);1393}13941395} else {1396if (status && (debug & DBG_HFC_URB_ERROR))1397printk(KERN_DEBUG "%s: %s: urb->status %s (%i)"1398"fifonum=%d\n",1399hw->name, __func__,1400symbolic(urb_errlist, status), status, fifon);1401}1402spin_unlock(&hw->lock);1403}14041405/*1406* allocs urbs and start isoc transfer with two pending urbs to avoid1407* gaps in the transfer chain1408*/1409static int1410start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,1411usb_complete_t complete, int packet_size)1412{1413struct hfcsusb *hw = fifo->hw;1414int i, k, errcode;14151416if (debug)1417printk(KERN_DEBUG "%s: %s: fifo %i\n",1418hw->name, __func__, fifo->fifonum);14191420/* allocate Memory for Iso out Urbs */1421for (i = 0; i < 2; i++) {1422if (!(fifo->iso[i].urb)) {1423fifo->iso[i].urb =1424usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);1425if (!(fifo->iso[i].urb)) {1426printk(KERN_DEBUG1427"%s: %s: alloc urb for fifo %i failed",1428hw->name, __func__, fifo->fifonum);1429}1430fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;1431fifo->iso[i].indx = i;14321433/* Init the first iso */1434if (ISO_BUFFER_SIZE >=1435(fifo->usb_packet_maxlen *1436num_packets_per_urb)) {1437fill_isoc_urb(fifo->iso[i].urb,1438fifo->hw->dev, fifo->pipe,1439fifo->iso[i].buffer,1440num_packets_per_urb,1441fifo->usb_packet_maxlen,1442fifo->intervall, complete,1443&fifo->iso[i]);1444memset(fifo->iso[i].buffer, 0,1445sizeof(fifo->iso[i].buffer));14461447for (k = 0; k < num_packets_per_urb; k++) {1448fifo->iso[i].urb->1449iso_frame_desc[k].offset =1450k * packet_size;1451fifo->iso[i].urb->1452iso_frame_desc[k].length =1453packet_size;1454}1455} else {1456printk(KERN_DEBUG1457"%s: %s: ISO Buffer size to small!\n",1458hw->name, __func__);1459}1460}1461fifo->bit_line = BITLINE_INF;14621463errcode = usb_submit_urb(fifo->iso[i].urb, GFP_KERNEL);1464fifo->active = (errcode >= 0) ? 1 : 0;1465fifo->stop_gracefull = 0;1466if (errcode < 0) {1467printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n",1468hw->name, __func__,1469symbolic(urb_errlist, errcode), i);1470}1471}1472return fifo->active;1473}14741475static void1476stop_iso_gracefull(struct usb_fifo *fifo)1477{1478struct hfcsusb *hw = fifo->hw;1479int i, timeout;1480u_long flags;14811482for (i = 0; i < 2; i++) {1483spin_lock_irqsave(&hw->lock, flags);1484if (debug)1485printk(KERN_DEBUG "%s: %s for fifo %i.%i\n",1486hw->name, __func__, fifo->fifonum, i);1487fifo->stop_gracefull = 1;1488spin_unlock_irqrestore(&hw->lock, flags);1489}14901491for (i = 0; i < 2; i++) {1492timeout = 3;1493while (fifo->stop_gracefull && timeout--)1494schedule_timeout_interruptible((HZ/1000)*16);1495if (debug && fifo->stop_gracefull)1496printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n",1497hw->name, __func__, fifo->fifonum, i);1498}1499}15001501static void1502stop_int_gracefull(struct usb_fifo *fifo)1503{1504struct hfcsusb *hw = fifo->hw;1505int timeout;1506u_long flags;15071508spin_lock_irqsave(&hw->lock, flags);1509if (debug)1510printk(KERN_DEBUG "%s: %s for fifo %i\n",1511hw->name, __func__, fifo->fifonum);1512fifo->stop_gracefull = 1;1513spin_unlock_irqrestore(&hw->lock, flags);15141515timeout = 3;1516while (fifo->stop_gracefull && timeout--)1517schedule_timeout_interruptible((HZ/1000)*3);1518if (debug && fifo->stop_gracefull)1519printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n",1520hw->name, __func__, fifo->fifonum);1521}15221523/* start the interrupt transfer for the given fifo */1524static void1525start_int_fifo(struct usb_fifo *fifo)1526{1527struct hfcsusb *hw = fifo->hw;1528int errcode;15291530if (debug)1531printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n",1532hw->name, __func__, fifo->fifonum);15331534if (!fifo->urb) {1535fifo->urb = usb_alloc_urb(0, GFP_KERNEL);1536if (!fifo->urb)1537return;1538}1539usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe,1540fifo->buffer, fifo->usb_packet_maxlen,1541(usb_complete_t)rx_int_complete, fifo, fifo->intervall);1542fifo->active = 1;1543fifo->stop_gracefull = 0;1544errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);1545if (errcode) {1546printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n",1547hw->name, __func__, errcode);1548fifo->active = 0;1549}1550}15511552static void1553setPortMode(struct hfcsusb *hw)1554{1555if (debug & DEBUG_HW)1556printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__,1557(hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");15581559if (hw->protocol == ISDN_P_TE_S0) {1560write_reg(hw, HFCUSB_SCTRL, 0x40);1561write_reg(hw, HFCUSB_SCTRL_E, 0x00);1562write_reg(hw, HFCUSB_CLKDEL, CLKDEL_TE);1563write_reg(hw, HFCUSB_STATES, 3 | 0x10);1564write_reg(hw, HFCUSB_STATES, 3);1565} else {1566write_reg(hw, HFCUSB_SCTRL, 0x44);1567write_reg(hw, HFCUSB_SCTRL_E, 0x09);1568write_reg(hw, HFCUSB_CLKDEL, CLKDEL_NT);1569write_reg(hw, HFCUSB_STATES, 1 | 0x10);1570write_reg(hw, HFCUSB_STATES, 1);1571}1572}15731574static void1575reset_hfcsusb(struct hfcsusb *hw)1576{1577struct usb_fifo *fifo;1578int i;15791580if (debug & DEBUG_HW)1581printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);15821583/* do Chip reset */1584write_reg(hw, HFCUSB_CIRM, 8);15851586/* aux = output, reset off */1587write_reg(hw, HFCUSB_CIRM, 0x10);15881589/* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */1590write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) |1591((hw->packet_size / 8) << 4));15921593/* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */1594write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size);15951596/* enable PCM/GCI master mode */1597write_reg(hw, HFCUSB_MST_MODE1, 0); /* set default values */1598write_reg(hw, HFCUSB_MST_MODE0, 1); /* enable master mode */15991600/* init the fifos */1601write_reg(hw, HFCUSB_F_THRES,1602(HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));16031604fifo = hw->fifos;1605for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {1606write_reg(hw, HFCUSB_FIFO, i); /* select the desired fifo */1607fifo[i].max_size =1608(i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;1609fifo[i].last_urblen = 0;16101611/* set 2 bit for D- & E-channel */1612write_reg(hw, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2));16131614/* enable all fifos */1615if (i == HFCUSB_D_TX)1616write_reg(hw, HFCUSB_CON_HDLC,1617(hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);1618else1619write_reg(hw, HFCUSB_CON_HDLC, 0x08);1620write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */1621}16221623write_reg(hw, HFCUSB_SCTRL_R, 0); /* disable both B receivers */1624handle_led(hw, LED_POWER_ON);1625}16261627/* start USB data pipes dependand on device's endpoint configuration */1628static void1629hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)1630{1631/* quick check if endpoint already running */1632if ((channel == HFC_CHAN_D) && (hw->fifos[HFCUSB_D_RX].active))1633return;1634if ((channel == HFC_CHAN_B1) && (hw->fifos[HFCUSB_B1_RX].active))1635return;1636if ((channel == HFC_CHAN_B2) && (hw->fifos[HFCUSB_B2_RX].active))1637return;1638if ((channel == HFC_CHAN_E) && (hw->fifos[HFCUSB_PCM_RX].active))1639return;16401641/* start rx endpoints using USB INT IN method */1642if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)1643start_int_fifo(hw->fifos + channel*2 + 1);16441645/* start rx endpoints using USB ISO IN method */1646if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) {1647switch (channel) {1648case HFC_CHAN_D:1649start_isoc_chain(hw->fifos + HFCUSB_D_RX,1650ISOC_PACKETS_D,1651(usb_complete_t)rx_iso_complete,165216);1653break;1654case HFC_CHAN_E:1655start_isoc_chain(hw->fifos + HFCUSB_PCM_RX,1656ISOC_PACKETS_D,1657(usb_complete_t)rx_iso_complete,165816);1659break;1660case HFC_CHAN_B1:1661start_isoc_chain(hw->fifos + HFCUSB_B1_RX,1662ISOC_PACKETS_B,1663(usb_complete_t)rx_iso_complete,166416);1665break;1666case HFC_CHAN_B2:1667start_isoc_chain(hw->fifos + HFCUSB_B2_RX,1668ISOC_PACKETS_B,1669(usb_complete_t)rx_iso_complete,167016);1671break;1672}1673}16741675/* start tx endpoints using USB ISO OUT method */1676switch (channel) {1677case HFC_CHAN_D:1678start_isoc_chain(hw->fifos + HFCUSB_D_TX,1679ISOC_PACKETS_B,1680(usb_complete_t)tx_iso_complete, 1);1681break;1682case HFC_CHAN_B1:1683start_isoc_chain(hw->fifos + HFCUSB_B1_TX,1684ISOC_PACKETS_D,1685(usb_complete_t)tx_iso_complete, 1);1686break;1687case HFC_CHAN_B2:1688start_isoc_chain(hw->fifos + HFCUSB_B2_TX,1689ISOC_PACKETS_B,1690(usb_complete_t)tx_iso_complete, 1);1691break;1692}1693}16941695/* stop USB data pipes dependand on device's endpoint configuration */1696static void1697hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)1698{1699/* quick check if endpoint currently running */1700if ((channel == HFC_CHAN_D) && (!hw->fifos[HFCUSB_D_RX].active))1701return;1702if ((channel == HFC_CHAN_B1) && (!hw->fifos[HFCUSB_B1_RX].active))1703return;1704if ((channel == HFC_CHAN_B2) && (!hw->fifos[HFCUSB_B2_RX].active))1705return;1706if ((channel == HFC_CHAN_E) && (!hw->fifos[HFCUSB_PCM_RX].active))1707return;17081709/* rx endpoints using USB INT IN method */1710if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)1711stop_int_gracefull(hw->fifos + channel*2 + 1);17121713/* rx endpoints using USB ISO IN method */1714if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO)1715stop_iso_gracefull(hw->fifos + channel*2 + 1);17161717/* tx endpoints using USB ISO OUT method */1718if (channel != HFC_CHAN_E)1719stop_iso_gracefull(hw->fifos + channel*2);1720}172117221723/* Hardware Initialization */1724static int1725setup_hfcsusb(struct hfcsusb *hw)1726{1727u_char b;17281729if (debug & DBG_HFC_CALL_TRACE)1730printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);17311732/* check the chip id */1733if (read_reg_atomic(hw, HFCUSB_CHIP_ID, &b) != 1) {1734printk(KERN_DEBUG "%s: %s: cannot read chip id\n",1735hw->name, __func__);1736return 1;1737}1738if (b != HFCUSB_CHIPID) {1739printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n",1740hw->name, __func__, b);1741return 1;1742}17431744/* first set the needed config, interface and alternate */1745(void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);17461747hw->led_state = 0;17481749/* init the background machinery for control requests */1750hw->ctrl_read.bRequestType = 0xc0;1751hw->ctrl_read.bRequest = 1;1752hw->ctrl_read.wLength = cpu_to_le16(1);1753hw->ctrl_write.bRequestType = 0x40;1754hw->ctrl_write.bRequest = 0;1755hw->ctrl_write.wLength = 0;1756usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe,1757(u_char *)&hw->ctrl_write, NULL, 0,1758(usb_complete_t)ctrl_complete, hw);17591760reset_hfcsusb(hw);1761return 0;1762}17631764static void1765release_hw(struct hfcsusb *hw)1766{1767if (debug & DBG_HFC_CALL_TRACE)1768printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);17691770/*1771* stop all endpoints gracefully1772* TODO: mISDN_core should generate CLOSE_CHANNEL1773* signals after calling mISDN_unregister_device()1774*/1775hfcsusb_stop_endpoint(hw, HFC_CHAN_D);1776hfcsusb_stop_endpoint(hw, HFC_CHAN_B1);1777hfcsusb_stop_endpoint(hw, HFC_CHAN_B2);1778if (hw->fifos[HFCUSB_PCM_RX].pipe)1779hfcsusb_stop_endpoint(hw, HFC_CHAN_E);1780if (hw->protocol == ISDN_P_TE_S0)1781l1_event(hw->dch.l1, CLOSE_CHANNEL);17821783mISDN_unregister_device(&hw->dch.dev);1784mISDN_freebchannel(&hw->bch[1]);1785mISDN_freebchannel(&hw->bch[0]);1786mISDN_freedchannel(&hw->dch);17871788if (hw->ctrl_urb) {1789usb_kill_urb(hw->ctrl_urb);1790usb_free_urb(hw->ctrl_urb);1791hw->ctrl_urb = NULL;1792}17931794if (hw->intf)1795usb_set_intfdata(hw->intf, NULL);1796list_del(&hw->list);1797kfree(hw);1798hw = NULL;1799}18001801static void1802deactivate_bchannel(struct bchannel *bch)1803{1804struct hfcsusb *hw = bch->hw;1805u_long flags;18061807if (bch->debug & DEBUG_HW)1808printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n",1809hw->name, __func__, bch->nr);18101811spin_lock_irqsave(&hw->lock, flags);1812mISDN_clear_bchannel(bch);1813spin_unlock_irqrestore(&hw->lock, flags);1814hfcsusb_setup_bch(bch, ISDN_P_NONE);1815hfcsusb_stop_endpoint(hw, bch->nr);1816}18171818/*1819* Layer 1 B-channel hardware access1820*/1821static int1822hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)1823{1824struct bchannel *bch = container_of(ch, struct bchannel, ch);1825int ret = -EINVAL;18261827if (bch->debug & DEBUG_HW)1828printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);18291830switch (cmd) {1831case HW_TESTRX_RAW:1832case HW_TESTRX_HDLC:1833case HW_TESTRX_OFF:1834ret = -EINVAL;1835break;18361837case CLOSE_CHANNEL:1838test_and_clear_bit(FLG_OPEN, &bch->Flags);1839if (test_bit(FLG_ACTIVE, &bch->Flags))1840deactivate_bchannel(bch);1841ch->protocol = ISDN_P_NONE;1842ch->peer = NULL;1843module_put(THIS_MODULE);1844ret = 0;1845break;1846case CONTROL_CHANNEL:1847ret = channel_bctrl(bch, arg);1848break;1849default:1850printk(KERN_WARNING "%s: unknown prim(%x)\n",1851__func__, cmd);1852}1853return ret;1854}18551856static int1857setup_instance(struct hfcsusb *hw, struct device *parent)1858{1859u_long flags;1860int err, i;18611862if (debug & DBG_HFC_CALL_TRACE)1863printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);18641865spin_lock_init(&hw->ctrl_lock);1866spin_lock_init(&hw->lock);18671868mISDN_initdchannel(&hw->dch, MAX_DFRAME_LEN_L1, ph_state);1869hw->dch.debug = debug & 0xFFFF;1870hw->dch.hw = hw;1871hw->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);1872hw->dch.dev.D.send = hfcusb_l2l1D;1873hw->dch.dev.D.ctrl = hfc_dctrl;18741875/* enable E-Channel logging */1876if (hw->fifos[HFCUSB_PCM_RX].pipe)1877mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL);18781879hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |1880(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));1881hw->dch.dev.nrbchan = 2;1882for (i = 0; i < 2; i++) {1883hw->bch[i].nr = i + 1;1884set_channelmap(i + 1, hw->dch.dev.channelmap);1885hw->bch[i].debug = debug;1886mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM);1887hw->bch[i].hw = hw;1888hw->bch[i].ch.send = hfcusb_l2l1B;1889hw->bch[i].ch.ctrl = hfc_bctrl;1890hw->bch[i].ch.nr = i + 1;1891list_add(&hw->bch[i].ch.list, &hw->dch.dev.bchannels);1892}18931894hw->fifos[HFCUSB_B1_TX].bch = &hw->bch[0];1895hw->fifos[HFCUSB_B1_RX].bch = &hw->bch[0];1896hw->fifos[HFCUSB_B2_TX].bch = &hw->bch[1];1897hw->fifos[HFCUSB_B2_RX].bch = &hw->bch[1];1898hw->fifos[HFCUSB_D_TX].dch = &hw->dch;1899hw->fifos[HFCUSB_D_RX].dch = &hw->dch;1900hw->fifos[HFCUSB_PCM_RX].ech = &hw->ech;1901hw->fifos[HFCUSB_PCM_TX].ech = &hw->ech;19021903err = setup_hfcsusb(hw);1904if (err)1905goto out;19061907snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME,1908hfcsusb_cnt + 1);1909printk(KERN_INFO "%s: registered as '%s'\n",1910DRIVER_NAME, hw->name);19111912err = mISDN_register_device(&hw->dch.dev, parent, hw->name);1913if (err)1914goto out;19151916hfcsusb_cnt++;1917write_lock_irqsave(&HFClock, flags);1918list_add_tail(&hw->list, &HFClist);1919write_unlock_irqrestore(&HFClock, flags);1920return 0;19211922out:1923mISDN_freebchannel(&hw->bch[1]);1924mISDN_freebchannel(&hw->bch[0]);1925mISDN_freedchannel(&hw->dch);1926kfree(hw);1927return err;1928}19291930static int1931hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)1932{1933struct hfcsusb *hw;1934struct usb_device *dev = interface_to_usbdev(intf);1935struct usb_host_interface *iface = intf->cur_altsetting;1936struct usb_host_interface *iface_used = NULL;1937struct usb_host_endpoint *ep;1938struct hfcsusb_vdata *driver_info;1939int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx,1940probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,1941ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,1942alt_used = 0;19431944vend_idx = 0xffff;1945for (i = 0; hfcsusb_idtab[i].idVendor; i++) {1946if ((le16_to_cpu(dev->descriptor.idVendor)1947== hfcsusb_idtab[i].idVendor) &&1948(le16_to_cpu(dev->descriptor.idProduct)1949== hfcsusb_idtab[i].idProduct)) {1950vend_idx = i;1951continue;1952}1953}19541955printk(KERN_DEBUG1956"%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",1957__func__, ifnum, iface->desc.bAlternateSetting,1958intf->minor, vend_idx);19591960if (vend_idx == 0xffff) {1961printk(KERN_WARNING1962"%s: no valid vendor found in USB descriptor\n",1963__func__);1964return -EIO;1965}1966/* if vendor and product ID is OK, start probing alternate settings */1967alt_idx = 0;1968small_match = -1;19691970/* default settings */1971iso_packet_size = 16;1972packet_size = 64;19731974while (alt_idx < intf->num_altsetting) {1975iface = intf->altsetting + alt_idx;1976probe_alt_setting = iface->desc.bAlternateSetting;1977cfg_used = 0;19781979while (validconf[cfg_used][0]) {1980cfg_found = 1;1981vcf = validconf[cfg_used];1982ep = iface->endpoint;1983memcpy(cmptbl, vcf, 16 * sizeof(int));19841985/* check for all endpoints in this alternate setting */1986for (i = 0; i < iface->desc.bNumEndpoints; i++) {1987ep_addr = ep->desc.bEndpointAddress;19881989/* get endpoint base */1990idx = ((ep_addr & 0x7f) - 1) * 2;1991if (ep_addr & 0x80)1992idx++;1993attr = ep->desc.bmAttributes;19941995if (cmptbl[idx] != EP_NOP) {1996if (cmptbl[idx] == EP_NUL)1997cfg_found = 0;1998if (attr == USB_ENDPOINT_XFER_INT1999&& cmptbl[idx] == EP_INT)2000cmptbl[idx] = EP_NUL;2001if (attr == USB_ENDPOINT_XFER_BULK2002&& cmptbl[idx] == EP_BLK)2003cmptbl[idx] = EP_NUL;2004if (attr == USB_ENDPOINT_XFER_ISOC2005&& cmptbl[idx] == EP_ISO)2006cmptbl[idx] = EP_NUL;20072008if (attr == USB_ENDPOINT_XFER_INT &&2009ep->desc.bInterval < vcf[17]) {2010cfg_found = 0;2011}2012}2013ep++;2014}20152016for (i = 0; i < 16; i++)2017if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL)2018cfg_found = 0;20192020if (cfg_found) {2021if (small_match < cfg_used) {2022small_match = cfg_used;2023alt_used = probe_alt_setting;2024iface_used = iface;2025}2026}2027cfg_used++;2028}2029alt_idx++;2030} /* (alt_idx < intf->num_altsetting) */20312032/* not found a valid USB Ta Endpoint config */2033if (small_match == -1)2034return -EIO;20352036iface = iface_used;2037hw = kzalloc(sizeof(struct hfcsusb), GFP_KERNEL);2038if (!hw)2039return -ENOMEM; /* got no mem */2040snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME);20412042ep = iface->endpoint;2043vcf = validconf[small_match];20442045for (i = 0; i < iface->desc.bNumEndpoints; i++) {2046struct usb_fifo *f;20472048ep_addr = ep->desc.bEndpointAddress;2049/* get endpoint base */2050idx = ((ep_addr & 0x7f) - 1) * 2;2051if (ep_addr & 0x80)2052idx++;2053f = &hw->fifos[idx & 7];20542055/* init Endpoints */2056if (vcf[idx] == EP_NOP || vcf[idx] == EP_NUL) {2057ep++;2058continue;2059}2060switch (ep->desc.bmAttributes) {2061case USB_ENDPOINT_XFER_INT:2062f->pipe = usb_rcvintpipe(dev,2063ep->desc.bEndpointAddress);2064f->usb_transfer_mode = USB_INT;2065packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);2066break;2067case USB_ENDPOINT_XFER_BULK:2068if (ep_addr & 0x80)2069f->pipe = usb_rcvbulkpipe(dev,2070ep->desc.bEndpointAddress);2071else2072f->pipe = usb_sndbulkpipe(dev,2073ep->desc.bEndpointAddress);2074f->usb_transfer_mode = USB_BULK;2075packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);2076break;2077case USB_ENDPOINT_XFER_ISOC:2078if (ep_addr & 0x80)2079f->pipe = usb_rcvisocpipe(dev,2080ep->desc.bEndpointAddress);2081else2082f->pipe = usb_sndisocpipe(dev,2083ep->desc.bEndpointAddress);2084f->usb_transfer_mode = USB_ISOC;2085iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);2086break;2087default:2088f->pipe = 0;2089}20902091if (f->pipe) {2092f->fifonum = idx & 7;2093f->hw = hw;2094f->usb_packet_maxlen =2095le16_to_cpu(ep->desc.wMaxPacketSize);2096f->intervall = ep->desc.bInterval;2097}2098ep++;2099}2100hw->dev = dev; /* save device */2101hw->if_used = ifnum; /* save used interface */2102hw->alt_used = alt_used; /* and alternate config */2103hw->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */2104hw->cfg_used = vcf[16]; /* store used config */2105hw->vend_idx = vend_idx; /* store found vendor */2106hw->packet_size = packet_size;2107hw->iso_packet_size = iso_packet_size;21082109/* create the control pipes needed for register access */2110hw->ctrl_in_pipe = usb_rcvctrlpipe(hw->dev, 0);2111hw->ctrl_out_pipe = usb_sndctrlpipe(hw->dev, 0);2112hw->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);21132114driver_info =2115(struct hfcsusb_vdata *)hfcsusb_idtab[vend_idx].driver_info;2116printk(KERN_DEBUG "%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n",2117hw->name, __func__, driver_info->vend_name,2118conf_str[small_match], ifnum, alt_used);21192120if (setup_instance(hw, dev->dev.parent))2121return -EIO;21222123hw->intf = intf;2124usb_set_intfdata(hw->intf, hw);2125return 0;2126}21272128/* function called when an active device is removed */2129static void2130hfcsusb_disconnect(struct usb_interface *intf)2131{2132struct hfcsusb *hw = usb_get_intfdata(intf);2133struct hfcsusb *next;2134int cnt = 0;21352136printk(KERN_INFO "%s: device disconnected\n", hw->name);21372138handle_led(hw, LED_POWER_OFF);2139release_hw(hw);21402141list_for_each_entry_safe(hw, next, &HFClist, list)2142cnt++;2143if (!cnt)2144hfcsusb_cnt = 0;21452146usb_set_intfdata(intf, NULL);2147}21482149static struct usb_driver hfcsusb_drv = {2150.name = DRIVER_NAME,2151.id_table = hfcsusb_idtab,2152.probe = hfcsusb_probe,2153.disconnect = hfcsusb_disconnect,2154};21552156static int __init2157hfcsusb_init(void)2158{2159printk(KERN_INFO DRIVER_NAME " driver Rev. %s debug(0x%x) poll(%i)\n",2160hfcsusb_rev, debug, poll);21612162if (usb_register(&hfcsusb_drv)) {2163printk(KERN_INFO DRIVER_NAME2164": Unable to register hfcsusb module at usb stack\n");2165return -ENODEV;2166}21672168return 0;2169}21702171static void __exit2172hfcsusb_cleanup(void)2173{2174if (debug & DBG_HFC_CALL_TRACE)2175printk(KERN_INFO DRIVER_NAME ": %s\n", __func__);21762177/* unregister Hardware */2178usb_deregister(&hfcsusb_drv); /* release our driver */2179}21802181module_init(hfcsusb_init);2182module_exit(hfcsusb_cleanup);218321842185