1 /* $Id: w6692.c,v 1.18.2.4 2004/02/11 13:21:34 keil Exp $
2  *
3  * Winbond W6692 specific routines
4  *
5  * Author       Petr Novak
6  * Copyright    by Petr Novak        <petr.novak@i.cz>
7  *
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  *
11  */
12 
13 #include <linux/init.h>
14 #include "hisax.h"
15 #include "w6692.h"
16 #include "isdnl1.h"
17 #include <linux/interrupt.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20 
21 /* table entry in the PCI devices list */
22 typedef struct {
23 	int vendor_id;
24 	int device_id;
25 	char *vendor_name;
26 	char *card_name;
27 } PCI_ENTRY;
28 
29 static const PCI_ENTRY id_list[] =
30 {
31 	{PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"},
32 	{PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"},
33 	{0, 0, "U.S.Robotics", "ISDN PCI Card TA"}
34 };
35 
36 #define W6692_SV_USR   0x16ec
37 #define W6692_SD_USR   0x3409
38 #define W6692_WINBOND  0
39 #define W6692_DYNALINK 1
40 #define W6692_USR      2
41 
42 static const char *w6692_revision = "$Revision: 1.18.2.4 $";
43 
44 #define DBUSY_TIMER_VALUE 80
45 
46 static char *W6692Ver[] =
47 {"W6692 V00", "W6692 V01", "W6692 V10",
48  "W6692 V11"};
49 
50 static void
W6692Version(struct IsdnCardState * cs,char * s)51 W6692Version(struct IsdnCardState *cs, char *s)
52 {
53 	int val;
54 
55 	val = cs->readW6692(cs, W_D_RBCH);
56 	printk(KERN_INFO "%s Winbond W6692 version (%x): %s\n", s, val, W6692Ver[(val >> 6) & 3]);
57 }
58 
59 static void
ph_command(struct IsdnCardState * cs,unsigned int command)60 ph_command(struct IsdnCardState *cs, unsigned int command)
61 {
62 	if (cs->debug & L1_DEB_ISAC)
63 		debugl1(cs, "ph_command %x", command);
64 	cs->writeisac(cs, W_CIX, command);
65 }
66 
67 
68 static void
W6692_new_ph(struct IsdnCardState * cs)69 W6692_new_ph(struct IsdnCardState *cs)
70 {
71 	switch (cs->dc.w6692.ph_state) {
72 		case (W_L1CMD_RST):
73 			ph_command(cs, W_L1CMD_DRC);
74 			l1_msg(cs, HW_RESET | INDICATION, NULL);
75 			/* fallthru */
76 		case (W_L1IND_CD):
77 			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
78 			break;
79 		case (W_L1IND_DRD):
80 			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
81 			break;
82 		case (W_L1IND_CE):
83 			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
84 			break;
85 		case (W_L1IND_LD):
86 			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
87 			break;
88 		case (W_L1IND_ARD):
89 			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
90 			break;
91 		case (W_L1IND_AI8):
92 			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
93 			break;
94 		case (W_L1IND_AI10):
95 			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
96 			break;
97 		default:
98 			break;
99 	}
100 }
101 
102 static void
W6692_bh(struct work_struct * work)103 W6692_bh(struct work_struct *work)
104 {
105 	struct IsdnCardState *cs =
106 		container_of(work, struct IsdnCardState, tqueue);
107 	struct PStack *stptr;
108 
109 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
110 		if (cs->debug)
111 			debugl1(cs, "D-Channel Busy cleared");
112 		stptr = cs->stlist;
113 		while (stptr != NULL) {
114 			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
115 			stptr = stptr->next;
116 		}
117 	}
118 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
119 		W6692_new_ph(cs);
120 	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
121 		DChannel_proc_rcv(cs);
122 	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
123 		DChannel_proc_xmt(cs);
124 /*
125    if (test_and_clear_bit(D_RX_MON1, &cs->event))
126    arcofi_fsm(cs, ARCOFI_RX_END, NULL);
127    if (test_and_clear_bit(D_TX_MON1, &cs->event))
128    arcofi_fsm(cs, ARCOFI_TX_END, NULL);
129  */
130 }
131 
132 static void
W6692_empty_fifo(struct IsdnCardState * cs,int count)133 W6692_empty_fifo(struct IsdnCardState *cs, int count)
134 {
135 	u_char *ptr;
136 
137 	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
138 		debugl1(cs, "W6692_empty_fifo");
139 
140 	if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
141 		if (cs->debug & L1_DEB_WARN)
142 			debugl1(cs, "W6692_empty_fifo overrun %d",
143 				cs->rcvidx + count);
144 		cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK);
145 		cs->rcvidx = 0;
146 		return;
147 	}
148 	ptr = cs->rcvbuf + cs->rcvidx;
149 	cs->rcvidx += count;
150 	cs->readW6692fifo(cs, ptr, count);
151 	cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK);
152 	if (cs->debug & L1_DEB_ISAC_FIFO) {
153 		char *t = cs->dlog;
154 
155 		t += sprintf(t, "W6692_empty_fifo cnt %d", count);
156 		QuickHex(t, ptr, count);
157 		debugl1(cs, cs->dlog);
158 	}
159 }
160 
161 static void
W6692_fill_fifo(struct IsdnCardState * cs)162 W6692_fill_fifo(struct IsdnCardState *cs)
163 {
164 	int count, more;
165 	u_char *ptr;
166 
167 	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
168 		debugl1(cs, "W6692_fill_fifo");
169 
170 	if (!cs->tx_skb)
171 		return;
172 
173 	count = cs->tx_skb->len;
174 	if (count <= 0)
175 		return;
176 
177 	more = 0;
178 	if (count > W_D_FIFO_THRESH) {
179 		more = !0;
180 		count = W_D_FIFO_THRESH;
181 	}
182 	ptr = cs->tx_skb->data;
183 	skb_pull(cs->tx_skb, count);
184 	cs->tx_cnt += count;
185 	cs->writeW6692fifo(cs, ptr, count);
186 	cs->writeW6692(cs, W_D_CMDR, more ? W_D_CMDR_XMS : (W_D_CMDR_XMS | W_D_CMDR_XME));
187 	if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
188 		debugl1(cs, "W6692_fill_fifo dbusytimer running");
189 		del_timer(&cs->dbusytimer);
190 	}
191 	init_timer(&cs->dbusytimer);
192 	cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
193 	add_timer(&cs->dbusytimer);
194 	if (cs->debug & L1_DEB_ISAC_FIFO) {
195 		char *t = cs->dlog;
196 
197 		t += sprintf(t, "W6692_fill_fifo cnt %d", count);
198 		QuickHex(t, ptr, count);
199 		debugl1(cs, cs->dlog);
200 	}
201 }
202 
203 static void
W6692B_empty_fifo(struct BCState * bcs,int count)204 W6692B_empty_fifo(struct BCState *bcs, int count)
205 {
206 	u_char *ptr;
207 	struct IsdnCardState *cs = bcs->cs;
208 
209 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
210 		debugl1(cs, "W6692B_empty_fifo");
211 
212 	if (bcs->hw.w6692.rcvidx + count > HSCX_BUFMAX) {
213 		if (cs->debug & L1_DEB_WARN)
214 			debugl1(cs, "W6692B_empty_fifo: incoming packet too large");
215 		cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
216 		bcs->hw.w6692.rcvidx = 0;
217 		return;
218 	}
219 	ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx;
220 	bcs->hw.w6692.rcvidx += count;
221 	READW6692BFIFO(cs, bcs->channel, ptr, count);
222 	cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
223 	if (cs->debug & L1_DEB_HSCX_FIFO) {
224 		char *t = bcs->blog;
225 
226 		t += sprintf(t, "W6692B_empty_fifo %c cnt %d",
227 			     bcs->channel + '1', count);
228 		QuickHex(t, ptr, count);
229 		debugl1(cs, bcs->blog);
230 	}
231 }
232 
233 static void
W6692B_fill_fifo(struct BCState * bcs)234 W6692B_fill_fifo(struct BCState *bcs)
235 {
236 	struct IsdnCardState *cs = bcs->cs;
237 	int more, count;
238 	u_char *ptr;
239 
240 	if (!bcs->tx_skb)
241 		return;
242 	if (bcs->tx_skb->len <= 0)
243 		return;
244 
245 	more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
246 	if (bcs->tx_skb->len > W_B_FIFO_THRESH) {
247 		more = 1;
248 		count = W_B_FIFO_THRESH;
249 	} else
250 		count = bcs->tx_skb->len;
251 
252 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
253 		debugl1(cs, "W6692B_fill_fifo%s%d", (more ? " ": " last "), count);
254 
255 	ptr = bcs->tx_skb->data;
256 	skb_pull(bcs->tx_skb, count);
257 	bcs->tx_cnt -= count;
258 	bcs->hw.w6692.count += count;
259 	WRITEW6692BFIFO(cs, bcs->channel, ptr, count);
260 	cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACT | W_B_CMDR_XMS | (more ? 0 : W_B_CMDR_XME));
261 	if (cs->debug & L1_DEB_HSCX_FIFO) {
262 		char *t = bcs->blog;
263 
264 		t += sprintf(t, "W6692B_fill_fifo %c cnt %d",
265 			     bcs->channel + '1', count);
266 		QuickHex(t, ptr, count);
267 		debugl1(cs, bcs->blog);
268 	}
269 }
270 
271 static void
W6692B_interrupt(struct IsdnCardState * cs,u_char bchan)272 W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
273 {
274 	u_char val;
275 	u_char r;
276 	struct BCState *bcs;
277 	struct sk_buff *skb;
278 	int count;
279 
280 	bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs+1);
281 	val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR);
282 	debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val);
283 
284 	if (!test_bit(BC_FLG_INIT, &bcs->Flag)) {
285 		debugl1(cs, "W6692B not INIT yet");
286 		return;
287 	}
288 	if (val & W_B_EXI_RME) {	/* RME */
289 		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
290 		if (r & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
291 			if (cs->debug & L1_DEB_WARN)
292 				debugl1(cs, "W6692 B STAR %x", r);
293 			if ((r & W_B_STAR_RDOV) && bcs->mode)
294 				if (cs->debug & L1_DEB_WARN)
295 					debugl1(cs, "W6692 B RDOV mode=%d",
296 						bcs->mode);
297 			if (r & W_B_STAR_CRCE)
298 				if (cs->debug & L1_DEB_WARN)
299 					debugl1(cs, "W6692 B CRC error");
300 			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
301 		} else {
302 			count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1);
303 			if (count == 0)
304 				count = W_B_FIFO_THRESH;
305 			W6692B_empty_fifo(bcs, count);
306 			if ((count = bcs->hw.w6692.rcvidx) > 0) {
307 				if (cs->debug & L1_DEB_HSCX_FIFO)
308 					debugl1(cs, "W6692 Bchan Frame %d", count);
309 				if (!(skb = dev_alloc_skb(count)))
310 					printk(KERN_WARNING "W6692: Bchan receive out of memory\n");
311 				else {
312 					memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count);
313 					skb_queue_tail(&bcs->rqueue, skb);
314 				}
315 			}
316 		}
317 		bcs->hw.w6692.rcvidx = 0;
318 		schedule_event(bcs, B_RCVBUFREADY);
319 	}
320 	if (val & W_B_EXI_RMR) {	/* RMR */
321 		W6692B_empty_fifo(bcs, W_B_FIFO_THRESH);
322 		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
323 		if (r & W_B_STAR_RDOV) {
324 			if (cs->debug & L1_DEB_WARN)
325 				debugl1(cs, "W6692 B RDOV(RMR) mode=%d",bcs->mode);
326 			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
327 			if (bcs->mode != L1_MODE_TRANS)
328 				bcs->hw.w6692.rcvidx = 0;
329 		}
330 		if (bcs->mode == L1_MODE_TRANS) {
331 			/* receive audio data */
332 			if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH)))
333 				printk(KERN_WARNING "HiSax: receive out of memory\n");
334 			else {
335 				memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH);
336 				skb_queue_tail(&bcs->rqueue, skb);
337 			}
338 			bcs->hw.w6692.rcvidx = 0;
339 			schedule_event(bcs, B_RCVBUFREADY);
340 		}
341 	}
342 	if (val & W_B_EXI_XDUN) {	/* XDUN */
343 		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
344 		if (cs->debug & L1_DEB_WARN)
345 			debugl1(cs, "W6692 B EXIR %x Lost TX", val);
346 		if (bcs->mode == 1)
347 			W6692B_fill_fifo(bcs);
348 		else {
349 			/* Here we lost an TX interrupt, so
350 			   * restart transmitting the whole frame.
351 			 */
352 			if (bcs->tx_skb) {
353 				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
354 				bcs->tx_cnt += bcs->hw.w6692.count;
355 				bcs->hw.w6692.count = 0;
356 			}
357 		}
358 		return;
359 	}
360 	if (val & W_B_EXI_XFR) {	/* XFR */
361 		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
362 		if (r & W_B_STAR_XDOW) {
363 			if (cs->debug & L1_DEB_WARN)
364 				debugl1(cs, "W6692 B STAR %x XDOW", r);
365 			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
366 			if (bcs->tx_skb && (bcs->mode != 1)) {
367 				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
368 				bcs->tx_cnt += bcs->hw.w6692.count;
369 				bcs->hw.w6692.count = 0;
370 			}
371 		}
372 		if (bcs->tx_skb) {
373 			if (bcs->tx_skb->len) {
374 				W6692B_fill_fifo(bcs);
375 				return;
376 			} else {
377 				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
378 					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
379 					u_long	flags;
380 					spin_lock_irqsave(&bcs->aclock, flags);
381 					bcs->ackcnt += bcs->hw.w6692.count;
382 					spin_unlock_irqrestore(&bcs->aclock, flags);
383 					schedule_event(bcs, B_ACKPENDING);
384 				}
385 				dev_kfree_skb_irq(bcs->tx_skb);
386 				bcs->hw.w6692.count = 0;
387 				bcs->tx_skb = NULL;
388 			}
389 		}
390 		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
391 			bcs->hw.w6692.count = 0;
392 			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
393 			W6692B_fill_fifo(bcs);
394 		} else {
395 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
396 			schedule_event(bcs, B_XMTBUFREADY);
397 		}
398 	}
399 }
400 
401 static irqreturn_t
W6692_interrupt(int intno,void * dev_id)402 W6692_interrupt(int intno, void *dev_id)
403 {
404 	struct IsdnCardState	*cs = dev_id;
405 	u_char			val, exval, v1;
406 	struct sk_buff		*skb;
407 	u_int			count;
408 	u_long			flags;
409 	int			icnt = 5;
410 
411 	spin_lock_irqsave(&cs->lock, flags);
412 	val = cs->readW6692(cs, W_ISTA);
413 	if (!val) {
414 		spin_unlock_irqrestore(&cs->lock, flags);
415 		return IRQ_NONE;
416 	}
417       StartW6692:
418 	if (cs->debug & L1_DEB_ISAC)
419 		debugl1(cs, "W6692 ISTA %x", val);
420 
421 	if (val & W_INT_D_RME) {	/* RME */
422 		exval = cs->readW6692(cs, W_D_RSTA);
423 		if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
424 			if (exval & W_D_RSTA_RDOV)
425 				if (cs->debug & L1_DEB_WARN)
426 					debugl1(cs, "W6692 RDOV");
427 			if (exval & W_D_RSTA_CRCE)
428 				if (cs->debug & L1_DEB_WARN)
429 					debugl1(cs, "W6692 D-channel CRC error");
430 			if (exval & W_D_RSTA_RMB)
431 				if (cs->debug & L1_DEB_WARN)
432 					debugl1(cs, "W6692 D-channel ABORT");
433 			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
434 		} else {
435 			count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
436 			if (count == 0)
437 				count = W_D_FIFO_THRESH;
438 			W6692_empty_fifo(cs, count);
439 			if ((count = cs->rcvidx) > 0) {
440 				cs->rcvidx = 0;
441 				if (!(skb = alloc_skb(count, GFP_ATOMIC)))
442 					printk(KERN_WARNING "HiSax: D receive out of memory\n");
443 				else {
444 					memcpy(skb_put(skb, count), cs->rcvbuf, count);
445 					skb_queue_tail(&cs->rq, skb);
446 				}
447 			}
448 		}
449 		cs->rcvidx = 0;
450 		schedule_event(cs, D_RCVBUFREADY);
451 	}
452 	if (val & W_INT_D_RMR) {	/* RMR */
453 		W6692_empty_fifo(cs, W_D_FIFO_THRESH);
454 	}
455 	if (val & W_INT_D_XFR) {	/* XFR */
456 		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
457 			del_timer(&cs->dbusytimer);
458 		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
459 			schedule_event(cs, D_CLEARBUSY);
460 		if (cs->tx_skb) {
461 			if (cs->tx_skb->len) {
462 				W6692_fill_fifo(cs);
463 				goto afterXFR;
464 			} else {
465 				dev_kfree_skb_irq(cs->tx_skb);
466 				cs->tx_cnt = 0;
467 				cs->tx_skb = NULL;
468 			}
469 		}
470 		if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
471 			cs->tx_cnt = 0;
472 			W6692_fill_fifo(cs);
473 		} else
474 			schedule_event(cs, D_XMTBUFREADY);
475 	}
476       afterXFR:
477 	if (val & (W_INT_XINT0 | W_INT_XINT1)) {	/* XINT0/1 - never */
478 		if (cs->debug & L1_DEB_ISAC)
479 			debugl1(cs, "W6692 spurious XINT!");
480 	}
481 	if (val & W_INT_D_EXI) {	/* EXI */
482 		exval = cs->readW6692(cs, W_D_EXIR);
483 		if (cs->debug & L1_DEB_WARN)
484 			debugl1(cs, "W6692 D_EXIR %02x", exval);
485 		if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {	/* Transmit underrun/collision */
486 			debugl1(cs, "W6692 D-chan underrun/collision");
487 			printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n");
488 			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
489 				del_timer(&cs->dbusytimer);
490 			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
491 				schedule_event(cs, D_CLEARBUSY);
492 			if (cs->tx_skb) {	/* Restart frame */
493 				skb_push(cs->tx_skb, cs->tx_cnt);
494 				cs->tx_cnt = 0;
495 				W6692_fill_fifo(cs);
496 			} else {
497 				printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n");
498 				debugl1(cs, "W6692 XDUN/XCOL no skb");
499 				cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);
500 			}
501 		}
502 		if (exval & W_D_EXI_RDOV) {	/* RDOV */
503 			debugl1(cs, "W6692 D-channel RDOV");
504 			printk(KERN_WARNING "HiSax: W6692 D-RDOV\n");
505 			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST);
506 		}
507 		if (exval & W_D_EXI_TIN2) {	/* TIN2 - never */
508 			debugl1(cs, "W6692 spurious TIN2 interrupt");
509 		}
510 		if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
511 			debugl1(cs, "W6692 spurious MOC interrupt");
512 			v1 = cs->readW6692(cs, W_MOSR);
513 			debugl1(cs, "W6692 MOSR %02x", v1);
514 		}
515 		if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
516 			v1 = cs->readW6692(cs, W_CIR);
517 			if (cs->debug & L1_DEB_ISAC)
518 				debugl1(cs, "W6692 ISC CIR=0x%02X", v1);
519 			if (v1 & W_CIR_ICC) {
520 				cs->dc.w6692.ph_state = v1 & W_CIR_COD_MASK;
521 				if (cs->debug & L1_DEB_ISAC)
522 					debugl1(cs, "ph_state_change %x", cs->dc.w6692.ph_state);
523 				schedule_event(cs, D_L1STATECHANGE);
524 			}
525 			if (v1 & W_CIR_SCC) {
526 				v1 = cs->readW6692(cs, W_SQR);
527 				debugl1(cs, "W6692 SCC SQR=0x%02X", v1);
528 			}
529 		}
530 		if (exval & W_D_EXI_WEXP) {
531 			debugl1(cs, "W6692 spurious WEXP interrupt!");
532 		}
533 		if (exval & W_D_EXI_TEXP) {
534 			debugl1(cs, "W6692 spurious TEXP interrupt!");
535 		}
536 	}
537 	if (val & W_INT_B1_EXI) {
538 		debugl1(cs, "W6692 B channel 1 interrupt");
539 		W6692B_interrupt(cs, 0);
540 	}
541 	if (val & W_INT_B2_EXI) {
542 		debugl1(cs, "W6692 B channel 2 interrupt");
543 		W6692B_interrupt(cs, 1);
544 	}
545 	val = cs->readW6692(cs, W_ISTA);
546 	if (val && icnt) {
547 		icnt--;
548 		goto StartW6692;
549 	}
550 	if (!icnt) {
551 		printk(KERN_WARNING "W6692 IRQ LOOP\n");
552 		cs->writeW6692(cs, W_IMASK, 0xff);
553 	}
554 	spin_unlock_irqrestore(&cs->lock, flags);
555 	return IRQ_HANDLED;
556 }
557 
558 static void
W6692_l1hw(struct PStack * st,int pr,void * arg)559 W6692_l1hw(struct PStack *st, int pr, void *arg)
560 {
561 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
562 	struct sk_buff *skb = arg;
563 	u_long flags;
564 	int val;
565 
566 	switch (pr) {
567 		case (PH_DATA | REQUEST):
568 			if (cs->debug & DEB_DLOG_HEX)
569 				LogFrame(cs, skb->data, skb->len);
570 			if (cs->debug & DEB_DLOG_VERBOSE)
571 				dlogframe(cs, skb, 0);
572 			spin_lock_irqsave(&cs->lock, flags);
573 			if (cs->tx_skb) {
574 				skb_queue_tail(&cs->sq, skb);
575 #ifdef L2FRAME_DEBUG		/* psa */
576 				if (cs->debug & L1_DEB_LAPD)
577 					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
578 #endif
579 			} else {
580 				cs->tx_skb = skb;
581 				cs->tx_cnt = 0;
582 #ifdef L2FRAME_DEBUG		/* psa */
583 				if (cs->debug & L1_DEB_LAPD)
584 					Logl2Frame(cs, skb, "PH_DATA", 0);
585 #endif
586 				W6692_fill_fifo(cs);
587 			}
588 			spin_unlock_irqrestore(&cs->lock, flags);
589 			break;
590 		case (PH_PULL | INDICATION):
591 			spin_lock_irqsave(&cs->lock, flags);
592 			if (cs->tx_skb) {
593 				if (cs->debug & L1_DEB_WARN)
594 					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
595 				skb_queue_tail(&cs->sq, skb);
596 				spin_unlock_irqrestore(&cs->lock, flags);
597 				break;
598 			}
599 			if (cs->debug & DEB_DLOG_HEX)
600 				LogFrame(cs, skb->data, skb->len);
601 			if (cs->debug & DEB_DLOG_VERBOSE)
602 				dlogframe(cs, skb, 0);
603 			cs->tx_skb = skb;
604 			cs->tx_cnt = 0;
605 #ifdef L2FRAME_DEBUG		/* psa */
606 			if (cs->debug & L1_DEB_LAPD)
607 				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
608 #endif
609 			W6692_fill_fifo(cs);
610 			spin_unlock_irqrestore(&cs->lock, flags);
611 			break;
612 		case (PH_PULL | REQUEST):
613 #ifdef L2FRAME_DEBUG		/* psa */
614 			if (cs->debug & L1_DEB_LAPD)
615 				debugl1(cs, "-> PH_REQUEST_PULL");
616 #endif
617 			if (!cs->tx_skb) {
618 				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
619 				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
620 			} else
621 				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
622 			break;
623 		case (HW_RESET | REQUEST):
624 			spin_lock_irqsave(&cs->lock, flags);
625 			if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) {
626 				ph_command(cs, W_L1CMD_ECK);
627 				spin_unlock_irqrestore(&cs->lock, flags);
628 			} else {
629 				ph_command(cs, W_L1CMD_RST);
630 				cs->dc.w6692.ph_state = W_L1CMD_RST;
631 				spin_unlock_irqrestore(&cs->lock, flags);
632 				W6692_new_ph(cs);
633 			}
634 			break;
635 		case (HW_ENABLE | REQUEST):
636 			spin_lock_irqsave(&cs->lock, flags);
637 			ph_command(cs, W_L1CMD_ECK);
638 			spin_unlock_irqrestore(&cs->lock, flags);
639 			break;
640 		case (HW_INFO3 | REQUEST):
641 			spin_lock_irqsave(&cs->lock, flags);
642 			ph_command(cs, W_L1CMD_AR8);
643 			spin_unlock_irqrestore(&cs->lock, flags);
644 			break;
645 		case (HW_TESTLOOP | REQUEST):
646 			val = 0;
647 			if (1 & (long) arg)
648 				val |= 0x0c;
649 			if (2 & (long) arg)
650 				val |= 0x3;
651 			/* !!! not implemented yet */
652 			break;
653 		case (HW_DEACTIVATE | RESPONSE):
654 			skb_queue_purge(&cs->rq);
655 			skb_queue_purge(&cs->sq);
656 			if (cs->tx_skb) {
657 				dev_kfree_skb_any(cs->tx_skb);
658 				cs->tx_skb = NULL;
659 			}
660 			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
661 				del_timer(&cs->dbusytimer);
662 			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
663 				schedule_event(cs, D_CLEARBUSY);
664 			break;
665 		default:
666 			if (cs->debug & L1_DEB_WARN)
667 				debugl1(cs, "W6692_l1hw unknown %04x", pr);
668 			break;
669 	}
670 }
671 
672 static void
setstack_W6692(struct PStack * st,struct IsdnCardState * cs)673 setstack_W6692(struct PStack *st, struct IsdnCardState *cs)
674 {
675 	st->l1.l1hw = W6692_l1hw;
676 }
677 
678 static void
DC_Close_W6692(struct IsdnCardState * cs)679 DC_Close_W6692(struct IsdnCardState *cs)
680 {
681 }
682 
683 static void
dbusy_timer_handler(struct IsdnCardState * cs)684 dbusy_timer_handler(struct IsdnCardState *cs)
685 {
686 	struct PStack *stptr;
687 	int rbch, star;
688 	u_long flags;
689 
690 	spin_lock_irqsave(&cs->lock, flags);
691 	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
692 		rbch = cs->readW6692(cs, W_D_RBCH);
693 		star = cs->readW6692(cs, W_D_STAR);
694 		if (cs->debug)
695 			debugl1(cs, "D-Channel Busy D_RBCH %02x D_STAR %02x",
696 				rbch, star);
697 		if (star & W_D_STAR_XBZ) {	/* D-Channel Busy */
698 			test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
699 			stptr = cs->stlist;
700 			while (stptr != NULL) {
701 				stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
702 				stptr = stptr->next;
703 			}
704 		} else {
705 			/* discard frame; reset transceiver */
706 			test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
707 			if (cs->tx_skb) {
708 				dev_kfree_skb_any(cs->tx_skb);
709 				cs->tx_cnt = 0;
710 				cs->tx_skb = NULL;
711 			} else {
712 				printk(KERN_WARNING "HiSax: W6692 D-Channel Busy no skb\n");
713 				debugl1(cs, "D-Channel Busy no skb");
714 			}
715 			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);	/* Transmitter reset */
716 			spin_unlock_irqrestore(&cs->lock, flags);
717 			cs->irq_func(cs->irq, cs);
718 			return;
719 		}
720 	}
721 	spin_unlock_irqrestore(&cs->lock, flags);
722 }
723 
724 static void
W6692Bmode(struct BCState * bcs,int mode,int bchan)725 W6692Bmode(struct BCState *bcs, int mode, int bchan)
726 {
727 	struct IsdnCardState *cs = bcs->cs;
728 
729 	if (cs->debug & L1_DEB_HSCX)
730 		debugl1(cs, "w6692 %c mode %d ichan %d",
731 			'1' + bchan, mode, bchan);
732 	bcs->mode = mode;
733 	bcs->channel = bchan;
734 	bcs->hw.w6692.bchan = bchan;
735 
736 	switch (mode) {
737 		case (L1_MODE_NULL):
738 			cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0);
739 			break;
740 		case (L1_MODE_TRANS):
741 			cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS);
742 			break;
743 		case (L1_MODE_HDLC):
744 			cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF);
745 			cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff);
746 			cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff);
747 			break;
748 	}
749 	if (mode)
750 		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RRST |
751 				 W_B_CMDR_RACT | W_B_CMDR_XRST);
752 	cs->BC_Write_Reg(cs, bchan, W_B_EXIM, 0x00);
753 }
754 
755 static void
W6692_l2l1(struct PStack * st,int pr,void * arg)756 W6692_l2l1(struct PStack *st, int pr, void *arg)
757 {
758 	struct sk_buff *skb = arg;
759 	struct BCState *bcs = st->l1.bcs;
760 	u_long flags;
761 
762 	switch (pr) {
763 		case (PH_DATA | REQUEST):
764 			spin_lock_irqsave(&bcs->cs->lock, flags);
765 			if (bcs->tx_skb) {
766 				skb_queue_tail(&bcs->squeue, skb);
767 			} else {
768 				bcs->tx_skb = skb;
769 				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
770 				bcs->hw.w6692.count = 0;
771 				bcs->cs->BC_Send_Data(bcs);
772 			}
773 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
774 			break;
775 		case (PH_PULL | INDICATION):
776 			if (bcs->tx_skb) {
777 				printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n");
778 				break;
779 			}
780 			spin_lock_irqsave(&bcs->cs->lock, flags);
781 			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
782 			bcs->tx_skb = skb;
783 			bcs->hw.w6692.count = 0;
784 			bcs->cs->BC_Send_Data(bcs);
785 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
786 			break;
787 		case (PH_PULL | REQUEST):
788 			if (!bcs->tx_skb) {
789 				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
790 				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
791 			} else
792 				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
793 			break;
794 		case (PH_ACTIVATE | REQUEST):
795 			spin_lock_irqsave(&bcs->cs->lock, flags);
796 			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
797 			W6692Bmode(bcs, st->l1.mode, st->l1.bc);
798 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
799 			l1_msg_b(st, pr, arg);
800 			break;
801 		case (PH_DEACTIVATE | REQUEST):
802 			l1_msg_b(st, pr, arg);
803 			break;
804 		case (PH_DEACTIVATE | CONFIRM):
805 			spin_lock_irqsave(&bcs->cs->lock, flags);
806 			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
807 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
808 			W6692Bmode(bcs, 0, st->l1.bc);
809 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
810 			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
811 			break;
812 	}
813 }
814 
815 static void
close_w6692state(struct BCState * bcs)816 close_w6692state(struct BCState *bcs)
817 {
818 	W6692Bmode(bcs, 0, bcs->channel);
819 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
820 		kfree(bcs->hw.w6692.rcvbuf);
821 		bcs->hw.w6692.rcvbuf = NULL;
822 		kfree(bcs->blog);
823 		bcs->blog = NULL;
824 		skb_queue_purge(&bcs->rqueue);
825 		skb_queue_purge(&bcs->squeue);
826 		if (bcs->tx_skb) {
827 			dev_kfree_skb_any(bcs->tx_skb);
828 			bcs->tx_skb = NULL;
829 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
830 		}
831 	}
832 }
833 
834 static int
open_w6692state(struct IsdnCardState * cs,struct BCState * bcs)835 open_w6692state(struct IsdnCardState *cs, struct BCState *bcs)
836 {
837 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
838 		if (!(bcs->hw.w6692.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
839 			printk(KERN_WARNING
840 			       "HiSax: No memory for w6692.rcvbuf\n");
841 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
842 			return (1);
843 		}
844 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
845 			printk(KERN_WARNING
846 			       "HiSax: No memory for bcs->blog\n");
847 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
848 			kfree(bcs->hw.w6692.rcvbuf);
849 			bcs->hw.w6692.rcvbuf = NULL;
850 			return (2);
851 		}
852 		skb_queue_head_init(&bcs->rqueue);
853 		skb_queue_head_init(&bcs->squeue);
854 	}
855 	bcs->tx_skb = NULL;
856 	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
857 	bcs->event = 0;
858 	bcs->hw.w6692.rcvidx = 0;
859 	bcs->tx_cnt = 0;
860 	return (0);
861 }
862 
863 static int
setstack_w6692(struct PStack * st,struct BCState * bcs)864 setstack_w6692(struct PStack *st, struct BCState *bcs)
865 {
866 	bcs->channel = st->l1.bc;
867 	if (open_w6692state(st->l1.hardware, bcs))
868 		return (-1);
869 	st->l1.bcs = bcs;
870 	st->l2.l2l1 = W6692_l2l1;
871 	setstack_manager(st);
872 	bcs->st = st;
873 	setstack_l1_B(st);
874 	return (0);
875 }
876 
resetW6692(struct IsdnCardState * cs)877 static void resetW6692(struct IsdnCardState *cs)
878 {
879 	cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
880 	mdelay(10);
881 	cs->writeW6692(cs, W_D_CTL, 0x00);
882 	mdelay(10);
883 	cs->writeW6692(cs, W_IMASK, 0xff);
884 	cs->writeW6692(cs, W_D_SAM, 0xff);
885 	cs->writeW6692(cs, W_D_TAM, 0xff);
886 	cs->writeW6692(cs, W_D_EXIM, 0x00);
887 	cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
888 	cs->writeW6692(cs, W_IMASK, 0x18);
889 	if (cs->subtyp == W6692_USR) {
890 		/* seems that USR implemented some power control features
891 		 * Pin 79 is connected to the oscilator circuit so we
892 		 * have to handle it here
893 		 */
894 		cs->writeW6692(cs, W_PCTL, 0x80);
895 		cs->writeW6692(cs, W_XDATA, 0x00);
896 	}
897 }
898 
initW6692(struct IsdnCardState * cs,int part)899 static void initW6692(struct IsdnCardState *cs, int part)
900 {
901 	if (part & 1) {
902 		cs->setstack_d = setstack_W6692;
903 		cs->DC_Close = DC_Close_W6692;
904 		cs->dbusytimer.function = (void *) dbusy_timer_handler;
905 		cs->dbusytimer.data = (long) cs;
906 		init_timer(&cs->dbusytimer);
907 		resetW6692(cs);
908 		ph_command(cs, W_L1CMD_RST);
909 		cs->dc.w6692.ph_state = W_L1CMD_RST;
910 		W6692_new_ph(cs);
911 		ph_command(cs, W_L1CMD_ECK);
912 
913 		cs->bcs[0].BC_SetStack = setstack_w6692;
914 		cs->bcs[1].BC_SetStack = setstack_w6692;
915 		cs->bcs[0].BC_Close = close_w6692state;
916 		cs->bcs[1].BC_Close = close_w6692state;
917 		W6692Bmode(cs->bcs, 0, 0);
918 		W6692Bmode(cs->bcs + 1, 0, 0);
919 	}
920 	if (part & 2) {
921 		/* Reenable all IRQ */
922 		cs->writeW6692(cs, W_IMASK, 0x18);
923 		cs->writeW6692(cs, W_D_EXIM, 0x00);
924 		cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00);
925 		cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00);
926 		/* Reset D-chan receiver and transmitter */
927 		cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
928 	}
929 }
930 
931 /* Interface functions */
932 
933 static u_char
ReadW6692(struct IsdnCardState * cs,u_char offset)934 ReadW6692(struct IsdnCardState *cs, u_char offset)
935 {
936 	return (inb(cs->hw.w6692.iobase + offset));
937 }
938 
939 static void
WriteW6692(struct IsdnCardState * cs,u_char offset,u_char value)940 WriteW6692(struct IsdnCardState *cs, u_char offset, u_char value)
941 {
942 	outb(value, cs->hw.w6692.iobase + offset);
943 }
944 
945 static void
ReadISACfifo(struct IsdnCardState * cs,u_char * data,int size)946 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
947 {
948 	insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size);
949 }
950 
951 static void
WriteISACfifo(struct IsdnCardState * cs,u_char * data,int size)952 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
953 {
954 	outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size);
955 }
956 
957 static u_char
ReadW6692B(struct IsdnCardState * cs,int bchan,u_char offset)958 ReadW6692B(struct IsdnCardState *cs, int bchan, u_char offset)
959 {
960 	return (inb(cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset));
961 }
962 
963 static void
WriteW6692B(struct IsdnCardState * cs,int bchan,u_char offset,u_char value)964 WriteW6692B(struct IsdnCardState *cs, int bchan, u_char offset, u_char value)
965 {
966 	outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset);
967 }
968 
969 static int
w6692_card_msg(struct IsdnCardState * cs,int mt,void * arg)970 w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
971 {
972 	switch (mt) {
973 		case CARD_RESET:
974 			resetW6692(cs);
975 			return (0);
976 		case CARD_RELEASE:
977 			cs->writeW6692(cs, W_IMASK, 0xff);
978 			release_region(cs->hw.w6692.iobase, 256);
979 			if (cs->subtyp == W6692_USR) {
980 				cs->writeW6692(cs, W_XDATA, 0x04);
981 			}
982 			return (0);
983 		case CARD_INIT:
984 			initW6692(cs, 3);
985 			return (0);
986 		case CARD_TEST:
987 			return (0);
988 	}
989 	return (0);
990 }
991 
992 static int id_idx ;
993 
994 static struct pci_dev *dev_w6692 __devinitdata = NULL;
995 
996 int __devinit
setup_w6692(struct IsdnCard * card)997 setup_w6692(struct IsdnCard *card)
998 {
999 	struct IsdnCardState *cs = card->cs;
1000 	char tmp[64];
1001 	u_char found = 0;
1002 	u_char pci_irq = 0;
1003 	u_int pci_ioaddr = 0;
1004 
1005 	strcpy(tmp, w6692_revision);
1006 	printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp));
1007 	if (cs->typ != ISDN_CTYPE_W6692)
1008 		return (0);
1009 
1010 	while (id_list[id_idx].vendor_id) {
1011 		dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
1012 					    id_list[id_idx].device_id,
1013 					    dev_w6692);
1014 		if (dev_w6692) {
1015 			if (pci_enable_device(dev_w6692))
1016 				continue;
1017 			cs->subtyp = id_idx;
1018 			break;
1019 		}
1020 		id_idx++;
1021 	}
1022 	if (dev_w6692) {
1023 		found = 1;
1024 		pci_irq = dev_w6692->irq;
1025 		/* I think address 0 is allways the configuration area */
1026 		/* and address 1 is the real IO space KKe 03.09.99 */
1027 		pci_ioaddr = pci_resource_start(dev_w6692, 1);
1028 		/* USR ISDN PCI card TA need some special handling */
1029 		if (cs->subtyp == W6692_WINBOND) {
1030 			if ((W6692_SV_USR == dev_w6692->subsystem_vendor) &&
1031 			    (W6692_SD_USR == dev_w6692->subsystem_device)) {
1032 				cs->subtyp = W6692_USR;
1033 			}
1034 		}
1035 	}
1036 	if (!found) {
1037 		printk(KERN_WARNING "W6692: No PCI card found\n");
1038 		return (0);
1039 	}
1040 	cs->irq = pci_irq;
1041 	if (!cs->irq) {
1042 		printk(KERN_WARNING "W6692: No IRQ for PCI card found\n");
1043 		return (0);
1044 	}
1045 	if (!pci_ioaddr) {
1046 		printk(KERN_WARNING "W6692: NO I/O Base Address found\n");
1047 		return (0);
1048 	}
1049 	cs->hw.w6692.iobase = pci_ioaddr;
1050 	printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
1051 	       id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
1052 	       pci_ioaddr, pci_irq);
1053 	if (!request_region(cs->hw.w6692.iobase, 256, id_list[cs->subtyp].card_name)) {
1054 		printk(KERN_WARNING
1055 		       "HiSax: %s I/O ports %x-%x already in use\n",
1056 		       id_list[cs->subtyp].card_name,
1057 		       cs->hw.w6692.iobase,
1058 		       cs->hw.w6692.iobase + 255);
1059 		return (0);
1060 	}
1061 
1062 	printk(KERN_INFO
1063 	       "HiSax: %s config irq:%d I/O:%x\n",
1064 	       id_list[cs->subtyp].card_name, cs->irq,
1065 	       cs->hw.w6692.iobase);
1066 
1067 	INIT_WORK(&cs->tqueue, W6692_bh);
1068 	cs->readW6692 = &ReadW6692;
1069 	cs->writeW6692 = &WriteW6692;
1070 	cs->readisacfifo = &ReadISACfifo;
1071 	cs->writeisacfifo = &WriteISACfifo;
1072 	cs->BC_Read_Reg = &ReadW6692B;
1073 	cs->BC_Write_Reg = &WriteW6692B;
1074 	cs->BC_Send_Data = &W6692B_fill_fifo;
1075 	cs->cardmsg = &w6692_card_msg;
1076 	cs->irq_func = &W6692_interrupt;
1077 	cs->irq_flags |= IRQF_SHARED;
1078 	W6692Version(cs, "W6692:");
1079 	printk(KERN_INFO "W6692 ISTA=0x%X\n", ReadW6692(cs, W_ISTA));
1080 	printk(KERN_INFO "W6692 IMASK=0x%X\n", ReadW6692(cs, W_IMASK));
1081 	printk(KERN_INFO "W6692 D_EXIR=0x%X\n", ReadW6692(cs, W_D_EXIR));
1082 	printk(KERN_INFO "W6692 D_EXIM=0x%X\n", ReadW6692(cs, W_D_EXIM));
1083 	printk(KERN_INFO "W6692 D_RSTA=0x%X\n", ReadW6692(cs, W_D_RSTA));
1084 	return (1);
1085 }
1086