Import 2.3.10pre5
[davej-history.git] / drivers / isdn / hisax / netjet.c
blob75696ad2c1ca649986c1bc7deb51a291bba712c0
1 /* $Id: netjet.c,v 1.8 1998/11/15 23:55:14 keil Exp $
3 * netjet.c low level stuff for Traverse Technologie NETJet ISDN cards
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * Thanks to Traverse Technologie Australia for documents and informations
10 * $Log: netjet.c,v $
11 * Revision 1.8 1998/11/15 23:55:14 keil
12 * changes from 2.0
14 * Revision 1.7 1998/09/30 22:24:48 keil
15 * Fix missing line in setstack*
17 * Revision 1.6 1998/08/13 23:36:54 keil
18 * HiSax 3.1 - don't work stable with current LinkLevel
20 * Revision 1.5 1998/05/25 12:58:21 keil
21 * HiSax golden code from certification, Don't use !!!
22 * No leased lines, no X75, but many changes.
24 * Revision 1.4 1998/04/15 16:42:35 keil
25 * new init code
26 * new PCI init (2.1.94)
28 * Revision 1.3 1998/02/12 23:08:05 keil
29 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
31 * Revision 1.2 1998/02/02 13:32:06 keil
32 * New
38 #define __NO_VERSION__
39 #include <linux/config.h>
40 #include "hisax.h"
41 #include "isac.h"
42 #include "hscx.h"
43 #include "isdnl1.h"
44 #include <linux/pci.h>
45 #include <linux/interrupt.h>
46 #include <linux/ppp_defs.h>
48 extern const char *CardType[];
50 const char *NETjet_revision = "$Revision: 1.8 $";
52 #define byteout(addr,val) outb(val,addr)
53 #define bytein(addr) inb(addr)
55 /* PCI stuff */
56 #define PCI_VENDOR_TRAVERSE_TECH 0xe159
57 #define PCI_NETJET_ID 0x0001
59 #define NETJET_CTRL 0x00
60 #define NETJET_DMACTRL 0x01
61 #define NETJET_AUXCTRL 0x02
62 #define NETJET_AUXDATA 0x03
63 #define NETJET_IRQMASK0 0x04
64 #define NETJET_IRQMASK1 0x05
65 #define NETJET_IRQSTAT0 0x06
66 #define NETJET_IRQSTAT1 0x07
67 #define NETJET_DMA_READ_START 0x08
68 #define NETJET_DMA_READ_IRQ 0x0c
69 #define NETJET_DMA_READ_END 0x10
70 #define NETJET_DMA_READ_ADR 0x14
71 #define NETJET_DMA_WRITE_START 0x18
72 #define NETJET_DMA_WRITE_IRQ 0x1c
73 #define NETJET_DMA_WRITE_END 0x20
74 #define NETJET_DMA_WRITE_ADR 0x24
75 #define NETJET_PULSE_CNT 0x28
77 #define NETJET_ISAC_OFF 0xc0
78 #define NETJET_ISACIRQ 0x10
79 #define NETJET_IRQM0_READ 0x0c
80 #define NETJET_IRQM0_READ_1 0x04
81 #define NETJET_IRQM0_READ_2 0x08
82 #define NETJET_IRQM0_WRITE 0x03
83 #define NETJET_IRQM0_WRITE_1 0x01
84 #define NETJET_IRQM0_WRITE_2 0x02
86 #define NETJET_DMA_SIZE 512
88 #define HDLC_ZERO_SEARCH 0
89 #define HDLC_FLAG_SEARCH 1
90 #define HDLC_FLAG_FOUND 2
91 #define HDLC_FRAME_FOUND 3
92 #define HDLC_NULL 4
93 #define HDLC_PART 5
94 #define HDLC_FULL 6
96 #define HDLC_FLAG_VALUE 0x7e
98 /* Interface functions */
100 static u_char
101 ReadISAC(struct IsdnCardState *cs, u_char offset)
103 long flags;
104 u_char ret;
106 save_flags(flags);
107 cli();
108 cs->hw.njet.auxd &= 0xfc;
109 cs->hw.njet.auxd |= (offset>>4) & 3;
110 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
111 ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2));
112 restore_flags(flags);
113 return(ret);
116 static void
117 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
119 long flags;
121 save_flags(flags);
122 cli();
123 cs->hw.njet.auxd &= 0xfc;
124 cs->hw.njet.auxd |= (offset>>4) & 3;
125 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
126 byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value);
127 restore_flags(flags);
130 static void
131 ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
133 cs->hw.njet.auxd &= 0xfc;
134 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
135 insb(cs->hw.njet.isac, data, size);
138 __u16 fcstab[256] =
140 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
141 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
142 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
143 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
144 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
145 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
146 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
147 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
148 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
149 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
150 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
151 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
152 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
153 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
154 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
155 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
156 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
157 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
158 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
159 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
160 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
161 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
162 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
163 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
164 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
165 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
166 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
167 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
168 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
169 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
170 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
171 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
174 static void
175 WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
177 cs->hw.njet.auxd &= 0xfc;
178 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
179 outsb(cs->hw.njet.isac, data, size);
182 void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
184 u_int mask=0x000000ff, val = 0, *p=pos;
185 u_int i;
187 val |= fill;
188 if (chan) {
189 val <<= 8;
190 mask <<= 8;
192 mask ^= 0xffffffff;
193 for (i=0; i<cnt; i++) {
194 *p &= mask;
195 *p++ |= val;
196 if (p > bcs->hw.tiger.s_end)
197 p = bcs->hw.tiger.send;
201 void
202 mode_tiger(struct BCState *bcs, int mode, int bc)
204 struct IsdnCardState *cs = bcs->cs;
206 if (cs->debug & L1_DEB_HSCX)
207 debugl1(cs, "Tiger mode %d bchan %d/%d",
208 mode, bc, bcs->channel);
209 bcs->mode = mode;
210 bcs->channel = bc;
211 switch (mode) {
212 case (L1_MODE_NULL):
213 fill_mem(bcs, bcs->hw.tiger.send,
214 NETJET_DMA_SIZE, bc, 0xff);
215 if (cs->debug & L1_DEB_HSCX)
216 debugl1(cs, "Tiger stat rec %d/%d send %d",
217 bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
218 bcs->hw.tiger.s_tot);
219 if ((cs->bcs[0].mode == L1_MODE_NULL) &&
220 (cs->bcs[1].mode == L1_MODE_NULL)) {
221 cs->hw.njet.dmactrl = 0;
222 byteout(cs->hw.njet.base + NETJET_DMACTRL,
223 cs->hw.njet.dmactrl);
224 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
226 break;
227 case (L1_MODE_TRANS):
228 break;
229 case (L1_MODE_HDLC):
230 fill_mem(bcs, bcs->hw.tiger.send,
231 NETJET_DMA_SIZE, bc, 0xff);
232 bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
233 bcs->hw.tiger.r_tot = 0;
234 bcs->hw.tiger.r_bitcnt = 0;
235 bcs->hw.tiger.r_one = 0;
236 bcs->hw.tiger.r_err = 0;
237 bcs->hw.tiger.s_tot = 0;
238 if (! cs->hw.njet.dmactrl) {
239 fill_mem(bcs, bcs->hw.tiger.send,
240 NETJET_DMA_SIZE, !bc, 0xff);
241 cs->hw.njet.dmactrl = 1;
242 byteout(cs->hw.njet.base + NETJET_DMACTRL,
243 cs->hw.njet.dmactrl);
244 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x3f);
246 bcs->hw.tiger.sendp = bcs->hw.tiger.send;
247 bcs->hw.tiger.free = NETJET_DMA_SIZE;
248 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
249 break;
251 if (cs->debug & L1_DEB_HSCX)
252 debugl1(cs, "tiger: set %x %x %x %x/%x pulse=%d",
253 bytein(cs->hw.njet.base + NETJET_DMACTRL),
254 bytein(cs->hw.njet.base + NETJET_IRQMASK0),
255 bytein(cs->hw.njet.base + NETJET_IRQSTAT0),
256 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
257 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
258 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
261 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
263 return(5);
266 static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value)
270 static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
271 char tmp[128];
272 char *t = tmp;
273 int i=count,j;
274 u_char *p = buf;
276 t += sprintf(t, "tiger %s(%4d)", s, count);
277 while (i>0) {
278 if (i>16)
279 j=16;
280 else
281 j=i;
282 QuickHex(t, p, j);
283 debugl1(cs, tmp);
284 p += j;
285 i -= j;
286 t = tmp;
287 t += sprintf(t, "tiger %s ", s);
291 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
292 bitcnt++;\
293 s_val >>= 1;\
294 if (val & 1) {\
295 s_one++;\
296 s_val |= 0x80;\
297 } else {\
298 s_one = 0;\
299 s_val &= 0x7f;\
301 if (bitcnt==8) {\
302 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
303 bitcnt = 0;\
305 if (s_one == 5) {\
306 s_val >>= 1;\
307 s_val &= 0x7f;\
308 bitcnt++;\
309 s_one = 0;\
311 if (bitcnt==8) {\
312 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
313 bitcnt = 0;\
315 val >>= 1;\
318 static int make_raw_data(struct BCState *bcs) {
319 register u_int i,s_cnt=0;
320 register u_char j;
321 register u_char val;
322 register u_char s_one = 0;
323 register u_char s_val = 0;
324 register u_char bitcnt = 0;
325 u_int fcs;
327 if (!bcs->tx_skb) {
328 debugl1(bcs->cs, "tiger make_raw: NULL skb");
329 return(1);
331 bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
332 fcs = PPP_INITFCS;
333 for (i=0; i<bcs->tx_skb->len; i++) {
334 val = bcs->tx_skb->data[i];
335 fcs = PPP_FCS (fcs, val);
336 MAKE_RAW_BYTE;
338 fcs ^= 0xffff;
339 val = fcs & 0xff;
340 MAKE_RAW_BYTE;
341 val = (fcs>>8) & 0xff;
342 MAKE_RAW_BYTE;
343 val = HDLC_FLAG_VALUE;
344 for (j=0; j<8; j++) {
345 bitcnt++;
346 s_val >>= 1;
347 if (val & 1)
348 s_val |= 0x80;
349 else
350 s_val &= 0x7f;
351 if (bitcnt==8) {
352 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
353 bitcnt = 0;
355 val >>= 1;
357 if (bcs->cs->debug & L1_DEB_HSCX)
358 debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d",
359 bcs->tx_skb->len, s_cnt, bitcnt);
360 if (bitcnt) {
361 while (8>bitcnt++) {
362 s_val >>= 1;
363 s_val |= 0x80;
365 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
367 bcs->hw.tiger.sendcnt = s_cnt;
368 bcs->tx_cnt -= bcs->tx_skb->len;
369 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
370 return(0);
373 static void got_frame(struct BCState *bcs, int count) {
374 struct sk_buff *skb;
376 if (!(skb = dev_alloc_skb(count)))
377 printk(KERN_WARNING "TIGER: receive out of memory\n");
378 else {
379 memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count);
380 skb_queue_tail(&bcs->rqueue, skb);
382 bcs->event |= 1 << B_RCVBUFREADY;
383 queue_task(&bcs->tqueue, &tq_immediate);
384 mark_bh(IMMEDIATE_BH);
386 if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
387 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
392 static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
393 int i;
394 register u_char j;
395 register u_char val;
396 u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_SIZE -1;
397 register u_char state = bcs->hw.tiger.r_state;
398 register u_char r_one = bcs->hw.tiger.r_one;
399 register u_char r_val = bcs->hw.tiger.r_val;
400 register u_int bitcnt = bcs->hw.tiger.r_bitcnt;
401 u_int *p = buf;
403 for (i=0;i<cnt;i++) {
404 val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
405 p++;
406 if (p > pend)
407 p = bcs->hw.tiger.rec;
408 if (val == 0xff) {
409 state = HDLC_ZERO_SEARCH;
410 bcs->hw.tiger.r_tot++;
411 bitcnt = 0;
412 r_one = 0;
413 continue;
415 for (j=0;j<8;j++) {
416 if (state == HDLC_ZERO_SEARCH) {
417 if (val & 1) {
418 r_one++;
419 } else {
420 r_one=0;
421 state= HDLC_FLAG_SEARCH;
422 if (bcs->cs->debug & L1_DEB_HSCX)
423 debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x",
424 bcs->hw.tiger.r_tot,i,j,val);
426 } else if (state == HDLC_FLAG_SEARCH) {
427 if (val & 1) {
428 r_one++;
429 if (r_one>6) {
430 state=HDLC_ZERO_SEARCH;
432 } else {
433 if (r_one==6) {
434 bitcnt=0;
435 r_val=0;
436 state=HDLC_FLAG_FOUND;
437 if (bcs->cs->debug & L1_DEB_HSCX)
438 debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x",
439 bcs->hw.tiger.r_tot,i,j,val);
441 r_one=0;
443 } else if (state == HDLC_FLAG_FOUND) {
444 if (val & 1) {
445 r_one++;
446 if (r_one>6) {
447 state=HDLC_ZERO_SEARCH;
448 } else {
449 r_val >>= 1;
450 r_val |= 0x80;
451 bitcnt++;
453 } else {
454 if (r_one==6) {
455 bitcnt=0;
456 r_val=0;
457 r_one=0;
458 val >>= 1;
459 continue;
460 } else if (r_one!=5) {
461 r_val >>= 1;
462 r_val &= 0x7f;
463 bitcnt++;
465 r_one=0;
467 if ((state != HDLC_ZERO_SEARCH) &&
468 !(bitcnt & 7)) {
469 state=HDLC_FRAME_FOUND;
470 bcs->hw.tiger.r_fcs = PPP_INITFCS;
471 bcs->hw.tiger.rcvbuf[0] = r_val;
472 bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
473 if (bcs->cs->debug & L1_DEB_HSCX)
474 debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
475 bcs->hw.tiger.r_tot,i,j,r_val,val,
476 bcs->cs->hw.njet.irqstat0);
478 } else if (state == HDLC_FRAME_FOUND) {
479 if (val & 1) {
480 r_one++;
481 if (r_one>6) {
482 state=HDLC_ZERO_SEARCH;
483 bitcnt=0;
484 } else {
485 r_val >>= 1;
486 r_val |= 0x80;
487 bitcnt++;
489 } else {
490 if (r_one==6) {
491 r_val=0;
492 r_one=0;
493 bitcnt++;
494 if (bitcnt & 7) {
495 debugl1(bcs->cs, "tiger: frame not byte aligned");
496 state=HDLC_FLAG_SEARCH;
497 bcs->hw.tiger.r_err++;
498 } else {
499 if (bcs->cs->debug & L1_DEB_HSCX)
500 debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",
501 i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
502 if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {
503 got_frame(bcs, (bitcnt>>3)-3);
504 } else
505 if (bcs->cs->debug) {
506 debugl1(bcs->cs, "tiger FCS error");
507 printframe(bcs->cs, bcs->hw.tiger.rcvbuf,
508 (bitcnt>>3)-1, "rec");
509 bcs->hw.tiger.r_err++;
511 state=HDLC_FLAG_FOUND;
513 bitcnt=0;
514 } else if (r_one==5) {
515 val >>= 1;
516 r_one=0;
517 continue;
518 } else {
519 r_val >>= 1;
520 r_val &= 0x7f;
521 bitcnt++;
523 r_one=0;
525 if ((state == HDLC_FRAME_FOUND) &&
526 !(bitcnt & 7)) {
527 if ((bitcnt>>3)>=HSCX_BUFMAX) {
528 debugl1(bcs->cs, "tiger: frame to big");
529 r_val=0;
530 state=HDLC_FLAG_SEARCH;
531 bcs->hw.tiger.r_err++;
532 } else {
533 bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;
534 bcs->hw.tiger.r_fcs =
535 PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
539 val >>= 1;
541 bcs->hw.tiger.r_tot++;
543 bcs->hw.tiger.r_state = state;
544 bcs->hw.tiger.r_one = r_one;
545 bcs->hw.tiger.r_val = r_val;
546 bcs->hw.tiger.r_bitcnt = bitcnt;
549 static void read_tiger(struct IsdnCardState *cs) {
550 u_int *p;
551 int cnt = NETJET_DMA_SIZE/2;
553 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {
554 debugl1(cs,"tiger warn read double dma %x/%x",
555 cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
556 return;
557 } else {
558 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
559 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
561 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
562 p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1;
563 else
564 p = cs->bcs[0].hw.tiger.rec + cnt - 1;
565 if (cs->bcs[0].mode == L1_MODE_HDLC)
566 read_raw(cs->bcs, p, cnt);
567 if (cs->bcs[1].mode == L1_MODE_HDLC)
568 read_raw(cs->bcs + 1, p, cnt);
569 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;
572 static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
574 static void fill_dma(struct BCState *bcs)
576 register u_int *p, *sp;
577 register int cnt;
579 if (!bcs->tx_skb)
580 return;
581 if (bcs->cs->debug & L1_DEB_HSCX)
582 debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
583 bcs->Flag);
584 if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
585 return;
586 if (make_raw_data(bcs))
587 return;
588 if (bcs->cs->debug & L1_DEB_HSCX)
589 debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
590 bcs->Flag);
591 if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
592 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
593 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
594 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
595 sp = bcs->hw.tiger.sendp;
596 if (p == bcs->hw.tiger.s_end)
597 p = bcs->hw.tiger.send -1;
598 if (sp == bcs->hw.tiger.s_end)
599 sp = bcs->hw.tiger.send -1;
600 cnt = p - sp;
601 if (cnt <0) {
602 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
603 } else {
604 p++;
605 cnt++;
606 if (p > bcs->hw.tiger.s_end)
607 p = bcs->hw.tiger.send;
608 p++;
609 cnt++;
610 if (p > bcs->hw.tiger.s_end)
611 p = bcs->hw.tiger.send;
612 write_raw(bcs, p, bcs->hw.tiger.free - cnt);
614 } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) {
615 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
616 cnt = bcs->hw.tiger.s_end - p;
617 if (cnt < 2) {
618 p = bcs->hw.tiger.send + 1;
619 cnt = NETJET_DMA_SIZE/2 - 2;
620 } else {
621 p++;
622 p++;
623 if (cnt <= (NETJET_DMA_SIZE/2))
624 cnt += NETJET_DMA_SIZE/2;
625 cnt--;
626 cnt--;
628 write_raw(bcs, p, cnt);
630 if (bcs->cs->debug & L1_DEB_HSCX)
631 debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
632 bcs->Flag);
635 static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
636 u_int mask, val, *p=buf;
637 u_int i, s_cnt;
639 if (cnt <= 0)
640 return;
641 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
642 if (bcs->hw.tiger.sendcnt> cnt) {
643 s_cnt = cnt;
644 bcs->hw.tiger.sendcnt -= cnt;
645 } else {
646 s_cnt = bcs->hw.tiger.sendcnt;
647 bcs->hw.tiger.sendcnt = 0;
649 if (bcs->channel)
650 mask = 0xffff00ff;
651 else
652 mask = 0xffffff00;
653 for (i=0; i<s_cnt; i++) {
654 val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :
655 (bcs->hw.tiger.sp[i]);
656 *p &= mask;
657 *p++ |= val;
658 if (p>bcs->hw.tiger.s_end)
659 p = bcs->hw.tiger.send;
661 bcs->hw.tiger.s_tot += s_cnt;
662 if (bcs->cs->debug & L1_DEB_HSCX)
663 debugl1(bcs->cs,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs->channel,
664 (u_int)buf, (u_int)p, s_cnt, cnt,
665 bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);
666 if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
667 printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd");
668 bcs->hw.tiger.sp += s_cnt;
669 bcs->hw.tiger.sendp = p;
670 if (!bcs->hw.tiger.sendcnt) {
671 if (!bcs->tx_skb) {
672 debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
673 } else {
674 if (bcs->st->lli.l1writewakeup &&
675 (PACKET_NOACK != bcs->tx_skb->pkt_type))
676 bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
677 dev_kfree_skb(bcs->tx_skb);
678 bcs->tx_skb = NULL;
680 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
681 bcs->hw.tiger.free = cnt - s_cnt;
682 if (bcs->hw.tiger.free > (NETJET_DMA_SIZE/2))
683 test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
684 else {
685 test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
686 test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
688 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
689 fill_dma(bcs);
690 } else {
691 mask ^= 0xffffffff;
692 if (s_cnt < cnt) {
693 for (i=s_cnt; i<cnt;i++) {
694 *p++ |= mask;
695 if (p>bcs->hw.tiger.s_end)
696 p = bcs->hw.tiger.send;
698 if (bcs->cs->debug & L1_DEB_HSCX)
699 debugl1(bcs->cs, "tiger write_raw: fill rest %d",
700 cnt - s_cnt);
702 bcs->event |= 1 << B_XMTBUFREADY;
703 queue_task(&bcs->tqueue, &tq_immediate);
704 mark_bh(IMMEDIATE_BH);
707 } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
708 test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
709 fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
710 bcs->hw.tiger.free += cnt;
711 if (bcs->cs->debug & L1_DEB_HSCX)
712 debugl1(bcs->cs,"tiger write_raw: fill half");
713 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
714 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
715 fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
716 if (bcs->cs->debug & L1_DEB_HSCX)
717 debugl1(bcs->cs,"tiger write_raw: fill full");
721 static void write_tiger(struct IsdnCardState *cs) {
722 u_int *p, cnt = NETJET_DMA_SIZE/2;
724 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {
725 debugl1(cs,"tiger warn write double dma %x/%x",
726 cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
727 return;
728 } else {
729 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
730 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
732 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1)
733 p = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1;
734 else
735 p = cs->bcs[0].hw.tiger.send + cnt - 1;
736 if (cs->bcs[0].mode == L1_MODE_HDLC)
737 write_raw(cs->bcs, p, cnt);
738 if (cs->bcs[1].mode == L1_MODE_HDLC)
739 write_raw(cs->bcs + 1, p, cnt);
740 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;
743 static void
744 tiger_l2l1(struct PStack *st, int pr, void *arg)
746 struct sk_buff *skb = arg;
747 long flags;
749 switch (pr) {
750 case (PH_DATA | REQUEST):
751 save_flags(flags);
752 cli();
753 if (st->l1.bcs->tx_skb) {
754 skb_queue_tail(&st->l1.bcs->squeue, skb);
755 restore_flags(flags);
756 } else {
757 st->l1.bcs->tx_skb = skb;
758 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
759 restore_flags(flags);
761 break;
762 case (PH_PULL | INDICATION):
763 if (st->l1.bcs->tx_skb) {
764 printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
765 break;
767 save_flags(flags);
768 cli();
769 st->l1.bcs->tx_skb = skb;
770 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
771 restore_flags(flags);
772 break;
773 case (PH_PULL | REQUEST):
774 if (!st->l1.bcs->tx_skb) {
775 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
776 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
777 } else
778 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
779 break;
780 case (PH_ACTIVATE | REQUEST):
781 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
782 mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc);
783 l1_msg_b(st, pr, arg);
784 break;
785 case (PH_DEACTIVATE | REQUEST):
786 l1_msg_b(st, pr, arg);
787 break;
788 case (PH_DEACTIVATE | CONFIRM):
789 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
790 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
791 mode_tiger(st->l1.bcs, 0, st->l1.bc);
792 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
793 break;
798 void
799 close_tigerstate(struct BCState *bcs)
801 mode_tiger(bcs, 0, bcs->channel);
802 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
803 if (bcs->hw.tiger.rcvbuf) {
804 kfree(bcs->hw.tiger.rcvbuf);
805 bcs->hw.tiger.rcvbuf = NULL;
807 if (bcs->hw.tiger.sendbuf) {
808 kfree(bcs->hw.tiger.sendbuf);
809 bcs->hw.tiger.sendbuf = NULL;
811 discard_queue(&bcs->rqueue);
812 discard_queue(&bcs->squeue);
813 if (bcs->tx_skb) {
814 dev_kfree_skb(bcs->tx_skb);
815 bcs->tx_skb = NULL;
816 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
821 static int
822 open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
824 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
825 if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
826 printk(KERN_WARNING
827 "HiSax: No memory for tiger.rcvbuf\n");
828 return (1);
830 if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
831 printk(KERN_WARNING
832 "HiSax: No memory for tiger.sendbuf\n");
833 return (1);
835 skb_queue_head_init(&bcs->rqueue);
836 skb_queue_head_init(&bcs->squeue);
838 bcs->tx_skb = NULL;
839 bcs->hw.tiger.sendcnt = 0;
840 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
841 bcs->event = 0;
842 bcs->tx_cnt = 0;
843 return (0);
847 setstack_tiger(struct PStack *st, struct BCState *bcs)
849 bcs->channel = st->l1.bc;
850 if (open_tigerstate(st->l1.hardware, bcs))
851 return (-1);
852 st->l1.bcs = bcs;
853 st->l2.l2l1 = tiger_l2l1;
854 setstack_manager(st);
855 bcs->st = st;
856 setstack_l1_B(st);
857 return (0);
861 void __init
862 inittiger(struct IsdnCardState *cs)
864 if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int),
865 GFP_KERNEL | GFP_DMA))) {
866 printk(KERN_WARNING
867 "HiSax: No memory for tiger.send\n");
868 return;
870 cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE/2 - 1;
871 cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1;
872 cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
873 cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
874 cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
876 memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int));
877 debugl1(cs, "tiger: send buf %x - %x", (u_int)cs->bcs[0].hw.tiger.send,
878 (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1));
879 outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
880 cs->hw.njet.base + NETJET_DMA_READ_START);
881 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
882 cs->hw.njet.base + NETJET_DMA_READ_IRQ);
883 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
884 cs->hw.njet.base + NETJET_DMA_READ_END);
885 if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int),
886 GFP_KERNEL | GFP_DMA))) {
887 printk(KERN_WARNING
888 "HiSax: No memory for tiger.rec\n");
889 return;
891 debugl1(cs, "tiger: rec buf %x - %x", (u_int)cs->bcs[0].hw.tiger.rec,
892 (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1));
893 cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
894 memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int));
895 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
896 cs->hw.njet.base + NETJET_DMA_WRITE_START);
897 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE/2 - 1),
898 cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
899 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1),
900 cs->hw.njet.base + NETJET_DMA_WRITE_END);
901 debugl1(cs, "tiger: dmacfg %x/%x pulse=%d",
902 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
903 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
904 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
905 cs->hw.njet.last_is0 = 0;
906 cs->bcs[0].BC_SetStack = setstack_tiger;
907 cs->bcs[1].BC_SetStack = setstack_tiger;
908 cs->bcs[0].BC_Close = close_tigerstate;
909 cs->bcs[1].BC_Close = close_tigerstate;
912 void
913 releasetiger(struct IsdnCardState *cs)
915 if (cs->bcs[0].hw.tiger.send) {
916 kfree(cs->bcs[0].hw.tiger.send);
917 cs->bcs[0].hw.tiger.send = NULL;
919 if (cs->bcs[1].hw.tiger.send) {
920 cs->bcs[1].hw.tiger.send = NULL;
922 if (cs->bcs[0].hw.tiger.rec) {
923 kfree(cs->bcs[0].hw.tiger.rec);
924 cs->bcs[0].hw.tiger.rec = NULL;
926 if (cs->bcs[1].hw.tiger.rec) {
927 cs->bcs[1].hw.tiger.rec = NULL;
931 static void
932 netjet_interrupt(int intno, void *dev_id, struct pt_regs *regs)
934 struct IsdnCardState *cs = dev_id;
935 u_char val, sval;
936 long flags;
938 if (!cs) {
939 printk(KERN_WARNING "NETjet: Spurious interrupt!\n");
940 return;
942 if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) &
943 NETJET_ISACIRQ)) {
944 val = ReadISAC(cs, ISAC_ISTA);
945 if (cs->debug & L1_DEB_ISAC)
946 debugl1(cs, "tiger: i1 %x %x", sval, val);
947 if (val) {
948 isac_interrupt(cs, val);
949 WriteISAC(cs, ISAC_MASK, 0xFF);
950 WriteISAC(cs, ISAC_MASK, 0x0);
953 save_flags(flags);
954 cli();
955 if ((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT0))) {
956 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
957 restore_flags(flags);
958 return;
960 cs->hw.njet.irqstat0 = sval;
961 restore_flags(flags);
962 /* debugl1(cs, "tiger: ist0 %x %x %x %x/%x pulse=%d",
963 sval,
964 bytein(cs->hw.njet.base + NETJET_DMACTRL),
965 bytein(cs->hw.njet.base + NETJET_IRQMASK0),
966 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
967 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
968 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
970 /* cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;
971 */ byteout(cs->hw.njet.base + NETJET_IRQSTAT0, cs->hw.njet.irqstat0);
972 /* byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);
973 */ if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ)
974 read_tiger(cs);
975 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE)
976 write_tiger(cs);
977 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
978 } else
979 restore_flags(flags);
981 /* if (!testcnt--) {
982 cs->hw.njet.dmactrl = 0;
983 byteout(cs->hw.njet.base + NETJET_DMACTRL,
984 cs->hw.njet.dmactrl);
985 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
990 static void
991 reset_netjet(struct IsdnCardState *cs)
993 long flags;
995 save_flags(flags);
996 sti();
997 cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
998 byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
999 current->state = TASK_INTERRUPTIBLE;
1000 schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
1001 cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
1002 byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
1003 current->state = TASK_INTERRUPTIBLE;
1004 schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
1005 restore_flags(flags);
1006 cs->hw.njet.auxd = 0;
1007 cs->hw.njet.dmactrl = 0;
1008 byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
1009 byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
1010 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
1013 void
1014 release_io_netjet(struct IsdnCardState *cs)
1016 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
1017 byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
1018 releasetiger(cs);
1019 release_region(cs->hw.njet.base, 256);
1023 static int
1024 NETjet_card_msg(struct IsdnCardState *cs, int mt, void *arg)
1026 switch (mt) {
1027 case CARD_RESET:
1028 reset_netjet(cs);
1029 return(0);
1030 case CARD_RELEASE:
1031 release_io_netjet(cs);
1032 return(0);
1033 case CARD_SETIRQ:
1034 return(request_irq(cs->irq, &netjet_interrupt,
1035 I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs));
1036 case CARD_INIT:
1037 inittiger(cs);
1038 clear_pending_isac_ints(cs);
1039 initisac(cs);
1040 /* Reenable all IRQ */
1041 cs->writeisac(cs, ISAC_MASK, 0);
1042 return(0);
1043 case CARD_TEST:
1044 return(0);
1046 return(0);
1051 static struct pci_dev *dev_netjet __initdata = NULL;
1053 int __init
1054 setup_netjet(struct IsdnCard *card)
1056 int bytecnt;
1057 struct IsdnCardState *cs = card->cs;
1058 char tmp[64];
1060 strcpy(tmp, NETjet_revision);
1061 printk(KERN_INFO "HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp));
1062 if (cs->typ != ISDN_CTYPE_NETJET)
1063 return(0);
1064 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1065 #if CONFIG_PCI
1066 if (!pci_present()) {
1067 printk(KERN_ERR "Netjet: no PCI bus present\n");
1068 return(0);
1070 if ((dev_netjet = pci_find_device(PCI_VENDOR_TRAVERSE_TECH,
1071 PCI_NETJET_ID, dev_netjet))) {
1072 cs->irq = dev_netjet->irq;
1073 if (!cs->irq) {
1074 printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n");
1075 return(0);
1077 cs->hw.njet.base = dev_netjet->base_address[0] &
1078 PCI_BASE_ADDRESS_IO_MASK;
1079 if (!cs->hw.njet.base) {
1080 printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n");
1081 return(0);
1083 cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
1084 cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
1085 bytecnt = 256;
1086 } else {
1087 printk(KERN_WARNING "NETjet: No PCI card found\n");
1088 return(0);
1090 #else
1091 printk(KERN_WARNING "NETjet: NO_PCI_BIOS\n");
1092 printk(KERN_WARNING "NETjet: unable to config NETJET PCI\n");
1093 return (0);
1094 #endif /* CONFIG_PCI */
1095 printk(KERN_INFO
1096 "NETjet: PCI card configured at 0x%x IRQ %d\n",
1097 cs->hw.njet.base, cs->irq);
1098 if (check_region(cs->hw.njet.base, bytecnt)) {
1099 printk(KERN_WARNING
1100 "HiSax: %s config port %x-%x already in use\n",
1101 CardType[card->typ],
1102 cs->hw.njet.base,
1103 cs->hw.njet.base + bytecnt);
1104 return (0);
1105 } else {
1106 request_region(cs->hw.njet.base, bytecnt, "netjet isdn");
1108 reset_netjet(cs);
1109 cs->readisac = &ReadISAC;
1110 cs->writeisac = &WriteISAC;
1111 cs->readisacfifo = &ReadISACfifo;
1112 cs->writeisacfifo = &WriteISACfifo;
1113 cs->BC_Read_Reg = &dummyrr;
1114 cs->BC_Write_Reg = &dummywr;
1115 cs->BC_Send_Data = &fill_dma;
1116 cs->cardmsg = &NETjet_card_msg;
1117 ISACVersion(cs, "NETjet:");
1118 return (1);