1 /*****************************************************************************
2 * sdlamain.c WANPIPE(tm) Multiprotocol WAN Link Driver. Main module.
4 * Author: Nenad Corbic <ncorbic@sangoma.com>
7 * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 * ============================================================================
14 * Sep 23, 1999 Nenad Corbic Added support for SMP
15 * Sep 13, 1999 Nenad Corbic Each port is treated as a separate device.
16 * Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
17 * Updates for Linux 2.2.X kernels.
18 * Sep 17, 1998 Jaspreet Singh Updated for 2.1.121+ kernel
19 * Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1
20 * Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags();
21 * Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0
22 * Oct 20, 1997 Jaspreet Singh Modified sdla_isr routine so that card->in_isr
23 * assignments are taken out and placed in the
24 * sdla_ppp.c, sdla_fr.c and sdla_x25.c isr
25 * routines. Took out 'wandev->tx_int_enabled' and
26 * replaced it with 'wandev->enable_tx_int'.
27 * May 29, 1997 Jaspreet Singh Flow Control Problem
28 * added "wandev->tx_int_enabled=1" line in the
29 * init module. This line intializes the flag for
30 * preventing Interrupt disabled with device set to
32 * Jan 15, 1997 Gene Kozin Version 3.1.0
33 * o added UDP management stuff
34 * Jan 02, 1997 Gene Kozin Initial version.
35 *****************************************************************************/
37 #include <linux/version.h>
38 #include <linux/config.h> /* OS configuration options */
39 #include <linux/stddef.h> /* offsetof(), etc. */
40 #include <linux/errno.h> /* return codes */
41 #include <linux/string.h> /* inline memset(), etc. */
42 #include <linux/malloc.h> /* kmalloc(), kfree() */
43 #include <linux/kernel.h> /* printk(), and other useful stuff */
44 #include <linux/module.h> /* support for loadable modules */
45 #include <linux/ioport.h> /* request_region(), release_region() */
46 #include <linux/tqueue.h> /* for kernel task queues */
47 #include <linux/wanrouter.h> /* WAN router definitions */
48 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
49 #include <asm/uaccess.h> /* kernel <-> user copy */
50 #include <asm/io.h> /* phys_to_virt() */
51 #include <linux/pci.h>
52 #include <linux/sdlapci.h>
54 /****** Defines & Macros ****************************************************/
62 #define DRV_VERSION 5 /* version number */
63 #define DRV_RELEASE 0 /* release (minor version) number */
64 #define MAX_CARDS 8 /* max number of adapters */
66 #ifndef CONFIG_WANPIPE_CARDS /* configurable option */
67 #define CONFIG_WANPIPE_CARDS 1
70 #define CMD_OK 0 /* normal firmware return code */
71 #define CMD_TIMEOUT 0xFF /* firmware command timed out */
72 #define MAX_CMD_RETRY 10 /* max number of firmware retries */
73 /****** Function Prototypes *************************************************/
75 extern void disable_irq(unsigned int);
76 extern void enable_irq(unsigned int);
78 /* Module entry points */
79 int init_module (void);
80 void cleanup_module (void);
82 /* WAN link driver entry points */
83 static int setup (wan_device_t
* wandev
, wandev_conf_t
* conf
);
84 static int shutdown (wan_device_t
* wandev
);
85 static int ioctl (wan_device_t
* wandev
, unsigned cmd
, unsigned long arg
);
88 static int ioctl_dump (sdla_t
* card
, sdla_dump_t
* u_dump
);
89 static int ioctl_exec (sdla_t
* card
, sdla_exec_t
* u_exec
);
91 /* Miscellaneous functions */
92 STATIC
void sdla_isr (int irq
, void* dev_id
, struct pt_regs
*regs
);
93 STATIC
void sdla_poll (void* data
);
94 static void release_hw (sdla_t
*card
);
96 /****** Global Data **********************************************************
97 * Note: All data must be explicitly initialized!!!
101 static char drvname
[] = "wanpipe";
102 static char fullname
[] = "WANPIPE(tm) Multiprotocol Driver";
103 static char copyright
[] = "(c) 1995-1999 Sangoma Technologies Inc.";
104 static int ncards
= CONFIG_WANPIPE_CARDS
;
105 static int active
; /* number of active cards */
106 static sdla_t
* card_array
; /* adapter data space */
108 /* Task queue element for creating a 'thread' */
109 static struct tq_struct sdla_tq
= { routine
: sdla_poll
};
111 /******* Kernel Loadable Module Entry Points ********************************/
113 /*============================================================================
114 * Module 'insert' entry point.
115 * o print announcement
116 * o allocate adapter data space
117 * o initialize static data
118 * o register all cards with WAN router
119 * o calibrate SDLA shared memory access delay.
127 int init_module (void)
129 int wanpipe_init2(void)
134 printk(KERN_INFO
"%s v%u.%u %s\n",
135 fullname
, DRV_VERSION
, DRV_RELEASE
, copyright
);
137 /* Verify number of cards and allocate adapter data space */
138 ncards
= min(ncards
, MAX_CARDS
);
139 ncards
= max(ncards
, 1);
140 card_array
= kmalloc(sizeof(sdla_t
) * ncards
, GFP_KERNEL
);
141 if (card_array
== NULL
)
144 memset(card_array
, 0, sizeof(sdla_t
) * ncards
);
146 /* Register adapters with WAN router */
147 for (cnt
= 0; cnt
< ncards
; ++ cnt
) {
148 sdla_t
* card
= &card_array
[cnt
];
149 wan_device_t
* wandev
= &card
->wandev
;
152 sprintf(card
->devname
, "%s%d", drvname
, cnt
+ 1);
153 wandev
->magic
= ROUTER_MAGIC
;
154 wandev
->name
= card
->devname
;
155 wandev
->private = card
;
156 wandev
->enable_tx_int
= 0;
157 wandev
->setup
= &setup
;
158 wandev
->shutdown
= &shutdown
;
159 wandev
->ioctl
= &ioctl
;
160 err
= register_wan_device(wandev
);
163 "%s: %s registration failed with error %d!\n",
164 drvname
, card
->devname
, err
);
169 ncards
= cnt
; /* adjust actual number of cards */
172 printk(KERN_INFO
"IN Init Module: NO Cards registered\n");
179 /*============================================================================
180 * Module 'remove' entry point.
181 * o unregister all adapters from the WAN router
182 * o release all remaining system resources
184 void cleanup_module (void)
188 for (i
= 0; i
< ncards
; ++i
) {
189 sdla_t
* card
= &card_array
[i
];
190 unregister_wan_device(card
->devname
);
197 /******* WAN Device Driver Entry Points *************************************/
199 /*============================================================================
200 * Setup/configure WAN link driver.
201 * o check adapter state
202 * o make sure firmware is present in configuration
203 * o make sure I/O port and IRQ are specified
204 * o make sure I/O region is available
205 * o allocate interrupt vector
206 * o setup SDLA hardware
207 * o call appropriate routine to perform protocol-specific initialization
208 * o mark I/O region as used
209 * o if this is the first active card, then schedule background task
211 * This function is called when router handles ROUTER_SETUP IOCTL. The
212 * configuration structure is in kernel memory (including extended data, if
216 static int setup (wan_device_t
* wandev
, wandev_conf_t
* conf
)
224 if ((wandev
== NULL
) || (wandev
->private == NULL
) || (conf
== NULL
))
227 card
= wandev
->private;
228 if (wandev
->state
!= WAN_UNCONFIGURED
)
229 return -EBUSY
; /* already configured */
231 printk(KERN_INFO
"\nProcessing WAN device %s...\n", wandev
->name
);
233 /* Initialize the counters for each wandev
234 * Used for counting number of times new_if and
237 wandev
->del_if_cnt
= 0;
238 wandev
->new_if_cnt
= 0;
239 wandev
->config_id
= conf
->config_id
;
241 if (!conf
->data_size
|| (conf
->data
== NULL
)) {
243 "%s: firmware not found in configuration data!\n",
248 /* only check I/O port and IRQ if not an S514 adapter */
249 if(!conf
->S514_CPU_no
[0]) {
251 if (conf
->ioport
<= 0) {
253 "%s: can't configure without I/O port address!\n",
258 if (conf
->irq
<= 0) {
259 printk(KERN_ERR
"%s: can't configure without IRQ!\n",
264 /* Check for already loaded card with the same IO port and IRQ
265 * If found, copy its hardware configuration and use its
266 * resources (i.e. piggybacking)
268 if (!card
->configured
){
269 for (i
= 0; i
< ncards
; i
++) {
270 sdla_t
*nxt_card
= &card_array
[i
];
271 if (nxt_card
->hw
.port
== conf
->ioport
&&
273 conf
->config_id
== WANCONFIG_CHDLC
&&
274 nxt_card
->wandev
.config_id
== WANCONFIG_CHDLC
){
275 irq
= nxt_card
->hw
.irq
;
276 memcpy(&card
->hw
, &nxt_card
->hw
, sizeof(sdlahw_t
));
277 nxt_card
->next
= card
;
278 card
->next
= nxt_card
;
279 card
->wandev
.piggyback
= WANOPT_YES
;
284 /* Make sure I/O port region is available */
285 if (check_region(conf
->ioport
, SDLA_MAXIORANGE
) &&
286 !card
->wandev
.piggyback
) {
288 "%s: I/O region 0x%X - 0x%X is in use!\n",
289 wandev
->name
, conf
->ioport
,
290 conf
->ioport
+ SDLA_MAXIORANGE
);
297 For a S514 adapter, check for a possible configuration error in that
298 we are loading an adapter in the same slot as a previously loaded S514
302 if (!card
->configured
){
303 for (i
= 0; i
< ncards
; i
++) {
304 sdla_t
* nxt_card
= &card_array
[i
];
307 if((nxt_card
->hw
.type
== SDLA_S514
) &&
308 (nxt_card
->hw
.S514_slot_no
== conf
->PCI_slot_no
) &&
309 (nxt_card
->hw
.S514_cpu_no
[0] == conf
->S514_CPU_no
[0])&&
310 (conf
->config_id
== WANCONFIG_CHDLC
)&&
311 (nxt_card
->wandev
.config_id
== WANCONFIG_CHDLC
)){
313 irq
= nxt_card
->hw
.irq
;
314 memcpy(&card
->hw
, &nxt_card
->hw
, sizeof(sdlahw_t
));
315 nxt_card
->next
= card
;
316 card
->next
= nxt_card
;
317 card
->wandev
.piggyback
= WANOPT_YES
;
323 /* If the current card has already been configured
324 * or its a piggyback card, do not try to allocate
327 if (!card
->wandev
.piggyback
&& !card
->configured
){
329 /* Configure hardware, load firmware, etc. */
330 memset(&card
->hw
, 0, sizeof(sdlahw_t
));
332 /* for an S514 adapter, pass the CPU number and the slot number read */
333 /* from 'router.conf' to the 'sdla_setup()' function via the 'port' */
335 if (conf
->S514_CPU_no
[0]){
337 card
->hw
.S514_cpu_no
[0] = conf
->S514_CPU_no
[0];
338 card
->hw
.S514_slot_no
= conf
->PCI_slot_no
;
339 printk(KERN_INFO
"Setting CPU to %c and Slot to %i\n",
340 card
->hw
.S514_cpu_no
[0], card
->hw
.S514_slot_no
);
343 /* 508 Card io port and irq initialization */
344 card
->hw
.port
= conf
->ioport
;
345 card
->hw
.irq
= (conf
->irq
== 9) ? 2 : conf
->irq
;
349 /* Compute the virtual address of the card in kernel space */
351 card
->hw
.dpmbase
= phys_to_virt(conf
->maddr
);
352 else /* But 0 means NULL */
353 card
->hw
.dpmbase
= (void *)conf
->maddr
;
355 card
->hw
.dpmsize
= SDLA_WINDOWSIZE
;
356 /* set the adapter type if using an S514 adapter */
357 card
->hw
.type
= (conf
->S514_CPU_no
[0]) ? SDLA_S514
: conf
->hw_opt
[0];
358 card
->hw
.pclk
= conf
->hw_opt
[1];
360 err
= sdla_setup(&card
->hw
, conf
->data
, conf
->data_size
);
365 if(card
->hw
.type
!= SDLA_S514
)
366 irq
= (conf
->irq
== 2) ? 9 : conf
->irq
; /* IRQ2 -> IRQ9 */
370 /* request an interrupt vector - note that interrupts may be shared */
371 /* when using the S514 PCI adapter */
372 if(request_irq(irq
, sdla_isr
,
373 (card
->hw
.type
== SDLA_S514
) ? SA_SHIRQ
: 0, wandev
->name
, card
)){
375 printk(KERN_ERR
"%s: Can't reserve IRQ %d!\n", wandev
->name
, irq
);
380 printk(KERN_INFO
"%s: Card Configured %i or Piggybacking %i!\n",
381 wandev
->name
,card
->configured
,card
->wandev
.piggyback
);
385 if (!card
->configured
){
388 /* Initialize the Spin lock */
389 printk(KERN_INFO
"%s: Initializing SMP\n",wandev
->name
);
390 spin_lock_init(&card
->lock
);
393 /* Intialize WAN device data space */
396 if(card
->hw
.type
!= SDLA_S514
){
397 wandev
->ioport
= card
->hw
.port
;
399 wandev
->S514_cpu_no
[0] = card
->hw
.S514_cpu_no
[0];
400 wandev
->S514_slot_no
= card
->hw
.S514_slot_no
;
402 wandev
->maddr
= (unsigned long)card
->hw
.dpmbase
;
403 wandev
->msize
= card
->hw
.dpmsize
;
404 wandev
->hw_opt
[0] = card
->hw
.type
;
405 wandev
->hw_opt
[1] = card
->hw
.pclk
;
406 wandev
->hw_opt
[2] = card
->hw
.memory
;
407 wandev
->hw_opt
[3] = card
->hw
.fwid
;
410 /* Protocol-specific initialization */
411 switch (card
->hw
.fwid
) {
412 #ifdef CONFIG_WANPIPE_X25
415 err
= wpx_init(card
, conf
);
419 #ifdef CONFIG_WANPIPE_FR
422 err
= wpf_init(card
, conf
);
426 #ifdef CONFIG_WANPIPE_PPP
429 err
= wpp_init(card
, conf
);
433 #ifdef CONFIG_WANPIPE_CHDLC
437 // printk(KERN_INFO "%s: Starting FT1 Configurator\n",
439 // err = wpft1_init(card, conf);
441 err
= wpc_init(card
, conf
);
446 #ifdef CONFIG_WANPIPE_BSTRM
448 err
= bsc_init(card
, conf
);
452 #ifdef CONFIG_WANPIPE_HDLC
454 err
= hdlc_init(card
, conf
);
459 printk(KERN_ERR
"%s: this firmware is not supported %X %X!\n",
460 wandev
->name
,card
->hw
.fwid
,SFID_CHDLC508
);
472 /* Reserve I/O region and schedule background task */
473 if(card
->hw
.type
!= SDLA_S514
&& !card
->wandev
.piggyback
)
474 request_region(card
->hw
.port
, card
->hw
.io_range
, wandev
->name
);
478 if (schedule_task(&sdla_tq
) == 0)
482 wandev
->critical
= 0;
486 /*============================================================================
487 * Shut down WAN link driver.
488 * o shut down adapter hardware
489 * o release system resources.
491 * This function is called by the router when device is being unregistered or
492 * when it handles ROUTER_DOWN IOCTL.
494 static int shutdown (wan_device_t
* wandev
)
499 if ((wandev
== NULL
) || (wandev
->private == NULL
))
502 if (wandev
->state
== WAN_UNCONFIGURED
)
505 /* If we are in a critical section we lose */
506 if (test_and_set_bit(0, (void*)&wandev
->critical
))
509 card
= wandev
->private;
510 wandev
->state
= WAN_UNCONFIGURED
;
513 schedule(); /* stop background thread */
515 /* Release Resources */
518 /* only free the allocated I/O range if not an S514 adapter */
519 if (wandev
->hw_opt
[0] != SDLA_S514
&& !card
->configured
){
520 release_region(card
->hw
.port
, card
->hw
.io_range
);
523 if (!card
->configured
){
524 memset(&card
->hw
, 0, sizeof(sdlahw_t
));
526 memset(&card
->next
->hw
, 0, sizeof(sdlahw_t
));
530 wandev
->critical
= 0;
534 static void release_hw (sdla_t
*card
)
538 /* Check if next device exists */
540 nxt_card
= card
->next
;
541 /* If next device is down then release resources */
542 if (nxt_card
->wandev
.state
== WAN_UNCONFIGURED
){
543 if (card
->wandev
.piggyback
){
544 /* If this device is piggyback then use
545 * information of the master device
547 printk(KERN_INFO
"%s: Piggyback shutting down\n",card
->devname
);
548 sdla_down(&card
->next
->hw
);
549 free_irq(card
->wandev
.irq
, card
->next
);
550 card
->configured
= 0;
551 card
->next
->configured
= 0;
552 card
->wandev
.piggyback
= 0;
554 /* Master device shutting down */
555 printk(KERN_INFO
"%s: Master shutting down\n",card
->devname
);
556 sdla_down(&card
->hw
);
557 free_irq(card
->wandev
.irq
, card
);
558 card
->configured
= 0;
559 card
->next
->configured
= 0;
562 printk(KERN_INFO
"%s: Device still running\n",
564 card
->configured
= 1;
567 printk(KERN_INFO
"%s: Master shutting down\n",card
->devname
);
568 sdla_down(&card
->hw
);
569 free_irq(card
->wandev
.irq
, card
);
570 card
->configured
= 0;
575 /*============================================================================
576 * Driver I/O control.
578 * o perform requested action
580 * This function is called when router handles one of the reserved user
581 * IOCTLs. Note that 'arg' stil points to user address space.
583 static int ioctl (wan_device_t
* wandev
, unsigned cmd
, unsigned long arg
)
589 if ((wandev
== NULL
) || (wandev
->private == NULL
))
591 if (wandev
->state
== WAN_UNCONFIGURED
)
594 card
= wandev
->private;
596 if(card
->hw
.type
!= SDLA_S514
){
597 disable_irq(card
->hw
.irq
);
600 if (test_and_set_bit(0, (void*)&wandev
->critical
)) {
601 if(card
->hw
.type
!= SDLA_S514
){
602 enable_irq(card
->hw
.irq
);
609 err
= ioctl_dump(wandev
->private, (void*)arg
);
613 err
= ioctl_exec(wandev
->private, (void*)arg
);
620 clear_bit(0, (void*)&wandev
->critical
);
621 if(card
->hw
.type
!= SDLA_S514
){
622 enable_irq(card
->hw
.irq
);
628 /****** Driver IOCTL Handlers ***********************************************/
630 /*============================================================================
631 * Dump adapter memory to user buffer.
632 * o verify request structure
633 * o copy request structure to kernel data space
634 * o verify length/offset
635 * o verify user buffer
636 * o copy adapter memory image to user buffer
638 * Note: when dumping memory, this routine switches curent dual-port memory
639 * vector, so care must be taken to avoid racing conditions.
641 static int ioctl_dump (sdla_t
* card
, sdla_dump_t
* u_dump
)
645 unsigned long oldvec
; /* DPM window vector */
649 if(copy_from_user((void*)&dump
, (void*)u_dump
, sizeof(sdla_dump_t
)))
652 if ((dump
.magic
!= WANPIPE_MAGIC
) ||
653 (dump
.offset
+ dump
.length
> card
->hw
.memory
))
656 winsize
= card
->hw
.dpmsize
;
658 cli(); /* >>> critical section start <<< */
660 if(card
->hw
.type
!= SDLA_S514
) {
661 oldvec
= card
->hw
.vector
;
662 while (dump
.length
) {
664 unsigned pos
= dump
.offset
% winsize
;
666 unsigned long vec
= dump
.offset
- pos
;
667 unsigned len
= (dump
.length
> (winsize
- pos
)) ?
668 (winsize
- pos
) : dump
.length
;
669 /* relocate window */
670 if (sdla_mapmem(&card
->hw
, vec
) != 0) {
674 /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
675 sti(); /* Not ideal but tough we have to do this */
676 if(copy_to_user((void *)dump
.ptr
,
677 (u8
*)card
->hw
.dpmbase
+ pos
, len
))
682 (char*)dump
.ptr
+= len
;
684 sdla_mapmem(&card
->hw
, oldvec
);/* restore DPM window position */
688 /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
689 sti(); /* Not ideal but tough we have to do this */
690 if(copy_to_user((void *)dump
.ptr
,
691 (u8
*)card
->hw
.dpmbase
+ dump
.offset
, dump
.length
))
696 restore_flags(flags
); /* >>> critical section end <<< */
700 /*============================================================================
701 * Execute adapter firmware command.
702 * o verify request structure
703 * o copy request structure to kernel data space
704 * o call protocol-specific 'exec' function
706 static int ioctl_exec (sdla_t
* card
, sdla_exec_t
* u_exec
)
710 if (card
->exec
== NULL
)
713 if(copy_from_user((void*)&exec
, (void*)u_exec
, sizeof(sdla_exec_t
)))
716 if ((exec
.magic
!= WANPIPE_MAGIC
) || (exec
.cmd
== NULL
))
718 return card
->exec(card
, exec
.cmd
, exec
.data
);
721 /******* Miscellaneous ******************************************************/
723 /*============================================================================
724 * SDLA Interrupt Service Routine.
725 * o acknowledge SDLA hardware interrupt.
726 * o call protocol-specific interrupt service routine, if any.
728 STATIC
void sdla_isr (int irq
, void* dev_id
, struct pt_regs
*regs
)
730 #define card ((sdla_t*)dev_id)
732 if(card
->hw
.type
== SDLA_S514
) { /* handle interrrupt on S514 */
734 unsigned char CPU_no
= card
->hw
.S514_cpu_no
[0];
735 unsigned char card_found_for_IRQ
;
740 read_S514_int_stat(&card
->hw
, &int_status
);
742 /* check if the interrupt is for this device */
743 if(!((unsigned char)int_status
&
744 (IRQ_CPU_A
| IRQ_CPU_B
)))
747 /* if the IRQ is for both CPUs on the same adapter, */
748 /* then alter the interrupt status so as to handle */
749 /* one CPU at a time */
750 if(((unsigned char)int_status
& (IRQ_CPU_A
| IRQ_CPU_B
))
751 == (IRQ_CPU_A
| IRQ_CPU_B
)) {
752 int_status
&= (CPU_no
== S514_CPU_A
) ?
753 ~IRQ_CPU_B
: ~IRQ_CPU_A
;
756 card_found_for_IRQ
= 0;
758 /* check to see that the CPU number for this device */
759 /* corresponds to the interrupt status read */
762 if((unsigned char)int_status
&
764 card_found_for_IRQ
= 1;
768 if((unsigned char)int_status
&
770 card_found_for_IRQ
= 1;
774 /* exit if the interrupt is for another CPU on the */
776 if(!card_found_for_IRQ
)
780 (card
->wandev
.state
== WAN_UNCONFIGURED
&& !card
->configured
)){
782 "Received IRQ %d for CPU #%c\n",
785 "IRQ for unconfigured adapter\n");
786 S514_intack(&card
->hw
, int_status
);
792 "%s: interrupt re-entrancy on IRQ %d\n",
793 card
->devname
, card
->wandev
.irq
);
794 S514_intack(&card
->hw
, int_status
);
798 S514_intack(&card
->hw
, int_status
);
803 /* handle a maximum of two interrupts (one for each */
804 /* CPU on the adapter) before returning */
805 if((++ IRQ_count
) == 2)
810 else { /* handle interrupt on S508 adapter */
812 if (!card
|| ((card
->wandev
.state
== WAN_UNCONFIGURED
) && !card
->configured
))
817 "%s: interrupt re-entrancy on IRQ %d!\n",
818 card
->devname
, card
->wandev
.irq
);
822 /* Use spin lock only for S508 */
825 spin_lock(&card
->lock
);
827 sdla_intack(&card
->hw
);
831 spin_unlock(&card
->lock
);
839 /*============================================================================
840 * SDLA polling routine.
841 * This routine simulates kernel thread to perform various housekeeping job.
843 * o for each configured device call its poll() routine
844 * o if there is at least one active card, then reschedule itself once again
846 STATIC
void sdla_poll (void* data
)
850 for (i
= 0; i
< ncards
; ++i
) {
851 sdla_t
* card
= &card_array
[i
];
853 if ((card
->wandev
.state
!= WAN_UNCONFIGURED
) && card
->poll
&&
854 !card
->wandev
.critical
) {
860 if (schedule_task(&sdla_tq
) == 0) /* Surely not? */
866 /*============================================================================
867 * This routine is called by the protocol-specific modules when network
868 * interface is being open. The only reason we need this, is because we
869 * have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's
870 * defined more than once into the same kernel module.
872 void wanpipe_open (sdla_t
* card
)
878 /*============================================================================
879 * This routine is called by the protocol-specific modules when network
880 * interface is being closed. The only reason we need this, is because we
881 * have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's
882 * defined more than once into the same kernel module.
884 void wanpipe_close (sdla_t
* card
)
890 /*============================================================================
891 * Set WAN device state.
893 void wanpipe_set_state (sdla_t
* card
, int state
)
899 if (card
->wandev
.state
!= state
) {
902 printk (KERN_INFO
"%s: link connected!\n",
907 printk (KERN_INFO
"%s: link connecting...\n",
911 case WAN_DISCONNECTED
:
912 printk (KERN_INFO
"%s: link disconnected!\n",
916 card
->wandev
.state
= state
;
918 card
->state_tick
= jiffies
;
919 restore_flags(flags
);
922 /****** End *****************************************************************/