Merge ../linux-2.6-watchdog-mm
[linux-drm-fsl-dcu.git] / drivers / isdn / hisax / diva.c
1 /* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $
2  *
3  * low level stuff for Eicon.Diehl Diva Family ISDN cards
4  *
5  * Author       Karsten Keil
6  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
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  * For changes and modifications please read
12  * Documentation/isdn/HiSax.cert
13  *
14  * Thanks to Eicon Technology for documents and information
15  *
16  */
17
18 #include <linux/init.h>
19 #include "hisax.h"
20 #include "isac.h"
21 #include "hscx.h"
22 #include "ipac.h"
23 #include "ipacx.h"
24 #include "isdnl1.h"
25 #include <linux/pci.h>
26 #include <linux/isapnp.h>
27
28 extern const char *CardType[];
29
30 static const char *Diva_revision = "$Revision: 1.33.2.6 $";
31
32 #define byteout(addr,val) outb(val,addr)
33 #define bytein(addr) inb(addr)
34
35 #define DIVA_HSCX_DATA          0
36 #define DIVA_HSCX_ADR           4
37 #define DIVA_ISA_ISAC_DATA      2
38 #define DIVA_ISA_ISAC_ADR       6
39 #define DIVA_ISA_CTRL           7
40 #define DIVA_IPAC_ADR           0
41 #define DIVA_IPAC_DATA          1
42
43 #define DIVA_PCI_ISAC_DATA      8
44 #define DIVA_PCI_ISAC_ADR       0xc
45 #define DIVA_PCI_CTRL           0x10
46
47 /* SUB Types */
48 #define DIVA_ISA        1
49 #define DIVA_PCI        2
50 #define DIVA_IPAC_ISA   3
51 #define DIVA_IPAC_PCI   4
52 #define DIVA_IPACX_PCI  5
53
54 /* CTRL (Read) */
55 #define DIVA_IRQ_STAT   0x01
56 #define DIVA_EEPROM_SDA 0x02
57
58 /* CTRL (Write) */
59 #define DIVA_IRQ_REQ    0x01
60 #define DIVA_RESET      0x08
61 #define DIVA_EEPROM_CLK 0x40
62 #define DIVA_PCI_LED_A  0x10
63 #define DIVA_PCI_LED_B  0x20
64 #define DIVA_ISA_LED_A  0x20
65 #define DIVA_ISA_LED_B  0x40
66 #define DIVA_IRQ_CLR    0x80
67
68 /* Siemens PITA */
69 #define PITA_MISC_REG           0x1c
70 #ifdef __BIG_ENDIAN
71 #define PITA_PARA_SOFTRESET     0x00000001
72 #define PITA_SER_SOFTRESET      0x00000002
73 #define PITA_PARA_MPX_MODE      0x00000004
74 #define PITA_INT0_ENABLE        0x00000200
75 #else
76 #define PITA_PARA_SOFTRESET     0x01000000
77 #define PITA_SER_SOFTRESET      0x02000000
78 #define PITA_PARA_MPX_MODE      0x04000000
79 #define PITA_INT0_ENABLE        0x00020000
80 #endif
81 #define PITA_INT0_STATUS        0x02
82
83 static inline u_char
84 readreg(unsigned int ale, unsigned int adr, u_char off)
85 {
86         register u_char ret;
87
88         byteout(ale, off);
89         ret = bytein(adr);
90         return (ret);
91 }
92
93 static inline void
94 readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
95 {
96         byteout(ale, off);
97         insb(adr, data, size);
98 }
99
100
101 static inline void
102 writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
103 {
104         byteout(ale, off);
105         byteout(adr, data);
106 }
107
108 static inline void
109 writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
110 {
111         byteout(ale, off);
112         outsb(adr, data, size);
113 }
114
115 static inline u_char
116 memreadreg(unsigned long adr, u_char off)
117 {
118         return(*((unsigned char *)
119                 (((unsigned int *)adr) + off)));
120 }
121
122 static inline void
123 memwritereg(unsigned long adr, u_char off, u_char data)
124 {
125         register u_char *p;
126         
127         p = (unsigned char *)(((unsigned int *)adr) + off);
128         *p = data;
129 }
130
131 /* Interface functions */
132
133 static u_char
134 ReadISAC(struct IsdnCardState *cs, u_char offset)
135 {
136         return(readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset));
137 }
138
139 static void
140 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
141 {
142         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value);
143 }
144
145 static void
146 ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
147 {
148         readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size);
149 }
150
151 static void
152 WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
153 {
154         writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size);
155 }
156
157 static u_char
158 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
159 {
160         return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80));
161 }
162
163 static void
164 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
165 {
166         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset|0x80, value);
167 }
168
169 static void
170 ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
171 {
172         readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
173 }
174
175 static void
176 WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
177 {
178         writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
179 }
180
181 static u_char
182 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
183 {
184         return(readreg(cs->hw.diva.hscx_adr,
185                 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0)));
186 }
187
188 static void
189 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
190 {
191         writereg(cs->hw.diva.hscx_adr,
192                 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value);
193 }
194
195 static u_char
196 MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
197 {
198         return (memreadreg(cs->hw.diva.cfg_reg, offset+0x80));
199 }
200
201 static void
202 MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
203 {
204         memwritereg(cs->hw.diva.cfg_reg, offset|0x80, value);
205 }
206
207 static void
208 MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
209 {
210         while(size--)
211                 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80);
212 }
213
214 static void
215 MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
216 {
217         while(size--)
218                 memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++);
219 }
220
221 static u_char
222 MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
223 {
224         return(memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0)));
225 }
226
227 static void
228 MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
229 {
230         memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value);
231 }
232
233 /* IO-Functions for IPACX type cards */
234 static u_char
235 MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset)
236 {
237         return (memreadreg(cs->hw.diva.cfg_reg, offset));
238 }
239
240 static void
241 MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value)
242 {
243         memwritereg(cs->hw.diva.cfg_reg, offset, value);
244 }
245
246 static void
247 MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
248 {
249         while(size--)
250                 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0);
251 }
252
253 static void
254 MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
255 {
256         while(size--)
257                 memwritereg(cs->hw.diva.cfg_reg, 0, *data++);
258 }
259
260 static u_char
261 MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset)
262 {
263         return(memreadreg(cs->hw.diva.cfg_reg, offset + 
264                     (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1)));
265 }
266
267 static void
268 MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
269 {
270         memwritereg(cs->hw.diva.cfg_reg, offset + 
271               (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
272 }
273
274 /*
275  * fast interrupt HSCX stuff goes here
276  */
277
278 #define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \
279                 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
280 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \
281                 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
282
283 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \
284                 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
285
286 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \
287                 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
288
289 #include "hscx_irq.c"
290
291 static irqreturn_t
292 diva_interrupt(int intno, void *dev_id)
293 {
294         struct IsdnCardState *cs = dev_id;
295         u_char val, sval;
296         u_long flags;
297         int cnt=5;
298
299         spin_lock_irqsave(&cs->lock, flags);
300         while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) {
301                 val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40);
302                 if (val)
303                         hscx_int_main(cs, val);
304                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA);
305                 if (val)
306                         isac_interrupt(cs, val);
307                 cnt--;
308         }
309         if (!cnt)
310                 printk(KERN_WARNING "Diva: IRQ LOOP\n");
311         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF);
312         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF);
313         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF);
314         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0);
315         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0);
316         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0);
317         spin_unlock_irqrestore(&cs->lock, flags);
318         return IRQ_HANDLED;
319 }
320
321 static irqreturn_t
322 diva_irq_ipac_isa(int intno, void *dev_id)
323 {
324         struct IsdnCardState *cs = dev_id;
325         u_char ista,val;
326         u_long flags;
327         int icnt=5;
328
329         spin_lock_irqsave(&cs->lock, flags);
330         ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA);
331 Start_IPACISA:
332         if (cs->debug & L1_DEB_IPAC)
333                 debugl1(cs, "IPAC ISTA %02X", ista);
334         if (ista & 0x0f) {
335                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40);
336                 if (ista & 0x01)
337                         val |= 0x01;
338                 if (ista & 0x04)
339                         val |= 0x02;
340                 if (ista & 0x08)
341                         val |= 0x04;
342                 if (val)
343                         hscx_int_main(cs, val);
344         }
345         if (ista & 0x20) {
346                 val = 0xfe & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80);
347                 if (val) {
348                         isac_interrupt(cs, val);
349                 }
350         }
351         if (ista & 0x10) {
352                 val = 0x01;
353                 isac_interrupt(cs, val);
354         }
355         ista  = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA);
356         if ((ista & 0x3f) && icnt) {
357                 icnt--;
358                 goto Start_IPACISA;
359         }
360         if (!icnt)
361                 printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n");
362         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF);
363         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0);
364         spin_unlock_irqrestore(&cs->lock, flags);
365         return IRQ_HANDLED;
366 }
367
368 static inline void
369 MemwaitforCEC(struct IsdnCardState *cs, int hscx)
370 {
371         int to = 50;
372
373         while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) {
374                 udelay(1);
375                 to--;
376         }
377         if (!to)
378                 printk(KERN_WARNING "HiSax: waitforCEC timeout\n");
379 }
380
381
382 static inline void
383 MemwaitforXFW(struct IsdnCardState *cs, int hscx)
384 {
385         int to = 50;
386
387         while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
388                 udelay(1);
389                 to--;
390         }
391         if (!to)
392                 printk(KERN_WARNING "HiSax: waitforXFW timeout\n");
393 }
394
395 static inline void
396 MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data)
397 {
398         MemwaitforCEC(cs, hscx);
399         MemWriteHSCX(cs, hscx, HSCX_CMDR, data);
400 }
401
402 static void
403 Memhscx_empty_fifo(struct BCState *bcs, int count)
404 {
405         u_char *ptr;
406         struct IsdnCardState *cs = bcs->cs;
407         int cnt;
408
409         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
410                 debugl1(cs, "hscx_empty_fifo");
411
412         if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
413                 if (cs->debug & L1_DEB_WARN)
414                         debugl1(cs, "hscx_empty_fifo: incoming packet too large");
415                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
416                 bcs->hw.hscx.rcvidx = 0;
417                 return;
418         }
419         ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
420         cnt = count;
421         while (cnt--)
422                 *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0);
423         MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
424         ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
425         bcs->hw.hscx.rcvidx += count;
426         if (cs->debug & L1_DEB_HSCX_FIFO) {
427                 char *t = bcs->blog;
428
429                 t += sprintf(t, "hscx_empty_fifo %c cnt %d",
430                              bcs->hw.hscx.hscx ? 'B' : 'A', count);
431                 QuickHex(t, ptr, count);
432                 debugl1(cs, bcs->blog);
433         }
434 }
435
436 static void
437 Memhscx_fill_fifo(struct BCState *bcs)
438 {
439         struct IsdnCardState *cs = bcs->cs;
440         int more, count, cnt;
441         int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
442         u_char *ptr,*p;
443
444         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
445                 debugl1(cs, "hscx_fill_fifo");
446
447         if (!bcs->tx_skb)
448                 return;
449         if (bcs->tx_skb->len <= 0)
450                 return;
451
452         more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
453         if (bcs->tx_skb->len > fifo_size) {
454                 more = !0;
455                 count = fifo_size;
456         } else
457                 count = bcs->tx_skb->len;
458         cnt = count;
459         MemwaitforXFW(cs, bcs->hw.hscx.hscx);
460         p = ptr = bcs->tx_skb->data;
461         skb_pull(bcs->tx_skb, count);
462         bcs->tx_cnt -= count;
463         bcs->hw.hscx.count += count;
464         while(cnt--)
465                 memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0,
466                         *p++);
467         MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
468         if (cs->debug & L1_DEB_HSCX_FIFO) {
469                 char *t = bcs->blog;
470
471                 t += sprintf(t, "hscx_fill_fifo %c cnt %d",
472                              bcs->hw.hscx.hscx ? 'B' : 'A', count);
473                 QuickHex(t, ptr, count);
474                 debugl1(cs, bcs->blog);
475         }
476 }
477
478 static void
479 Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
480 {
481         u_char r;
482         struct BCState *bcs = cs->bcs + hscx;
483         struct sk_buff *skb;
484         int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
485         int count;
486
487         if (!test_bit(BC_FLG_INIT, &bcs->Flag))
488                 return;
489
490         if (val & 0x80) {       /* RME */
491                 r = MemReadHSCX(cs, hscx, HSCX_RSTA);
492                 if ((r & 0xf0) != 0xa0) {
493                         if (!(r & 0x80))
494                                 if (cs->debug & L1_DEB_WARN)
495                                         debugl1(cs, "HSCX invalid frame");
496                         if ((r & 0x40) && bcs->mode)
497                                 if (cs->debug & L1_DEB_WARN)
498                                         debugl1(cs, "HSCX RDO mode=%d",
499                                                 bcs->mode);
500                         if (!(r & 0x20))
501                                 if (cs->debug & L1_DEB_WARN)
502                                         debugl1(cs, "HSCX CRC error");
503                         MemWriteHSCXCMDR(cs, hscx, 0x80);
504                 } else {
505                         count = MemReadHSCX(cs, hscx, HSCX_RBCL) & (
506                                 test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
507                         if (count == 0)
508                                 count = fifo_size;
509                         Memhscx_empty_fifo(bcs, count);
510                         if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
511                                 if (cs->debug & L1_DEB_HSCX_FIFO)
512                                         debugl1(cs, "HX Frame %d", count);
513                                 if (!(skb = dev_alloc_skb(count)))
514                                         printk(KERN_WARNING "HSCX: receive out of memory\n");
515                                 else {
516                                         memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
517                                         skb_queue_tail(&bcs->rqueue, skb);
518                                 }
519                         }
520                 }
521                 bcs->hw.hscx.rcvidx = 0;
522                 schedule_event(bcs, B_RCVBUFREADY);
523         }
524         if (val & 0x40) {       /* RPF */
525                 Memhscx_empty_fifo(bcs, fifo_size);
526                 if (bcs->mode == L1_MODE_TRANS) {
527                         /* receive audio data */
528                         if (!(skb = dev_alloc_skb(fifo_size)))
529                                 printk(KERN_WARNING "HiSax: receive out of memory\n");
530                         else {
531                                 memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
532                                 skb_queue_tail(&bcs->rqueue, skb);
533                         }
534                         bcs->hw.hscx.rcvidx = 0;
535                         schedule_event(bcs, B_RCVBUFREADY);
536                 }
537         }
538         if (val & 0x10) {       /* XPR */
539                 if (bcs->tx_skb) {
540                         if (bcs->tx_skb->len) {
541                                 Memhscx_fill_fifo(bcs);
542                                 return;
543                         } else {
544                                 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
545                                         (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
546                                         u_long  flags;
547                                         spin_lock_irqsave(&bcs->aclock, flags);
548                                         bcs->ackcnt += bcs->hw.hscx.count;
549                                         spin_unlock_irqrestore(&bcs->aclock, flags);
550                                         schedule_event(bcs, B_ACKPENDING);
551                                 }
552                                 dev_kfree_skb_irq(bcs->tx_skb);
553                                 bcs->hw.hscx.count = 0; 
554                                 bcs->tx_skb = NULL;
555                         }
556                 }
557                 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
558                         bcs->hw.hscx.count = 0;
559                         test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
560                         Memhscx_fill_fifo(bcs);
561                 } else {
562                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
563                         schedule_event(bcs, B_XMTBUFREADY);
564                 }
565         }
566 }
567
568 static inline void
569 Memhscx_int_main(struct IsdnCardState *cs, u_char val)
570 {
571
572         u_char exval;
573         struct BCState *bcs;
574
575         if (val & 0x01) { // EXB
576                 bcs = cs->bcs + 1;
577                 exval = MemReadHSCX(cs, 1, HSCX_EXIR);
578                 if (exval & 0x40) {
579                         if (bcs->mode == 1)
580                                 Memhscx_fill_fifo(bcs);
581                         else {
582                                 /* Here we lost an TX interrupt, so
583                                    * restart transmitting the whole frame.
584                                  */
585                                 if (bcs->tx_skb) {
586                                         skb_push(bcs->tx_skb, bcs->hw.hscx.count);
587                                         bcs->tx_cnt += bcs->hw.hscx.count;
588                                         bcs->hw.hscx.count = 0;
589                                 }
590                                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
591                                 if (cs->debug & L1_DEB_WARN)
592                                         debugl1(cs, "HSCX B EXIR %x Lost TX", exval);
593                         }
594                 } else if (cs->debug & L1_DEB_HSCX)
595                         debugl1(cs, "HSCX B EXIR %x", exval);
596         }
597         if (val & 0xf8) {
598                 if (cs->debug & L1_DEB_HSCX)
599                         debugl1(cs, "HSCX B interrupt %x", val);
600                 Memhscx_interrupt(cs, val, 1);
601         }
602         if (val & 0x02) {       // EXA
603                 bcs = cs->bcs;
604                 exval = MemReadHSCX(cs, 0, HSCX_EXIR);
605                 if (exval & 0x40) {
606                         if (bcs->mode == L1_MODE_TRANS)
607                                 Memhscx_fill_fifo(bcs);
608                         else {
609                                 /* Here we lost an TX interrupt, so
610                                    * restart transmitting the whole frame.
611                                  */
612                                 if (bcs->tx_skb) {
613                                         skb_push(bcs->tx_skb, bcs->hw.hscx.count);
614                                         bcs->tx_cnt += bcs->hw.hscx.count;
615                                         bcs->hw.hscx.count = 0;
616                                 }
617                                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
618                                 if (cs->debug & L1_DEB_WARN)
619                                         debugl1(cs, "HSCX A EXIR %x Lost TX", exval);
620                         }
621                 } else if (cs->debug & L1_DEB_HSCX)
622                         debugl1(cs, "HSCX A EXIR %x", exval);
623         }
624         if (val & 0x04) {       // ICA
625                 exval = MemReadHSCX(cs, 0, HSCX_ISTA);
626                 if (cs->debug & L1_DEB_HSCX)
627                         debugl1(cs, "HSCX A interrupt %x", exval);
628                 Memhscx_interrupt(cs, exval, 0);
629         }
630 }
631
632 static irqreturn_t
633 diva_irq_ipac_pci(int intno, void *dev_id)
634 {
635         struct IsdnCardState *cs = dev_id;
636         u_char ista,val;
637         int icnt=5;
638         u_char *cfg;
639         u_long flags;
640
641         spin_lock_irqsave(&cs->lock, flags);
642         cfg = (u_char *) cs->hw.diva.pci_cfg;
643         val = *cfg;
644         if (!(val & PITA_INT0_STATUS)) {
645                 spin_unlock_irqrestore(&cs->lock, flags);
646                 return IRQ_NONE; /* other shared IRQ */
647         }
648         *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */
649         ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA);
650 Start_IPACPCI:
651         if (cs->debug & L1_DEB_IPAC)
652                 debugl1(cs, "IPAC ISTA %02X", ista);
653         if (ista & 0x0f) {
654                 val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40);
655                 if (ista & 0x01)
656                         val |= 0x01;
657                 if (ista & 0x04)
658                         val |= 0x02;
659                 if (ista & 0x08)
660                         val |= 0x04;
661                 if (val)
662                         Memhscx_int_main(cs, val);
663         }
664         if (ista & 0x20) {
665                 val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80);
666                 if (val) {
667                         isac_interrupt(cs, val);
668                 }
669         }
670         if (ista & 0x10) {
671                 val = 0x01;
672                 isac_interrupt(cs, val);
673         }
674         ista  = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA);
675         if ((ista & 0x3f) && icnt) {
676                 icnt--;
677                 goto Start_IPACPCI;
678         }
679         if (!icnt)
680                 printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n");
681         memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF);
682         memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0);
683         spin_unlock_irqrestore(&cs->lock, flags);
684         return IRQ_HANDLED;
685 }
686
687 static irqreturn_t
688 diva_irq_ipacx_pci(int intno, void *dev_id)
689 {
690         struct IsdnCardState *cs = dev_id;
691         u_char val;
692         u_char *cfg;
693         u_long flags;
694
695         spin_lock_irqsave(&cs->lock, flags);
696         cfg = (u_char *) cs->hw.diva.pci_cfg;
697         val = *cfg;
698         if (!(val &PITA_INT0_STATUS)) {
699                 spin_unlock_irqrestore(&cs->lock, flags);
700                 return IRQ_NONE; // other shared IRQ
701         }
702         interrupt_ipacx(cs);      // handler for chip
703         *cfg = PITA_INT0_STATUS;  // Reset PLX interrupt
704         spin_unlock_irqrestore(&cs->lock, flags);
705         return IRQ_HANDLED;
706 }
707
708 static void
709 release_io_diva(struct IsdnCardState *cs)
710 {
711         int bytecnt;
712
713         if ((cs->subtyp == DIVA_IPAC_PCI) || 
714             (cs->subtyp == DIVA_IPACX_PCI)   ) {
715                 u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg;
716
717                 *cfg = 0; /* disable INT0/1 */ 
718                 *cfg = 2; /* reset pending INT0 */
719                 if (cs->hw.diva.cfg_reg)
720                         iounmap((void *)cs->hw.diva.cfg_reg);
721                 if (cs->hw.diva.pci_cfg)
722                         iounmap((void *)cs->hw.diva.pci_cfg);
723                 return;
724         } else if (cs->subtyp != DIVA_IPAC_ISA) {
725                 del_timer(&cs->hw.diva.tl);
726                 if (cs->hw.diva.cfg_reg)
727                         byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
728         }
729         if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA))
730                 bytecnt = 8;
731         else
732                 bytecnt = 32;
733         if (cs->hw.diva.cfg_reg) {
734                 release_region(cs->hw.diva.cfg_reg, bytecnt);
735         }
736 }
737
738 static void
739 iounmap_diva(struct IsdnCardState *cs)
740 {
741         if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) {
742                 if (cs->hw.diva.cfg_reg) {
743                         iounmap((void *)cs->hw.diva.cfg_reg);
744                         cs->hw.diva.cfg_reg = 0;
745                 }
746                 if (cs->hw.diva.pci_cfg) {
747                         iounmap((void *)cs->hw.diva.pci_cfg);
748                         cs->hw.diva.pci_cfg = 0;
749                 }
750         }
751
752         return;
753 }
754
755 static void
756 reset_diva(struct IsdnCardState *cs)
757 {
758         if (cs->subtyp == DIVA_IPAC_ISA) {
759                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20);
760                 mdelay(10);
761                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00);
762                 mdelay(10);
763                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0);
764         } else if (cs->subtyp == DIVA_IPAC_PCI) {
765                 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
766                                         PITA_MISC_REG);
767                 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
768                 mdelay(10);
769                 *ireg = PITA_PARA_MPX_MODE;
770                 mdelay(10);
771                 memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0);
772         } else if (cs->subtyp == DIVA_IPACX_PCI) {
773                 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
774                                         PITA_MISC_REG);
775                 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
776                 mdelay(10);
777                 *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET;
778                 mdelay(10);
779                 MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off
780         } else { /* DIVA 2.0 */
781                 cs->hw.diva.ctrl_reg = 0;        /* Reset On */
782                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
783                 mdelay(10);
784                 cs->hw.diva.ctrl_reg |= DIVA_RESET;  /* Reset Off */
785                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
786                 mdelay(10);
787                 if (cs->subtyp == DIVA_ISA)
788                         cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A;
789                 else {
790                         /* Workaround PCI9060 */
791                         byteout(cs->hw.diva.pci_cfg + 0x69, 9);
792                         cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A;
793                 }
794                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
795         }
796 }
797
798 #define DIVA_ASSIGN 1
799
800 static void
801 diva_led_handler(struct IsdnCardState *cs)
802 {
803         int blink = 0;
804
805         if ((cs->subtyp == DIVA_IPAC_ISA) ||
806             (cs->subtyp == DIVA_IPAC_PCI) ||
807             (cs->subtyp == DIVA_IPACX_PCI)   )
808                 return;
809         del_timer(&cs->hw.diva.tl);
810         if (cs->hw.diva.status & DIVA_ASSIGN)
811                 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
812                         DIVA_ISA_LED_A : DIVA_PCI_LED_A;
813         else {
814                 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
815                         DIVA_ISA_LED_A : DIVA_PCI_LED_A;
816                 blink = 250;
817         }
818         if (cs->hw.diva.status & 0xf000)
819                 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
820                         DIVA_ISA_LED_B : DIVA_PCI_LED_B;
821         else if (cs->hw.diva.status & 0x0f00) {
822                 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
823                         DIVA_ISA_LED_B : DIVA_PCI_LED_B;
824                 blink = 500;
825         } else
826                 cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ?
827                         DIVA_ISA_LED_B : DIVA_PCI_LED_B);
828
829         byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
830         if (blink) {
831                 init_timer(&cs->hw.diva.tl);
832                 cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000);
833                 add_timer(&cs->hw.diva.tl);
834         }
835 }
836
837 static int
838 Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg)
839 {
840         u_int *ireg;
841         u_long flags;
842
843         switch (mt) {
844                 case CARD_RESET:
845                         spin_lock_irqsave(&cs->lock, flags);
846                         reset_diva(cs);
847                         spin_unlock_irqrestore(&cs->lock, flags);
848                         return(0);
849                 case CARD_RELEASE:
850                         release_io_diva(cs);
851                         return(0);
852                 case CARD_INIT:
853                         spin_lock_irqsave(&cs->lock, flags);
854                         reset_diva(cs);
855                         if (cs->subtyp == DIVA_IPACX_PCI) {
856                                 ireg = (unsigned int *)cs->hw.diva.pci_cfg;
857                                 *ireg = PITA_INT0_ENABLE;
858                                 init_ipacx(cs, 3); // init chip and enable interrupts
859                                 spin_unlock_irqrestore(&cs->lock, flags);
860                                 return (0);
861                         }
862                         if (cs->subtyp == DIVA_IPAC_PCI) {
863                                 ireg = (unsigned int *)cs->hw.diva.pci_cfg;
864                                 *ireg = PITA_INT0_ENABLE;
865                         }
866                         inithscxisac(cs, 3);
867                         spin_unlock_irqrestore(&cs->lock, flags);
868                         return(0);
869                 case CARD_TEST:
870                         return(0);
871                 case (MDL_REMOVE | REQUEST):
872                         cs->hw.diva.status = 0;
873                         break;
874                 case (MDL_ASSIGN | REQUEST):
875                         cs->hw.diva.status |= DIVA_ASSIGN;
876                         break;
877                 case MDL_INFO_SETUP:
878                         if ((long)arg)
879                                 cs->hw.diva.status |=  0x0200;
880                         else
881                                 cs->hw.diva.status |=  0x0100;
882                         break;
883                 case MDL_INFO_CONN:
884                         if ((long)arg)
885                                 cs->hw.diva.status |=  0x2000;
886                         else
887                                 cs->hw.diva.status |=  0x1000;
888                         break;
889                 case MDL_INFO_REL:
890                         if ((long)arg) {
891                                 cs->hw.diva.status &=  ~0x2000;
892                                 cs->hw.diva.status &=  ~0x0200;
893                         } else {
894                                 cs->hw.diva.status &=  ~0x1000;
895                                 cs->hw.diva.status &=  ~0x0100;
896                         }
897                         break;
898         }
899         if ((cs->subtyp != DIVA_IPAC_ISA) && 
900             (cs->subtyp != DIVA_IPAC_PCI) &&
901             (cs->subtyp != DIVA_IPACX_PCI)) {
902                 spin_lock_irqsave(&cs->lock, flags);
903                 diva_led_handler(cs);
904                 spin_unlock_irqrestore(&cs->lock, flags);
905         }
906         return(0);
907 }
908
909 static struct pci_dev *dev_diva __devinitdata = NULL;
910 static struct pci_dev *dev_diva_u __devinitdata = NULL;
911 static struct pci_dev *dev_diva201 __devinitdata = NULL;
912 static struct pci_dev *dev_diva202 __devinitdata = NULL;
913
914 #ifdef __ISAPNP__
915 static struct isapnp_device_id diva_ids[] __devinitdata = {
916         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
917           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
918           (unsigned long) "Diva picola" },
919         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
920           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
921           (unsigned long) "Diva picola" },
922         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
923           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
924           (unsigned long) "Diva 2.0" },
925         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
926           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
927           (unsigned long) "Diva 2.0" },
928         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
929           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
930           (unsigned long) "Diva 2.01" },
931         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
932           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
933           (unsigned long) "Diva 2.01" },
934         { 0, }
935 };
936
937 static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0];
938 static struct pnp_card *pnp_c __devinitdata = NULL;
939 #endif
940
941
942 int __devinit
943 setup_diva(struct IsdnCard *card)
944 {
945         int bytecnt = 8;
946         u_char val;
947         struct IsdnCardState *cs = card->cs;
948         char tmp[64];
949
950         strcpy(tmp, Diva_revision);
951         printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
952         if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
953                 return(0);
954         cs->hw.diva.status = 0;
955         if (card->para[1]) {
956                 cs->hw.diva.ctrl_reg = 0;
957                 cs->hw.diva.cfg_reg = card->para[1];
958                 val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
959                         cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
960                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
961                 if ((val == 1) || (val==2)) {
962                         cs->subtyp = DIVA_IPAC_ISA;
963                         cs->hw.diva.ctrl = 0;
964                         cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
965                         cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;
966                         cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
967                         cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;
968                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
969                 } else {
970                         cs->subtyp = DIVA_ISA;
971                         cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
972                         cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
973                         cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
974                         cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
975                         cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
976                 }
977                 cs->irq = card->para[0];
978         } else {
979 #ifdef __ISAPNP__
980                 if (isapnp_present()) {
981                         struct pnp_dev *pnp_d;
982                         while(ipid->card_vendor) {
983                                 if ((pnp_c = pnp_find_card(ipid->card_vendor,
984                                         ipid->card_device, pnp_c))) {
985                                         pnp_d = NULL;
986                                         if ((pnp_d = pnp_find_dev(pnp_c,
987                                                 ipid->vendor, ipid->function, pnp_d))) {
988                                                 int err;
989
990                                                 printk(KERN_INFO "HiSax: %s detected\n",
991                                                         (char *)ipid->driver_data);
992                                                 pnp_disable_dev(pnp_d);
993                                                 err = pnp_activate_dev(pnp_d);
994                                                 if (err<0) {
995                                                         printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
996                                                                 __FUNCTION__, err);
997                                                         return(0);
998                                                 }
999                                                 card->para[1] = pnp_port_start(pnp_d, 0);
1000                                                 card->para[0] = pnp_irq(pnp_d, 0);
1001                                                 if (!card->para[0] || !card->para[1]) {
1002                                                         printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
1003                                                                 card->para[0], card->para[1]);
1004                                                         pnp_disable_dev(pnp_d); 
1005                                                         return(0);
1006                                                 }
1007                                                 cs->hw.diva.cfg_reg  = card->para[1];
1008                                                 cs->irq = card->para[0];
1009                                                 if (ipid->function == ISAPNP_FUNCTION(0xA1)) {
1010                                                         cs->subtyp = DIVA_IPAC_ISA;
1011                                                         cs->hw.diva.ctrl = 0;
1012                                                         cs->hw.diva.isac =
1013                                                                 card->para[1] + DIVA_IPAC_DATA;
1014                                                         cs->hw.diva.hscx =
1015                                                                 card->para[1] + DIVA_IPAC_DATA;
1016                                                         cs->hw.diva.isac_adr =
1017                                                                 card->para[1] + DIVA_IPAC_ADR;
1018                                                         cs->hw.diva.hscx_adr =
1019                                                                 card->para[1] + DIVA_IPAC_ADR;
1020                                                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
1021                                                 } else {
1022                                                         cs->subtyp = DIVA_ISA;
1023                                                         cs->hw.diva.ctrl =
1024                                                                 card->para[1] + DIVA_ISA_CTRL;
1025                                                         cs->hw.diva.isac =
1026                                                                 card->para[1] + DIVA_ISA_ISAC_DATA;
1027                                                         cs->hw.diva.hscx =
1028                                                                 card->para[1] + DIVA_HSCX_DATA;
1029                                                         cs->hw.diva.isac_adr =
1030                                                                 card->para[1] + DIVA_ISA_ISAC_ADR;
1031                                                         cs->hw.diva.hscx_adr =
1032                                                                 card->para[1] + DIVA_HSCX_ADR;
1033                                                 }
1034                                                 goto ready;
1035                                         } else {
1036                                                 printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
1037                                                 return(0);
1038                                         }
1039                                 }
1040                                 ipid++;
1041                                 pnp_c=NULL;
1042                         } 
1043                         if (!ipid->card_vendor) {
1044                                 printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
1045                         }
1046                 }
1047 #endif
1048 #ifdef CONFIG_PCI
1049                 cs->subtyp = 0;
1050                 if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
1051                         PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
1052                         if (pci_enable_device(dev_diva))
1053                                 return(0);
1054                         cs->subtyp = DIVA_PCI;
1055                         cs->irq = dev_diva->irq;
1056                         cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
1057                 } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
1058                         PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
1059                         if (pci_enable_device(dev_diva_u))
1060                                 return(0);
1061                         cs->subtyp = DIVA_PCI;
1062                         cs->irq = dev_diva_u->irq;
1063                         cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
1064                 } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
1065                         PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
1066                         if (pci_enable_device(dev_diva201))
1067                                 return(0);
1068                         cs->subtyp = DIVA_IPAC_PCI;
1069                         cs->irq = dev_diva201->irq;
1070                         cs->hw.diva.pci_cfg =
1071                                 (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
1072                         cs->hw.diva.cfg_reg =
1073                                 (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
1074                 } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON,
1075                         PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
1076                         if (pci_enable_device(dev_diva202))
1077                                 return(0);
1078                         cs->subtyp = DIVA_IPACX_PCI;
1079                         cs->irq = dev_diva202->irq;
1080                         cs->hw.diva.pci_cfg =
1081                                 (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096);
1082                         cs->hw.diva.cfg_reg =
1083                                 (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096);
1084                 } else {
1085                         printk(KERN_WARNING "Diva: No PCI card found\n");
1086                         return(0);
1087                 }
1088
1089                 if (!cs->irq) {
1090                         printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
1091                         iounmap_diva(cs);
1092                         return(0);
1093                 }
1094
1095                 if (!cs->hw.diva.cfg_reg) {
1096                         printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
1097                         iounmap_diva(cs);
1098                         return(0);
1099                 }
1100                 cs->irq_flags |= IRQF_SHARED;
1101 #else
1102                 printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n");
1103                 printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");
1104                 return (0);
1105 #endif /* CONFIG_PCI */
1106                 if ((cs->subtyp == DIVA_IPAC_PCI) ||
1107                     (cs->subtyp == DIVA_IPACX_PCI)   ) {
1108                         cs->hw.diva.ctrl = 0;
1109                         cs->hw.diva.isac = 0;
1110                         cs->hw.diva.hscx = 0;
1111                         cs->hw.diva.isac_adr = 0;
1112                         cs->hw.diva.hscx_adr = 0;
1113                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
1114                         bytecnt = 0;
1115                 } else {
1116                         cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL;
1117                         cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA;
1118                         cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA;
1119                         cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR;
1120                         cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR;
1121                         bytecnt = 32;
1122                 }
1123         }
1124 ready:
1125         printk(KERN_INFO
1126                 "Diva: %s card configured at %#lx IRQ %d\n",
1127                 (cs->subtyp == DIVA_PCI) ? "PCI" :
1128                 (cs->subtyp == DIVA_ISA) ? "ISA" : 
1129                 (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
1130                 (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
1131                 cs->hw.diva.cfg_reg, cs->irq);
1132         if ((cs->subtyp == DIVA_IPAC_PCI)  || 
1133             (cs->subtyp == DIVA_IPACX_PCI) || 
1134             (cs->subtyp == DIVA_PCI)         )
1135                 printk(KERN_INFO "Diva: %s space at %#lx\n",
1136                         (cs->subtyp == DIVA_PCI) ? "PCI" :
1137                         (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
1138                         cs->hw.diva.pci_cfg);
1139         if ((cs->subtyp != DIVA_IPAC_PCI) &&
1140             (cs->subtyp != DIVA_IPACX_PCI)   ) {
1141                 if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) {
1142                         printk(KERN_WARNING
1143                                "HiSax: %s config port %lx-%lx already in use\n",
1144                                CardType[card->typ],
1145                                cs->hw.diva.cfg_reg,
1146                                cs->hw.diva.cfg_reg + bytecnt);
1147                         iounmap_diva(cs);
1148                         return (0);
1149                 }
1150         }
1151         cs->BC_Read_Reg  = &ReadHSCX;
1152         cs->BC_Write_Reg = &WriteHSCX;
1153         cs->BC_Send_Data = &hscx_fill_fifo;
1154         cs->cardmsg = &Diva_card_msg;
1155         setup_isac(cs);
1156         if (cs->subtyp == DIVA_IPAC_ISA) {
1157                 cs->readisac  = &ReadISAC_IPAC;
1158                 cs->writeisac = &WriteISAC_IPAC;
1159                 cs->readisacfifo  = &ReadISACfifo_IPAC;
1160                 cs->writeisacfifo = &WriteISACfifo_IPAC;
1161                 cs->irq_func = &diva_irq_ipac_isa;
1162                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
1163                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
1164         } else if (cs->subtyp == DIVA_IPAC_PCI) {
1165                 cs->readisac  = &MemReadISAC_IPAC;
1166                 cs->writeisac = &MemWriteISAC_IPAC;
1167                 cs->readisacfifo  = &MemReadISACfifo_IPAC;
1168                 cs->writeisacfifo = &MemWriteISACfifo_IPAC;
1169                 cs->BC_Read_Reg  = &MemReadHSCX;
1170                 cs->BC_Write_Reg = &MemWriteHSCX;
1171                 cs->BC_Send_Data = &Memhscx_fill_fifo;
1172                 cs->irq_func = &diva_irq_ipac_pci;
1173                 val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
1174                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
1175         } else if (cs->subtyp == DIVA_IPACX_PCI) {
1176                 cs->readisac  = &MemReadISAC_IPACX;
1177                 cs->writeisac = &MemWriteISAC_IPACX;
1178                 cs->readisacfifo  = &MemReadISACfifo_IPACX;
1179                 cs->writeisacfifo = &MemWriteISACfifo_IPACX;
1180                 cs->BC_Read_Reg  = &MemReadHSCX_IPACX;
1181                 cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
1182                 cs->BC_Send_Data = NULL; // function located in ipacx module
1183                 cs->irq_func = &diva_irq_ipacx_pci;
1184                 printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
1185                         MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
1186         } else { /* DIVA 2.0 */
1187                 cs->hw.diva.tl.function = (void *) diva_led_handler;
1188                 cs->hw.diva.tl.data = (long) cs;
1189                 init_timer(&cs->hw.diva.tl);
1190                 cs->readisac  = &ReadISAC;
1191                 cs->writeisac = &WriteISAC;
1192                 cs->readisacfifo  = &ReadISACfifo;
1193                 cs->writeisacfifo = &WriteISACfifo;
1194                 cs->irq_func = &diva_interrupt;
1195                 ISACVersion(cs, "Diva:");
1196                 if (HscxVersion(cs, "Diva:")) {
1197                         printk(KERN_WARNING
1198                        "Diva: wrong HSCX versions check IO address\n");
1199                         release_io_diva(cs);
1200                         return (0);
1201                 }
1202         }
1203         return (1);
1204 }