1 /* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
3 * Module for AVM T1 HEMA-card.
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/skbuff.h>
15 #include <linux/delay.h>
17 #include <linux/interrupt.h>
18 #include <linux/ioport.h>
19 #include <linux/capi.h>
20 #include <linux/netdevice.h>
21 #include <linux/kernelcapi.h>
22 #include <linux/init.h>
23 #include <linux/pci.h>
24 #include <linux/gfp.h>
26 #include <linux/isdn/capicmd.h>
27 #include <linux/isdn/capiutil.h>
28 #include <linux/isdn/capilli.h>
31 /* ------------------------------------------------------------- */
33 static char *revision
= "$Revision: 1.1.2.3 $";
35 /* ------------------------------------------------------------- */
37 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
38 MODULE_AUTHOR("Carsten Paeth");
39 MODULE_LICENSE("GPL");
41 /* ------------------------------------------------------------- */
43 static int hema_irq_table
[16] =
62 static int t1_detectandinit(unsigned int base
, unsigned irq
, int cardnr
)
64 unsigned char cregs
[8];
65 unsigned char reverse_cardnr
;
69 reverse_cardnr
= ((cardnr
& 0x01) << 3) | ((cardnr
& 0x02) << 1)
70 | ((cardnr
& 0x04) >> 1) | ((cardnr
& 0x08) >> 3);
71 cregs
[0] = (HEMA_VERSION_ID
<< 4) | (reverse_cardnr
& 0xf);
72 cregs
[1] = 0x00; /* fast & slow link connected to CON1 */
73 cregs
[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
75 cregs
[4] = 0x11; /* zero wait state */
76 cregs
[5] = hema_irq_table
[irq
& 0xf];
81 * no one else should use the ISA bus in this moment,
82 * but no function there to prevent this :-(
83 * save_flags(flags); cli();
87 t1outp(base
, T1_RESETBOARD
, 0xf);
89 dummy
= t1inp(base
, T1_FASTLINK
+T1_OUTSTAT
); /* first read */
92 dummy
= (base
>> 4) & 0xff;
93 for (i
=1;i
<=0xf;i
++) t1outp(base
, i
, dummy
);
94 t1outp(base
, HEMA_PAL_ID
& 0xf, dummy
);
95 t1outp(base
, HEMA_PAL_ID
>> 4, cregs
[0]);
96 for(i
=1;i
<7;i
++) t1outp(base
, 0, cregs
[i
]);
97 t1outp(base
, ((base
>> 4)) & 0x3, cregs
[7]);
98 /* restore_flags(flags); */
101 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 0);
102 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 0);
104 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 1);
105 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 1);
107 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 0);
108 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 0);
110 t1outp(base
, T1_FASTLINK
+T1_ANALYSE
, 0);
112 t1outp(base
, T1_SLOWLINK
+T1_ANALYSE
, 0);
114 if (t1inp(base
, T1_FASTLINK
+T1_OUTSTAT
) != 0x1) /* tx empty */
116 if (t1inp(base
, T1_FASTLINK
+T1_INSTAT
) != 0x0) /* rx empty */
118 if (t1inp(base
, T1_FASTLINK
+T1_IRQENABLE
) != 0x0)
120 if ((t1inp(base
, T1_FASTLINK
+T1_FIFOSTAT
) & 0xf0) != 0x70)
122 if ((t1inp(base
, T1_FASTLINK
+T1_IRQMASTER
) & 0x0e) != 0)
124 if ((t1inp(base
, T1_FASTLINK
+T1_IDENT
) & 0x7d) != 1)
126 if (t1inp(base
, T1_SLOWLINK
+T1_OUTSTAT
) != 0x1) /* tx empty */
128 if ((t1inp(base
, T1_SLOWLINK
+T1_IRQMASTER
) & 0x0e) != 0)
130 if ((t1inp(base
, T1_SLOWLINK
+T1_IDENT
) & 0x7d) != 0)
135 static irqreturn_t
t1isa_interrupt(int interrupt
, void *devptr
)
137 avmcard
*card
= devptr
;
138 avmctrl_info
*cinfo
= &card
->ctrlinfo
[0];
139 struct capi_ctr
*ctrl
= &cinfo
->capi_ctrl
;
150 spin_lock_irqsave(&card
->lock
, flags
);
152 while (b1_rx_full(card
->port
)) {
154 b1cmd
= b1_get_byte(card
->port
);
158 case RECEIVE_DATA_B3_IND
:
160 ApplId
= (unsigned) b1_get_word(card
->port
);
161 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
162 DataB3Len
= t1_get_slice(card
->port
, card
->databuf
);
163 spin_unlock_irqrestore(&card
->lock
, flags
);
165 if (MsgLen
< 30) { /* not CAPI 64Bit */
166 memset(card
->msgbuf
+MsgLen
, 0, 30-MsgLen
);
168 CAPIMSG_SETLEN(card
->msgbuf
, 30);
170 if (!(skb
= alloc_skb(DataB3Len
+MsgLen
, GFP_ATOMIC
))) {
171 printk(KERN_ERR
"%s: incoming packet dropped\n",
174 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
175 memcpy(skb_put(skb
, DataB3Len
), card
->databuf
, DataB3Len
);
176 capi_ctr_handle_message(ctrl
, ApplId
, skb
);
180 case RECEIVE_MESSAGE
:
182 ApplId
= (unsigned) b1_get_word(card
->port
);
183 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
184 if (!(skb
= alloc_skb(MsgLen
, GFP_ATOMIC
))) {
185 spin_unlock_irqrestore(&card
->lock
, flags
);
186 printk(KERN_ERR
"%s: incoming packet dropped\n",
189 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
190 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3
)
191 capilib_data_b3_conf(&cinfo
->ncci_head
, ApplId
,
192 CAPIMSG_NCCI(skb
->data
),
193 CAPIMSG_MSGID(skb
->data
));
194 spin_unlock_irqrestore(&card
->lock
, flags
);
195 capi_ctr_handle_message(ctrl
, ApplId
, skb
);
199 case RECEIVE_NEW_NCCI
:
201 ApplId
= b1_get_word(card
->port
);
202 NCCI
= b1_get_word(card
->port
);
203 WindowSize
= b1_get_word(card
->port
);
204 capilib_new_ncci(&cinfo
->ncci_head
, ApplId
, NCCI
, WindowSize
);
205 spin_unlock_irqrestore(&card
->lock
, flags
);
208 case RECEIVE_FREE_NCCI
:
210 ApplId
= b1_get_word(card
->port
);
211 NCCI
= b1_get_word(card
->port
);
212 if (NCCI
!= 0xffffffff)
213 capilib_free_ncci(&cinfo
->ncci_head
, ApplId
, NCCI
);
214 spin_unlock_irqrestore(&card
->lock
, flags
);
218 b1_put_byte(card
->port
, SEND_POLLACK
);
219 spin_unlock_irqrestore(&card
->lock
, flags
);
220 capi_ctr_resume_output(ctrl
);
224 spin_unlock_irqrestore(&card
->lock
, flags
);
225 capi_ctr_suspend_output(ctrl
);
230 cinfo
->versionlen
= t1_get_slice(card
->port
, cinfo
->versionbuf
);
231 spin_unlock_irqrestore(&card
->lock
, flags
);
232 b1_parse_version(cinfo
);
233 printk(KERN_INFO
"%s: %s-card (%s) now active\n",
235 cinfo
->version
[VER_CARDTYPE
],
236 cinfo
->version
[VER_DRIVER
]);
237 capi_ctr_ready(ctrl
);
240 case RECEIVE_TASK_READY
:
241 ApplId
= (unsigned) b1_get_word(card
->port
);
242 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
243 spin_unlock_irqrestore(&card
->lock
, flags
);
244 card
->msgbuf
[MsgLen
] = 0;
246 && ( card
->msgbuf
[MsgLen
-1] == '\n'
247 || card
->msgbuf
[MsgLen
-1] == '\r')) {
248 card
->msgbuf
[MsgLen
-1] = 0;
251 printk(KERN_INFO
"%s: task %d \"%s\" ready.\n",
252 card
->name
, ApplId
, card
->msgbuf
);
255 case RECEIVE_DEBUGMSG
:
256 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
257 spin_unlock_irqrestore(&card
->lock
, flags
);
258 card
->msgbuf
[MsgLen
] = 0;
260 && ( card
->msgbuf
[MsgLen
-1] == '\n'
261 || card
->msgbuf
[MsgLen
-1] == '\r')) {
262 card
->msgbuf
[MsgLen
-1] = 0;
265 printk(KERN_INFO
"%s: DEBUG: %s\n", card
->name
, card
->msgbuf
);
270 spin_unlock_irqrestore(&card
->lock
, flags
);
271 printk(KERN_ERR
"%s: card reseted ?\n", card
->name
);
274 spin_unlock_irqrestore(&card
->lock
, flags
);
275 printk(KERN_ERR
"%s: b1_interrupt: 0x%x ???\n",
283 /* ------------------------------------------------------------- */
285 static int t1isa_load_firmware(struct capi_ctr
*ctrl
, capiloaddata
*data
)
287 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
288 avmcard
*card
= cinfo
->card
;
289 unsigned int port
= card
->port
;
293 t1_disable_irq(port
);
296 if ((retval
= b1_load_t4file(card
, &data
->firmware
))) {
298 printk(KERN_ERR
"%s: failed to load t4file!!\n",
303 if (data
->configuration
.len
> 0 && data
->configuration
.data
) {
304 if ((retval
= b1_load_config(card
, &data
->configuration
))) {
306 printk(KERN_ERR
"%s: failed to load config!!\n",
312 if (!b1_loaded(card
)) {
313 printk(KERN_ERR
"%s: failed to load t4file.\n", card
->name
);
317 spin_lock_irqsave(&card
->lock
, flags
);
318 b1_setinterrupt(port
, card
->irq
, card
->cardtype
);
319 b1_put_byte(port
, SEND_INIT
);
320 b1_put_word(port
, CAPI_MAXAPPL
);
321 b1_put_word(port
, AVM_NCCI_PER_CHANNEL
*30);
322 b1_put_word(port
, ctrl
->cnr
- 1);
323 spin_unlock_irqrestore(&card
->lock
, flags
);
328 static void t1isa_reset_ctr(struct capi_ctr
*ctrl
)
330 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
331 avmcard
*card
= cinfo
->card
;
332 unsigned int port
= card
->port
;
335 t1_disable_irq(port
);
339 memset(cinfo
->version
, 0, sizeof(cinfo
->version
));
340 spin_lock_irqsave(&card
->lock
, flags
);
341 capilib_release(&cinfo
->ncci_head
);
342 spin_unlock_irqrestore(&card
->lock
, flags
);
346 static void t1isa_remove(struct pci_dev
*pdev
)
348 avmctrl_info
*cinfo
= pci_get_drvdata(pdev
);
356 t1_disable_irq(card
->port
);
357 b1_reset(card
->port
);
358 b1_reset(card
->port
);
359 t1_reset(card
->port
);
361 detach_capi_ctr(&cinfo
->capi_ctrl
);
362 free_irq(card
->irq
, card
);
363 release_region(card
->port
, AVMB1_PORTLEN
);
367 /* ------------------------------------------------------------- */
369 static u16
t1isa_send_message(struct capi_ctr
*ctrl
, struct sk_buff
*skb
);
370 static char *t1isa_procinfo(struct capi_ctr
*ctrl
);
372 static int t1isa_probe(struct pci_dev
*pdev
, int cardnr
)
378 card
= b1_alloc_card(1);
380 printk(KERN_WARNING
"t1isa: no memory.\n");
385 cinfo
= card
->ctrlinfo
;
386 card
->port
= pci_resource_start(pdev
, 0);
387 card
->irq
= pdev
->irq
;
388 card
->cardtype
= avm_t1isa
;
389 card
->cardnr
= cardnr
;
390 sprintf(card
->name
, "t1isa-%x", card
->port
);
392 if (!(((card
->port
& 0x7) == 0) && ((card
->port
& 0x30) != 0x30))) {
393 printk(KERN_WARNING
"t1isa: invalid port 0x%x.\n", card
->port
);
397 if (hema_irq_table
[card
->irq
& 0xf] == 0) {
398 printk(KERN_WARNING
"t1isa: irq %d not valid.\n", card
->irq
);
402 if (!request_region(card
->port
, AVMB1_PORTLEN
, card
->name
)) {
403 printk(KERN_INFO
"t1isa: ports 0x%03x-0x%03x in use.\n",
404 card
->port
, card
->port
+ AVMB1_PORTLEN
);
408 retval
= request_irq(card
->irq
, t1isa_interrupt
, 0, card
->name
, card
);
410 printk(KERN_INFO
"t1isa: unable to get IRQ %d.\n", card
->irq
);
412 goto err_release_region
;
415 if ((retval
= t1_detectandinit(card
->port
, card
->irq
, card
->cardnr
)) != 0) {
416 printk(KERN_INFO
"t1isa: NO card at 0x%x (%d)\n",
421 t1_disable_irq(card
->port
);
422 b1_reset(card
->port
);
424 cinfo
->capi_ctrl
.owner
= THIS_MODULE
;
425 cinfo
->capi_ctrl
.driver_name
= "t1isa";
426 cinfo
->capi_ctrl
.driverdata
= cinfo
;
427 cinfo
->capi_ctrl
.register_appl
= b1_register_appl
;
428 cinfo
->capi_ctrl
.release_appl
= b1_release_appl
;
429 cinfo
->capi_ctrl
.send_message
= t1isa_send_message
;
430 cinfo
->capi_ctrl
.load_firmware
= t1isa_load_firmware
;
431 cinfo
->capi_ctrl
.reset_ctr
= t1isa_reset_ctr
;
432 cinfo
->capi_ctrl
.procinfo
= t1isa_procinfo
;
433 cinfo
->capi_ctrl
.proc_fops
= &b1ctl_proc_fops
;
434 strcpy(cinfo
->capi_ctrl
.name
, card
->name
);
436 retval
= attach_capi_ctr(&cinfo
->capi_ctrl
);
438 printk(KERN_INFO
"t1isa: attach controller failed.\n");
442 printk(KERN_INFO
"t1isa: AVM T1 ISA at i/o %#x, irq %d, card %d\n",
443 card
->port
, card
->irq
, card
->cardnr
);
445 pci_set_drvdata(pdev
, cinfo
);
449 free_irq(card
->irq
, card
);
451 release_region(card
->port
, AVMB1_PORTLEN
);
458 static u16
t1isa_send_message(struct capi_ctr
*ctrl
, struct sk_buff
*skb
)
460 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
461 avmcard
*card
= cinfo
->card
;
462 unsigned int port
= card
->port
;
464 u16 len
= CAPIMSG_LEN(skb
->data
);
465 u8 cmd
= CAPIMSG_COMMAND(skb
->data
);
466 u8 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
469 spin_lock_irqsave(&card
->lock
, flags
);
470 if (CAPICMD(cmd
, subcmd
) == CAPI_DATA_B3_REQ
) {
471 retval
= capilib_data_b3_req(&cinfo
->ncci_head
,
472 CAPIMSG_APPID(skb
->data
),
473 CAPIMSG_NCCI(skb
->data
),
474 CAPIMSG_MSGID(skb
->data
));
475 if (retval
!= CAPI_NOERROR
) {
476 spin_unlock_irqrestore(&card
->lock
, flags
);
479 dlen
= CAPIMSG_DATALEN(skb
->data
);
481 b1_put_byte(port
, SEND_DATA_B3_REQ
);
482 t1_put_slice(port
, skb
->data
, len
);
483 t1_put_slice(port
, skb
->data
+ len
, dlen
);
485 b1_put_byte(port
, SEND_MESSAGE
);
486 t1_put_slice(port
, skb
->data
, len
);
488 spin_unlock_irqrestore(&card
->lock
, flags
);
489 dev_kfree_skb_any(skb
);
492 /* ------------------------------------------------------------- */
494 static char *t1isa_procinfo(struct capi_ctr
*ctrl
)
496 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
500 sprintf(cinfo
->infobuf
, "%s %s 0x%x %d %d",
501 cinfo
->cardname
[0] ? cinfo
->cardname
: "-",
502 cinfo
->version
[VER_DRIVER
] ? cinfo
->version
[VER_DRIVER
] : "-",
503 cinfo
->card
? cinfo
->card
->port
: 0x0,
504 cinfo
->card
? cinfo
->card
->irq
: 0,
505 cinfo
->card
? cinfo
->card
->cardnr
: 0
507 return cinfo
->infobuf
;
511 /* ------------------------------------------------------------- */
514 static struct pci_dev isa_dev
[MAX_CARDS
];
515 static int io
[MAX_CARDS
];
516 static int irq
[MAX_CARDS
];
517 static int cardnr
[MAX_CARDS
];
519 module_param_array(io
, int, NULL
, 0);
520 module_param_array(irq
, int, NULL
, 0);
521 module_param_array(cardnr
, int, NULL
, 0);
522 MODULE_PARM_DESC(io
, "I/O base address(es)");
523 MODULE_PARM_DESC(irq
, "IRQ number(s) (assigned)");
524 MODULE_PARM_DESC(cardnr
, "Card number(s) (as jumpered)");
526 static int t1isa_add_card(struct capi_driver
*driver
, capicardparams
*data
)
530 for (i
= 0; i
< MAX_CARDS
; i
++) {
531 if (isa_dev
[i
].resource
[0].start
)
534 isa_dev
[i
].resource
[0].start
= data
->port
;
535 isa_dev
[i
].irq
= data
->irq
;
537 if (t1isa_probe(&isa_dev
[i
], data
->cardnr
) == 0)
543 static struct capi_driver capi_driver_t1isa
= {
546 .add_card
= t1isa_add_card
,
549 static int __init
t1isa_init(void)
555 if ((p
= strchr(revision
, ':')) != NULL
&& p
[1]) {
556 strlcpy(rev
, p
+ 2, 32);
557 if ((p
= strchr(rev
, '$')) != NULL
&& p
> rev
)
562 for (i
= 0; i
< MAX_CARDS
; i
++) {
566 isa_dev
[i
].resource
[0].start
= io
[i
];
567 isa_dev
[i
].irq
= irq
[i
];
569 if (t1isa_probe(&isa_dev
[i
], cardnr
[i
]) != 0)
573 strlcpy(capi_driver_t1isa
.revision
, rev
, 32);
574 register_capi_driver(&capi_driver_t1isa
);
575 printk(KERN_INFO
"t1isa: revision %s\n", rev
);
580 static void __exit
t1isa_exit(void)
584 unregister_capi_driver(&capi_driver_t1isa
);
585 for (i
= 0; i
< MAX_CARDS
; i
++) {
589 t1isa_remove(&isa_dev
[i
]);
593 module_init(t1isa_init
);
594 module_exit(t1isa_exit
);