File Index
Files and directories
Sign in
FILE

w6692.c

File preview with syntax highlighting.

linux-6.19.14/drivers/isdn/hardware/mISDN/w6692.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * w6692.c     mISDN driver for Winbond w6692 based cards
   4 *
   5 * Author      Karsten Keil <kkeil@suse.de>
   6 *             based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
   7 *
   8 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
   9 */
  10
  11#include <linux/interrupt.h>
  12#include <linux/module.h>
  13#include <linux/pci.h>
  14#include <linux/delay.h>
  15#include <linux/mISDNhw.h>
  16#include <linux/slab.h>
  17#include "w6692.h"
  18
  19#define W6692_REV	"2.0"
  20
  21#define DBUSY_TIMER_VALUE	80
  22
  23enum {
  24	W6692_ASUS,
  25	W6692_WINBOND,
  26	W6692_USR
  27};
  28
  29/* private data in the PCI devices list */
  30struct w6692map {
  31	u_int	subtype;
  32	char	*name;
  33};
  34
  35static const struct w6692map  w6692_map[] =
  36{
  37	{W6692_ASUS, "Dynalink/AsusCom IS64PH"},
  38	{W6692_WINBOND, "Winbond W6692"},
  39	{W6692_USR, "USR W6692"}
  40};
  41
  42#define PCI_DEVICE_ID_USR_6692	0x3409
  43
  44struct w6692_ch {
  45	struct bchannel		bch;
  46	u32			addr;
  47	struct timer_list	timer;
  48	u8			b_mode;
  49};
  50
  51struct w6692_hw {
  52	struct list_head	list;
  53	struct pci_dev		*pdev;
  54	char			name[MISDN_MAX_IDLEN];
  55	u32			irq;
  56	u32			irqcnt;
  57	u32			addr;
  58	u32			fmask;	/* feature mask - bit set per card nr */
  59	int			subtype;
  60	spinlock_t		lock;	/* hw lock */
  61	u8			imask;
  62	u8			pctl;
  63	u8			xaddr;
  64	u8			xdata;
  65	u8			state;
  66	struct w6692_ch		bc[2];
  67	struct dchannel		dch;
  68	char			log[64];
  69};
  70
  71static LIST_HEAD(Cards);
  72static DEFINE_RWLOCK(card_lock); /* protect Cards */
  73
  74static int w6692_cnt;
  75static int debug;
  76static u32 led;
  77static u32 pots;
  78
  79static void
  80_set_debug(struct w6692_hw *card)
  81{
  82	card->dch.debug = debug;
  83	card->bc[0].bch.debug = debug;
  84	card->bc[1].bch.debug = debug;
  85}
  86
  87static int
  88set_debug(const char *val, const struct kernel_param *kp)
  89{
  90	int ret;
  91	struct w6692_hw *card;
  92
  93	ret = param_set_uint(val, kp);
  94	if (!ret) {
  95		read_lock(&card_lock);
  96		list_for_each_entry(card, &Cards, list)
  97			_set_debug(card);
  98		read_unlock(&card_lock);
  99	}
 100	return ret;
 101}
 102
 103MODULE_AUTHOR("Karsten Keil");
 104MODULE_DESCRIPTION("mISDN driver for Winbond w6692 based cards");
 105MODULE_LICENSE("GPL v2");
 106MODULE_VERSION(W6692_REV);
 107module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 108MODULE_PARM_DESC(debug, "W6692 debug mask");
 109module_param(led, uint, S_IRUGO | S_IWUSR);
 110MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)");
 111module_param(pots, uint, S_IRUGO | S_IWUSR);
 112MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)");
 113
 114static inline u8
 115ReadW6692(struct w6692_hw *card, u8 offset)
 116{
 117	return inb(card->addr + offset);
 118}
 119
 120static inline void
 121WriteW6692(struct w6692_hw *card, u8 offset, u8 value)
 122{
 123	outb(value, card->addr + offset);
 124}
 125
 126static inline u8
 127ReadW6692B(struct w6692_ch *bc, u8 offset)
 128{
 129	return inb(bc->addr + offset);
 130}
 131
 132static inline void
 133WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value)
 134{
 135	outb(value, bc->addr + offset);
 136}
 137
 138static void
 139enable_hwirq(struct w6692_hw *card)
 140{
 141	WriteW6692(card, W_IMASK, card->imask);
 142}
 143
 144static void
 145disable_hwirq(struct w6692_hw *card)
 146{
 147	WriteW6692(card, W_IMASK, 0xff);
 148}
 149
 150static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"};
 151
 152static void
 153W6692Version(struct w6692_hw *card)
 154{
 155	int val;
 156
 157	val = ReadW6692(card, W_D_RBCH);
 158	pr_notice("%s: Winbond W6692 version: %s\n", card->name,
 159		  W6692Ver[(val >> 6) & 3]);
 160}
 161
 162static void
 163w6692_led_handler(struct w6692_hw *card, int on)
 164{
 165	if ((!(card->fmask & led)) || card->subtype == W6692_USR)
 166		return;
 167	if (on) {
 168		card->xdata &= 0xfb;	/*  LED ON */
 169		WriteW6692(card, W_XDATA, card->xdata);
 170	} else {
 171		card->xdata |= 0x04;	/*  LED OFF */
 172		WriteW6692(card, W_XDATA, card->xdata);
 173	}
 174}
 175
 176static void
 177ph_command(struct w6692_hw *card, u8 cmd)
 178{
 179	pr_debug("%s: ph_command %x\n", card->name, cmd);
 180	WriteW6692(card, W_CIX, cmd);
 181}
 182
 183static void
 184W6692_new_ph(struct w6692_hw *card)
 185{
 186	if (card->state == W_L1CMD_RST)
 187		ph_command(card, W_L1CMD_DRC);
 188	schedule_event(&card->dch, FLG_PHCHANGE);
 189}
 190
 191static void
 192W6692_ph_bh(struct dchannel *dch)
 193{
 194	struct w6692_hw *card = dch->hw;
 195
 196	switch (card->state) {
 197	case W_L1CMD_RST:
 198		dch->state = 0;
 199		l1_event(dch->l1, HW_RESET_IND);
 200		break;
 201	case W_L1IND_CD:
 202		dch->state = 3;
 203		l1_event(dch->l1, HW_DEACT_CNF);
 204		break;
 205	case W_L1IND_DRD:
 206		dch->state = 3;
 207		l1_event(dch->l1, HW_DEACT_IND);
 208		break;
 209	case W_L1IND_CE:
 210		dch->state = 4;
 211		l1_event(dch->l1, HW_POWERUP_IND);
 212		break;
 213	case W_L1IND_LD:
 214		if (dch->state <= 5) {
 215			dch->state = 5;
 216			l1_event(dch->l1, ANYSIGNAL);
 217		} else {
 218			dch->state = 8;
 219			l1_event(dch->l1, LOSTFRAMING);
 220		}
 221		break;
 222	case W_L1IND_ARD:
 223		dch->state = 6;
 224		l1_event(dch->l1, INFO2);
 225		break;
 226	case W_L1IND_AI8:
 227		dch->state = 7;
 228		l1_event(dch->l1, INFO4_P8);
 229		break;
 230	case W_L1IND_AI10:
 231		dch->state = 7;
 232		l1_event(dch->l1, INFO4_P10);
 233		break;
 234	default:
 235		pr_debug("%s: TE unknown state %02x dch state %02x\n",
 236			 card->name, card->state, dch->state);
 237		break;
 238	}
 239	pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
 240}
 241
 242static void
 243W6692_empty_Dfifo(struct w6692_hw *card, int count)
 244{
 245	struct dchannel *dch = &card->dch;
 246	u8 *ptr;
 247
 248	pr_debug("%s: empty_Dfifo %d\n", card->name, count);
 249	if (!dch->rx_skb) {
 250		dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC);
 251		if (!dch->rx_skb) {
 252			pr_info("%s: D receive out of memory\n", card->name);
 253			WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
 254			return;
 255		}
 256	}
 257	if ((dch->rx_skb->len + count) >= dch->maxlen) {
 258		pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
 259			 dch->rx_skb->len + count);
 260		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
 261		return;
 262	}
 263	ptr = skb_put(dch->rx_skb, count);
 264	insb(card->addr + W_D_RFIFO, ptr, count);
 265	WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
 266	if (debug & DEBUG_HW_DFIFO) {
 267		snprintf(card->log, 63, "D-recv %s %d ",
 268			 card->name, count);
 269		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 270	}
 271}
 272
 273static void
 274W6692_fill_Dfifo(struct w6692_hw *card)
 275{
 276	struct dchannel *dch = &card->dch;
 277	int count;
 278	u8 *ptr;
 279	u8 cmd = W_D_CMDR_XMS;
 280
 281	pr_debug("%s: fill_Dfifo\n", card->name);
 282	if (!dch->tx_skb)
 283		return;
 284	count = dch->tx_skb->len - dch->tx_idx;
 285	if (count <= 0)
 286		return;
 287	if (count > W_D_FIFO_THRESH)
 288		count = W_D_FIFO_THRESH;
 289	else
 290		cmd |= W_D_CMDR_XME;
 291	ptr = dch->tx_skb->data + dch->tx_idx;
 292	dch->tx_idx += count;
 293	outsb(card->addr + W_D_XFIFO, ptr, count);
 294	WriteW6692(card, W_D_CMDR, cmd);
 295	if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
 296		pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
 297		timer_delete(&dch->timer);
 298	}
 299	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
 300	add_timer(&dch->timer);
 301	if (debug & DEBUG_HW_DFIFO) {
 302		snprintf(card->log, 63, "D-send %s %d ",
 303			 card->name, count);
 304		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 305	}
 306}
 307
 308static void
 309d_retransmit(struct w6692_hw *card)
 310{
 311	struct dchannel *dch = &card->dch;
 312
 313	if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
 314		timer_delete(&dch->timer);
 315#ifdef FIXME
 316	if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
 317		dchannel_sched_event(dch, D_CLEARBUSY);
 318#endif
 319	if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
 320		/* Restart frame */
 321		dch->tx_idx = 0;
 322		W6692_fill_Dfifo(card);
 323	} else if (dch->tx_skb) { /* should not happen */
 324		pr_info("%s: %s without TX_BUSY\n", card->name, __func__);
 325		test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
 326		dch->tx_idx = 0;
 327		W6692_fill_Dfifo(card);
 328	} else {
 329		pr_info("%s: XDU no TX_BUSY\n", card->name);
 330		if (get_next_dframe(dch))
 331			W6692_fill_Dfifo(card);
 332	}
 333}
 334
 335static void
 336handle_rxD(struct w6692_hw *card) {
 337	u8	stat;
 338	int	count;
 339
 340	stat = ReadW6692(card, W_D_RSTA);
 341	if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
 342		if (stat & W_D_RSTA_RDOV) {
 343			pr_debug("%s: D-channel RDOV\n", card->name);
 344#ifdef ERROR_STATISTIC
 345			card->dch.err_rx++;
 346#endif
 347		}
 348		if (stat & W_D_RSTA_CRCE) {
 349			pr_debug("%s: D-channel CRC error\n", card->name);
 350#ifdef ERROR_STATISTIC
 351			card->dch.err_crc++;
 352#endif
 353		}
 354		if (stat & W_D_RSTA_RMB) {
 355			pr_debug("%s: D-channel ABORT\n", card->name);
 356#ifdef ERROR_STATISTIC
 357			card->dch.err_rx++;
 358#endif
 359		}
 360		dev_kfree_skb(card->dch.rx_skb);
 361		card->dch.rx_skb = NULL;
 362		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
 363	} else {
 364		count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
 365		if (count == 0)
 366			count = W_D_FIFO_THRESH;
 367		W6692_empty_Dfifo(card, count);
 368		recv_Dchannel(&card->dch);
 369	}
 370}
 371
 372static void
 373handle_txD(struct w6692_hw *card) {
 374	if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
 375		timer_delete(&card->dch.timer);
 376	if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
 377		W6692_fill_Dfifo(card);
 378	} else {
 379		dev_kfree_skb(card->dch.tx_skb);
 380		if (get_next_dframe(&card->dch))
 381			W6692_fill_Dfifo(card);
 382	}
 383}
 384
 385static void
 386handle_statusD(struct w6692_hw *card)
 387{
 388	struct dchannel *dch = &card->dch;
 389	u8 exval, v1, cir;
 390
 391	exval = ReadW6692(card, W_D_EXIR);
 392
 393	pr_debug("%s: D_EXIR %02x\n", card->name, exval);
 394	if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {
 395		/* Transmit underrun/collision */
 396		pr_debug("%s: D-channel underrun/collision\n", card->name);
 397#ifdef ERROR_STATISTIC
 398		dch->err_tx++;
 399#endif
 400		d_retransmit(card);
 401	}
 402	if (exval & W_D_EXI_RDOV) {	/* RDOV */
 403		pr_debug("%s: D-channel RDOV\n", card->name);
 404		WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST);
 405	}
 406	if (exval & W_D_EXI_TIN2)	/* TIN2 - never */
 407		pr_debug("%s: spurious TIN2 interrupt\n", card->name);
 408	if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
 409		v1 = ReadW6692(card, W_MOSR);
 410		pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
 411			 card->name, v1);
 412	}
 413	if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
 414		cir = ReadW6692(card, W_CIR);
 415		pr_debug("%s: ISC CIR %02X\n", card->name, cir);
 416		if (cir & W_CIR_ICC) {
 417			v1 = cir & W_CIR_COD_MASK;
 418			pr_debug("%s: ph_state_change %x -> %x\n", card->name,
 419				 dch->state, v1);
 420			card->state = v1;
 421			if (card->fmask & led) {
 422				switch (v1) {
 423				case W_L1IND_AI8:
 424				case W_L1IND_AI10:
 425					w6692_led_handler(card, 1);
 426					break;
 427				default:
 428					w6692_led_handler(card, 0);
 429					break;
 430				}
 431			}
 432			W6692_new_ph(card);
 433		}
 434		if (cir & W_CIR_SCC) {
 435			v1 = ReadW6692(card, W_SQR);
 436			pr_debug("%s: SCC SQR %02X\n", card->name, v1);
 437		}
 438	}
 439	if (exval & W_D_EXI_WEXP)
 440		pr_debug("%s: spurious WEXP interrupt!\n", card->name);
 441	if (exval & W_D_EXI_TEXP)
 442		pr_debug("%s: spurious TEXP interrupt!\n", card->name);
 443}
 444
 445static void
 446W6692_empty_Bfifo(struct w6692_ch *wch, int count)
 447{
 448	struct w6692_hw *card = wch->bch.hw;
 449	u8 *ptr;
 450	int maxlen;
 451
 452	pr_debug("%s: empty_Bfifo %d\n", card->name, count);
 453	if (unlikely(wch->bch.state == ISDN_P_NONE)) {
 454		pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name);
 455		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 456		if (wch->bch.rx_skb)
 457			skb_trim(wch->bch.rx_skb, 0);
 458		return;
 459	}
 460	if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) {
 461		wch->bch.dropcnt += count;
 462		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 463		return;
 464	}
 465	maxlen = bchannel_get_rxbuf(&wch->bch, count);
 466	if (maxlen < 0) {
 467		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 468		if (wch->bch.rx_skb)
 469			skb_trim(wch->bch.rx_skb, 0);
 470		pr_warn("%s.B%d: No bufferspace for %d bytes\n",
 471			card->name, wch->bch.nr, count);
 472		return;
 473	}
 474	ptr = skb_put(wch->bch.rx_skb, count);
 475	insb(wch->addr + W_B_RFIFO, ptr, count);
 476	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 477	if (debug & DEBUG_HW_DFIFO) {
 478		snprintf(card->log, 63, "B%1d-recv %s %d ",
 479			 wch->bch.nr, card->name, count);
 480		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 481	}
 482}
 483
 484static void
 485W6692_fill_Bfifo(struct w6692_ch *wch)
 486{
 487	struct w6692_hw *card = wch->bch.hw;
 488	int count, fillempty = 0;
 489	u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
 490
 491	pr_debug("%s: fill Bfifo\n", card->name);
 492	if (!wch->bch.tx_skb) {
 493		if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags))
 494			return;
 495		ptr = wch->bch.fill;
 496		count = W_B_FIFO_THRESH;
 497		fillempty = 1;
 498	} else {
 499		count = wch->bch.tx_skb->len - wch->bch.tx_idx;
 500		if (count <= 0)
 501			return;
 502		ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
 503	}
 504	if (count > W_B_FIFO_THRESH)
 505		count = W_B_FIFO_THRESH;
 506	else if (test_bit(FLG_HDLC, &wch->bch.Flags))
 507		cmd |= W_B_CMDR_XME;
 508
 509	pr_debug("%s: fill Bfifo%d/%d\n", card->name,
 510		 count, wch->bch.tx_idx);
 511	wch->bch.tx_idx += count;
 512	if (fillempty) {
 513		while (count > 0) {
 514			outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE);
 515			count -= MISDN_BCH_FILL_SIZE;
 516		}
 517	} else {
 518		outsb(wch->addr + W_B_XFIFO, ptr, count);
 519	}
 520	WriteW6692B(wch, W_B_CMDR, cmd);
 521	if ((debug & DEBUG_HW_BFIFO) && !fillempty) {
 522		snprintf(card->log, 63, "B%1d-send %s %d ",
 523			 wch->bch.nr, card->name, count);
 524		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 525	}
 526}
 527
 528#if 0
 529static int
 530setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
 531{
 532	struct w6692_hw *card = wch->bch.hw;
 533	u16 *vol = (u16 *)skb->data;
 534	u8 val;
 535
 536	if ((!(card->fmask & pots)) ||
 537	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
 538		return -ENODEV;
 539	if (skb->len < 2)
 540		return -EINVAL;
 541	if (*vol > 7)
 542		return -EINVAL;
 543	val = *vol & 7;
 544	val = 7 - val;
 545	if (mic) {
 546		val <<= 3;
 547		card->xaddr &= 0xc7;
 548	} else {
 549		card->xaddr &= 0xf8;
 550	}
 551	card->xaddr |= val;
 552	WriteW6692(card, W_XADDR, card->xaddr);
 553	return 0;
 554}
 555
 556static int
 557enable_pots(struct w6692_ch *wch)
 558{
 559	struct w6692_hw *card = wch->bch.hw;
 560
 561	if ((!(card->fmask & pots)) ||
 562	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
 563		return -ENODEV;
 564	wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0;
 565	WriteW6692B(wch, W_B_MODE, wch->b_mode);
 566	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
 567	card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0);
 568	WriteW6692(card, W_PCTL, card->pctl);
 569	return 0;
 570}
 571#endif
 572
 573static int
 574disable_pots(struct w6692_ch *wch)
 575{
 576	struct w6692_hw *card = wch->bch.hw;
 577
 578	if (!(card->fmask & pots))
 579		return -ENODEV;
 580	wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
 581	WriteW6692B(wch, W_B_MODE, wch->b_mode);
 582	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
 583		    W_B_CMDR_XRST);
 584	return 0;
 585}
 586
 587static int
 588w6692_mode(struct w6692_ch *wch, u32 pr)
 589{
 590	struct w6692_hw	*card;
 591
 592	card = wch->bch.hw;
 593	pr_debug("%s: B%d protocol %x-->%x\n", card->name,
 594		 wch->bch.nr, wch->bch.state, pr);
 595	switch (pr) {
 596	case ISDN_P_NONE:
 597		if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
 598			disable_pots(wch);
 599		wch->b_mode = 0;
 600		mISDN_clear_bchannel(&wch->bch);
 601		WriteW6692B(wch, W_B_MODE, wch->b_mode);
 602		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
 603		test_and_clear_bit(FLG_HDLC, &wch->bch.Flags);
 604		test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags);
 605		break;
 606	case ISDN_P_B_RAW:
 607		wch->b_mode = W_B_MODE_MMS;
 608		WriteW6692B(wch, W_B_MODE, wch->b_mode);
 609		WriteW6692B(wch, W_B_EXIM, 0);
 610		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
 611			    W_B_CMDR_XRST);
 612		test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
 613		break;
 614	case ISDN_P_B_HDLC:
 615		wch->b_mode = W_B_MODE_ITF;
 616		WriteW6692B(wch, W_B_MODE, wch->b_mode);
 617		WriteW6692B(wch, W_B_ADM1, 0xff);
 618		WriteW6692B(wch, W_B_ADM2, 0xff);
 619		WriteW6692B(wch, W_B_EXIM, 0);
 620		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
 621			    W_B_CMDR_XRST);
 622		test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
 623		break;
 624	default:
 625		pr_info("%s: protocol %x not known\n", card->name, pr);
 626		return -ENOPROTOOPT;
 627	}
 628	wch->bch.state = pr;
 629	return 0;
 630}
 631
 632static void
 633send_next(struct w6692_ch *wch)
 634{
 635	if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) {
 636		W6692_fill_Bfifo(wch);
 637	} else {
 638		dev_kfree_skb(wch->bch.tx_skb);
 639		if (get_next_bframe(&wch->bch)) {
 640			W6692_fill_Bfifo(wch);
 641			test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags);
 642		} else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) {
 643			W6692_fill_Bfifo(wch);
 644		}
 645	}
 646}
 647
 648static void
 649W6692B_interrupt(struct w6692_hw *card, int ch)
 650{
 651	struct w6692_ch	*wch = &card->bc[ch];
 652	int		count;
 653	u8		stat, star = 0;
 654
 655	stat = ReadW6692B(wch, W_B_EXIR);
 656	pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat);
 657	if (stat & W_B_EXI_RME) {
 658		star = ReadW6692B(wch, W_B_STAR);
 659		if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
 660			if ((star & W_B_STAR_RDOV) &&
 661			    test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
 662				pr_debug("%s: B%d RDOV proto=%x\n", card->name,
 663					 wch->bch.nr, wch->bch.state);
 664#ifdef ERROR_STATISTIC
 665				wch->bch.err_rdo++;
 666#endif
 667			}
 668			if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
 669				if (star & W_B_STAR_CRCE) {
 670					pr_debug("%s: B%d CRC error\n",
 671						 card->name, wch->bch.nr);
 672#ifdef ERROR_STATISTIC
 673					wch->bch.err_crc++;
 674#endif
 675				}
 676				if (star & W_B_STAR_RMB) {
 677					pr_debug("%s: B%d message abort\n",
 678						 card->name, wch->bch.nr);
 679#ifdef ERROR_STATISTIC
 680					wch->bch.err_inv++;
 681#endif
 682				}
 683			}
 684			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
 685				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 686			if (wch->bch.rx_skb)
 687				skb_trim(wch->bch.rx_skb, 0);
 688		} else {
 689			count = ReadW6692B(wch, W_B_RBCL) &
 690				(W_B_FIFO_THRESH - 1);
 691			if (count == 0)
 692				count = W_B_FIFO_THRESH;
 693			W6692_empty_Bfifo(wch, count);
 694			recv_Bchannel(&wch->bch, 0, false);
 695		}
 696	}
 697	if (stat & W_B_EXI_RMR) {
 698		if (!(stat & W_B_EXI_RME))
 699			star = ReadW6692B(wch, W_B_STAR);
 700		if (star & W_B_STAR_RDOV) {
 701			pr_debug("%s: B%d RDOV proto=%x\n", card->name,
 702				 wch->bch.nr, wch->bch.state);
 703#ifdef ERROR_STATISTIC
 704			wch->bch.err_rdo++;
 705#endif
 706			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
 707				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 708		} else {
 709			W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
 710			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
 711				recv_Bchannel(&wch->bch, 0, false);
 712		}
 713	}
 714	if (stat & W_B_EXI_RDOV) {
 715		/* only if it is not handled yet */
 716		if (!(star & W_B_STAR_RDOV)) {
 717			pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
 718				 wch->bch.nr, wch->bch.state);
 719#ifdef ERROR_STATISTIC
 720			wch->bch.err_rdo++;
 721#endif
 722			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
 723				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 724		}
 725	}
 726	if (stat & W_B_EXI_XFR) {
 727		if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
 728			star = ReadW6692B(wch, W_B_STAR);
 729			pr_debug("%s: B%d star %02x\n", card->name,
 730				 wch->bch.nr, star);
 731		}
 732		if (star & W_B_STAR_XDOW) {
 733			pr_warn("%s: B%d XDOW proto=%x\n", card->name,
 734				wch->bch.nr, wch->bch.state);
 735#ifdef ERROR_STATISTIC
 736			wch->bch.err_xdu++;
 737#endif
 738			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
 739				    W_B_CMDR_RACT);
 740			/* resend */
 741			if (wch->bch.tx_skb) {
 742				if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
 743					wch->bch.tx_idx = 0;
 744			}
 745		}
 746		send_next(wch);
 747		if (star & W_B_STAR_XDOW)
 748			return; /* handle XDOW only once */
 749	}
 750	if (stat & W_B_EXI_XDUN) {
 751		pr_warn("%s: B%d XDUN proto=%x\n", card->name,
 752			wch->bch.nr, wch->bch.state);
 753#ifdef ERROR_STATISTIC
 754		wch->bch.err_xdu++;
 755#endif
 756		/* resend - no XRST needed */
 757		if (wch->bch.tx_skb) {
 758			if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
 759				wch->bch.tx_idx = 0;
 760		} else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) {
 761			test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags);
 762		}
 763		send_next(wch);
 764	}
 765}
 766
 767static irqreturn_t
 768w6692_irq(int intno, void *dev_id)
 769{
 770	struct w6692_hw	*card = dev_id;
 771	u8		ista;
 772
 773	spin_lock(&card->lock);
 774	ista = ReadW6692(card, W_ISTA);
 775	if ((ista | card->imask) == card->imask) {
 776		/* possible a shared  IRQ reqest */
 777		spin_unlock(&card->lock);
 778		return IRQ_NONE;
 779	}
 780	card->irqcnt++;
 781	pr_debug("%s: ista %02x\n", card->name, ista);
 782	ista &= ~card->imask;
 783	if (ista & W_INT_B1_EXI)
 784		W6692B_interrupt(card, 0);
 785	if (ista & W_INT_B2_EXI)
 786		W6692B_interrupt(card, 1);
 787	if (ista & W_INT_D_RME)
 788		handle_rxD(card);
 789	if (ista & W_INT_D_RMR)
 790		W6692_empty_Dfifo(card, W_D_FIFO_THRESH);
 791	if (ista & W_INT_D_XFR)
 792		handle_txD(card);
 793	if (ista & W_INT_D_EXI)
 794		handle_statusD(card);
 795	if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */
 796		pr_debug("%s: W6692 spurious XINT!\n", card->name);
 797/* End IRQ Handler */
 798	spin_unlock(&card->lock);
 799	return IRQ_HANDLED;
 800}
 801
 802static void
 803dbusy_timer_handler(struct timer_list *t)
 804{
 805	struct dchannel *dch = timer_container_of(dch, t, timer);
 806	struct w6692_hw	*card = dch->hw;
 807	int		rbch, star;
 808	u_long		flags;
 809
 810	if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
 811		spin_lock_irqsave(&card->lock, flags);
 812		rbch = ReadW6692(card, W_D_RBCH);
 813		star = ReadW6692(card, W_D_STAR);
 814		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
 815			 card->name, rbch, star);
 816		if (star & W_D_STAR_XBZ)	/* D-Channel Busy */
 817			test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
 818		else {
 819			/* discard frame; reset transceiver */
 820			test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
 821			if (dch->tx_idx)
 822				dch->tx_idx = 0;
 823			else
 824				pr_info("%s: W6692 D-Channel Busy no tx_idx\n",
 825					card->name);
 826			/* Transmitter reset */
 827			WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST);
 828		}
 829		spin_unlock_irqrestore(&card->lock, flags);
 830	}
 831}
 832
 833static void initW6692(struct w6692_hw *card)
 834{
 835	u8	val;
 836
 837	timer_setup(&card->dch.timer, dbusy_timer_handler, 0);
 838	w6692_mode(&card->bc[0], ISDN_P_NONE);
 839	w6692_mode(&card->bc[1], ISDN_P_NONE);
 840	WriteW6692(card, W_D_CTL, 0x00);
 841	disable_hwirq(card);
 842	WriteW6692(card, W_D_SAM, 0xff);
 843	WriteW6692(card, W_D_TAM, 0xff);
 844	WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
 845	card->state = W_L1CMD_RST;
 846	ph_command(card, W_L1CMD_RST);
 847	ph_command(card, W_L1CMD_ECK);
 848	/* enable all IRQ but extern */
 849	card->imask = 0x18;
 850	WriteW6692(card, W_D_EXIM, 0x00);
 851	WriteW6692B(&card->bc[0], W_B_EXIM, 0);
 852	WriteW6692B(&card->bc[1], W_B_EXIM, 0);
 853	/* Reset D-chan receiver and transmitter */
 854	WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
 855	/* Reset B-chan receiver and transmitter */
 856	WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
 857	WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
 858	/* enable peripheral */
 859	if (card->subtype == W6692_USR) {
 860		/* seems that USR implemented some power control features
 861		 * Pin 79 is connected to the oscilator circuit so we
 862		 * have to handle it here
 863		 */
 864		card->pctl = 0x80;
 865		card->xdata = 0;
 866		WriteW6692(card, W_PCTL, card->pctl);
 867		WriteW6692(card, W_XDATA, card->xdata);
 868	} else {
 869		card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
 870			W_PCTL_OE1 | W_PCTL_OE0;
 871		card->xaddr = 0x00;/* all sw off */
 872		if (card->fmask & pots)
 873			card->xdata |= 0x06;	/*  POWER UP/ LED OFF / ALAW */
 874		if (card->fmask & led)
 875			card->xdata |= 0x04;	/* LED OFF */
 876		if ((card->fmask & pots) || (card->fmask & led)) {
 877			WriteW6692(card, W_PCTL, card->pctl);
 878			WriteW6692(card, W_XADDR, card->xaddr);
 879			WriteW6692(card, W_XDATA, card->xdata);
 880			val = ReadW6692(card, W_XADDR);
 881			if (debug & DEBUG_HW)
 882				pr_notice("%s: W_XADDR=%02x\n",
 883					  card->name, val);
 884		}
 885	}
 886}
 887
 888static void
 889reset_w6692(struct w6692_hw *card)
 890{
 891	WriteW6692(card, W_D_CTL, W_D_CTL_SRST);
 892	mdelay(10);
 893	WriteW6692(card, W_D_CTL, 0);
 894}
 895
 896static int
 897init_card(struct w6692_hw *card)
 898{
 899	int	cnt = 3;
 900	u_long	flags;
 901
 902	spin_lock_irqsave(&card->lock, flags);
 903	disable_hwirq(card);
 904	spin_unlock_irqrestore(&card->lock, flags);
 905	if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) {
 906		pr_info("%s: couldn't get interrupt %d\n", card->name,
 907			card->irq);
 908		return -EIO;
 909	}
 910	while (cnt--) {
 911		spin_lock_irqsave(&card->lock, flags);
 912		initW6692(card);
 913		enable_hwirq(card);
 914		spin_unlock_irqrestore(&card->lock, flags);
 915		/* Timeout 10ms */
 916		msleep_interruptible(10);
 917		if (debug & DEBUG_HW)
 918			pr_notice("%s: IRQ %d count %d\n", card->name,
 919				  card->irq, card->irqcnt);
 920		if (!card->irqcnt) {
 921			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
 922				card->name, card->irq, 3 - cnt);
 923			reset_w6692(card);
 924		} else
 925			return 0;
 926	}
 927	free_irq(card->irq, card);
 928	return -EIO;
 929}
 930
 931static int
 932w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 933{
 934	struct bchannel *bch = container_of(ch, struct bchannel, ch);
 935	struct w6692_ch	*bc = container_of(bch, struct w6692_ch, bch);
 936	struct w6692_hw *card = bch->hw;
 937	int ret = -EINVAL;
 938	struct mISDNhead *hh = mISDN_HEAD_P(skb);
 939	unsigned long flags;
 940
 941	switch (hh->prim) {
 942	case PH_DATA_REQ:
 943		spin_lock_irqsave(&card->lock, flags);
 944		ret = bchannel_senddata(bch, skb);
 945		if (ret > 0) { /* direct TX */
 946			ret = 0;
 947			W6692_fill_Bfifo(bc);
 948		}
 949		spin_unlock_irqrestore(&card->lock, flags);
 950		return ret;
 951	case PH_ACTIVATE_REQ:
 952		spin_lock_irqsave(&card->lock, flags);
 953		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
 954			ret = w6692_mode(bc, ch->protocol);
 955		else
 956			ret = 0;
 957		spin_unlock_irqrestore(&card->lock, flags);
 958		if (!ret)
 959			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
 960				    NULL, GFP_KERNEL);
 961		break;
 962	case PH_DEACTIVATE_REQ:
 963		spin_lock_irqsave(&card->lock, flags);
 964		mISDN_clear_bchannel(bch);
 965		w6692_mode(bc, ISDN_P_NONE);
 966		spin_unlock_irqrestore(&card->lock, flags);
 967		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
 968			    NULL, GFP_KERNEL);
 969		ret = 0;
 970		break;
 971	default:
 972		pr_info("%s: %s unknown prim(%x,%x)\n",
 973			card->name, __func__, hh->prim, hh->id);
 974		ret = -EINVAL;
 975	}
 976	if (!ret)
 977		dev_kfree_skb(skb);
 978	return ret;
 979}
 980
 981static int
 982channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 983{
 984	return mISDN_ctrl_bchannel(bch, cq);
 985}
 986
 987static int
 988open_bchannel(struct w6692_hw *card, struct channel_req *rq)
 989{
 990	struct bchannel *bch;
 991
 992	if (rq->adr.channel == 0 || rq->adr.channel > 2)
 993		return -EINVAL;
 994	if (rq->protocol == ISDN_P_NONE)
 995		return -EINVAL;
 996	bch = &card->bc[rq->adr.channel - 1].bch;
 997	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
 998		return -EBUSY; /* b-channel can be only open once */
 999	bch->ch.protocol = rq->protocol;
1000	rq->ch = &bch->ch;
1001	return 0;
1002}
1003
1004static int
1005channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq)
1006{
1007	int	ret = 0;
1008
1009	switch (cq->op) {
1010	case MISDN_CTRL_GETOP:
1011		cq->op = MISDN_CTRL_L1_TIMER3;
1012		break;
1013	case MISDN_CTRL_L1_TIMER3:
1014		ret = l1_event(card->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
1015		break;
1016	default:
1017		pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op);
1018		ret = -EINVAL;
1019		break;
1020	}
1021	return ret;
1022}
1023
1024static int
1025w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1026{
1027	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1028	struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
1029	struct w6692_hw *card = bch->hw;
1030	int ret = -EINVAL;
1031	u_long flags;
1032
1033	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
1034	switch (cmd) {
1035	case CLOSE_CHANNEL:
1036		test_and_clear_bit(FLG_OPEN, &bch->Flags);
1037		cancel_work_sync(&bch->workq);
1038		spin_lock_irqsave(&card->lock, flags);
1039		mISDN_clear_bchannel(bch);
1040		w6692_mode(bc, ISDN_P_NONE);
1041		spin_unlock_irqrestore(&card->lock, flags);
1042		ch->protocol = ISDN_P_NONE;
1043		ch->peer = NULL;
1044		module_put(THIS_MODULE);
1045		ret = 0;
1046		break;
1047	case CONTROL_CHANNEL:
1048		ret = channel_bctrl(bch, arg);
1049		break;
1050	default:
1051		pr_info("%s: %s unknown prim(%x)\n",
1052			card->name, __func__, cmd);
1053	}
1054	return ret;
1055}
1056
1057static int
1058w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
1059{
1060	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
1061	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
1062	struct w6692_hw		*card = container_of(dch, struct w6692_hw, dch);
1063	int			ret = -EINVAL;
1064	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
1065	u32			id;
1066	u_long			flags;
1067
1068	switch (hh->prim) {
1069	case PH_DATA_REQ:
1070		spin_lock_irqsave(&card->lock, flags);
1071		ret = dchannel_senddata(dch, skb);
1072		if (ret > 0) { /* direct TX */
1073			id = hh->id; /* skb can be freed */
1074			W6692_fill_Dfifo(card);
1075			ret = 0;
1076			spin_unlock_irqrestore(&card->lock, flags);
1077			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
1078		} else
1079			spin_unlock_irqrestore(&card->lock, flags);
1080		return ret;
1081	case PH_ACTIVATE_REQ:
1082		ret = l1_event(dch->l1, hh->prim);
1083		break;
1084	case PH_DEACTIVATE_REQ:
1085		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
1086		ret = l1_event(dch->l1, hh->prim);
1087		break;
1088	}
1089
1090	if (!ret)
1091		dev_kfree_skb(skb);
1092	return ret;
1093}
1094
1095static int
1096w6692_l1callback(struct dchannel *dch, u32 cmd)
1097{
1098	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
1099	u_long flags;
1100
1101	pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
1102	switch (cmd) {
1103	case INFO3_P8:
1104		spin_lock_irqsave(&card->lock, flags);
1105		ph_command(card, W_L1CMD_AR8);
1106		spin_unlock_irqrestore(&card->lock, flags);
1107		break;
1108	case INFO3_P10:
1109		spin_lock_irqsave(&card->lock, flags);
1110		ph_command(card, W_L1CMD_AR10);
1111		spin_unlock_irqrestore(&card->lock, flags);
1112		break;
1113	case HW_RESET_REQ:
1114		spin_lock_irqsave(&card->lock, flags);
1115		if (card->state != W_L1IND_DRD)
1116			ph_command(card, W_L1CMD_RST);
1117		ph_command(card, W_L1CMD_ECK);
1118		spin_unlock_irqrestore(&card->lock, flags);
1119		break;
1120	case HW_DEACT_REQ:
1121		skb_queue_purge(&dch->squeue);
1122		if (dch->tx_skb) {
1123			dev_kfree_skb(dch->tx_skb);
1124			dch->tx_skb = NULL;
1125		}
1126		dch->tx_idx = 0;
1127		if (dch->rx_skb) {
1128			dev_kfree_skb(dch->rx_skb);
1129			dch->rx_skb = NULL;
1130		}
1131		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
1132		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
1133			timer_delete(&dch->timer);
1134		break;
1135	case HW_POWERUP_REQ:
1136		spin_lock_irqsave(&card->lock, flags);
1137		ph_command(card, W_L1CMD_ECK);
1138		spin_unlock_irqrestore(&card->lock, flags);
1139		break;
1140	case PH_ACTIVATE_IND:
1141		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
1142		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
1143			    GFP_ATOMIC);
1144		break;
1145	case PH_DEACTIVATE_IND:
1146		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
1147		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
1148			    GFP_ATOMIC);
1149		break;
1150	default:
1151		pr_debug("%s: %s unknown command %x\n", card->name,
1152			 __func__, cmd);
1153		return -1;
1154	}
1155	return 0;
1156}
1157
1158static int
1159open_dchannel(struct w6692_hw *card, struct channel_req *rq, void *caller)
1160{
1161	pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
1162		 card->dch.dev.id, caller);
1163	if (rq->protocol != ISDN_P_TE_S0)
1164		return -EINVAL;
1165	if (rq->adr.channel == 1)
1166		/* E-Channel not supported */
1167		return -EINVAL;
1168	rq->ch = &card->dch.dev.D;
1169	rq->ch->protocol = rq->protocol;
1170	if (card->dch.state == 7)
1171		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
1172			    0, NULL, GFP_KERNEL);
1173	return 0;
1174}
1175
1176static int
1177w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1178{
1179	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1180	struct dchannel *dch = container_of(dev, struct dchannel, dev);
1181	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
1182	struct channel_req *rq;
1183	int err = 0;
1184
1185	pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg);
1186	switch (cmd) {
1187	case OPEN_CHANNEL:
1188		rq = arg;
1189		if (rq->protocol == ISDN_P_TE_S0)
1190			err = open_dchannel(card, rq, __builtin_return_address(0));
1191		else
1192			err = open_bchannel(card, rq);
1193		if (err)
1194			break;
1195		if (!try_module_get(THIS_MODULE))
1196			pr_info("%s: cannot get module\n", card->name);
1197		break;
1198	case CLOSE_CHANNEL:
1199		pr_debug("%s: dev(%d) close from %p\n", card->name,
1200			 dch->dev.id, __builtin_return_address(0));
1201		module_put(THIS_MODULE);
1202		break;
1203	case CONTROL_CHANNEL:
1204		err = channel_ctrl(card, arg);
1205		break;
1206	default:
1207		pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd);
1208		return -EINVAL;
1209	}
1210	return err;
1211}
1212
1213static int
1214setup_w6692(struct w6692_hw *card)
1215{
1216	u32	val;
1217
1218	if (!request_region(card->addr, 256, card->name)) {
1219		pr_info("%s: config port %x-%x already in use\n", card->name,
1220			card->addr, card->addr + 255);
1221		return -EIO;
1222	}
1223	W6692Version(card);
1224	card->bc[0].addr = card->addr;
1225	card->bc[1].addr = card->addr + 0x40;
1226	val = ReadW6692(card, W_ISTA);
1227	if (debug & DEBUG_HW)
1228		pr_notice("%s ISTA=%02x\n", card->name, val);
1229	val = ReadW6692(card, W_IMASK);
1230	if (debug & DEBUG_HW)
1231		pr_notice("%s IMASK=%02x\n", card->name, val);
1232	val = ReadW6692(card, W_D_EXIR);
1233	if (debug & DEBUG_HW)
1234		pr_notice("%s D_EXIR=%02x\n", card->name, val);
1235	val = ReadW6692(card, W_D_EXIM);
1236	if (debug & DEBUG_HW)
1237		pr_notice("%s D_EXIM=%02x\n", card->name, val);
1238	val = ReadW6692(card, W_D_RSTA);
1239	if (debug & DEBUG_HW)
1240		pr_notice("%s D_RSTA=%02x\n", card->name, val);
1241	return 0;
1242}
1243
1244static void
1245release_card(struct w6692_hw *card)
1246{
1247	u_long	flags;
1248
1249	spin_lock_irqsave(&card->lock, flags);
1250	disable_hwirq(card);
1251	w6692_mode(&card->bc[0], ISDN_P_NONE);
1252	w6692_mode(&card->bc[1], ISDN_P_NONE);
1253	if ((card->fmask & led) || card->subtype == W6692_USR) {
1254		card->xdata |= 0x04;	/*  LED OFF */
1255		WriteW6692(card, W_XDATA, card->xdata);
1256	}
1257	spin_unlock_irqrestore(&card->lock, flags);
1258	free_irq(card->irq, card);
1259	l1_event(card->dch.l1, CLOSE_CHANNEL);
1260	mISDN_unregister_device(&card->dch.dev);
1261	release_region(card->addr, 256);
1262	mISDN_freebchannel(&card->bc[1].bch);
1263	mISDN_freebchannel(&card->bc[0].bch);
1264	mISDN_freedchannel(&card->dch);
1265	write_lock_irqsave(&card_lock, flags);
1266	list_del(&card->list);
1267	write_unlock_irqrestore(&card_lock, flags);
1268	pci_disable_device(card->pdev);
1269	pci_set_drvdata(card->pdev, NULL);
1270	kfree(card);
1271}
1272
1273static int
1274setup_instance(struct w6692_hw *card)
1275{
1276	int		i, err;
1277	u_long		flags;
1278
1279	snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
1280	write_lock_irqsave(&card_lock, flags);
1281	list_add_tail(&card->list, &Cards);
1282	write_unlock_irqrestore(&card_lock, flags);
1283	card->fmask = (1 << w6692_cnt);
1284	_set_debug(card);
1285	spin_lock_init(&card->lock);
1286	mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
1287	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
1288	card->dch.dev.D.send = w6692_l2l1D;
1289	card->dch.dev.D.ctrl = w6692_dctrl;
1290	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1291		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1292	card->dch.hw = card;
1293	card->dch.dev.nrbchan = 2;
1294	for (i = 0; i < 2; i++) {
1295		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
1296				   W_B_FIFO_THRESH);
1297		card->bc[i].bch.hw = card;
1298		card->bc[i].bch.nr = i + 1;
1299		card->bc[i].bch.ch.nr = i + 1;
1300		card->bc[i].bch.ch.send = w6692_l2l1B;
1301		card->bc[i].bch.ch.ctrl = w6692_bctrl;
1302		set_channelmap(i + 1, card->dch.dev.channelmap);
1303		list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
1304	}
1305	err = setup_w6692(card);
1306	if (err)
1307		goto error_setup;
1308	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
1309				    card->name);
1310	if (err)
1311		goto error_reg;
1312	err = init_card(card);
1313	if (err)
1314		goto error_init;
1315	err = create_l1(&card->dch, w6692_l1callback);
1316	if (!err) {
1317		w6692_cnt++;
1318		pr_notice("W6692 %d cards installed\n", w6692_cnt);
1319		return 0;
1320	}
1321
1322	free_irq(card->irq, card);
1323error_init:
1324	mISDN_unregister_device(&card->dch.dev);
1325error_reg:
1326	release_region(card->addr, 256);
1327error_setup:
1328	mISDN_freebchannel(&card->bc[1].bch);
1329	mISDN_freebchannel(&card->bc[0].bch);
1330	mISDN_freedchannel(&card->dch);
1331	write_lock_irqsave(&card_lock, flags);
1332	list_del(&card->list);
1333	write_unlock_irqrestore(&card_lock, flags);
1334	kfree(card);
1335	return err;
1336}
1337
1338static int
1339w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1340{
1341	int		err = -ENOMEM;
1342	struct w6692_hw	*card;
1343	struct w6692map	*m = (struct w6692map *)ent->driver_data;
1344
1345	card = kzalloc(sizeof(struct w6692_hw), GFP_KERNEL);
1346	if (!card) {
1347		pr_info("No kmem for w6692 card\n");
1348		return err;
1349	}
1350	card->pdev = pdev;
1351	card->subtype = m->subtype;
1352	err = pci_enable_device(pdev);
1353	if (err) {
1354		kfree(card);
1355		return err;
1356	}
1357
1358	printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n",
1359	       m->name, pci_name(pdev));
1360
1361	card->addr = pci_resource_start(pdev, 1);
1362	card->irq = pdev->irq;
1363	pci_set_drvdata(pdev, card);
1364	err = setup_instance(card);
1365	if (err)
1366		pci_set_drvdata(pdev, NULL);
1367	return err;
1368}
1369
1370static void
1371w6692_remove_pci(struct pci_dev *pdev)
1372{
1373	struct w6692_hw	*card = pci_get_drvdata(pdev);
1374
1375	if (card)
1376		release_card(card);
1377	else
1378		if (debug)
1379			pr_notice("%s: drvdata already removed\n", __func__);
1380}
1381
1382static const struct pci_device_id w6692_ids[] = {
1383	{ PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
1384	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
1385	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
1386	  PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0,
1387	  (ulong)&w6692_map[2]},
1388	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
1389	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]},
1390	{ }
1391};
1392MODULE_DEVICE_TABLE(pci, w6692_ids);
1393
1394static struct pci_driver w6692_driver = {
1395	.name =  "w6692",
1396	.probe = w6692_probe,
1397	.remove = w6692_remove_pci,
1398	.id_table = w6692_ids,
1399};
1400
1401static int __init w6692_init(void)
1402{
1403	int err;
1404
1405	pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV);
1406
1407	err = pci_register_driver(&w6692_driver);
1408	return err;
1409}
1410
1411static void __exit w6692_cleanup(void)
1412{
1413	pci_unregister_driver(&w6692_driver);
1414}
1415
1416module_init(w6692_init);
1417module_exit(w6692_cleanup);
~/ Read-only file preview.