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