Import 2.3.10pre5
[davej-history.git] / drivers / isdn / hisax / isar.c
blobba9247a9f5a2c7ebfe56e7b1867b7c1a1d8a7397
1 /* $Id: isar.c,v 1.2 1998/11/15 23:54:53 keil Exp $
3 * isar.c ISAR (Siemens PSB 7110) specific routines
5 * Author Karsten Keil (keil@isdn4linux.de)
8 * $Log: isar.c,v $
9 * Revision 1.2 1998/11/15 23:54:53 keil
10 * changes from 2.0
12 * Revision 1.1 1998/08/13 23:33:47 keil
13 * First version, only init
18 #define __NO_VERSION__
19 #include "hisax.h"
20 #include "isar.h"
21 #include "isdnl1.h"
22 #include <linux/interrupt.h>
24 #define DBG_LOADFIRM 0
25 #define DUMP_MBOXFRAME 2
27 #define MIN(a,b) ((a<b)?a:b)
29 void isar_setup(struct IsdnCardState *cs);
31 static inline int
32 waitforHIA(struct IsdnCardState *cs, int timeout)
35 while ((cs->BC_Read_Reg(cs, 0, ISAR_HIA) & 1) && timeout) {
36 udelay(1);
37 timeout--;
39 if (!timeout)
40 printk(KERN_WARNING "HiSax: ISAR waitforHIA timeout\n");
41 return(timeout);
45 int
46 sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
47 u_char *msg)
49 long flags;
50 int i;
52 if (!waitforHIA(cs, 4000))
53 return(0);
54 #if DUMP_MBOXFRAME
55 if (cs->debug & L1_DEB_HSCX)
56 debugl1(cs, "sendmsg(%02x,%02x,%d)", his, creg, len);
57 #endif
58 save_flags(flags);
59 cli();
60 cs->BC_Write_Reg(cs, 0, ISAR_CTRL_H, creg);
61 cs->BC_Write_Reg(cs, 0, ISAR_CTRL_L, len);
62 cs->BC_Write_Reg(cs, 0, ISAR_WADR, 0);
63 if (msg && len) {
64 cs->BC_Write_Reg(cs, 1, ISAR_MBOX, msg[0]);
65 for (i=1; i<len; i++)
66 cs->BC_Write_Reg(cs, 2, ISAR_MBOX, msg[i]);
67 #if DUMP_MBOXFRAME>1
68 if (cs->debug & L1_DEB_HSCX_FIFO) {
69 char tmp[256], *t;
71 i = len;
72 while (i>0) {
73 t = tmp;
74 t += sprintf(t, "sendmbox cnt %d", len);
75 QuickHex(t, &msg[len-i], (i>64) ? 64:i);
76 debugl1(cs, tmp);
77 i -= 64;
80 #endif
82 cs->BC_Write_Reg(cs, 1, ISAR_HIS, his);
83 restore_flags(flags);
84 waitforHIA(cs, 10000);
85 return(1);
88 /* Call only with IRQ disabled !!! */
89 inline void
90 rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
92 int i;
94 cs->BC_Write_Reg(cs, 1, ISAR_RADR, 0);
95 if (msg && ireg->clsb) {
96 msg[0] = cs->BC_Read_Reg(cs, 1, ISAR_MBOX);
97 for (i=1; i < ireg->clsb; i++)
98 msg[i] = cs->BC_Read_Reg(cs, 2, ISAR_MBOX);
99 #if DUMP_MBOXFRAME>1
100 if (cs->debug & L1_DEB_HSCX_FIFO) {
101 char tmp[256], *t;
103 i = ireg->clsb;
104 while (i>0) {
105 t = tmp;
106 t += sprintf(t, "rcv_mbox cnt %d", ireg->clsb);
107 QuickHex(t, &msg[ireg->clsb-i], (i>64) ? 64:i);
108 debugl1(cs, tmp);
109 i -= 64;
112 #endif
114 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
117 /* Call only with IRQ disabled !!! */
118 inline void
119 get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
121 ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS);
122 ireg->cmsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_H);
123 ireg->clsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_L);
124 #if DUMP_MBOXFRAME
125 if (cs->debug & L1_DEB_HSCX)
126 debugl1(cs, "rcv_mbox(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
127 ireg->clsb);
128 #endif
132 waitrecmsg(struct IsdnCardState *cs, u_char *len,
133 u_char *msg, int maxdelay)
135 int timeout = 0;
136 long flags;
137 struct isar_reg *ir = cs->bcs[0].hw.isar.reg;
140 while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
141 (timeout++ < maxdelay))
142 udelay(1);
143 if (timeout >= maxdelay) {
144 printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
145 return(0);
147 save_flags(flags);
148 cli();
149 get_irq_infos(cs, ir);
150 rcv_mbox(cs, ir, msg);
151 *len = ir->clsb;
152 restore_flags(flags);
153 return(1);
157 ISARVersion(struct IsdnCardState *cs, char *s)
159 int ver;
160 u_char msg[] = ISAR_MSG_HWVER;
161 u_char tmp[64];
162 u_char len;
163 int debug;
165 cs->cardmsg(cs, CARD_RESET, NULL);
166 /* disable ISAR IRQ */
167 cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
168 debug = cs->debug;
169 cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
170 if (!sendmsg(cs, ISAR_HIS_VNR, 0, 3, msg))
171 return(-1);
172 if (!waitrecmsg(cs, &len, tmp, 100000))
173 return(-2);
174 cs->debug = debug;
175 if (cs->bcs[0].hw.isar.reg->iis == ISAR_IIS_VNR) {
176 if (len == 1) {
177 ver = tmp[0] & 0xf;
178 printk(KERN_INFO "%s ISAR version %d\n", s, ver);
179 return(ver);
181 return(-3);
183 return(-4);
187 isar_load_firmware(struct IsdnCardState *cs, u_char *buf)
189 int ret, size, cnt, debug;
190 u_char len, nom, noc;
191 u_short sadr, left, *sp;
192 u_char *p = buf;
193 u_char *msg, *tmpmsg, *mp, tmp[64];
194 long flags;
195 struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;
197 struct {u_short sadr;
198 u_short len;
199 u_short d_key;
200 } blk_head;
202 #define BLK_HEAD_SIZE 6
203 if (1 != (ret = ISARVersion(cs, "Testing"))) {
204 printk(KERN_ERR"isar_load_firmware wrong isar version %d\n", ret);
205 return(1);
207 debug = cs->debug;
208 #if DBG_LOADFIRM<2
209 cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
210 #endif
211 printk(KERN_DEBUG"isar_load_firmware buf %#lx\n", (u_long)buf);
212 if ((ret = verify_area(VERIFY_READ, (void *) p, sizeof(int)))) {
213 printk(KERN_ERR"isar_load_firmware verify_area ret %d\n", ret);
214 return ret;
216 if ((ret = copy_from_user(&size, p, sizeof(int)))) {
217 printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
218 return ret;
220 p += sizeof(int);
221 printk(KERN_DEBUG"isar_load_firmware size: %d\n", size);
222 if ((ret = verify_area(VERIFY_READ, (void *) p, size))) {
223 printk(KERN_ERR"isar_load_firmware verify_area ret %d\n", ret);
224 return ret;
226 cnt = 0;
227 /* disable ISAR IRQ */
228 cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
229 if (!(msg = kmalloc(256, GFP_KERNEL))) {
230 printk(KERN_ERR"isar_load_firmware no buffer\n");
231 return (1);
233 if (!(tmpmsg = kmalloc(256, GFP_KERNEL))) {
234 printk(KERN_ERR"isar_load_firmware no tmp buffer\n");
235 kfree(msg);
236 return (1);
238 while (cnt < size) {
239 if ((ret = copy_from_user(&blk_head, p, BLK_HEAD_SIZE))) {
240 printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
241 goto reterror;
243 cnt += BLK_HEAD_SIZE;
244 p += BLK_HEAD_SIZE;
245 printk(KERN_DEBUG"isar firmware block (%#x,%5d,%#x)\n",
246 blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
247 sadr = blk_head.sadr;
248 left = blk_head.len;
249 if (!sendmsg(cs, ISAR_HIS_DKEY, blk_head.d_key & 0xff, 0, NULL)) {
250 printk(KERN_ERR"isar sendmsg dkey failed\n");
251 ret = 1;goto reterror;
253 if (!waitrecmsg(cs, &len, tmp, 100000)) {
254 printk(KERN_ERR"isar waitrecmsg dkey failed\n");
255 ret = 1;goto reterror;
257 if ((ireg->iis != ISAR_IIS_DKEY) || ireg->cmsb || len) {
258 printk(KERN_ERR"isar wrong dkey response (%x,%x,%x)\n",
259 ireg->iis, ireg->cmsb, len);
260 ret = 1;goto reterror;
262 while (left>0) {
263 noc = MIN(126, left);
264 nom = 2*noc;
265 mp = msg;
266 *mp++ = sadr / 256;
267 *mp++ = sadr % 256;
268 left -= noc;
269 *mp++ = noc;
270 if ((ret = copy_from_user(tmpmsg, p, nom))) {
271 printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
272 goto reterror;
274 p += nom;
275 cnt += nom;
276 nom += 3;
277 sp = (u_short *)tmpmsg;
278 #if DBG_LOADFIRM
279 printk(KERN_DEBUG"isar: load %3d words at %04x\n",
280 noc, sadr);
281 #endif
282 sadr += noc;
283 while(noc) {
284 *mp++ = *sp / 256;
285 *mp++ = *sp % 256;
286 sp++;
287 noc--;
289 if (!sendmsg(cs, ISAR_HIS_FIRM, 0, nom, msg)) {
290 printk(KERN_ERR"isar sendmsg prog failed\n");
291 ret = 1;goto reterror;
293 if (!waitrecmsg(cs, &len, tmp, 100000)) {
294 printk(KERN_ERR"isar waitrecmsg prog failed\n");
295 ret = 1;goto reterror;
297 if ((ireg->iis != ISAR_IIS_FIRM) || ireg->cmsb || len) {
298 printk(KERN_ERR"isar wrong prog response (%x,%x,%x)\n",
299 ireg->iis, ireg->cmsb, len);
300 ret = 1;goto reterror;
303 printk(KERN_DEBUG"isar firmware block %5d words loaded\n",
304 blk_head.len);
306 msg[0] = 0xff;
307 msg[1] = 0xfe;
308 ireg->bstat = 0;
309 if (!sendmsg(cs, ISAR_HIS_STDSP, 0, 2, msg)) {
310 printk(KERN_ERR"isar sendmsg start dsp failed\n");
311 ret = 1;goto reterror;
313 if (!waitrecmsg(cs, &len, tmp, 100000)) {
314 printk(KERN_ERR"isar waitrecmsg start dsp failed\n");
315 ret = 1;goto reterror;
317 if ((ireg->iis != ISAR_IIS_STDSP) || ireg->cmsb || len) {
318 printk(KERN_ERR"isar wrong start dsp response (%x,%x,%x)\n",
319 ireg->iis, ireg->cmsb, len);
320 ret = 1;goto reterror;
321 } else
322 printk(KERN_DEBUG"isar start dsp success\n");
323 /* NORMAL mode entered */
324 /* Enable IRQs of ISAR */
325 cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, ISAR_IRQSTA);
326 save_flags(flags);
327 sti();
328 cnt = 1000; /* max 1s */
329 while ((!ireg->bstat) && cnt) {
330 udelay(1000);
331 cnt--;
333 if (!cnt) {
334 printk(KERN_ERR"isar no general status event received\n");
335 ret = 1;goto reterrflg;
336 } else {
337 printk(KERN_DEBUG"isar general status event %x\n",
338 ireg->bstat);
340 ireg->iis = 0;
341 if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
342 printk(KERN_ERR"isar sendmsg self tst failed\n");
343 ret = 1;goto reterrflg;
345 cnt = 1000; /* max 10 ms */
346 while ((ireg->iis != ISAR_IIS_DIAG) && cnt) {
347 udelay(10);
348 cnt--;
350 if (!cnt) {
351 printk(KERN_ERR"isar no self tst response\n");
352 ret = 1;goto reterrflg;
353 } else if ((ireg->cmsb == ISAR_CTRL_STST) && (ireg->clsb == 1)
354 && (ireg->par[0] == 0)) {
355 printk(KERN_DEBUG"isar selftest OK\n");
356 } else {
357 printk(KERN_DEBUG"isar selftest not OK %x/%x/%x\n",
358 ireg->cmsb, ireg->clsb, ireg->par[0]);
359 ret = 1;goto reterror;
361 ireg->iis = 0;
362 if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
363 printk(KERN_ERR"isar RQST SVN failed\n");
364 ret = 1;goto reterror;
366 cnt = 10000; /* max 100 ms */
367 while ((ireg->iis != ISAR_IIS_DIAG) && cnt) {
368 udelay(10);
369 cnt--;
371 if (!cnt) {
372 printk(KERN_ERR"isar no SVN response\n");
373 ret = 1;goto reterrflg;
374 } else {
375 if ((ireg->cmsb == ISAR_CTRL_SWVER) && (ireg->clsb == 1))
376 printk(KERN_DEBUG"isar software version %#x\n",
377 ireg->par[0]);
378 else {
379 printk(KERN_ERR"isar wrong swver response (%x,%x) cnt(%d)\n",
380 ireg->cmsb, ireg->clsb, cnt);
381 ret = 1;goto reterrflg;
384 cs->debug = debug;
385 isar_setup(cs);
386 ret = 0;
387 reterrflg:
388 restore_flags(flags);
389 reterror:
390 cs->debug = debug;
391 if (ret)
392 /* disable ISAR IRQ */
393 cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
394 kfree(msg);
395 kfree(tmpmsg);
396 return(ret);
399 void
400 isar_sched_event(struct BCState *bcs, int event)
402 bcs->event |= 1 << event;
403 queue_task(&bcs->tqueue, &tq_immediate);
404 mark_bh(IMMEDIATE_BH);
407 static inline void
408 isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
410 u_char *ptr;
411 struct sk_buff *skb;
412 struct isar_reg *ireg = bcs->hw.isar.reg;
414 if (!ireg->clsb) {
415 debugl1(cs, "isar zero len frame");
416 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
417 return;
419 switch (bcs->mode) {
420 case L1_MODE_NULL:
421 debugl1(cs, "isar mode 0 spurious IIS_RDATA %x/%x/%x",
422 ireg->iis, ireg->cmsb, ireg->clsb);
423 printk(KERN_WARNING"isar mode 0 spurious IIS_RDATA %x/%x/%x\n",
424 ireg->iis, ireg->cmsb, ireg->clsb);
425 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
426 break;
427 case L1_MODE_TRANS:
428 if ((skb = dev_alloc_skb(ireg->clsb))) {
429 rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb));
430 skb_queue_tail(&bcs->rqueue, skb);
431 isar_sched_event(bcs, B_RCVBUFREADY);
432 } else {
433 printk(KERN_WARNING "HiSax: skb out of memory\n");
434 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
436 break;
437 case L1_MODE_HDLC:
438 if ((bcs->hw.isar.rcvidx + ireg->clsb) > HSCX_BUFMAX) {
439 if (cs->debug & L1_DEB_WARN)
440 debugl1(cs, "isar_rcv_frame: incoming packet too large");
441 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
442 bcs->hw.isar.rcvidx = 0;
443 } else if (ireg->cmsb & HDLC_ERROR) {
444 if (cs->debug & L1_DEB_WARN)
445 debugl1(cs, "isar frame error %x len %d",
446 ireg->cmsb, ireg->clsb);
447 bcs->hw.isar.rcvidx = 0;
448 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
449 } else {
450 if (ireg->cmsb & HDLC_FSD)
451 bcs->hw.isar.rcvidx = 0;
452 ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx;
453 bcs->hw.isar.rcvidx += ireg->clsb;
454 rcv_mbox(cs, ireg, ptr);
455 if (ireg->cmsb & HDLC_FED) {
456 if (bcs->hw.isar.rcvidx < 3) { /* last 2 bytes are the FCS */
457 printk(KERN_WARNING "ISAR: HDLC frame too short(%d)\n",
458 bcs->hw.isar.rcvidx);
459 } else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2)))
460 printk(KERN_WARNING "ISAR: receive out of memory\n");
461 else {
462 memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2),
463 bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2);
464 skb_queue_tail(&bcs->rqueue, skb);
465 isar_sched_event(bcs, B_RCVBUFREADY);
469 break;
470 default:
471 printk(KERN_ERR"isar_rcv_frame mode (%x)error\n", bcs->mode);
472 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
473 break;
477 void
478 isar_fill_fifo(struct BCState *bcs)
480 struct IsdnCardState *cs = bcs->cs;
481 int count;
482 u_char msb;
483 u_char *ptr;
484 long flags;
486 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
487 debugl1(cs, "isar_fill_fifo");
488 if (!bcs->tx_skb)
489 return;
490 if (bcs->tx_skb->len <= 0)
491 return;
492 if (!(bcs->hw.isar.reg->bstat &
493 (bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
494 return;
495 if (bcs->tx_skb->len > bcs->hw.isar.mml) {
496 msb = 0;
497 count = bcs->hw.isar.mml;
498 } else {
499 count = bcs->tx_skb->len;
500 msb = HDLC_FED;
502 if (!bcs->hw.isar.txcnt)
503 msb |= HDLC_FST;
504 save_flags(flags);
505 cli();
506 ptr = bcs->tx_skb->data;
507 skb_pull(bcs->tx_skb, count);
508 bcs->tx_cnt -= count;
509 bcs->hw.isar.txcnt += count;
510 switch (bcs->mode) {
511 case L1_MODE_NULL:
512 printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");
513 break;
514 case L1_MODE_TRANS:
515 if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
516 0, count, ptr)) {
517 if (cs->debug)
518 debugl1(cs, "isar bin data send dp%d failed",
519 bcs->hw.isar.dpath);
521 break;
522 case L1_MODE_HDLC:
523 if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
524 msb, count, ptr)) {
525 if (cs->debug)
526 debugl1(cs, "isar hdlc data send dp%d failed",
527 bcs->hw.isar.dpath);
529 break;
530 default:
531 printk(KERN_ERR"isar_fill_fifo mode (%x)error\n", bcs->mode);
532 break;
534 restore_flags(flags);
537 inline
538 struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
540 if ((!dpath) || (dpath == 3))
541 return(NULL);
542 if (cs->bcs[0].hw.isar.dpath == dpath)
543 return(&cs->bcs[0]);
544 if (cs->bcs[1].hw.isar.dpath == dpath)
545 return(&cs->bcs[1]);
546 return(NULL);
549 inline void
550 send_frames(struct BCState *bcs)
552 if (bcs->tx_skb) {
553 if (bcs->tx_skb->len) {
554 isar_fill_fifo(bcs);
555 return;
556 } else {
557 if (bcs->st->lli.l1writewakeup &&
558 (PACKET_NOACK != bcs->tx_skb->pkt_type))
559 bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt);
560 dev_kfree_skb(bcs->tx_skb);
561 bcs->hw.isar.txcnt = 0;
562 bcs->tx_skb = NULL;
565 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
566 bcs->hw.isar.txcnt = 0;
567 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
568 isar_fill_fifo(bcs);
569 } else {
570 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
571 isar_sched_event(bcs, B_XMTBUFREADY);
575 inline void
576 check_send(struct IsdnCardState *cs, u_char rdm)
578 struct BCState *bcs;
580 if (rdm & BSTAT_RDM1) {
581 if ((bcs = sel_bcs_isar(cs, 1))) {
582 if (bcs->mode) {
583 send_frames(bcs);
587 if (rdm & BSTAT_RDM2) {
588 if ((bcs = sel_bcs_isar(cs, 2))) {
589 if (bcs->mode) {
590 send_frames(bcs);
597 static char debbuf[64];
599 void
600 isar_int_main(struct IsdnCardState *cs)
602 long flags;
603 struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;
604 struct BCState *bcs;
606 save_flags(flags);
607 cli();
608 get_irq_infos(cs, ireg);
609 switch (ireg->iis & ISAR_IIS_MSCMSD) {
610 case ISAR_IIS_RDATA:
611 if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
612 isar_rcv_frame(cs, bcs);
613 } else {
614 debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x",
615 ireg->iis, ireg->cmsb, ireg->clsb);
616 printk(KERN_WARNING"isar spurious IIS_RDATA %x/%x/%x\n",
617 ireg->iis, ireg->cmsb, ireg->clsb);
618 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
620 break;
621 case ISAR_IIS_GSTEV:
622 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
623 ireg->bstat |= ireg->cmsb;
624 check_send(cs, ireg->cmsb);
625 break;
626 case ISAR_IIS_BSTEV:
627 cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
628 if (cs->debug & L1_DEB_WARN)
629 debugl1(cs, "Buffer STEV dpath%d msb(%x)",
630 ireg->iis>>6, ireg->cmsb);
631 break;
632 case ISAR_IIS_DIAG:
633 case ISAR_IIS_PSTRSP:
634 case ISAR_IIS_PSTEV:
635 case ISAR_IIS_BSTRSP:
636 case ISAR_IIS_IOM2RSP:
637 rcv_mbox(cs, ireg, (u_char *)ireg->par);
638 if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO))
639 == L1_DEB_HSCX) {
640 u_char *tp=debbuf;
642 tp += sprintf(debbuf, "msg iis(%x) msb(%x)",
643 ireg->iis, ireg->cmsb);
644 QuickHex(tp, (u_char *)ireg->par, ireg->clsb);
645 debugl1(cs, debbuf);
647 break;
648 default:
649 rcv_mbox(cs, ireg, debbuf);
650 if (cs->debug & L1_DEB_WARN)
651 debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)",
652 ireg->iis, ireg->cmsb, ireg->clsb);
653 break;
655 restore_flags(flags);
658 void
659 setup_pump(struct BCState *bcs) {
660 struct IsdnCardState *cs = bcs->cs;
661 u_char dps = SET_DPS(bcs->hw.isar.dpath);
663 switch (bcs->mode) {
664 case L1_MODE_NULL:
665 case L1_MODE_TRANS:
666 case L1_MODE_HDLC:
667 if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL)) {
668 if (cs->debug)
669 debugl1(cs, "isar pump bypass cfg dp%d failed",
670 bcs->hw.isar.dpath);
672 break;
674 if (!sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL)) {
675 if (cs->debug)
676 debugl1(cs, "isar pump status req dp%d failed",
677 bcs->hw.isar.dpath);
681 void
682 setup_sart(struct BCState *bcs) {
683 struct IsdnCardState *cs = bcs->cs;
684 u_char dps = SET_DPS(bcs->hw.isar.dpath);
686 switch (bcs->mode) {
687 case L1_MODE_NULL:
688 if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0, NULL)) {
689 if (cs->debug)
690 debugl1(cs, "isar sart disable dp%d failed",
691 bcs->hw.isar.dpath);
693 break;
694 case L1_MODE_TRANS:
695 if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2, "\0\0")) {
696 if (cs->debug)
697 debugl1(cs, "isar sart binary dp%d failed",
698 bcs->hw.isar.dpath);
700 break;
701 case L1_MODE_HDLC:
702 if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, "\0")) {
703 if (cs->debug)
704 debugl1(cs, "isar sart binary dp%d failed",
705 bcs->hw.isar.dpath);
707 break;
709 if (!sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL)) {
710 if (cs->debug)
711 debugl1(cs, "isar buf stat req dp%d failed",
712 bcs->hw.isar.dpath);
716 void
717 setup_iom2(struct BCState *bcs) {
718 struct IsdnCardState *cs = bcs->cs;
719 u_char dps = SET_DPS(bcs->hw.isar.dpath);
720 u_char cmsb = 0, msg[5] = {0x10,0,0,0,0};
722 switch (bcs->mode) {
723 case L1_MODE_NULL:
724 /* dummy slot */
725 msg[1] = msg[3] = bcs->hw.isar.dpath + 2;
726 break;
727 case L1_MODE_TRANS:
728 case L1_MODE_HDLC:
729 cmsb = 0x80;
730 if (bcs->channel)
731 msg[1] = msg[3] = 1;
732 break;
734 if (!sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg)) {
735 if (cs->debug)
736 debugl1(cs, "isar iom2 dp%d failed", bcs->hw.isar.dpath);
738 if (!sendmsg(cs, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL)) {
739 if (cs->debug)
740 debugl1(cs, "isar IOM2 cfg req dp%d failed",
741 bcs->hw.isar.dpath);
746 modeisar(struct BCState *bcs, int mode, int bc)
748 struct IsdnCardState *cs = bcs->cs;
750 /* Here we are selecting the best datapath for requested mode */
751 if(bcs->mode == L1_MODE_NULL) { /* New Setup */
752 bcs->channel = bc;
753 switch (mode) {
754 case L1_MODE_NULL: /* init */
755 break;
756 case L1_MODE_TRANS:
757 case L1_MODE_HDLC:
758 /* best is datapath 2 */
759 if (!test_and_set_bit(ISAR_DP2_USE,
760 &bcs->hw.isar.reg->Flags))
761 bcs->hw.isar.dpath = 2;
762 else if (!test_and_set_bit(ISAR_DP1_USE,
763 &bcs->hw.isar.reg->Flags))
764 bcs->hw.isar.dpath = 1;
765 else {
766 printk(KERN_ERR"isar modeisar both pathes in use\n");
767 return(1);
769 break;
772 if (cs->debug & L1_DEB_HSCX)
773 debugl1(cs, "isar dp%d mode %d->%d ichan %d",
774 bcs->hw.isar.dpath, bcs->mode, mode, bc);
775 bcs->mode = mode;
776 setup_pump(bcs);
777 setup_sart(bcs);
778 setup_iom2(bcs);
779 if (bcs->mode == L1_MODE_NULL) {
780 /* Clear resources */
781 if (bcs->hw.isar.dpath == 1)
782 test_and_clear_bit(ISAR_DP1_USE, &bcs->hw.isar.reg->Flags);
783 else if (bcs->hw.isar.dpath == 2)
784 test_and_clear_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags);
785 bcs->hw.isar.dpath = 0;
787 return(0);
790 void
791 isar_setup(struct IsdnCardState *cs)
793 u_char msg;
794 int i;
796 /* Dpath 1, 2 */
797 msg = 61;
798 for (i=0; i<2; i++) {
799 /* Buffer Config */
800 if (!sendmsg(cs, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
801 ISAR_HIS_P12CFG, 4, 1, &msg)) {
802 if (cs->debug)
803 debugl1(cs, "isar P%dCFG failed", i+1);
805 cs->bcs[i].hw.isar.mml = msg;
806 cs->bcs[i].mode = 0;
807 cs->bcs[i].hw.isar.dpath = i + 1;
808 modeisar(&cs->bcs[i], 0, 0);
812 void
813 isar_l2l1(struct PStack *st, int pr, void *arg)
815 struct sk_buff *skb = arg;
816 long flags;
818 switch (pr) {
819 case (PH_DATA | REQUEST):
820 save_flags(flags);
821 cli();
822 if (st->l1.bcs->tx_skb) {
823 skb_queue_tail(&st->l1.bcs->squeue, skb);
824 restore_flags(flags);
825 } else {
826 st->l1.bcs->tx_skb = skb;
827 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
828 if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
829 debugl1(st->l1.bcs->cs, "DRQ set BC_FLG_BUSY");
830 st->l1.bcs->hw.isar.txcnt = 0;
831 restore_flags(flags);
832 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
834 break;
835 case (PH_PULL | INDICATION):
836 if (st->l1.bcs->tx_skb) {
837 printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n");
838 break;
840 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
841 if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
842 debugl1(st->l1.bcs->cs, "PUI set BC_FLG_BUSY");
843 st->l1.bcs->tx_skb = skb;
844 st->l1.bcs->hw.isar.txcnt = 0;
845 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
846 break;
847 case (PH_PULL | REQUEST):
848 if (!st->l1.bcs->tx_skb) {
849 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
850 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
851 } else
852 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
853 break;
854 case (PH_ACTIVATE | REQUEST):
855 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
856 modeisar(st->l1.bcs, st->l1.mode, st->l1.bc);
857 l1_msg_b(st, pr, arg);
858 break;
859 case (PH_DEACTIVATE | REQUEST):
860 l1_msg_b(st, pr, arg);
861 break;
862 case (PH_DEACTIVATE | CONFIRM):
863 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
864 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
865 if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
866 debugl1(st->l1.bcs->cs, "PDAC clear BC_FLG_BUSY");
867 modeisar(st->l1.bcs, 0, st->l1.bc);
868 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
869 break;
873 void
874 close_isarstate(struct BCState *bcs)
876 modeisar(bcs, 0, bcs->channel);
877 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
878 if (bcs->hw.isar.rcvbuf) {
879 kfree(bcs->hw.isar.rcvbuf);
880 bcs->hw.isar.rcvbuf = NULL;
882 discard_queue(&bcs->rqueue);
883 discard_queue(&bcs->squeue);
884 if (bcs->tx_skb) {
885 dev_kfree_skb(bcs->tx_skb);
886 bcs->tx_skb = NULL;
887 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
888 if (bcs->cs->debug & L1_DEB_HSCX)
889 debugl1(bcs->cs, "closeisar clear BC_FLG_BUSY");
895 open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
897 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
898 if (!(bcs->hw.isar.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
899 printk(KERN_WARNING
900 "HiSax: No memory for isar.rcvbuf\n");
901 return (1);
903 skb_queue_head_init(&bcs->rqueue);
904 skb_queue_head_init(&bcs->squeue);
906 bcs->tx_skb = NULL;
907 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
908 if (cs->debug & L1_DEB_HSCX)
909 debugl1(cs, "openisar clear BC_FLG_BUSY");
910 bcs->event = 0;
911 bcs->hw.isar.rcvidx = 0;
912 bcs->tx_cnt = 0;
913 return (0);
917 setstack_isar(struct PStack *st, struct BCState *bcs)
919 bcs->channel = st->l1.bc;
920 if (open_isarstate(st->l1.hardware, bcs))
921 return (-1);
922 st->l1.bcs = bcs;
923 st->l2.l2l1 = isar_l2l1;
924 setstack_manager(st);
925 bcs->st = st;
926 setstack_l1_B(st);
927 return (0);
930 HISAX_INITFUNC(void
931 initisar(struct IsdnCardState *cs))
933 cs->bcs[0].BC_SetStack = setstack_isar;
934 cs->bcs[1].BC_SetStack = setstack_isar;
935 cs->bcs[0].BC_Close = close_isarstate;
936 cs->bcs[1].BC_Close = close_isarstate;