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>
25 #include <linux/isdn/capicmd.h>
26 #include <linux/isdn/capiutil.h>
27 #include <linux/isdn/capilli.h>
30 /* ------------------------------------------------------------- */
32 static char *revision
= "$Revision: 1.1.2.3 $";
34 /* ------------------------------------------------------------- */
36 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
37 MODULE_AUTHOR("Carsten Paeth");
38 MODULE_LICENSE("GPL");
40 /* ------------------------------------------------------------- */
42 static int hema_irq_table
[16] =
61 static int t1_detectandinit(unsigned int base
, unsigned irq
, int cardnr
)
63 unsigned char cregs
[8];
64 unsigned char reverse_cardnr
;
68 reverse_cardnr
= ((cardnr
& 0x01) << 3) | ((cardnr
& 0x02) << 1)
69 | ((cardnr
& 0x04) >> 1) | ((cardnr
& 0x08) >> 3);
70 cregs
[0] = (HEMA_VERSION_ID
<< 4) | (reverse_cardnr
& 0xf);
71 cregs
[1] = 0x00; /* fast & slow link connected to CON1 */
72 cregs
[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
74 cregs
[4] = 0x11; /* zero wait state */
75 cregs
[5] = hema_irq_table
[irq
& 0xf];
80 * no one else should use the ISA bus in this moment,
81 * but no function there to prevent this :-(
82 * save_flags(flags); cli();
86 t1outp(base
, T1_RESETBOARD
, 0xf);
88 dummy
= t1inp(base
, T1_FASTLINK
+T1_OUTSTAT
); /* first read */
91 dummy
= (base
>> 4) & 0xff;
92 for (i
=1;i
<=0xf;i
++) t1outp(base
, i
, dummy
);
93 t1outp(base
, HEMA_PAL_ID
& 0xf, dummy
);
94 t1outp(base
, HEMA_PAL_ID
>> 4, cregs
[0]);
95 for(i
=1;i
<7;i
++) t1outp(base
, 0, cregs
[i
]);
96 t1outp(base
, ((base
>> 4)) & 0x3, cregs
[7]);
97 /* restore_flags(flags); */
100 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 0);
101 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 0);
103 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 1);
104 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 1);
106 t1outp(base
, T1_FASTLINK
+T1_RESETLINK
, 0);
107 t1outp(base
, T1_SLOWLINK
+T1_RESETLINK
, 0);
109 t1outp(base
, T1_FASTLINK
+T1_ANALYSE
, 0);
111 t1outp(base
, T1_SLOWLINK
+T1_ANALYSE
, 0);
113 if (t1inp(base
, T1_FASTLINK
+T1_OUTSTAT
) != 0x1) /* tx empty */
115 if (t1inp(base
, T1_FASTLINK
+T1_INSTAT
) != 0x0) /* rx empty */
117 if (t1inp(base
, T1_FASTLINK
+T1_IRQENABLE
) != 0x0)
119 if ((t1inp(base
, T1_FASTLINK
+T1_FIFOSTAT
) & 0xf0) != 0x70)
121 if ((t1inp(base
, T1_FASTLINK
+T1_IRQMASTER
) & 0x0e) != 0)
123 if ((t1inp(base
, T1_FASTLINK
+T1_IDENT
) & 0x7d) != 1)
125 if (t1inp(base
, T1_SLOWLINK
+T1_OUTSTAT
) != 0x1) /* tx empty */
127 if ((t1inp(base
, T1_SLOWLINK
+T1_IRQMASTER
) & 0x0e) != 0)
129 if ((t1inp(base
, T1_SLOWLINK
+T1_IDENT
) & 0x7d) != 0)
134 static irqreturn_t
t1isa_interrupt(int interrupt
, void *devptr
, struct pt_regs
*regs
)
136 avmcard
*card
= devptr
;
137 avmctrl_info
*cinfo
= &card
->ctrlinfo
[0];
138 struct capi_ctr
*ctrl
= &cinfo
->capi_ctrl
;
149 spin_lock_irqsave(&card
->lock
, flags
);
151 while (b1_rx_full(card
->port
)) {
153 b1cmd
= b1_get_byte(card
->port
);
157 case RECEIVE_DATA_B3_IND
:
159 ApplId
= (unsigned) b1_get_word(card
->port
);
160 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
161 DataB3Len
= t1_get_slice(card
->port
, card
->databuf
);
162 spin_unlock_irqrestore(&card
->lock
, flags
);
164 if (MsgLen
< 30) { /* not CAPI 64Bit */
165 memset(card
->msgbuf
+MsgLen
, 0, 30-MsgLen
);
167 CAPIMSG_SETLEN(card
->msgbuf
, 30);
169 if (!(skb
= alloc_skb(DataB3Len
+MsgLen
, GFP_ATOMIC
))) {
170 printk(KERN_ERR
"%s: incoming packet dropped\n",
173 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
174 memcpy(skb_put(skb
, DataB3Len
), card
->databuf
, DataB3Len
);
175 capi_ctr_handle_message(ctrl
, ApplId
, skb
);
179 case RECEIVE_MESSAGE
:
181 ApplId
= (unsigned) b1_get_word(card
->port
);
182 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
183 spin_unlock_irqrestore(&card
->lock
, flags
);
184 if (!(skb
= alloc_skb(MsgLen
, GFP_ATOMIC
))) {
185 printk(KERN_ERR
"%s: incoming packet dropped\n",
188 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
189 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3
)
190 capilib_data_b3_conf(&cinfo
->ncci_head
, ApplId
,
191 CAPIMSG_NCCI(skb
->data
),
192 CAPIMSG_MSGID(skb
->data
));
194 capi_ctr_handle_message(ctrl
, ApplId
, skb
);
198 case RECEIVE_NEW_NCCI
:
200 ApplId
= b1_get_word(card
->port
);
201 NCCI
= b1_get_word(card
->port
);
202 WindowSize
= b1_get_word(card
->port
);
203 spin_unlock_irqrestore(&card
->lock
, flags
);
205 capilib_new_ncci(&cinfo
->ncci_head
, ApplId
, NCCI
, WindowSize
);
209 case RECEIVE_FREE_NCCI
:
211 ApplId
= b1_get_word(card
->port
);
212 NCCI
= b1_get_word(card
->port
);
213 spin_unlock_irqrestore(&card
->lock
, flags
);
215 if (NCCI
!= 0xffffffff)
216 capilib_free_ncci(&cinfo
->ncci_head
, ApplId
, NCCI
);
221 b1_put_byte(card
->port
, SEND_POLLACK
);
222 spin_unlock_irqrestore(&card
->lock
, flags
);
223 capi_ctr_resume_output(ctrl
);
227 spin_unlock_irqrestore(&card
->lock
, flags
);
228 capi_ctr_suspend_output(ctrl
);
233 cinfo
->versionlen
= t1_get_slice(card
->port
, cinfo
->versionbuf
);
234 spin_unlock_irqrestore(&card
->lock
, flags
);
235 b1_parse_version(cinfo
);
236 printk(KERN_INFO
"%s: %s-card (%s) now active\n",
238 cinfo
->version
[VER_CARDTYPE
],
239 cinfo
->version
[VER_DRIVER
]);
240 capi_ctr_ready(ctrl
);
243 case RECEIVE_TASK_READY
:
244 ApplId
= (unsigned) b1_get_word(card
->port
);
245 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
246 spin_unlock_irqrestore(&card
->lock
, flags
);
247 card
->msgbuf
[MsgLen
] = 0;
249 && ( card
->msgbuf
[MsgLen
-1] == '\n'
250 || card
->msgbuf
[MsgLen
-1] == '\r')) {
251 card
->msgbuf
[MsgLen
-1] = 0;
254 printk(KERN_INFO
"%s: task %d \"%s\" ready.\n",
255 card
->name
, ApplId
, card
->msgbuf
);
258 case RECEIVE_DEBUGMSG
:
259 MsgLen
= t1_get_slice(card
->port
, card
->msgbuf
);
260 spin_unlock_irqrestore(&card
->lock
, flags
);
261 card
->msgbuf
[MsgLen
] = 0;
263 && ( card
->msgbuf
[MsgLen
-1] == '\n'
264 || card
->msgbuf
[MsgLen
-1] == '\r')) {
265 card
->msgbuf
[MsgLen
-1] = 0;
268 printk(KERN_INFO
"%s: DEBUG: %s\n", card
->name
, card
->msgbuf
);
273 spin_unlock_irqrestore(&card
->lock
, flags
);
274 printk(KERN_ERR
"%s: card reseted ?\n", card
->name
);
277 spin_unlock_irqrestore(&card
->lock
, flags
);
278 printk(KERN_ERR
"%s: b1_interrupt: 0x%x ???\n",
286 /* ------------------------------------------------------------- */
288 static int t1isa_load_firmware(struct capi_ctr
*ctrl
, capiloaddata
*data
)
290 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
291 avmcard
*card
= cinfo
->card
;
292 unsigned int port
= card
->port
;
296 t1_disable_irq(port
);
299 if ((retval
= b1_load_t4file(card
, &data
->firmware
))) {
301 printk(KERN_ERR
"%s: failed to load t4file!!\n",
306 if (data
->configuration
.len
> 0 && data
->configuration
.data
) {
307 if ((retval
= b1_load_config(card
, &data
->configuration
))) {
309 printk(KERN_ERR
"%s: failed to load config!!\n",
315 if (!b1_loaded(card
)) {
316 printk(KERN_ERR
"%s: failed to load t4file.\n", card
->name
);
320 spin_lock_irqsave(&card
->lock
, flags
);
321 b1_setinterrupt(port
, card
->irq
, card
->cardtype
);
322 b1_put_byte(port
, SEND_INIT
);
323 b1_put_word(port
, CAPI_MAXAPPL
);
324 b1_put_word(port
, AVM_NCCI_PER_CHANNEL
*30);
325 b1_put_word(port
, ctrl
->cnr
- 1);
326 spin_unlock_irqrestore(&card
->lock
, flags
);
331 static void t1isa_reset_ctr(struct capi_ctr
*ctrl
)
333 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
334 avmcard
*card
= cinfo
->card
;
335 unsigned int port
= card
->port
;
337 t1_disable_irq(port
);
341 memset(cinfo
->version
, 0, sizeof(cinfo
->version
));
342 capilib_release(&cinfo
->ncci_head
);
343 capi_ctr_reseted(ctrl
);
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
.ctr_read_proc
= b1ctl_read_proc
;
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 if (CAPICMD(cmd
, subcmd
) == CAPI_DATA_B3_REQ
) {
470 retval
= capilib_data_b3_req(&cinfo
->ncci_head
,
471 CAPIMSG_APPID(skb
->data
),
472 CAPIMSG_NCCI(skb
->data
),
473 CAPIMSG_MSGID(skb
->data
));
474 if (retval
!= CAPI_NOERROR
)
477 dlen
= CAPIMSG_DATALEN(skb
->data
);
479 spin_lock_irqsave(&card
->lock
, flags
);
480 b1_put_byte(port
, SEND_DATA_B3_REQ
);
481 t1_put_slice(port
, skb
->data
, len
);
482 t1_put_slice(port
, skb
->data
+ len
, dlen
);
483 spin_unlock_irqrestore(&card
->lock
, flags
);
486 spin_lock_irqsave(&card
->lock
, flags
);
487 b1_put_byte(port
, SEND_MESSAGE
);
488 t1_put_slice(port
, skb
->data
, len
);
489 spin_unlock_irqrestore(&card
->lock
, flags
);
492 dev_kfree_skb_any(skb
);
495 /* ------------------------------------------------------------- */
497 static char *t1isa_procinfo(struct capi_ctr
*ctrl
)
499 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
503 sprintf(cinfo
->infobuf
, "%s %s 0x%x %d %d",
504 cinfo
->cardname
[0] ? cinfo
->cardname
: "-",
505 cinfo
->version
[VER_DRIVER
] ? cinfo
->version
[VER_DRIVER
] : "-",
506 cinfo
->card
? cinfo
->card
->port
: 0x0,
507 cinfo
->card
? cinfo
->card
->irq
: 0,
508 cinfo
->card
? cinfo
->card
->cardnr
: 0
510 return cinfo
->infobuf
;
514 /* ------------------------------------------------------------- */
517 static struct pci_dev isa_dev
[MAX_CARDS
];
518 static int io
[MAX_CARDS
];
519 static int irq
[MAX_CARDS
];
520 static int cardnr
[MAX_CARDS
];
522 module_param_array(io
, int, NULL
, 0);
523 module_param_array(irq
, int, NULL
, 0);
524 module_param_array(cardnr
, int, NULL
, 0);
525 MODULE_PARM_DESC(io
, "I/O base address(es)");
526 MODULE_PARM_DESC(irq
, "IRQ number(s) (assigned)");
527 MODULE_PARM_DESC(cardnr
, "Card number(s) (as jumpered)");
529 static int t1isa_add_card(struct capi_driver
*driver
, capicardparams
*data
)
533 for (i
= 0; i
< MAX_CARDS
; i
++) {
534 if (isa_dev
[i
].resource
[0].start
)
537 isa_dev
[i
].resource
[0].start
= data
->port
;
538 isa_dev
[i
].irq
= data
->irq
;
540 if (t1isa_probe(&isa_dev
[i
], data
->cardnr
) == 0)
546 static struct capi_driver capi_driver_t1isa
= {
549 .add_card
= t1isa_add_card
,
552 static int __init
t1isa_init(void)
558 if ((p
= strchr(revision
, ':')) != 0 && p
[1]) {
559 strlcpy(rev
, p
+ 2, 32);
560 if ((p
= strchr(rev
, '$')) != 0 && p
> rev
)
565 for (i
= 0; i
< MAX_CARDS
; i
++) {
569 isa_dev
[i
].resource
[0].start
= io
[i
];
570 isa_dev
[i
].irq
= irq
[i
];
572 if (t1isa_probe(&isa_dev
[i
], cardnr
[i
]) != 0)
576 strlcpy(capi_driver_t1isa
.revision
, rev
, 32);
577 register_capi_driver(&capi_driver_t1isa
);
578 printk(KERN_INFO
"t1isa: revision %s\n", rev
);
583 static void __exit
t1isa_exit(void)
587 for (i
= 0; i
< MAX_CARDS
; i
++) {
591 t1isa_remove(&isa_dev
[i
]);
595 module_init(t1isa_init
);
596 module_exit(t1isa_exit
);