1 /*************************************************************************/
2 /* $Id: hfc4s8s_l1.c,v 1.10 2005/02/09 16:31:09 martinb1 Exp $ */
3 /* HFC-4S/8S low layer interface for Cologne Chip HFC-4S/8S isdn chips */
4 /* The low layer (L1) is implemented as a loadable module for usage with */
5 /* the HiSax isdn driver for passive cards. */
7 /* Author: Werner Cornelius */
8 /* (C) 2003 Cornelius Consult (werner@cornelius-consult.de) */
10 /* Driver maintained by Cologne Chip */
11 /* - Martin Bachem, support@colognechip.com */
13 /* This driver only works with chip revisions >= 1, older revision 0 */
14 /* engineering samples (only first manufacturer sample cards) will not */
15 /* work and are rejected by the driver. */
17 /* This file distributed under the GNU GPL. */
19 /* See Version History at the end of this file */
21 /*************************************************************************/
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/pci.h>
26 #include <linux/interrupt.h>
27 #include <linux/delay.h>
28 #include <linux/timer.h>
29 #include <linux/skbuff.h>
30 #include <linux/wait.h>
33 #include "hfc4s8s_l1.h"
35 static const char hfc4s8s_rev
[] = "Revision: 1.10";
37 /***************************************************************/
38 /* adjustable transparent mode fifo threshold */
39 /* The value defines the used fifo threshold with the equation */
41 /* notify number of bytes = 2 * 2 ^ TRANS_FIFO_THRES */
43 /* The default value is 5 which results in a buffer size of 64 */
44 /* and an interrupt rate of 8ms. */
45 /* The maximum value is 7 due to fifo size restrictions. */
46 /* Values below 3-4 are not recommended due to high interrupt */
47 /* load of the processor. For non critical applications the */
48 /* value should be raised to 7 to reduce any interrupt overhead*/
49 /***************************************************************/
50 #define TRANS_FIFO_THRES 5
55 #define CLOCKMODE_0 0 /* ext. 24.576 MhZ clk freq, int. single clock mode */
56 #define CLOCKMODE_1 1 /* ext. 49.576 MhZ clk freq, int. single clock mode */
57 #define CHIP_ID_SHIFT 4
59 #define MAX_D_FRAME_SIZE 270
60 #define MAX_B_FRAME_SIZE 1536
61 #define TRANS_TIMER_MODE (TRANS_FIFO_THRES & 0xf)
62 #define TRANS_FIFO_BYTES (2 << TRANS_FIFO_THRES)
63 #define MAX_F_CNT 0x0f
65 #define CLKDEL_NT 0x6c
70 #define L1_TIMER_T4 2 /* minimum in jiffies */
71 #define L1_TIMER_T3 (7 * HZ) /* activation timeout */
72 #define L1_TIMER_T1 ((120 * HZ) / 1000) /* NT mode deactivation timeout */
80 /* private driver_data */
88 static struct pci_device_id hfc4s8s_ids
[] = {
89 {.vendor
= PCI_VENDOR_ID_CCD
,
90 .device
= PCI_DEVICE_ID_4S
,
94 (unsigned long) &((hfc4s8s_param
) {CHIP_ID_4S
, CLOCKMODE_0
, 4,
95 "HFC-4S Evaluation Board"}),
97 {.vendor
= PCI_VENDOR_ID_CCD
,
98 .device
= PCI_DEVICE_ID_8S
,
102 (unsigned long) &((hfc4s8s_param
) {CHIP_ID_8S
, CLOCKMODE_0
, 8,
103 "HFC-8S Evaluation Board"}),
105 {.vendor
= PCI_VENDOR_ID_CCD
,
106 .device
= PCI_DEVICE_ID_4S
,
110 (unsigned long) &((hfc4s8s_param
) {CHIP_ID_4S
, CLOCKMODE_1
, 4,
113 {.vendor
= PCI_VENDOR_ID_CCD
,
114 .device
= PCI_DEVICE_ID_8S
,
118 (unsigned long) &((hfc4s8s_param
) {CHIP_ID_8S
, CLOCKMODE_1
, 8,
124 MODULE_DEVICE_TABLE(pci
, hfc4s8s_ids
);
126 MODULE_AUTHOR("Werner Cornelius, werner@cornelius-consult.de");
127 MODULE_DESCRIPTION("ISDN layer 1 for Cologne Chip HFC-4S/8S chips");
128 MODULE_LICENSE("GPL");
133 struct hfc4s8s_btype
{
135 struct hisax_b_if b_if
;
136 struct hfc4s8s_l1
*l1p
;
137 struct sk_buff_head tx_queue
;
138 struct sk_buff
*tx_skb
;
139 struct sk_buff
*rx_skb
;
150 struct _hfc4s8s_hw
*hw
; /* pointer to hardware area */
151 int l1_state
; /* actual l1 state */
152 struct timer_list l1_timer
; /* layer 1 timer structure */
153 int nt_mode
; /* set to nt mode */
154 int st_num
; /* own index */
155 int enabled
; /* interface is enabled */
156 struct sk_buff_head d_tx_queue
; /* send queue */
157 int tx_cnt
; /* bytes to send */
158 struct hisax_d_if d_if
; /* D-channel interface */
159 struct hfc4s8s_btype b_ch
[2]; /* B-channel data */
160 struct hisax_b_if
*b_table
[2];
163 /**********************/
164 /* hardware structure */
165 /**********************/
166 typedef struct _hfc4s8s_hw
{
177 hfc4s8s_param driver_data
;
180 struct work_struct tqueue
;
181 struct hfc4s8s_l1 l1
[HFC_MAX_ST
];
186 volatile u_char r_irq_statech
; /* active isdn l1 status */
187 u_char r_irqmsk_statchg
; /* enabled isdn status ints */
188 u_char r_irq_fifo_blx
[8]; /* fifo status registers */
189 u_char fifo_rx_trans_enables
[8]; /* mask for enabled transparent rx fifos */
190 u_char fifo_slow_timer_service
[8]; /* mask for fifos needing slower timer service */
191 volatile u_char r_irq_oview
; /* contents of overview register */
192 volatile u_char timer_irq
;
193 int timer_usg_cnt
; /* number of channels using timer */
199 /***************************/
200 /* inline function defines */
201 /***************************/
202 #ifdef HISAX_HFC4S8S_PCIMEM /* inline functions memory mapped */
204 /* memory write and dummy IO read to avoid PCI byte merge problems */
205 #define Write_hfc8(a,b,c) {(*((volatile u_char *)(a->membase+b)) = c); inb(a->iobase+4);}
206 /* memory write without dummy IO access for fifo data access */
207 #define fWrite_hfc8(a,b,c) (*((volatile u_char *)(a->membase+b)) = c)
208 #define Read_hfc8(a,b) (*((volatile u_char *)(a->membase+b)))
209 #define Write_hfc16(a,b,c) (*((volatile unsigned short *)(a->membase+b)) = c)
210 #define Read_hfc16(a,b) (*((volatile unsigned short *)(a->membase+b)))
211 #define Write_hfc32(a,b,c) (*((volatile unsigned long *)(a->membase+b)) = c)
212 #define Read_hfc32(a,b) (*((volatile unsigned long *)(a->membase+b)))
213 #define wait_busy(a) {while ((Read_hfc8(a, R_STATUS) & M_BUSY));}
214 #define PCI_ENA_MEMIO 0x03
218 /* inline functions io mapped */
220 SetRegAddr(hfc4s8s_hw
* a
, u_char b
)
222 outb(b
, (a
->iobase
) + 4);
226 GetRegAddr(hfc4s8s_hw
* a
)
228 return (inb((volatile u_int
) (a
->iobase
+ 4)));
233 Write_hfc8(hfc4s8s_hw
* a
, u_char b
, u_char c
)
240 fWrite_hfc8(hfc4s8s_hw
* a
, u_char c
)
246 Write_hfc16(hfc4s8s_hw
* a
, u_char b
, u_short c
)
253 Write_hfc32(hfc4s8s_hw
* a
, u_char b
, u_long c
)
260 fWrite_hfc32(hfc4s8s_hw
* a
, u_long c
)
266 Read_hfc8(hfc4s8s_hw
* a
, u_char b
)
269 return (inb((volatile u_int
) a
->iobase
));
273 fRead_hfc8(hfc4s8s_hw
* a
)
275 return (inb((volatile u_int
) a
->iobase
));
279 static inline u_short
280 Read_hfc16(hfc4s8s_hw
* a
, u_char b
)
283 return (inw((volatile u_int
) a
->iobase
));
287 Read_hfc32(hfc4s8s_hw
* a
, u_char b
)
290 return (inl((volatile u_int
) a
->iobase
));
294 fRead_hfc32(hfc4s8s_hw
* a
)
296 return (inl((volatile u_int
) a
->iobase
));
300 wait_busy(hfc4s8s_hw
* a
)
302 SetRegAddr(a
, R_STATUS
);
303 while (inb((volatile u_int
) a
->iobase
) & M_BUSY
);
306 #define PCI_ENA_REGIO 0x01
308 #endif /* HISAX_HFC4S8S_PCIMEM */
310 /******************************************************/
311 /* function to read critical counter registers that */
312 /* may be udpated by the chip during read */
313 /******************************************************/
315 Read_hfc8_stable(hfc4s8s_hw
* hw
, int reg
)
319 ref8
= Read_hfc8(hw
, reg
);
320 while (((in8
= Read_hfc8(hw
, reg
)) != ref8
)) {
327 Read_hfc16_stable(hfc4s8s_hw
* hw
, int reg
)
332 ref16
= Read_hfc16(hw
, reg
);
333 while (((in16
= Read_hfc16(hw
, reg
)) != ref16
)) {
339 /*****************************/
340 /* D-channel call from HiSax */
341 /*****************************/
343 dch_l2l1(struct hisax_d_if
*iface
, int pr
, void *arg
)
345 struct hfc4s8s_l1
*l1
= iface
->ifc
.priv
;
346 struct sk_buff
*skb
= (struct sk_buff
*) arg
;
351 case (PH_DATA
| REQUEST
):
356 spin_lock_irqsave(&l1
->lock
, flags
);
357 skb_queue_tail(&l1
->d_tx_queue
, skb
);
358 if ((skb_queue_len(&l1
->d_tx_queue
) == 1) &&
360 l1
->hw
->mr
.r_irq_fifo_blx
[l1
->st_num
] |=
362 spin_unlock_irqrestore(&l1
->lock
, flags
);
363 schedule_work(&l1
->hw
->tqueue
);
365 spin_unlock_irqrestore(&l1
->lock
, flags
);
368 case (PH_ACTIVATE
| REQUEST
):
372 if (l1
->l1_state
< 6) {
373 spin_lock_irqsave(&l1
->lock
,
376 Write_hfc8(l1
->hw
, R_ST_SEL
,
378 Write_hfc8(l1
->hw
, A_ST_WR_STA
,
380 mod_timer(&l1
->l1_timer
,
381 jiffies
+ L1_TIMER_T3
);
382 spin_unlock_irqrestore(&l1
->lock
,
384 } else if (l1
->l1_state
== 7)
385 l1
->d_if
.ifc
.l1l2(&l1
->d_if
.ifc
,
390 if (l1
->l1_state
!= 3) {
391 spin_lock_irqsave(&l1
->lock
,
393 Write_hfc8(l1
->hw
, R_ST_SEL
,
395 Write_hfc8(l1
->hw
, A_ST_WR_STA
,
397 spin_unlock_irqrestore(&l1
->lock
,
399 } else if (l1
->l1_state
== 3)
400 l1
->d_if
.ifc
.l1l2(&l1
->d_if
.ifc
,
409 "HFC-4S/8S: Unknown D-chan cmd 0x%x received, ignored\n",
414 l1
->d_if
.ifc
.l1l2(&l1
->d_if
.ifc
,
415 PH_DEACTIVATE
| INDICATION
, NULL
);
418 /*****************************/
419 /* B-channel call from HiSax */
420 /*****************************/
422 bch_l2l1(struct hisax_if
*ifc
, int pr
, void *arg
)
424 struct hfc4s8s_btype
*bch
= ifc
->priv
;
425 struct hfc4s8s_l1
*l1
= bch
->l1p
;
426 struct sk_buff
*skb
= (struct sk_buff
*) arg
;
427 long mode
= (long) arg
;
432 case (PH_DATA
| REQUEST
):
433 if (!l1
->enabled
|| (bch
->mode
== L1_MODE_NULL
)) {
437 spin_lock_irqsave(&l1
->lock
, flags
);
438 skb_queue_tail(&bch
->tx_queue
, skb
);
439 if (!bch
->tx_skb
&& (bch
->tx_cnt
<= 0)) {
440 l1
->hw
->mr
.r_irq_fifo_blx
[l1
->st_num
] |=
441 ((bch
->bchan
== 1) ? 1 : 4);
442 spin_unlock_irqrestore(&l1
->lock
, flags
);
443 schedule_work(&l1
->hw
->tqueue
);
445 spin_unlock_irqrestore(&l1
->lock
, flags
);
448 case (PH_ACTIVATE
| REQUEST
):
449 case (PH_DEACTIVATE
| REQUEST
):
452 if (pr
== (PH_DEACTIVATE
| REQUEST
))
457 spin_lock_irqsave(&l1
->lock
,
459 l1
->hw
->mr
.timer_usg_cnt
++;
461 fifo_slow_timer_service
[l1
->
466 Write_hfc8(l1
->hw
, R_FIFO
,
471 Write_hfc8(l1
->hw
, A_CON_HDLC
, 0xc); /* HDLC mode, flag fill, connect ST */
472 Write_hfc8(l1
->hw
, A_SUBCH_CFG
, 0); /* 8 bits */
473 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 1); /* enable TX interrupts for hdlc */
474 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
477 Write_hfc8(l1
->hw
, R_FIFO
,
482 Write_hfc8(l1
->hw
, A_CON_HDLC
, 0xc); /* HDLC mode, flag fill, connect ST */
483 Write_hfc8(l1
->hw
, A_SUBCH_CFG
, 0); /* 8 bits */
484 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 1); /* enable RX interrupts for hdlc */
485 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
487 Write_hfc8(l1
->hw
, R_ST_SEL
,
489 l1
->hw
->mr
.r_ctrl0
|=
491 Write_hfc8(l1
->hw
, A_ST_CTRL0
,
493 bch
->mode
= L1_MODE_HDLC
;
494 spin_unlock_irqrestore(&l1
->lock
,
497 bch
->b_if
.ifc
.l1l2(&bch
->b_if
.ifc
,
504 spin_lock_irqsave(&l1
->lock
,
507 fifo_rx_trans_enables
[l1
->
512 l1
->hw
->mr
.timer_usg_cnt
++;
513 Write_hfc8(l1
->hw
, R_FIFO
,
518 Write_hfc8(l1
->hw
, A_CON_HDLC
, 0xf); /* Transparent mode, 1 fill, connect ST */
519 Write_hfc8(l1
->hw
, A_SUBCH_CFG
, 0); /* 8 bits */
520 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 0); /* disable TX interrupts */
521 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
524 Write_hfc8(l1
->hw
, R_FIFO
,
529 Write_hfc8(l1
->hw
, A_CON_HDLC
, 0xf); /* Transparent mode, 1 fill, connect ST */
530 Write_hfc8(l1
->hw
, A_SUBCH_CFG
, 0); /* 8 bits */
531 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 0); /* disable RX interrupts */
532 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
534 Write_hfc8(l1
->hw
, R_ST_SEL
,
536 l1
->hw
->mr
.r_ctrl0
|=
538 Write_hfc8(l1
->hw
, A_ST_CTRL0
,
540 bch
->mode
= L1_MODE_TRANS
;
541 spin_unlock_irqrestore(&l1
->lock
,
544 bch
->b_if
.ifc
.l1l2(&bch
->b_if
.ifc
,
551 if (bch
->mode
== L1_MODE_NULL
)
553 spin_lock_irqsave(&l1
->lock
,
556 fifo_slow_timer_service
[l1
->
562 fifo_rx_trans_enables
[l1
->
567 l1
->hw
->mr
.timer_usg_cnt
--;
568 Write_hfc8(l1
->hw
, R_FIFO
,
573 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 0); /* disable TX interrupts */
575 Write_hfc8(l1
->hw
, R_FIFO
,
580 Write_hfc8(l1
->hw
, A_IRQ_MSK
, 0); /* disable RX interrupts */
581 Write_hfc8(l1
->hw
, R_ST_SEL
,
583 l1
->hw
->mr
.r_ctrl0
&=
585 Write_hfc8(l1
->hw
, A_ST_CTRL0
,
587 spin_unlock_irqrestore(&l1
->lock
,
590 bch
->mode
= L1_MODE_NULL
;
591 bch
->b_if
.ifc
.l1l2(&bch
->b_if
.ifc
,
596 dev_kfree_skb(bch
->tx_skb
);
600 dev_kfree_skb(bch
->rx_skb
);
603 skb_queue_purge(&bch
->tx_queue
);
609 /* timer is only used when at least one b channel */
610 /* is set up to transparent mode */
611 if (l1
->hw
->mr
.timer_usg_cnt
) {
612 Write_hfc8(l1
->hw
, R_IRQMSK_MISC
,
615 Write_hfc8(l1
->hw
, R_IRQMSK_MISC
, 0);
622 "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n",
627 bch
->b_if
.ifc
.l1l2(&bch
->b_if
.ifc
,
628 PH_DEACTIVATE
| INDICATION
, NULL
);
631 /**************************/
632 /* layer 1 timer function */
633 /**************************/
635 hfc_l1_timer(struct hfc4s8s_l1
*l1
)
642 spin_lock_irqsave(&l1
->lock
, flags
);
645 Write_hfc8(l1
->hw
, R_ST_SEL
, l1
->st_num
);
646 Write_hfc8(l1
->hw
, A_ST_WR_STA
, 0x11);
647 spin_unlock_irqrestore(&l1
->lock
, flags
);
648 l1
->d_if
.ifc
.l1l2(&l1
->d_if
.ifc
,
649 PH_DEACTIVATE
| INDICATION
, NULL
);
650 spin_lock_irqsave(&l1
->lock
, flags
);
652 Write_hfc8(l1
->hw
, A_ST_WR_STA
, 0x1);
653 spin_unlock_irqrestore(&l1
->lock
, flags
);
655 /* activation timed out */
656 Write_hfc8(l1
->hw
, R_ST_SEL
, l1
->st_num
);
657 Write_hfc8(l1
->hw
, A_ST_WR_STA
, 0x13);
658 spin_unlock_irqrestore(&l1
->lock
, flags
);
659 l1
->d_if
.ifc
.l1l2(&l1
->d_if
.ifc
,
660 PH_DEACTIVATE
| INDICATION
, NULL
);
661 spin_lock_irqsave(&l1
->lock
, flags
);
662 Write_hfc8(l1
->hw
, R_ST_SEL
, l1
->st_num
);
663 Write_hfc8(l1
->hw
, A_ST_WR_STA
, 0x3);
664 spin_unlock_irqrestore(&l1
->lock
, flags
);
668 /****************************************/
669 /* a complete D-frame has been received */
670 /****************************************/
672 rx_d_frame(struct hfc4s8s_l1
*l1p
, int ech
)
684 Write_hfc8(l1p
->hw
, R_FIFO
,
685 (l1p
->st_num
* 8 + ((ech
) ? 7 : 5)));
688 f1
= Read_hfc8_stable(l1p
->hw
, A_F1
);
689 f2
= Read_hfc8(l1p
->hw
, A_F2
);
692 df
= f1
- f2
+ MAX_F_CNT
+ 1;
696 return; /* no complete frame in fifo */
699 z1
= Read_hfc16_stable(l1p
->hw
, A_Z1
);
700 z2
= Read_hfc16(l1p
->hw
, A_Z2
);
706 if (!(skb
= dev_alloc_skb(MAX_D_FRAME_SIZE
))) {
708 "HFC-4S/8S: Could not allocate D/E "
709 "channel receive buffer");
710 Write_hfc8(l1p
->hw
, A_INC_RES_FIFO
, 2);
715 if (((z1
< 4) || (z1
> MAX_D_FRAME_SIZE
))) {
718 /* remove errornous D frame */
721 Write_hfc8(l1p
->hw
, A_INC_RES_FIFO
, 2);
725 /* read errornous D frame */
727 #ifndef HISAX_HFC4S8S_PCIMEM
728 SetRegAddr(l1p
->hw
, A_FIFO_DATA0
);
732 #ifdef HISAX_HFC4S8S_PCIMEM
733 Read_hfc32(l1p
->hw
, A_FIFO_DATA0
);
735 fRead_hfc32(l1p
->hw
);
741 #ifdef HISAX_HFC4S8S_PCIMEM
742 Read_hfc8(l1p
->hw
, A_FIFO_DATA0
);
747 Write_hfc8(l1p
->hw
, A_INC_RES_FIFO
, 1);
755 #ifndef HISAX_HFC4S8S_PCIMEM
756 SetRegAddr(l1p
->hw
, A_FIFO_DATA0
);
760 #ifdef HISAX_HFC4S8S_PCIMEM
761 *((unsigned long *) cp
) =
762 Read_hfc32(l1p
->hw
, A_FIFO_DATA0
);
764 *((unsigned long *) cp
) = fRead_hfc32(l1p
->hw
);
771 #ifdef HISAX_HFC4S8S_PCIMEM
772 *cp
++ = Read_hfc8(l1p
->hw
, A_FIFO_DATA0
);
774 *cp
++ = fRead_hfc8(l1p
->hw
);
777 Write_hfc8(l1p
->hw
, A_INC_RES_FIFO
, 1); /* increment f counter */
783 skb
->len
= (cp
- skb
->data
) - 2;
785 l1p
->d_if
.ifc
.l1l2(&l1p
->d_if
.ifc
,
786 PH_DATA_E
| INDICATION
,
789 l1p
->d_if
.ifc
.l1l2(&l1p
->d_if
.ifc
,
790 PH_DATA
| INDICATION
,
796 /*************************************************************/
797 /* a B-frame has been received (perhaps not fully completed) */
798 /*************************************************************/
800 rx_b_frame(struct hfc4s8s_btype
*bch
)
802 int z1
, z2
, hdlc_complete
;
804 struct hfc4s8s_l1
*l1
= bch
->l1p
;
807 if (!l1
->enabled
|| (bch
->mode
== L1_MODE_NULL
))
812 Write_hfc8(l1
->hw
, R_FIFO
,
813 (l1
->st_num
* 8 + ((bch
->bchan
== 1) ? 1 : 3)));
816 if (bch
->mode
== L1_MODE_HDLC
) {
817 f1
= Read_hfc8_stable(l1
->hw
, A_F1
);
818 f2
= Read_hfc8(l1
->hw
, A_F2
);
819 hdlc_complete
= ((f1
^ f2
) & MAX_F_CNT
);
822 z1
= Read_hfc16_stable(l1
->hw
, A_Z1
);
823 z2
= Read_hfc16(l1
->hw
, A_Z2
);
833 if (!(skb
= bch
->rx_skb
)) {
836 dev_alloc_skb((bch
->mode
==
838 : (MAX_B_FRAME_SIZE
+ 3)))) {
840 "HFC-4S/8S: Could not allocate B "
841 "channel receive buffer");
844 bch
->rx_ptr
= skb
->data
;
848 skb
->len
= (bch
->rx_ptr
- skb
->data
) + z1
;
850 /* HDLC length check */
851 if ((bch
->mode
== L1_MODE_HDLC
) &&
852 ((hdlc_complete
&& (skb
->len
< 4)) ||
853 (skb
->len
> (MAX_B_FRAME_SIZE
+ 3)))) {
856 bch
->rx_ptr
= skb
->data
;
857 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
861 #ifndef HISAX_HFC4S8S_PCIMEM
862 SetRegAddr(l1
->hw
, A_FIFO_DATA0
);
866 #ifdef HISAX_HFC4S8S_PCIMEM
867 *((unsigned long *) bch
->rx_ptr
) =
868 Read_hfc32(l1
->hw
, A_FIFO_DATA0
);
870 *((unsigned long *) bch
->rx_ptr
) =
878 #ifdef HISAX_HFC4S8S_PCIMEM
879 *(bch
->rx_ptr
++) = Read_hfc8(l1
->hw
, A_FIFO_DATA0
);
881 *(bch
->rx_ptr
++) = fRead_hfc8(l1
->hw
);
885 /* increment f counter */
886 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 1);
893 bch
->rx_ptr
= skb
->data
;
898 if (hdlc_complete
|| (bch
->mode
== L1_MODE_TRANS
)) {
901 bch
->b_if
.ifc
.l1l2(&bch
->b_if
.ifc
,
902 PH_DATA
| INDICATION
, skb
);
908 /********************************************/
909 /* a D-frame has been/should be transmitted */
910 /********************************************/
912 tx_d_frame(struct hfc4s8s_l1
*l1p
)
919 if (l1p
->l1_state
!= 7)
923 Write_hfc8(l1p
->hw
, R_FIFO
, (l1p
->st_num
* 8 + 4));
926 f1
= Read_hfc8(l1p
->hw
, A_F1
);
927 f2
= Read_hfc8_stable(l1p
->hw
, A_F2
);
929 if ((f1
^ f2
) & MAX_F_CNT
)
930 return; /* fifo is still filled */
932 if (l1p
->tx_cnt
> 0) {
935 l1p
->d_if
.ifc
.l1l2(&l1p
->d_if
.ifc
, PH_DATA
| CONFIRM
,
939 if ((skb
= skb_dequeue(&l1p
->d_tx_queue
))) {
942 #ifndef HISAX_HFC4S8S_PCIMEM
943 SetRegAddr(l1p
->hw
, A_FIFO_DATA0
);
947 #ifdef HISAX_HFC4S8S_PCIMEM
948 fWrite_hfc32(l1p
->hw
, A_FIFO_DATA0
,
949 *(unsigned long *) cp
);
951 SetRegAddr(l1p
->hw
, A_FIFO_DATA0
);
952 fWrite_hfc32(l1p
->hw
, *(unsigned long *) cp
);
958 #ifdef HISAX_HFC4S8S_PCIMEM
960 fWrite_hfc8(l1p
->hw
, A_FIFO_DATA0
, *cp
++);
963 fWrite_hfc8(l1p
->hw
, *cp
++);
966 l1p
->tx_cnt
= skb
->truesize
;
967 Write_hfc8(l1p
->hw
, A_INC_RES_FIFO
, 1); /* increment f counter */
974 /******************************************************/
975 /* a B-frame may be transmitted (or is not completed) */
976 /******************************************************/
978 tx_b_frame(struct hfc4s8s_btype
*bch
)
981 struct hfc4s8s_l1
*l1
= bch
->l1p
;
983 int cnt
, max
, hdlc_num
;
986 if (!l1
->enabled
|| (bch
->mode
== L1_MODE_NULL
))
990 Write_hfc8(l1
->hw
, R_FIFO
,
991 (l1
->st_num
* 8 + ((bch
->bchan
== 1) ? 0 : 2)));
995 if (bch
->mode
== L1_MODE_HDLC
) {
996 hdlc_num
= Read_hfc8(l1
->hw
, A_F1
) & MAX_F_CNT
;
998 (Read_hfc8_stable(l1
->hw
, A_F2
) & MAX_F_CNT
);
1002 break; /* fifo still filled up with hdlc frames */
1006 if (!(skb
= bch
->tx_skb
)) {
1007 if (!(skb
= skb_dequeue(&bch
->tx_queue
))) {
1008 l1
->hw
->mr
.fifo_slow_timer_service
[l1
->
1010 &= ~((bch
->bchan
== 1) ? 1 : 4);
1011 break; /* list empty */
1018 l1
->hw
->mr
.fifo_slow_timer_service
[l1
->st_num
] |=
1019 ((bch
->bchan
== 1) ? 1 : 4);
1021 l1
->hw
->mr
.fifo_slow_timer_service
[l1
->st_num
] &=
1022 ~((bch
->bchan
== 1) ? 1 : 4);
1024 max
= Read_hfc16_stable(l1
->hw
, A_Z2
);
1025 max
-= Read_hfc16(l1
->hw
, A_Z1
);
1031 break; /* don't write to small amounts of bytes */
1033 cnt
= skb
->len
- bch
->tx_cnt
;
1036 cp
= skb
->data
+ bch
->tx_cnt
;
1039 #ifndef HISAX_HFC4S8S_PCIMEM
1040 SetRegAddr(l1
->hw
, A_FIFO_DATA0
);
1043 #ifdef HISAX_HFC4S8S_PCIMEM
1044 fWrite_hfc32(l1
->hw
, A_FIFO_DATA0
,
1045 *(unsigned long *) cp
);
1047 fWrite_hfc32(l1
->hw
, *(unsigned long *) cp
);
1054 #ifdef HISAX_HFC4S8S_PCIMEM
1055 fWrite_hfc8(l1
->hw
, A_FIFO_DATA0
, *cp
++);
1057 fWrite_hfc8(l1
->hw
, *cp
++);
1060 if (bch
->tx_cnt
>= skb
->len
) {
1061 if (bch
->mode
== L1_MODE_HDLC
) {
1062 /* increment f counter */
1063 Write_hfc8(l1
->hw
, A_INC_RES_FIFO
, 1);
1065 ack_len
+= skb
->truesize
;
1071 Write_hfc8(l1
->hw
, R_FIFO
,
1073 ((bch
->bchan
== 1) ? 0 : 2)));
1078 bch
->b_if
.ifc
.l1l2((struct hisax_if
*) &bch
->b_if
,
1079 PH_DATA
| CONFIRM
, (void *) ack_len
);
1082 /*************************************/
1083 /* bottom half handler for interrupt */
1084 /*************************************/
1086 hfc4s8s_bh(struct work_struct
*work
)
1088 hfc4s8s_hw
*hw
= container_of(work
, hfc4s8s_hw
, tqueue
);
1090 struct hfc4s8s_l1
*l1p
;
1091 volatile u_char
*fifo_stat
;
1094 /* handle layer 1 state changes */
1098 if ((b
& hw
->mr
.r_irq_statech
)) {
1099 /* reset l1 event */
1100 hw
->mr
.r_irq_statech
&= ~b
;
1103 u_char oldstate
= l1p
->l1_state
;
1105 Write_hfc8(l1p
->hw
, R_ST_SEL
,
1112 && (l1p
->l1_state
!= 3))
1113 l1p
->d_if
.ifc
.l1l2(&l1p
->
1121 if (l1p
->l1_state
!= 2) {
1122 del_timer(&l1p
->l1_timer
);
1123 if (l1p
->l1_state
== 3) {
1133 /* allow transition */
1134 Write_hfc8(hw
, A_ST_WR_STA
,
1136 mod_timer(&l1p
->l1_timer
,
1141 "HFC-4S/8S: NT ch %d l1 state %d -> %d\n",
1142 l1p
->st_num
, oldstate
,
1145 u_char oldstate
= l1p
->l1_state
;
1147 Write_hfc8(l1p
->hw
, R_ST_SEL
,
1153 if (((l1p
->l1_state
== 3) &&
1155 (oldstate
== 8))) ||
1158 && (l1p
->l1_state
== 8))) {
1159 mod_timer(&l1p
->l1_timer
,
1163 if (l1p
->l1_state
== 7) {
1175 if (l1p
->l1_state
== 3) {
1190 "HFC-4S/8S: TE %d ch %d l1 state %d -> %d\n",
1192 l1p
->st_num
, oldstate
,
1201 /* now handle the fifos */
1203 fifo_stat
= hw
->mr
.r_irq_fifo_blx
;
1205 while (idx
< hw
->driver_data
.max_st_ports
) {
1207 if (hw
->mr
.timer_irq
) {
1208 *fifo_stat
|= hw
->mr
.fifo_rx_trans_enables
[idx
];
1209 if (hw
->fifo_sched_cnt
<= 0) {
1211 hw
->mr
.fifo_slow_timer_service
[l1p
->
1215 /* ignore fifo 6 (TX E fifo) */
1216 *fifo_stat
&= 0xff - 0x40;
1218 while (*fifo_stat
) {
1220 if (!l1p
->nt_mode
) {
1221 /* RX Fifo has data to read */
1222 if ((*fifo_stat
& 0x20)) {
1223 *fifo_stat
&= ~0x20;
1226 /* E Fifo has data to read */
1227 if ((*fifo_stat
& 0x80)) {
1228 *fifo_stat
&= ~0x80;
1231 /* TX Fifo completed send */
1232 if ((*fifo_stat
& 0x10)) {
1233 *fifo_stat
&= ~0x10;
1237 /* B1 RX Fifo has data to read */
1238 if ((*fifo_stat
& 0x2)) {
1240 rx_b_frame(l1p
->b_ch
);
1242 /* B1 TX Fifo has send completed */
1243 if ((*fifo_stat
& 0x1)) {
1245 tx_b_frame(l1p
->b_ch
);
1247 /* B2 RX Fifo has data to read */
1248 if ((*fifo_stat
& 0x8)) {
1250 rx_b_frame(l1p
->b_ch
+ 1);
1252 /* B2 TX Fifo has send completed */
1253 if ((*fifo_stat
& 0x4)) {
1255 tx_b_frame(l1p
->b_ch
+ 1);
1263 if (hw
->fifo_sched_cnt
<= 0)
1264 hw
->fifo_sched_cnt
+= (1 << (7 - TRANS_TIMER_MODE
));
1265 hw
->mr
.timer_irq
= 0; /* clear requested timer irq */
1268 /*********************/
1269 /* interrupt handler */
1270 /*********************/
1272 hfc4s8s_interrupt(int intno
, void *dev_id
)
1274 hfc4s8s_hw
*hw
= dev_id
;
1276 volatile u_char
*ovp
;
1280 if (!hw
|| !(hw
->mr
.r_irq_ctrl
& M_GLOB_IRQ_EN
))
1283 #ifndef HISAX_HFC4S8S_PCIMEM
1284 /* read current selected regsister */
1285 old_ioreg
= GetRegAddr(hw
);
1288 /* Layer 1 State change */
1289 hw
->mr
.r_irq_statech
|=
1290 (Read_hfc8(hw
, R_SCI
) & hw
->mr
.r_irqmsk_statchg
);
1292 (b
= (Read_hfc8(hw
, R_STATUS
) & (M_MISC_IRQSTA
| M_FR_IRQSTA
)))
1293 && !hw
->mr
.r_irq_statech
) {
1294 #ifndef HISAX_HFC4S8S_PCIMEM
1295 SetRegAddr(hw
, old_ioreg
);
1301 if (Read_hfc8(hw
, R_IRQ_MISC
) & M_TI_IRQ
) {
1302 hw
->mr
.timer_irq
= 1;
1303 hw
->fifo_sched_cnt
--;
1307 if ((ovr
= Read_hfc8(hw
, R_IRQ_OVIEW
))) {
1308 hw
->mr
.r_irq_oview
|= ovr
;
1309 idx
= R_IRQ_FIFO_BL0
;
1310 ovp
= hw
->mr
.r_irq_fifo_blx
;
1313 *ovp
|= Read_hfc8(hw
, idx
);
1321 /* queue the request to allow other cards to interrupt */
1322 schedule_work(&hw
->tqueue
);
1324 #ifndef HISAX_HFC4S8S_PCIMEM
1325 SetRegAddr(hw
, old_ioreg
);
1328 } /* hfc4s8s_interrupt */
1330 /***********************************************************************/
1331 /* reset the complete chip, don't release the chips irq but disable it */
1332 /***********************************************************************/
1334 chipreset(hfc4s8s_hw
* hw
)
1338 spin_lock_irqsave(&hw
->lock
, flags
);
1339 Write_hfc8(hw
, R_CTRL
, 0); /* use internal RAM */
1340 Write_hfc8(hw
, R_RAM_MISC
, 0); /* 32k*8 RAM */
1341 Write_hfc8(hw
, R_FIFO_MD
, 0); /* fifo mode 386 byte/fifo simple mode */
1342 Write_hfc8(hw
, R_CIRM
, M_SRES
); /* reset chip */
1343 hw
->mr
.r_irq_ctrl
= 0; /* interrupt is inactive */
1344 spin_unlock_irqrestore(&hw
->lock
, flags
);
1347 Write_hfc8(hw
, R_CIRM
, 0); /* disable reset */
1350 Write_hfc8(hw
, R_PCM_MD0
, M_PCM_MD
); /* master mode */
1351 Write_hfc8(hw
, R_RAM_MISC
, M_FZ_MD
); /* transmit fifo option */
1352 if (hw
->driver_data
.clock_mode
== 1)
1353 Write_hfc8(hw
, R_BRG_PCM_CFG
, M_PCM_CLK
); /* PCM clk / 2 */
1354 Write_hfc8(hw
, R_TI_WD
, TRANS_TIMER_MODE
); /* timer interval */
1356 memset(&hw
->mr
, 0, sizeof(hw
->mr
));
1359 /********************************************/
1360 /* disable/enable hardware in nt or te mode */
1361 /********************************************/
1363 hfc_hardware_enable(hfc4s8s_hw
* hw
, int enable
, int nt_mode
)
1370 /* save system vars */
1371 hw
->nt_mode
= nt_mode
;
1373 /* enable fifo and state irqs, but not global irq enable */
1374 hw
->mr
.r_irq_ctrl
= M_FIFO_IRQ
;
1375 Write_hfc8(hw
, R_IRQ_CTRL
, hw
->mr
.r_irq_ctrl
);
1376 hw
->mr
.r_irqmsk_statchg
= 0;
1377 Write_hfc8(hw
, R_SCI_MSK
, hw
->mr
.r_irqmsk_statchg
);
1378 Write_hfc8(hw
, R_PWM_MD
, 0x80);
1379 Write_hfc8(hw
, R_PWM1
, 26);
1381 Write_hfc8(hw
, R_ST_SYNC
, M_AUTO_SYNC
);
1383 /* enable the line interfaces and fifos */
1384 for (i
= 0; i
< hw
->driver_data
.max_st_ports
; i
++) {
1385 hw
->mr
.r_irqmsk_statchg
|= (1 << i
);
1386 Write_hfc8(hw
, R_SCI_MSK
, hw
->mr
.r_irqmsk_statchg
);
1387 Write_hfc8(hw
, R_ST_SEL
, i
);
1388 Write_hfc8(hw
, A_ST_CLK_DLY
,
1389 ((nt_mode
) ? CLKDEL_NT
: CLKDEL_TE
));
1390 hw
->mr
.r_ctrl0
= ((nt_mode
) ? CTRL0_NT
: CTRL0_TE
);
1391 Write_hfc8(hw
, A_ST_CTRL0
, hw
->mr
.r_ctrl0
);
1392 Write_hfc8(hw
, A_ST_CTRL2
, 3);
1393 Write_hfc8(hw
, A_ST_WR_STA
, 0); /* enable state machine */
1395 hw
->l1
[i
].enabled
= 1;
1396 hw
->l1
[i
].nt_mode
= nt_mode
;
1400 Write_hfc8(hw
, R_FIFO
, i
* 8 + 7); /* E fifo */
1402 Write_hfc8(hw
, A_CON_HDLC
, 0x11); /* HDLC mode, 1 fill, connect ST */
1403 Write_hfc8(hw
, A_SUBCH_CFG
, 2); /* only 2 bits */
1404 Write_hfc8(hw
, A_IRQ_MSK
, 1); /* enable interrupt */
1405 Write_hfc8(hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
1408 /* setup D RX-fifo */
1409 Write_hfc8(hw
, R_FIFO
, i
* 8 + 5); /* RX fifo */
1411 Write_hfc8(hw
, A_CON_HDLC
, 0x11); /* HDLC mode, 1 fill, connect ST */
1412 Write_hfc8(hw
, A_SUBCH_CFG
, 2); /* only 2 bits */
1413 Write_hfc8(hw
, A_IRQ_MSK
, 1); /* enable interrupt */
1414 Write_hfc8(hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
1417 /* setup D TX-fifo */
1418 Write_hfc8(hw
, R_FIFO
, i
* 8 + 4); /* TX fifo */
1420 Write_hfc8(hw
, A_CON_HDLC
, 0x11); /* HDLC mode, 1 fill, connect ST */
1421 Write_hfc8(hw
, A_SUBCH_CFG
, 2); /* only 2 bits */
1422 Write_hfc8(hw
, A_IRQ_MSK
, 1); /* enable interrupt */
1423 Write_hfc8(hw
, A_INC_RES_FIFO
, 2); /* reset fifo */
1427 sprintf(if_name
, "hfc4s8s_%d%d_", hw
->cardnum
, i
);
1430 (&hw
->l1
[i
].d_if
, hw
->l1
[i
].b_table
, if_name
,
1431 ((nt_mode
) ? 3 : 2))) {
1433 hw
->l1
[i
].enabled
= 0;
1434 hw
->mr
.r_irqmsk_statchg
&= ~(1 << i
);
1435 Write_hfc8(hw
, R_SCI_MSK
,
1436 hw
->mr
.r_irqmsk_statchg
);
1438 "HFC-4S/8S: Unable to register S/T device %s, break\n",
1443 spin_lock_irqsave(&hw
->lock
, flags
);
1444 hw
->mr
.r_irq_ctrl
|= M_GLOB_IRQ_EN
;
1445 Write_hfc8(hw
, R_IRQ_CTRL
, hw
->mr
.r_irq_ctrl
);
1446 spin_unlock_irqrestore(&hw
->lock
, flags
);
1448 /* disable hardware */
1449 spin_lock_irqsave(&hw
->lock
, flags
);
1450 hw
->mr
.r_irq_ctrl
&= ~M_GLOB_IRQ_EN
;
1451 Write_hfc8(hw
, R_IRQ_CTRL
, hw
->mr
.r_irq_ctrl
);
1452 spin_unlock_irqrestore(&hw
->lock
, flags
);
1454 for (i
= hw
->driver_data
.max_st_ports
- 1; i
>= 0; i
--) {
1455 hw
->l1
[i
].enabled
= 0;
1456 hisax_unregister(&hw
->l1
[i
].d_if
);
1457 del_timer(&hw
->l1
[i
].l1_timer
);
1458 skb_queue_purge(&hw
->l1
[i
].d_tx_queue
);
1459 skb_queue_purge(&hw
->l1
[i
].b_ch
[0].tx_queue
);
1460 skb_queue_purge(&hw
->l1
[i
].b_ch
[1].tx_queue
);
1464 } /* hfc_hardware_enable */
1466 /******************************************/
1467 /* disable memory mapped ports / io ports */
1468 /******************************************/
1470 release_pci_ports(hfc4s8s_hw
* hw
)
1472 pci_write_config_word(hw
->pdev
, PCI_COMMAND
, 0);
1473 #ifdef HISAX_HFC4S8S_PCIMEM
1475 iounmap((void *) hw
->membase
);
1478 release_region(hw
->iobase
, 8);
1482 /*****************************************/
1483 /* enable memory mapped ports / io ports */
1484 /*****************************************/
1486 enable_pci_ports(hfc4s8s_hw
* hw
)
1488 #ifdef HISAX_HFC4S8S_PCIMEM
1489 pci_write_config_word(hw
->pdev
, PCI_COMMAND
, PCI_ENA_MEMIO
);
1491 pci_write_config_word(hw
->pdev
, PCI_COMMAND
, PCI_ENA_REGIO
);
1495 /*************************************/
1496 /* initialise the HFC-4s/8s hardware */
1497 /* return 0 on success. */
1498 /*************************************/
1499 static int __devinit
1500 setup_instance(hfc4s8s_hw
* hw
)
1505 for (i
= 0; i
< HFC_MAX_ST
; i
++) {
1506 struct hfc4s8s_l1
*l1p
;
1509 spin_lock_init(&l1p
->lock
);
1511 l1p
->l1_timer
.function
= (void *) hfc_l1_timer
;
1512 l1p
->l1_timer
.data
= (long) (l1p
);
1513 init_timer(&l1p
->l1_timer
);
1515 skb_queue_head_init(&l1p
->d_tx_queue
);
1516 l1p
->d_if
.ifc
.priv
= hw
->l1
+ i
;
1517 l1p
->d_if
.ifc
.l2l1
= (void *) dch_l2l1
;
1519 spin_lock_init(&l1p
->b_ch
[0].lock
);
1520 l1p
->b_ch
[0].b_if
.ifc
.l2l1
= (void *) bch_l2l1
;
1521 l1p
->b_ch
[0].b_if
.ifc
.priv
= (void *) &l1p
->b_ch
[0];
1522 l1p
->b_ch
[0].l1p
= hw
->l1
+ i
;
1523 l1p
->b_ch
[0].bchan
= 1;
1524 l1p
->b_table
[0] = &l1p
->b_ch
[0].b_if
;
1525 skb_queue_head_init(&l1p
->b_ch
[0].tx_queue
);
1527 spin_lock_init(&l1p
->b_ch
[1].lock
);
1528 l1p
->b_ch
[1].b_if
.ifc
.l2l1
= (void *) bch_l2l1
;
1529 l1p
->b_ch
[1].b_if
.ifc
.priv
= (void *) &l1p
->b_ch
[1];
1530 l1p
->b_ch
[1].l1p
= hw
->l1
+ i
;
1531 l1p
->b_ch
[1].bchan
= 2;
1532 l1p
->b_table
[1] = &l1p
->b_ch
[1].b_if
;
1533 skb_queue_head_init(&l1p
->b_ch
[1].tx_queue
);
1536 enable_pci_ports(hw
);
1539 i
= Read_hfc8(hw
, R_CHIP_ID
) >> CHIP_ID_SHIFT
;
1540 if (i
!= hw
->driver_data
.chip_id
) {
1542 "HFC-4S/8S: invalid chip id 0x%x instead of 0x%x, card ignored\n",
1543 i
, hw
->driver_data
.chip_id
);
1547 i
= Read_hfc8(hw
, R_CHIP_RV
) & 0xf;
1550 "HFC-4S/8S: chip revision 0 not supported, card ignored\n");
1554 INIT_WORK(&hw
->tqueue
, hfc4s8s_bh
);
1557 (hw
->irq
, hfc4s8s_interrupt
, IRQF_SHARED
, hw
->card_name
, hw
)) {
1559 "HFC-4S/8S: unable to alloc irq %d, card ignored\n",
1563 #ifdef HISAX_HFC4S8S_PCIMEM
1565 "HFC-4S/8S: found PCI card at membase 0x%p, irq %d\n",
1566 hw
->hw_membase
, hw
->irq
);
1569 "HFC-4S/8S: found PCI card at iobase 0x%x, irq %d\n",
1570 hw
->iobase
, hw
->irq
);
1573 hfc_hardware_enable(hw
, 1, 0);
1579 release_pci_ports(hw
);
1584 /*****************************************/
1585 /* PCI hotplug interface: probe new card */
1586 /*****************************************/
1587 static int __devinit
1588 hfc4s8s_probe(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1591 hfc4s8s_param
*driver_data
= (hfc4s8s_param
*) ent
->driver_data
;
1594 if (!(hw
= kzalloc(sizeof(hfc4s8s_hw
), GFP_ATOMIC
))) {
1595 printk(KERN_ERR
"No kmem for HFC-4S/8S card\n");
1600 err
= pci_enable_device(pdev
);
1605 hw
->cardnum
= card_cnt
;
1606 sprintf(hw
->card_name
, "hfc4s8s_%d", hw
->cardnum
);
1607 printk(KERN_INFO
"HFC-4S/8S: found adapter %s (%s) at %s\n",
1608 driver_data
->device_name
, hw
->card_name
, pci_name(pdev
));
1610 spin_lock_init(&hw
->lock
);
1612 hw
->driver_data
= *driver_data
;
1613 hw
->irq
= pdev
->irq
;
1614 hw
->iobase
= pci_resource_start(pdev
, 0);
1616 #ifdef HISAX_HFC4S8S_PCIMEM
1617 hw
->hw_membase
= (u_char
*) pci_resource_start(pdev
, 1);
1618 hw
->membase
= ioremap((ulong
) hw
->hw_membase
, 256);
1620 if (!request_region(hw
->iobase
, 8, hw
->card_name
)) {
1622 "HFC-4S/8S: failed to rquest address space at 0x%04x\n",
1628 pci_set_drvdata(pdev
, hw
);
1629 err
= setup_instance(hw
);
1639 /**************************************/
1640 /* PCI hotplug interface: remove card */
1641 /**************************************/
1642 static void __devexit
1643 hfc4s8s_remove(struct pci_dev
*pdev
)
1645 hfc4s8s_hw
*hw
= pci_get_drvdata(pdev
);
1647 printk(KERN_INFO
"HFC-4S/8S: removing card %d\n", hw
->cardnum
);
1648 hfc_hardware_enable(hw
, 0, 0);
1651 free_irq(hw
->irq
, hw
);
1653 release_pci_ports(hw
);
1656 pci_disable_device(pdev
);
1661 static struct pci_driver hfc4s8s_driver
= {
1662 .name
= "hfc4s8s_l1",
1663 .probe
= hfc4s8s_probe
,
1664 .remove
= __devexit_p(hfc4s8s_remove
),
1665 .id_table
= hfc4s8s_ids
,
1668 /**********************/
1669 /* driver Module init */
1670 /**********************/
1672 hfc4s8s_module_init(void)
1677 "HFC-4S/8S: Layer 1 driver module for HFC-4S/8S isdn chips, %s\n",
1680 "HFC-4S/8S: (C) 2003 Cornelius Consult, www.cornelius-consult.de\n");
1684 err
= pci_register_driver(&hfc4s8s_driver
);
1688 printk(KERN_INFO
"HFC-4S/8S: found %d cards\n", card_cnt
);
1690 #if !defined(CONFIG_HOTPLUG)
1693 pci_unregister_driver(&hfc4s8s_driver
);
1701 } /* hfc4s8s_init_hw */
1703 /*************************************/
1704 /* driver module exit : */
1705 /* release the HFC-4s/8s hardware */
1706 /*************************************/
1708 hfc4s8s_module_exit(void)
1710 pci_unregister_driver(&hfc4s8s_driver
);
1711 printk(KERN_INFO
"HFC-4S/8S: module removed\n");
1712 } /* hfc4s8s_release_hw */
1714 module_init(hfc4s8s_module_init
);
1715 module_exit(hfc4s8s_module_exit
);