Merge branch 'atmel'
[pandora-kernel.git] / drivers / net / wan / sdladrv.c
1 /*****************************************************************************
2 * sdladrv.c     SDLA Support Module.  Main module.
3 *
4 *               This module is a library of common hardware-specific functions
5 *               used by all Sangoma drivers.
6 *
7 * Author:       Gideon Hack     
8 *
9 * Copyright:    (c) 1995-2000 Sangoma Technologies Inc.
10 *
11 *               This program is free software; you can redistribute it and/or
12 *               modify it under the terms of the GNU General Public License
13 *               as published by the Free Software Foundation; either version
14 *               2 of the License, or (at your option) any later version.
15 * ============================================================================
16 * Mar 20, 2001  Nenad Corbic    Added the auto_pci_cfg filed, to support
17 *                               the PCISLOT #0. 
18 * Apr 04, 2000  Nenad Corbic    Fixed the auto memory detection code.
19 *                               The memory test at address 0xC8000.
20 * Mar 09, 2000  Nenad Corbic    Added Gideon's Bug Fix: clear pci
21 *                               interrupt flags on initial load.
22 * Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
23 *                               Updates for Linux 2.2.X kernels.        
24 * Sep 17, 1998  Jaspreet Singh  Updates for linux 2.2.X kernels
25 * Dec 20, 1996  Gene Kozin      Version 3.0.0. Complete overhaul.
26 * Jul 12, 1996  Gene Kozin      Changes for Linux 2.0 compatibility.
27 * Jun 12, 1996  Gene Kozin      Added support for S503 card.
28 * Apr 30, 1996  Gene Kozin      SDLA hardware interrupt is acknowledged before
29 *                               calling protocolspecific ISR.
30 *                               Register I/O ports with Linux kernel.
31 *                               Miscellaneous bug fixes.
32 * Dec 20, 1995  Gene Kozin      Fixed a bug in interrupt routine.
33 * Oct 14, 1995  Gene Kozin      Initial version.
34 *****************************************************************************/
35
36 /*****************************************************************************
37  * Notes:
38  * ------
39  * 1. This code is ment to be system-independent (as much as possible).  To
40  *    achive this, various macros are used to hide system-specific interfaces.
41  *    To compile this code, one of the following constants must be defined:
42  *
43  *      Platform        Define
44  *      --------        ------
45  *      Linux           _LINUX_
46  *      SCO Unix        _SCO_UNIX_
47  *
48  * 2. Supported adapter types:
49  *
50  *      S502A
51  *      ES502A (S502E)
52  *      S503
53  *      S507
54  *      S508 (S509)
55  *
56  * 3. S502A Notes:
57  *
58  *      There is no separate DPM window enable/disable control in S502A.  It
59  *      opens immediately after a window number it written to the HMCR
60  *      register.  To close the window, HMCR has to be written a value
61  *      ????1111b (e.g. 0x0F or 0xFF).
62  *
63  *      S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
64  *
65  *      There should be a delay of ??? before reading back S502A status
66  *      register.
67  *
68  * 4. S502E Notes:
69  *
70  *      S502E has a h/w bug: although default IRQ line state is HIGH, enabling
71  *      interrupts by setting bit 1 of the control register (BASE) to '1'
72  *      causes it to go LOW! Therefore, disabling interrupts by setting that
73  *      bit to '0' causes low-to-high transition on IRQ line (ghosty
74  *      interrupt). The same occurs when disabling CPU by resetting bit 0 of
75  *      CPU control register (BASE+3) - see the next note.
76  *
77  *      S502E CPU and DPM control is limited:
78  *
79  *      o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
80  *        control register (BASE+3) shuts the board down entirely, including
81  *        DPM;
82  *
83  *      o DPM access cannot be controlled dynamically. Ones CPU is started,
84  *        bit 1 of the control register (BASE) is used to enable/disable IRQ,
85  *        so that access to shared memory cannot be disabled while CPU is
86  *        running.
87  ****************************************************************************/
88
89 #define _LINUX_
90
91 #if     defined(_LINUX_)        /****** Linux *******************************/
92
93 #include <linux/config.h>
94 #include <linux/kernel.h>       /* printk(), and other useful stuff */
95 #include <linux/stddef.h>       /* offsetof(), etc. */
96 #include <linux/errno.h>        /* return codes */
97 #include <linux/string.h>       /* inline memset(), etc. */
98 #include <linux/module.h>       /* support for loadable modules */
99 #include <linux/jiffies.h>      /* for jiffies, HZ, etc. */
100 #include <linux/sdladrv.h>      /* API definitions */
101 #include <linux/sdlasfm.h>      /* SDLA firmware module definitions */
102 #include <linux/sdlapci.h>      /* SDLA PCI hardware definitions */
103 #include <linux/pci.h>          /* PCI defines and function prototypes */
104 #include <asm/io.h>             /* for inb(), outb(), etc. */
105
106 #define _INB(port)              (inb(port))
107 #define _OUTB(port, byte)       (outb((byte),(port)))
108 #define SYSTEM_TICK             jiffies
109
110 #include <linux/init.h>
111
112
113 #elif   defined(_SCO_UNIX_)     /****** SCO Unix ****************************/
114
115 #if     !defined(INKERNEL)
116 #error  This code MUST be compiled in kernel mode!
117 #endif
118 #include <sys/sdladrv.h>        /* API definitions */
119 #include <sys/sdlasfm.h>        /* SDLA firmware module definitions */
120 #include <sys/inline.h>         /* for inb(), outb(), etc. */
121 #define _INB(port)              (inb(port))
122 #define _OUTB(port, byte)       (outb((port),(byte)))
123 #define SYSTEM_TICK             lbolt
124
125 #else
126 #error  Unknown system type!
127 #endif
128
129 #define MOD_VERSION     3
130 #define MOD_RELEASE     0
131
132 #define SDLA_IODELAY    100     /* I/O Rd/Wr delay, 10 works for 486DX2-66 */
133 #define EXEC_DELAY      20      /* shared memory access delay, mks */
134 #define EXEC_TIMEOUT    (HZ*2)  /* command timeout, in ticks */
135
136 /* I/O port address range */
137 #define S502A_IORANGE   3
138 #define S502E_IORANGE   4
139 #define S503_IORANGE    3
140 #define S507_IORANGE    4
141 #define S508_IORANGE    4
142
143 /* Maximum amount of memory */
144 #define S502_MAXMEM     0x10000L
145 #define S503_MAXMEM     0x10000L
146 #define S507_MAXMEM     0x40000L
147 #define S508_MAXMEM     0x40000L
148
149 /* Minimum amount of memory */
150 #define S502_MINMEM     0x8000L
151 #define S503_MINMEM     0x8000L
152 #define S507_MINMEM     0x20000L
153 #define S508_MINMEM     0x20000L
154 #define NO_PORT         -1
155
156
157
158
159
160 /****** Function Prototypes *************************************************/
161
162 /* Hardware-specific functions */
163 static int sdla_detect  (sdlahw_t* hw);
164 static int sdla_autodpm (sdlahw_t* hw);
165 static int sdla_setdpm  (sdlahw_t* hw);
166 static int sdla_load    (sdlahw_t* hw, sfm_t* sfm, unsigned len);
167 static int sdla_init    (sdlahw_t* hw);
168 static unsigned long sdla_memtest (sdlahw_t* hw);
169 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
170 static unsigned char make_config_byte (sdlahw_t* hw);
171 static int sdla_start   (sdlahw_t* hw, unsigned addr);
172
173 static int init_s502a   (sdlahw_t* hw);
174 static int init_s502e   (sdlahw_t* hw);
175 static int init_s503    (sdlahw_t* hw);
176 static int init_s507    (sdlahw_t* hw);
177 static int init_s508    (sdlahw_t* hw);
178             
179 static int detect_s502a (int port);
180 static int detect_s502e (int port);
181 static int detect_s503  (int port);
182 static int detect_s507  (int port);
183 static int detect_s508  (int port);
184 static int detect_s514  (sdlahw_t* hw);
185 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
186
187 /* Miscellaneous functions */
188 static void peek_by_4 (unsigned long src, void* buf, unsigned len);
189 static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
190 static int calibrate_delay (int mks);
191 static int get_option_index (unsigned* optlist, unsigned optval);
192 static unsigned check_memregion (void* ptr, unsigned len);
193 static unsigned test_memregion (void* ptr, unsigned len);
194 static unsigned short checksum (unsigned char* buf, unsigned len);
195 static int init_pci_slot(sdlahw_t *);
196
197 static int pci_probe(sdlahw_t *hw);
198
199 /****** Global Data **********************************************************
200  * Note: All data must be explicitly initialized!!!
201  */
202
203 static struct pci_device_id sdladrv_pci_tbl[] = {
204         { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
205         { }                     /* Terminating entry */
206 };
207 MODULE_DEVICE_TABLE(pci, sdladrv_pci_tbl);
208
209 MODULE_LICENSE("GPL");
210
211 /* private data */
212 static char modname[]   = "sdladrv";
213 static char fullname[]  = "SDLA Support Module";
214 static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
215 static unsigned exec_idle;
216
217 /* Hardware configuration options.
218  * These are arrays of configuration options used by verification routines.
219  * The first element of each array is its size (i.e. number of options).
220  */
221 static unsigned s502_port_options[] =
222         { 4, 0x250, 0x300, 0x350, 0x360 }
223 ;
224 static unsigned s503_port_options[] =
225         { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
226 ;
227 static unsigned s508_port_options[] =
228         { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
229 ;
230
231 static unsigned s502a_irq_options[] = { 0 };
232 static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
233 static unsigned s503_irq_options[]  = { 5, 2, 3, 4, 5, 7 };
234 static unsigned s508_irq_options[]  = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
235
236 static unsigned s502a_dpmbase_options[] =
237 {
238         28,
239         0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
240         0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
241         0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
242         0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
243 };
244 static unsigned s507_dpmbase_options[] =
245 {
246         32,
247         0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
248         0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
249         0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
250         0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
251 };
252 static unsigned s508_dpmbase_options[] =        /* incl. S502E and S503 */
253 {
254         32,
255         0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
256         0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
257         0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
258         0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
259 };
260
261 /*
262 static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
263 static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
264 static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
265 */
266
267 static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
268 static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
269 static unsigned s503_pclk_options[]  = { 3, 7200, 8000, 10000 };
270 static unsigned s507_pclk_options[]  = { 1, 12288 };
271 static unsigned s508_pclk_options[]  = { 1, 16000 };
272
273 /* Host memory control register masks */
274 static unsigned char s502a_hmcr[] =
275 {
276         0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C,       /* A0000 - AC000 */
277         0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C,       /* C0000 - CC000 */
278         0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,       /* D0000 - DC000 */
279         0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C,       /* E0000 - EC000 */
280 };
281 static unsigned char s502e_hmcr[] =
282 {
283         0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */
284         0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */
285         0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */
286         0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */
287 };
288 static unsigned char s507_hmcr[] =
289 {
290         0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */
291         0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */
292         0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */
293         0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */
294 };
295 static unsigned char s508_hmcr[] =
296 {
297         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */
298         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */
299         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */
300         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */
301 };
302
303 static unsigned char s507_irqmask[] =
304 {
305         0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
306 };
307
308 static int pci_slot_ar[MAX_S514_CARDS];
309
310 /******* Kernel Loadable Module Entry Points ********************************/
311
312 /*============================================================================
313  * Module 'insert' entry point.
314  * o print announcement
315  * o initialize static data
316  * o calibrate SDLA shared memory access delay.
317  *
318  * Return:      0       Ok
319  *              < 0     error.
320  * Context:     process
321  */
322
323 static int __init sdladrv_init(void)
324 {
325         int i=0;
326
327         printk(KERN_INFO "%s v%u.%u %s\n",
328                 fullname, MOD_VERSION, MOD_RELEASE, copyright);
329         exec_idle = calibrate_delay(EXEC_DELAY);
330 #ifdef WANDEBUG 
331         printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
332 #endif  
333
334         /* Initialize the PCI Card array, which
335          * will store flags, used to mark 
336          * card initialization state */
337         for (i=0; i<MAX_S514_CARDS; i++)
338                 pci_slot_ar[i] = 0xFF;
339
340         return 0;
341 }
342
343 /*============================================================================
344  * Module 'remove' entry point.
345  * o release all remaining system resources
346  */
347 static void __exit sdladrv_cleanup(void)
348 {
349 }
350
351 module_init(sdladrv_init);
352 module_exit(sdladrv_cleanup);
353
354 /******* Kernel APIs ********************************************************/
355
356 /*============================================================================
357  * Set up adapter.
358  * o detect adapter type
359  * o verify hardware configuration options
360  * o check for hardware conflicts
361  * o set up adapter shared memory
362  * o test adapter memory
363  * o load firmware
364  * Return:      0       ok.
365  *              < 0     error
366  */
367
368 EXPORT_SYMBOL(sdla_setup);
369
370 int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
371 {
372         unsigned* irq_opt       = NULL; /* IRQ options */
373         unsigned* dpmbase_opt   = NULL; /* DPM window base options */
374         unsigned* pclk_opt      = NULL; /* CPU clock rate options */
375         int err=0;
376
377         if (sdla_detect(hw)) {
378                 if(hw->type != SDLA_S514)
379                         printk(KERN_INFO "%s: no SDLA card found at port 0x%X\n",
380                         modname, hw->port);
381                 return -EINVAL;
382         }
383
384         if(hw->type != SDLA_S514) {
385                 printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
386                 modname, hw->type, hw->port);
387
388                 hw->dpmsize = SDLA_WINDOWSIZE;
389                 switch (hw->type) {
390                 case SDLA_S502A:
391                         hw->io_range    = S502A_IORANGE;
392                         irq_opt         = s502a_irq_options;
393                         dpmbase_opt     = s502a_dpmbase_options;
394                         pclk_opt        = s502a_pclk_options;
395                         break;
396
397                 case SDLA_S502E:
398                         hw->io_range    = S502E_IORANGE;
399                         irq_opt         = s502e_irq_options;
400                         dpmbase_opt     = s508_dpmbase_options;
401                         pclk_opt        = s502e_pclk_options;
402                         break;
403
404                 case SDLA_S503:
405                         hw->io_range    = S503_IORANGE;
406                         irq_opt         = s503_irq_options;
407                         dpmbase_opt     = s508_dpmbase_options;
408                         pclk_opt        = s503_pclk_options;
409                         break;
410
411                 case SDLA_S507:
412                         hw->io_range    = S507_IORANGE;
413                         irq_opt         = s508_irq_options;
414                         dpmbase_opt     = s507_dpmbase_options;
415                         pclk_opt        = s507_pclk_options;
416                         break;
417
418                 case SDLA_S508:
419                         hw->io_range    = S508_IORANGE;
420                         irq_opt         = s508_irq_options;
421                         dpmbase_opt     = s508_dpmbase_options;
422                         pclk_opt        = s508_pclk_options;
423                         break;
424                 }
425
426                 /* Verify IRQ configuration options */
427                 if (!get_option_index(irq_opt, hw->irq)) {
428                         printk(KERN_INFO "%s: IRQ %d is invalid!\n",
429                                 modname, hw->irq);
430                       return -EINVAL;
431                 } 
432
433                 /* Verify CPU clock rate configuration options */
434                 if (hw->pclk == 0)
435                         hw->pclk = pclk_opt[1];  /* use default */
436         
437                 else if (!get_option_index(pclk_opt, hw->pclk)) {
438                         printk(KERN_INFO "%s: CPU clock %u is invalid!\n",
439                                 modname, hw->pclk);
440                         return -EINVAL;
441                 } 
442                 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
443                         modname, hw->pclk);
444
445                 /* Setup adapter dual-port memory window and test memory */
446                 if (hw->dpmbase == 0) {
447                         err = sdla_autodpm(hw);
448                         if (err) {
449                                 printk(KERN_INFO
450                                 "%s: can't find available memory region!\n",
451                                         modname);
452                                 return err;
453                         }
454                 }
455                 else if (!get_option_index(dpmbase_opt,
456                         virt_to_phys(hw->dpmbase))) {
457                         printk(KERN_INFO
458                                 "%s: memory address 0x%lX is invalid!\n",
459                                 modname, virt_to_phys(hw->dpmbase));
460                         return -EINVAL;
461                 }               
462                 else if (sdla_setdpm(hw)) {
463                         printk(KERN_INFO
464                         "%s: 8K memory region at 0x%lX is not available!\n",
465                                 modname, virt_to_phys(hw->dpmbase));
466                         return -EINVAL;
467                 } 
468                 printk(KERN_INFO
469                         "%s: dual-port memory window is set at 0x%lX.\n",
470                                 modname, virt_to_phys(hw->dpmbase));
471
472
473                 /* If we find memory in 0xE**** Memory region, 
474                  * warn the user to disable the SHADOW RAM.  
475                  * Since memory corruption can occur if SHADOW is
476                  * enabled. This can causes random crashes ! */
477                 if (virt_to_phys(hw->dpmbase) >= 0xE0000){
478                         printk(KERN_WARNING "\n%s: !!!!!!!!  WARNING !!!!!!!!\n",modname);
479                         printk(KERN_WARNING "%s: WANPIPE is using 0x%lX memory region !!!\n",
480                                                 modname, virt_to_phys(hw->dpmbase));
481                         printk(KERN_WARNING "         Please disable the SHADOW RAM, otherwise\n");
482                         printk(KERN_WARNING "         your system might crash randomly from time to time !\n");
483                         printk(KERN_WARNING "%s: !!!!!!!!  WARNING !!!!!!!!\n\n",modname);
484                 }
485         }
486
487         else {
488                 hw->memory = test_memregion((void*)hw->dpmbase, 
489                         MAX_SIZEOF_S514_MEMORY);
490                 if(hw->memory < (256 * 1024)) {
491                         printk(KERN_INFO
492                                 "%s: error in testing S514 memory (0x%lX)\n",
493                                 modname, hw->memory);
494                         sdla_down(hw);
495                         return -EINVAL;
496                 }
497         }
498     
499         printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
500                 modname, hw->memory / 1024);
501
502         /* Load firmware. If loader fails then shut down adapter */
503         err = sdla_load(hw, sfm, len);
504         if (err) sdla_down(hw);         /* shutdown adapter */
505
506         return err;
507
508
509 /*============================================================================
510  * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
511  */
512
513 EXPORT_SYMBOL(sdla_down);
514
515 int sdla_down (sdlahw_t* hw)
516 {
517         unsigned port = hw->port;
518         int i;
519         unsigned char CPU_no;
520         u32 int_config, int_status;
521
522         if(!port && (hw->type != SDLA_S514))
523                 return -EFAULT;
524
525         switch (hw->type) {
526         case SDLA_S502A:
527                 _OUTB(port, 0x08);              /* halt CPU */
528                 _OUTB(port, 0x08);
529                 _OUTB(port, 0x08);
530                 hw->regs[0] = 0x08;
531                 _OUTB(port + 1, 0xFF);          /* close memory window */
532                 hw->regs[1] = 0xFF;
533                 break;
534
535         case SDLA_S502E:
536                 _OUTB(port + 3, 0);             /* stop CPU */
537                 _OUTB(port, 0);                 /* reset board */
538                 for (i = 0; i < S502E_IORANGE; ++i)
539                         hw->regs[i] = 0
540                 ;
541                 break;
542
543         case SDLA_S503:
544         case SDLA_S507:
545         case SDLA_S508:
546                 _OUTB(port, 0);                 /* reset board logic */
547                 hw->regs[0] = 0;
548                 break;
549
550         case SDLA_S514:
551                 /* halt the adapter */
552                 *(char *)hw->vector = S514_CPU_HALT;
553                 CPU_no = hw->S514_cpu_no[0];
554
555                 /* disable the PCI IRQ and disable memory access */
556                 pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config);
557                 int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B;
558                 pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config);
559                 read_S514_int_stat(hw, &int_status);
560                 S514_intack(hw, int_status);
561                 if(CPU_no == S514_CPU_A)
562                         pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD,
563                                 PCI_CPU_A_MEM_DISABLE);
564                 else
565                         pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
566                                 PCI_CPU_B_MEM_DISABLE);
567
568                 /* free up the allocated virtual memory */
569                 iounmap((void *)hw->dpmbase);
570                 iounmap((void *)hw->vector);
571                 break;
572
573
574         default:
575                 return -EINVAL;
576         }
577         return 0;
578 }
579
580 /*============================================================================
581  * Map shared memory window into SDLA address space.
582  */
583
584 EXPORT_SYMBOL(sdla_mapmem);
585
586 int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
587 {
588         unsigned port = hw->port;
589         register int tmp;
590
591         switch (hw->type) {
592         case SDLA_S502A:
593         case SDLA_S502E:
594                 if (addr < S502_MAXMEM) { /* verify parameter */
595                         tmp = addr >> 13;       /* convert to register mask */
596                         _OUTB(port + 2, tmp);
597                         hw->regs[2] = tmp;
598                 }
599                 else return -EINVAL;
600                 break;
601
602         case SDLA_S503:
603                 if (addr < S503_MAXMEM) { /* verify parameter */
604                         tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
605                         _OUTB(port, tmp);
606                         hw->regs[0] = tmp;
607                 }
608                 else return -EINVAL;
609                 break;
610
611         case SDLA_S507:
612                 if (addr < S507_MAXMEM) {
613                         if (!(_INB(port) & 0x02))
614                                 return -EIO;
615                         tmp = addr >> 13;       /* convert to register mask */
616                         _OUTB(port + 2, tmp);
617                         hw->regs[2] = tmp;
618                 }
619                 else return -EINVAL;
620                 break;
621
622         case SDLA_S508:
623                 if (addr < S508_MAXMEM) {
624                         tmp = addr >> 13;       /* convert to register mask */
625                         _OUTB(port + 2, tmp);
626                         hw->regs[2] = tmp;
627                 }
628                 else return -EINVAL;
629                 break;
630
631         case SDLA_S514:
632                 return 0;
633
634         default:
635                 return -EINVAL;
636         }
637         hw->vector = addr & 0xFFFFE000L;
638         return 0;
639 }
640
641 /*============================================================================
642  * Enable interrupt generation.
643  */
644
645 static int sdla_inten (sdlahw_t* hw)
646 {
647         unsigned port = hw->port;
648         int tmp, i;
649
650         switch (hw->type) {
651         case SDLA_S502E:
652                 /* Note thar interrupt control operations on S502E are allowed
653                  * only if CPU is enabled (bit 0 of status register is set).
654                  */
655                 if (_INB(port) & 0x01) {
656                         _OUTB(port, 0x02);      /* bit1 = 1, bit2 = 0 */
657                         _OUTB(port, 0x06);      /* bit1 = 1, bit2 = 1 */
658                         hw->regs[0] = 0x06;
659                 }
660                 else return -EIO;
661                 break;
662
663         case SDLA_S503:
664                 tmp = hw->regs[0] | 0x04;
665                 _OUTB(port, tmp);
666                 hw->regs[0] = tmp;              /* update mirror */
667                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
668                 if (!(_INB(port) & 0x02))               /* verify */
669                         return -EIO;
670                 break;
671
672         case SDLA_S508:
673                 tmp = hw->regs[0] | 0x10;
674                 _OUTB(port, tmp);
675                 hw->regs[0] = tmp;              /* update mirror */
676                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
677                 if (!(_INB(port + 1) & 0x10))           /* verify */
678                         return -EIO;
679                 break;
680
681         case SDLA_S502A:
682         case SDLA_S507:
683                 break;
684
685         case SDLA_S514:
686                 break;
687
688         default:
689                 return -EINVAL;
690
691         }
692         return 0;
693 }
694
695 /*============================================================================
696  * Disable interrupt generation.
697  */
698
699 #if 0
700 int sdla_intde (sdlahw_t* hw)
701 {
702         unsigned port = hw->port;
703         int tmp, i;
704
705         switch (hw->type) {
706         case SDLA_S502E:
707                 /* Notes:
708                  *  1) interrupt control operations are allowed only if CPU is
709                  *     enabled (bit 0 of status register is set).
710                  *  2) disabling interrupts using bit 1 of control register
711                  *     causes IRQ line go high, therefore we are going to use
712                  *     0x04 instead: lower it to inhibit interrupts to PC.
713                  */
714                 if (_INB(port) & 0x01) {
715                         _OUTB(port, hw->regs[0] & ~0x04);
716                         hw->regs[0] &= ~0x04;
717                 }
718                 else return -EIO;
719                 break;
720
721         case SDLA_S503:
722                 tmp = hw->regs[0] & ~0x04;
723                 _OUTB(port, tmp);
724                 hw->regs[0] = tmp;                      /* update mirror */
725                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
726                 if (_INB(port) & 0x02)                  /* verify */
727                         return -EIO;
728                 break;
729
730         case SDLA_S508:
731                 tmp = hw->regs[0] & ~0x10;
732                 _OUTB(port, tmp);
733                 hw->regs[0] = tmp;                      /* update mirror */
734                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
735                 if (_INB(port) & 0x10)                  /* verify */
736                         return -EIO;
737                 break;
738
739         case SDLA_S502A:
740         case SDLA_S507:
741                 break;
742
743         default:
744                 return -EINVAL;
745         }
746         return 0;
747 }
748 #endif  /*  0  */
749
750 /*============================================================================
751  * Acknowledge SDLA hardware interrupt.
752  */
753
754 static int sdla_intack (sdlahw_t* hw)
755 {
756         unsigned port = hw->port;
757         int tmp;
758
759         switch (hw->type) {
760         case SDLA_S502E:
761                 /* To acknoledge hardware interrupt we have to toggle bit 3 of
762                  * control register: \_/
763                  * Note that interrupt control operations on S502E are allowed
764                  * only if CPU is enabled (bit 1 of status register is set).
765                  */
766                 if (_INB(port) & 0x01) {
767                         tmp = hw->regs[0] & ~0x04;
768                         _OUTB(port, tmp);
769                         tmp |= 0x04;
770                         _OUTB(port, tmp);
771                         hw->regs[0] = tmp;
772                 }
773                 else return -EIO;
774                 break;
775
776         case SDLA_S503:
777                 if (_INB(port) & 0x04) {
778                         tmp = hw->regs[0] & ~0x08;
779                         _OUTB(port, tmp);
780                         tmp |= 0x08;
781                         _OUTB(port, tmp);
782                         hw->regs[0] = tmp;
783                 }
784                 break;
785
786         case SDLA_S502A:
787         case SDLA_S507:
788         case SDLA_S508:
789         break;
790
791         default:
792                 return -EINVAL;
793         }
794         return 0;
795 }
796
797
798 /*============================================================================
799  * Acknowledge S514 hardware interrupt.
800  */
801
802 EXPORT_SYMBOL(S514_intack);
803
804 void S514_intack (sdlahw_t* hw, u32 int_status)
805 {
806         pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
807 }
808
809
810 /*============================================================================
811  * Read the S514 hardware interrupt status.
812  */
813
814 EXPORT_SYMBOL(read_S514_int_stat);
815
816 void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
817 {
818         pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
819 }
820
821
822 /*============================================================================
823  * Generate an interrupt to adapter's CPU.
824  */
825
826 #if 0
827 int sdla_intr (sdlahw_t* hw)
828 {
829         unsigned port = hw->port;
830
831         switch (hw->type) {
832         case SDLA_S502A:
833                 if (!(_INB(port) & 0x40)) {
834                         _OUTB(port, 0x10);              /* issue NMI to CPU */
835                         hw->regs[0] = 0x10;
836                 }
837                 else return -EIO;
838                 break;
839
840         case SDLA_S507:
841                 if ((_INB(port) & 0x06) == 0x06) {
842                         _OUTB(port + 3, 0);
843                 }
844                 else return -EIO;
845                 break;
846
847         case SDLA_S508:
848                 if (_INB(port + 1) & 0x02) {
849                         _OUTB(port, 0x08);
850                 }
851                 else return -EIO;
852                 break;
853
854         case SDLA_S502E:
855         case SDLA_S503:
856         default:
857                 return -EINVAL;
858         }
859         return 0;
860 }
861 #endif  /*  0  */
862
863 /*============================================================================
864  * Execute Adapter Command.
865  * o Set exec flag.
866  * o Busy-wait until flag is reset.
867  * o Return number of loops made, or 0 if command timed out.
868  */
869
870 EXPORT_SYMBOL(sdla_exec);
871
872 int sdla_exec (void* opflag)
873 {
874         volatile unsigned char* flag = opflag;
875         unsigned long tstop;
876         int nloops;
877
878         if(readb(flag) != 0x00) {
879                 printk(KERN_INFO
880                         "WANPIPE: opp flag set on entry to sdla_exec\n");
881                 return 0;
882         }
883         
884         writeb(0x01, flag);
885
886         tstop = SYSTEM_TICK + EXEC_TIMEOUT;
887
888         for (nloops = 1; (readb(flag) == 0x01); ++ nloops) {
889                 unsigned delay = exec_idle;
890                 while (-- delay);                       /* delay */
891                 if (SYSTEM_TICK > tstop) return 0;      /* time is up! */
892         }
893         return nloops;
894 }
895
896 /*============================================================================
897  * Read absolute adapter memory.
898  * Transfer data from adapter's memory to data buffer.
899  *
900  * Note:
901  * Care should be taken when crossing dual-port memory window boundary.
902  * This function is not atomic, so caller must disable interrupt if
903  * interrupt routines are accessing adapter shared memory.
904  */
905
906 EXPORT_SYMBOL(sdla_peek);
907
908 int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
909 {
910
911         if (addr + len > hw->memory)    /* verify arguments */
912                 return -EINVAL;
913
914         if(hw->type == SDLA_S514) {     /* copy data for the S514 adapter */
915                 peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
916                 return 0;
917         }
918
919         else {                          /* copy data for the S508 adapter */
920                 unsigned long oldvec = hw->vector;
921                 unsigned winsize = hw->dpmsize;
922                 unsigned curpos, curlen;   /* current offset and block size */
923                 unsigned long curvec;      /* current DPM window vector */
924                 int err = 0;
925
926                 while (len && !err) {
927                         curpos = addr % winsize;  /* current window offset */
928                         curvec = addr - curpos;   /* current window vector */
929                         curlen = (len > (winsize - curpos)) ?
930                                 (winsize - curpos) : len;
931                         /* Relocate window and copy block of data */
932                         err = sdla_mapmem(hw, curvec);
933                         peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
934                                 curlen);
935                         addr       += curlen;
936                         buf         = (char*)buf + curlen;
937                         len        -= curlen;
938                 }
939
940                 /* Restore DPM window position */
941                 sdla_mapmem(hw, oldvec);
942                 return err;
943         }
944 }
945
946
947 /*============================================================================
948  * Read data from adapter's memory to a data buffer in 4-byte chunks.
949  * Note that we ensure that the SDLA memory address is on a 4-byte boundary
950  * before we begin moving the data in 4-byte chunks.
951 */
952
953 static void peek_by_4 (unsigned long src, void* buf, unsigned len)
954 {
955
956         /* byte copy data until we get to a 4-byte boundary */
957         while (len && (src & 0x03)) {
958                 *(char *)buf ++ = readb(src ++);
959                 len --;
960         }
961
962         /* copy data in 4-byte chunks */
963         while (len >= 4) {
964                 *(unsigned long *)buf = readl(src);
965                 buf += 4;
966                 src += 4;
967                 len -= 4;
968         }
969
970         /* byte copy any remaining data */
971         while (len) {
972                 *(char *)buf ++ = readb(src ++);
973                 len --;
974         }
975 }
976
977
978 /*============================================================================
979  * Write Absolute Adapter Memory.
980  * Transfer data from data buffer to adapter's memory.
981  *
982  * Note:
983  * Care should be taken when crossing dual-port memory window boundary.
984  * This function is not atomic, so caller must disable interrupt if
985  * interrupt routines are accessing adapter shared memory.
986  */
987
988 EXPORT_SYMBOL(sdla_poke);
989  
990 int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
991 {
992
993         if (addr + len > hw->memory)    /* verify arguments */
994                 return -EINVAL;
995    
996         if(hw->type == SDLA_S514) {     /* copy data for the S514 adapter */
997                 poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
998                 return 0;
999         }
1000         
1001         else {                          /* copy data for the S508 adapter */
1002                 unsigned long oldvec = hw->vector;
1003                 unsigned winsize = hw->dpmsize;
1004                 unsigned curpos, curlen;     /* current offset and block size */
1005                 unsigned long curvec;        /* current DPM window vector */
1006                 int err = 0;
1007
1008                 while (len && !err) {
1009                         curpos = addr % winsize;    /* current window offset */
1010                         curvec = addr - curpos;     /* current window vector */
1011                         curlen = (len > (winsize - curpos)) ?
1012                                 (winsize - curpos) : len;
1013                         /* Relocate window and copy block of data */
1014                         sdla_mapmem(hw, curvec);
1015                         poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
1016                                 curlen);
1017                         addr       += curlen;
1018                         buf         = (char*)buf + curlen;
1019                         len        -= curlen;
1020                 }
1021
1022                 /* Restore DPM window position */
1023                 sdla_mapmem(hw, oldvec);
1024                 return err;
1025         }
1026 }
1027
1028
1029 /*============================================================================
1030  * Write from a data buffer to adapter's memory in 4-byte chunks.
1031  * Note that we ensure that the SDLA memory address is on a 4-byte boundary
1032  * before we begin moving the data in 4-byte chunks.
1033 */
1034
1035 static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
1036 {
1037
1038         /* byte copy data until we get to a 4-byte boundary */
1039         while (len && (dest & 0x03)) {
1040                 writeb (*(char *)buf ++, dest ++);
1041                 len --;
1042         }
1043
1044         /* copy data in 4-byte chunks */
1045         while (len >= 4) {
1046                 writel (*(unsigned long *)buf, dest);
1047                 dest += 4;
1048                 buf += 4;
1049                 len -= 4;
1050         }
1051
1052         /* byte copy any remaining data */
1053         while (len) {
1054                 writeb (*(char *)buf ++ , dest ++);
1055                 len --;
1056         }
1057 }
1058
1059
1060 #ifdef  DONT_COMPIPLE_THIS
1061 #endif  /* DONT_COMPIPLE_THIS */
1062
1063 /****** Hardware-Specific Functions *****************************************/
1064
1065 /*============================================================================
1066  * Detect adapter type.
1067  * o if adapter type is specified then call detection routine for that adapter
1068  *   type.  Otherwise call detection routines for every adapter types until
1069  *   adapter is detected.
1070  *
1071  * Notes:
1072  * 1) Detection tests are destructive! Adapter will be left in shutdown state
1073  *    after the test.
1074  */
1075 static int sdla_detect (sdlahw_t* hw)
1076 {
1077         unsigned port = hw->port;
1078         int err = 0;
1079
1080         if (!port && (hw->type != SDLA_S514))
1081                 return -EFAULT;
1082
1083         switch (hw->type) {
1084         case SDLA_S502A:
1085                 if (!detect_s502a(port)) err = -ENODEV;
1086                 break;
1087
1088         case SDLA_S502E:
1089                 if (!detect_s502e(port)) err = -ENODEV;
1090                 break;
1091
1092         case SDLA_S503:
1093                 if (!detect_s503(port)) err = -ENODEV;
1094                 break;
1095
1096         case SDLA_S507:
1097                 if (!detect_s507(port)) err = -ENODEV;
1098                 break;
1099
1100         case SDLA_S508:
1101                 if (!detect_s508(port)) err = -ENODEV;
1102                 break;
1103
1104         case SDLA_S514:
1105                 if (!detect_s514(hw)) err = -ENODEV;
1106                 break;
1107
1108         default:
1109                 if (detect_s502a(port))
1110                         hw->type = SDLA_S502A;
1111                 else if (detect_s502e(port))
1112                         hw->type = SDLA_S502E;
1113                 else if (detect_s503(port))
1114                         hw->type = SDLA_S503;
1115                 else if (detect_s507(port))
1116                         hw->type = SDLA_S507;
1117                 else if (detect_s508(port))
1118                         hw->type = SDLA_S508;
1119                 else err = -ENODEV;
1120         }
1121         return err;
1122 }
1123
1124 /*============================================================================
1125  * Autoselect memory region. 
1126  * o try all available DMP address options from the top down until success.
1127  */
1128 static int sdla_autodpm (sdlahw_t* hw)
1129 {
1130         int i, err = -EINVAL;
1131         unsigned* opt;
1132
1133         switch (hw->type) {
1134         case SDLA_S502A:
1135                 opt = s502a_dpmbase_options;
1136                 break;
1137
1138         case SDLA_S502E:
1139         case SDLA_S503:
1140         case SDLA_S508:
1141                 opt = s508_dpmbase_options;
1142                 break;
1143
1144         case SDLA_S507:
1145                 opt = s507_dpmbase_options;
1146                 break;
1147
1148         default:
1149                 return -EINVAL;
1150         }
1151
1152         /* Start testing from 8th position, address
1153          * 0xC8000 from the 508 address table. 
1154          * We don't want to test A**** addresses, since
1155          * they are usually used for Video */
1156         for (i = 8; i <= opt[0] && err; i++) {
1157                 hw->dpmbase = phys_to_virt(opt[i]);
1158                 err = sdla_setdpm(hw);
1159         }
1160         return err;
1161 }
1162
1163 /*============================================================================
1164  * Set up adapter dual-port memory window. 
1165  * o shut down adapter
1166  * o make sure that no physical memory exists in this region, i.e entire
1167  *   region reads 0xFF and is not writable when adapter is shut down.
1168  * o initialize adapter hardware
1169  * o make sure that region is usable with SDLA card, i.e. we can write to it
1170  *   when adapter is configured.
1171  */
1172 static int sdla_setdpm (sdlahw_t* hw)
1173 {
1174         int err;
1175
1176         /* Shut down card and verify memory region */
1177         sdla_down(hw);
1178         if (check_memregion(hw->dpmbase, hw->dpmsize))
1179                 return -EINVAL;
1180
1181         /* Initialize adapter and test on-board memory segment by segment.
1182          * If memory size appears to be less than shared memory window size,
1183          * assume that memory region is unusable.
1184          */
1185         err = sdla_init(hw);
1186         if (err) return err;
1187
1188         if (sdla_memtest(hw) < hw->dpmsize) {   /* less than window size */
1189                 sdla_down(hw);
1190                 return -EIO;
1191         }
1192         sdla_mapmem(hw, 0L);    /* set window vector at bottom */
1193         return 0;
1194 }
1195
1196 /*============================================================================
1197  * Load adapter from the memory image of the SDLA firmware module. 
1198  * o verify firmware integrity and compatibility
1199  * o start adapter up
1200  */
1201 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1202 {
1203
1204         int i;
1205
1206         /* Verify firmware signature */
1207         if (strcmp(sfm->signature, SFM_SIGNATURE)) {
1208                 printk(KERN_INFO "%s: not SDLA firmware!\n",
1209                         modname);
1210                 return -EINVAL;
1211         }
1212
1213         /* Verify firmware module format version */
1214         if (sfm->version != SFM_VERSION) {
1215                 printk(KERN_INFO
1216                         "%s: firmware format %u rejected! Expecting %u.\n",
1217                         modname, sfm->version, SFM_VERSION);
1218                 return -EINVAL;
1219         }
1220
1221         /* Verify firmware module length and checksum */
1222         if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
1223                 (checksum((void*)&sfm->info,
1224                 sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) {
1225                 printk(KERN_INFO "%s: firmware corrupted!\n", modname);
1226                 return -EINVAL;
1227         }
1228
1229         /* Announce */
1230         printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1231                 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1232                 sfm->info.codeid);
1233
1234         if(hw->type == SDLA_S514)
1235                 printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
1236                         modname, hw->S514_cpu_no[0]);
1237
1238         /* Scan through the list of compatible adapters and make sure our
1239          * adapter type is listed.
1240          */
1241         for (i = 0;
1242              (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1243              ++i);
1244         
1245         if (i == SFM_MAX_SDLA) {
1246                 printk(KERN_INFO "%s: firmware is not compatible with S%u!\n",
1247                         modname, hw->type);
1248                 return -EINVAL;
1249         }
1250
1251
1252         /* Make sure there is enough on-board memory */
1253         if (hw->memory < sfm->info.memsize) {
1254                 printk(KERN_INFO
1255                         "%s: firmware needs %lu bytes of on-board memory!\n",
1256                         modname, sfm->info.memsize);
1257                 return -EINVAL;
1258         }
1259
1260         /* Move code onto adapter */
1261         if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) {
1262                 printk(KERN_INFO "%s: failed to load code segment!\n",
1263                         modname);
1264                 return -EIO;
1265         }
1266
1267         /* Prepare boot-time configuration data and kick-off CPU */
1268         sdla_bootcfg(hw, &sfm->info);
1269         if (sdla_start(hw, sfm->info.startoffs)) {
1270                 printk(KERN_INFO "%s: Damn... Adapter won't start!\n",
1271                         modname);
1272                 return -EIO;
1273         }
1274
1275         /* position DPM window over the mailbox and enable interrupts */
1276         if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) {
1277                 printk(KERN_INFO "%s: adapter hardware failure!\n",
1278                         modname);
1279                 return -EIO;
1280         }
1281         hw->fwid = sfm->info.codeid;            /* set firmware ID */
1282         return 0;
1283 }
1284
1285 /*============================================================================
1286  * Initialize SDLA hardware: setup memory window, IRQ, etc.
1287  */
1288 static int sdla_init (sdlahw_t* hw)
1289 {
1290         int i;
1291
1292         for (i = 0; i < SDLA_MAXIORANGE; ++i)
1293                 hw->regs[i] = 0;
1294
1295         switch (hw->type) {
1296         case SDLA_S502A: return init_s502a(hw);
1297         case SDLA_S502E: return init_s502e(hw);
1298         case SDLA_S503:  return init_s503(hw);
1299         case SDLA_S507:  return init_s507(hw);
1300         case SDLA_S508:  return init_s508(hw);
1301         }
1302         return -EINVAL;
1303 }
1304
1305 /*============================================================================
1306  * Test adapter on-board memory.
1307  * o slide DPM window from the bottom up and test adapter memory segment by
1308  *   segment.
1309  * Return adapter memory size.
1310  */
1311 static unsigned long sdla_memtest (sdlahw_t* hw)
1312 {
1313         unsigned long memsize;
1314         unsigned winsize;
1315
1316         for (memsize = 0, winsize = hw->dpmsize;
1317              !sdla_mapmem(hw, memsize) &&
1318                 (test_memregion(hw->dpmbase, winsize) == winsize)
1319              ;
1320              memsize += winsize)
1321         ;
1322         hw->memory = memsize;
1323         return memsize;
1324 }
1325
1326 /*============================================================================
1327  * Prepare boot-time firmware configuration data.
1328  * o position DPM window
1329  * o initialize configuration data area
1330  */
1331 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1332 {
1333         unsigned char* data;
1334
1335         if (!sfminfo->datasize) return 0;       /* nothing to do */
1336
1337         if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1338                 return -EIO;
1339
1340         if(hw->type == SDLA_S514)
1341                 data = (void*)(hw->dpmbase + sfminfo->dataoffs);
1342         else
1343                 data = (void*)((u8 *)hw->dpmbase +
1344                         (sfminfo->dataoffs - hw->vector));
1345
1346         memset_io (data, 0, sfminfo->datasize);
1347
1348         writeb (make_config_byte(hw), &data[0x00]);
1349
1350         switch (sfminfo->codeid) {
1351         case SFID_X25_502:
1352         case SFID_X25_508:
1353                 writeb (3, &data[0x01]);        /* T1 timer */
1354                 writeb (10, &data[0x03]);       /* N2 */
1355                 writeb (7, &data[0x06]);        /* HDLC window size */
1356                 writeb (1, &data[0x0B]);        /* DTE */
1357                 writeb (2, &data[0x0C]);        /* X.25 packet window size */
1358                 writew (128, &data[0x0D]);      /* default X.25 data size */
1359                 writew (128, &data[0x0F]);      /* maximum X.25 data size */
1360                 break;
1361         }
1362         return 0;
1363 }
1364
1365 /*============================================================================
1366  * Prepare configuration byte identifying adapter type and CPU clock rate.
1367  */
1368 static unsigned char make_config_byte (sdlahw_t* hw)
1369 {
1370         unsigned char byte = 0;
1371
1372         switch (hw->pclk) {
1373                 case 5000:  byte = 0x01; break;
1374                 case 7200:  byte = 0x02; break;
1375                 case 8000:  byte = 0x03; break;
1376                 case 10000: byte = 0x04; break;
1377                 case 16000: byte = 0x05; break;
1378         }
1379
1380         switch (hw->type) {
1381                 case SDLA_S502E: byte |= 0x80; break;
1382                 case SDLA_S503:  byte |= 0x40; break;
1383         }
1384         return byte;
1385 }
1386
1387 /*============================================================================
1388  * Start adapter's CPU.
1389  * o calculate a pointer to adapter's cold boot entry point
1390  * o position DPM window
1391  * o place boot instruction (jp addr) at cold boot entry point
1392  * o start CPU
1393  */
1394 static int sdla_start (sdlahw_t* hw, unsigned addr)
1395 {
1396         unsigned port = hw->port;
1397         unsigned char *bootp;
1398         int err, tmp, i;
1399
1400         if (!port && (hw->type != SDLA_S514)) return -EFAULT;
1401
1402         switch (hw->type) {
1403         case SDLA_S502A:
1404                 bootp = hw->dpmbase;
1405                 bootp += 0x66;
1406                 break;
1407
1408         case SDLA_S502E:
1409         case SDLA_S503:
1410         case SDLA_S507:
1411         case SDLA_S508:
1412         case SDLA_S514:
1413                 bootp = hw->dpmbase;
1414                 break;
1415
1416         default:
1417                 return -EINVAL;
1418         }
1419
1420         err = sdla_mapmem(hw, 0);
1421         if (err) return err;
1422
1423         writeb (0xC3, bootp);   /* Z80: 'jp' opcode */
1424         bootp ++;
1425         writew (addr, bootp);
1426
1427         switch (hw->type) {
1428         case SDLA_S502A:
1429                 _OUTB(port, 0x10);              /* issue NMI to CPU */
1430                 hw->regs[0] = 0x10;
1431                 break;
1432
1433         case SDLA_S502E:
1434                 _OUTB(port + 3, 0x01);          /* start CPU */
1435                 hw->regs[3] = 0x01;
1436                 for (i = 0; i < SDLA_IODELAY; ++i);
1437                 if (_INB(port) & 0x01) {        /* verify */
1438                         /*
1439                          * Enabling CPU changes functionality of the
1440                          * control register, so we have to reset its
1441                          * mirror.
1442                          */
1443                         _OUTB(port, 0);         /* disable interrupts */
1444                         hw->regs[0] = 0;
1445                 }
1446                 else return -EIO;
1447                 break;
1448
1449         case SDLA_S503:
1450                 tmp = hw->regs[0] | 0x09;       /* set bits 0 and 3 */
1451                 _OUTB(port, tmp);
1452                 hw->regs[0] = tmp;              /* update mirror */
1453                 for (i = 0; i < SDLA_IODELAY; ++i);
1454                 if (!(_INB(port) & 0x01))       /* verify */
1455                         return -EIO;
1456                 break;
1457
1458         case SDLA_S507:
1459                 tmp = hw->regs[0] | 0x02;
1460                 _OUTB(port, tmp);
1461                 hw->regs[0] = tmp;              /* update mirror */
1462                 for (i = 0; i < SDLA_IODELAY; ++i);
1463                 if (!(_INB(port) & 0x04))       /* verify */
1464                         return -EIO;
1465                 break;
1466
1467         case SDLA_S508:
1468                 tmp = hw->regs[0] | 0x02;
1469                 _OUTB(port, tmp);
1470                 hw->regs[0] = tmp;      /* update mirror */
1471                 for (i = 0; i < SDLA_IODELAY; ++i);
1472                 if (!(_INB(port + 1) & 0x02))   /* verify */
1473                         return -EIO;
1474                 break;
1475
1476         case SDLA_S514:
1477                 writeb (S514_CPU_START, hw->vector);
1478                 break;
1479
1480         default:
1481                 return -EINVAL;
1482         }
1483         return 0;
1484 }
1485
1486 /*============================================================================
1487  * Initialize S502A adapter.
1488  */
1489 static int init_s502a (sdlahw_t* hw)
1490 {
1491         unsigned port = hw->port;
1492         int tmp, i;
1493
1494         if (!detect_s502a(port))
1495                 return -ENODEV;
1496
1497         hw->regs[0] = 0x08;
1498         hw->regs[1] = 0xFF;
1499
1500         /* Verify configuration options */
1501         i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1502         if (i == 0)
1503                 return -EINVAL;
1504
1505         tmp = s502a_hmcr[i - 1];
1506         switch (hw->dpmsize) {
1507         case 0x2000:
1508                 tmp |= 0x01;
1509                 break;
1510
1511         case 0x10000L:
1512                 break;
1513
1514         default:
1515                 return -EINVAL;
1516         }
1517
1518         /* Setup dual-port memory window (this also enables memory access) */
1519         _OUTB(port + 1, tmp);
1520         hw->regs[1] = tmp;
1521         hw->regs[0] = 0x08;
1522         return 0;
1523 }
1524
1525 /*============================================================================
1526  * Initialize S502E adapter.
1527  */
1528 static int init_s502e (sdlahw_t* hw)
1529 {
1530         unsigned port = hw->port;
1531         int tmp, i;
1532
1533         if (!detect_s502e(port))
1534                 return -ENODEV;
1535
1536         /* Verify configuration options */
1537         i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1538         if (i == 0)
1539                 return -EINVAL;
1540
1541         tmp = s502e_hmcr[i - 1];
1542         switch (hw->dpmsize) {
1543         case 0x2000:
1544                 tmp |= 0x01;
1545                 break;
1546
1547         case 0x10000L:
1548                 break;
1549
1550         default:
1551                 return -EINVAL;
1552         }
1553
1554         /* Setup dual-port memory window */
1555         _OUTB(port + 1, tmp);
1556         hw->regs[1] = tmp;
1557
1558         /* Enable memory access */
1559         _OUTB(port, 0x02);
1560         hw->regs[0] = 0x02;
1561         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1562         return (_INB(port) & 0x02) ? 0 : -EIO;
1563 }
1564
1565 /*============================================================================
1566  * Initialize S503 adapter.
1567  * ---------------------------------------------------------------------------
1568  */
1569 static int init_s503 (sdlahw_t* hw)
1570 {
1571         unsigned port = hw->port;
1572         int tmp, i;
1573
1574         if (!detect_s503(port))
1575                 return -ENODEV;
1576
1577         /* Verify configuration options */
1578         i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1579         if (i == 0)
1580                 return -EINVAL;
1581
1582         tmp = s502e_hmcr[i - 1];
1583         switch (hw->dpmsize) {
1584         case 0x2000:
1585                 tmp |= 0x01;
1586                 break;
1587
1588         case 0x10000L:
1589                 break;
1590
1591         default:
1592                 return -EINVAL;
1593         }
1594
1595         /* Setup dual-port memory window */
1596         _OUTB(port + 1, tmp);
1597         hw->regs[1] = tmp;
1598
1599         /* Enable memory access */
1600         _OUTB(port, 0x02);
1601         hw->regs[0] = 0x02;     /* update mirror */
1602         return 0;
1603 }
1604
1605 /*============================================================================
1606  * Initialize S507 adapter.
1607  */
1608 static int init_s507 (sdlahw_t* hw)
1609 {
1610         unsigned port = hw->port;
1611         int tmp, i;
1612
1613         if (!detect_s507(port))
1614                 return -ENODEV;
1615
1616         /* Verify configuration options */
1617         i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1618         if (i == 0)
1619                 return -EINVAL;
1620
1621         tmp = s507_hmcr[i - 1];
1622         switch (hw->dpmsize) {
1623         case 0x2000:
1624                 tmp |= 0x01;
1625                 break;
1626
1627         case 0x10000L:
1628                 break;
1629
1630         default:
1631                 return -EINVAL;
1632         }
1633
1634         /* Enable adapter's logic */
1635         _OUTB(port, 0x01);
1636         hw->regs[0] = 0x01;
1637         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1638         if (!(_INB(port) & 0x20))
1639                 return -EIO;
1640
1641         /* Setup dual-port memory window */
1642         _OUTB(port + 1, tmp);
1643         hw->regs[1] = tmp;
1644
1645         /* Enable memory access */
1646         tmp = hw->regs[0] | 0x04;
1647         if (hw->irq) {
1648                 i = get_option_index(s508_irq_options, hw->irq);
1649                 if (i) tmp |= s507_irqmask[i - 1];
1650         }
1651         _OUTB(port, tmp);
1652         hw->regs[0] = tmp;              /* update mirror */
1653         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1654         return (_INB(port) & 0x08) ? 0 : -EIO;
1655 }
1656
1657 /*============================================================================
1658  * Initialize S508 adapter.
1659  */
1660 static int init_s508 (sdlahw_t* hw)
1661 {
1662         unsigned port = hw->port;
1663         int tmp, i;
1664
1665         if (!detect_s508(port))
1666                 return -ENODEV;
1667
1668         /* Verify configuration options */
1669         i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1670         if (i == 0)
1671                 return -EINVAL;
1672
1673         /* Setup memory configuration */
1674         tmp = s508_hmcr[i - 1];
1675         _OUTB(port + 1, tmp);
1676         hw->regs[1] = tmp;
1677
1678         /* Enable memory access */
1679         _OUTB(port, 0x04);
1680         hw->regs[0] = 0x04;             /* update mirror */
1681         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1682         return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1683 }
1684
1685 /*============================================================================
1686  * Detect S502A adapter.
1687  *      Following tests are used to detect S502A adapter:
1688  *      1. All registers other than status (BASE) should read 0xFF
1689  *      2. After writing 00001000b to control register, status register should
1690  *         read 01000000b.
1691  *      3. After writing 0 to control register, status register should still
1692  *         read  01000000b.
1693  *      4. After writing 00000100b to control register, status register should
1694  *         read 01000100b.
1695  *      Return 1 if detected o.k. or 0 if failed.
1696  *      Note:   This test is destructive! Adapter will be left in shutdown
1697  *              state after the test.
1698  */
1699 static int detect_s502a (int port)
1700 {
1701         int i, j;
1702
1703         if (!get_option_index(s502_port_options, port))
1704                 return 0;
1705         
1706         for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1707                 if (_INB(port + j) != 0xFF)
1708                         return 0;
1709                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1710         }
1711
1712         _OUTB(port, 0x08);                      /* halt CPU */
1713         _OUTB(port, 0x08);
1714         _OUTB(port, 0x08);
1715         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1716         if (_INB(port) != 0x40)
1717                 return 0;
1718         _OUTB(port, 0x00);
1719         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1720         if (_INB(port) != 0x40)
1721                 return 0;
1722         _OUTB(port, 0x04);
1723         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1724         if (_INB(port) != 0x44)
1725                 return 0;
1726
1727         /* Reset adapter */
1728         _OUTB(port, 0x08);
1729         _OUTB(port, 0x08);
1730         _OUTB(port, 0x08);
1731         _OUTB(port + 1, 0xFF);
1732         return 1;
1733 }
1734
1735 /*============================================================================
1736  * Detect S502E adapter.
1737  *      Following tests are used to verify adapter presence:
1738  *      1. All registers other than status (BASE) should read 0xFF.
1739  *      2. After writing 0 to CPU control register (BASE+3), status register
1740  *         (BASE) should read 11111000b.
1741  *      3. After writing 00000100b to port BASE (set bit 2), status register
1742  *         (BASE) should read 11111100b.
1743  *      Return 1 if detected o.k. or 0 if failed.
1744  *      Note:   This test is destructive! Adapter will be left in shutdown
1745  *              state after the test.
1746  */
1747 static int detect_s502e (int port)
1748 {
1749         int i, j;
1750
1751         if (!get_option_index(s502_port_options, port))
1752                 return 0;
1753         for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1754                 if (_INB(port + j) != 0xFF)
1755                         return 0;
1756                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1757         }
1758
1759         _OUTB(port + 3, 0);                     /* CPU control reg. */
1760         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1761         if (_INB(port) != 0xF8)                 /* read status */
1762                 return 0;
1763         _OUTB(port, 0x04);                      /* set bit 2 */
1764         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1765         if (_INB(port) != 0xFC)                 /* verify */
1766                 return 0;
1767
1768         /* Reset adapter */
1769         _OUTB(port, 0);
1770         return 1;
1771 }
1772
1773 /*============================================================================
1774  * Detect s503 adapter.
1775  *      Following tests are used to verify adapter presence:
1776  *      1. All registers other than status (BASE) should read 0xFF.
1777  *      2. After writing 0 to control register (BASE), status register (BASE)
1778  *         should read 11110000b.
1779  *      3. After writing 00000100b (set bit 2) to control register (BASE),
1780  *         status register should read 11110010b.
1781  *      Return 1 if detected o.k. or 0 if failed.
1782  *      Note:   This test is destructive! Adapter will be left in shutdown
1783  *              state after the test.
1784  */
1785 static int detect_s503 (int port)
1786 {
1787         int i, j;
1788
1789         if (!get_option_index(s503_port_options, port))
1790                 return 0;
1791         for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1792                 if (_INB(port + j) != 0xFF)
1793                         return 0;
1794                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1795         }
1796
1797         _OUTB(port, 0);                         /* reset control reg.*/
1798         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1799         if (_INB(port) != 0xF0)                 /* read status */
1800                 return 0;
1801         _OUTB(port, 0x04);                      /* set bit 2 */
1802         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1803         if (_INB(port) != 0xF2)                 /* verify */
1804                 return 0;
1805
1806         /* Reset adapter */
1807         _OUTB(port, 0);
1808         return 1;
1809 }
1810
1811 /*============================================================================
1812  * Detect s507 adapter.
1813  *      Following tests are used to detect s507 adapter:
1814  *      1. All ports should read the same value.
1815  *      2. After writing 0x00 to control register, status register should read
1816  *         ?011000?b.
1817  *      3. After writing 0x01 to control register, status register should read
1818  *         ?011001?b.
1819  *      Return 1 if detected o.k. or 0 if failed.
1820  *      Note:   This test is destructive! Adapter will be left in shutdown
1821  *              state after the test.
1822  */
1823 static int detect_s507 (int port)
1824 {
1825         int tmp, i, j;
1826
1827         if (!get_option_index(s508_port_options, port))
1828                 return 0;
1829         tmp = _INB(port);
1830         for (j = 1; j < S507_IORANGE; ++j) {
1831                 if (_INB(port + j) != tmp)
1832                         return 0;
1833                 for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1834         }
1835
1836         _OUTB(port, 0x00);
1837         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1838         if ((_INB(port) & 0x7E) != 0x30)
1839                 return 0;
1840         _OUTB(port, 0x01);
1841         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1842         if ((_INB(port) & 0x7E) != 0x32)
1843                 return 0;
1844
1845         /* Reset adapter */
1846         _OUTB(port, 0x00);
1847         return 1;
1848 }
1849
1850 /*============================================================================
1851  * Detect s508 adapter.
1852  *      Following tests are used to detect s508 adapter:
1853  *      1. After writing 0x00 to control register, status register should read
1854  *         ??000000b.
1855  *      2. After writing 0x10 to control register, status register should read
1856  *         ??010000b
1857  *      Return 1 if detected o.k. or 0 if failed.
1858  *      Note:   This test is destructive! Adapter will be left in shutdown
1859  *              state after the test.
1860  */
1861 static int detect_s508 (int port)
1862 {
1863         int i;
1864
1865         if (!get_option_index(s508_port_options, port))
1866                 return 0;
1867         _OUTB(port, 0x00);
1868         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1869         if ((_INB(port + 1) & 0x3F) != 0x00)
1870                 return 0;
1871         _OUTB(port, 0x10);
1872         for (i = 0; i < SDLA_IODELAY; ++i);     /* delay */
1873         if ((_INB(port + 1) & 0x3F) != 0x10)
1874                 return 0;
1875
1876         /* Reset adapter */
1877         _OUTB(port, 0x00);
1878         return 1;
1879 }
1880
1881 /*============================================================================
1882  * Detect s514 PCI adapter.
1883  *      Return 1 if detected o.k. or 0 if failed.
1884  *      Note:   This test is destructive! Adapter will be left in shutdown
1885  *              state after the test.
1886  */
1887 static int detect_s514 (sdlahw_t* hw)
1888 {
1889         unsigned char CPU_no, slot_no, auto_slot_cfg;
1890         int number_S514_cards = 0;
1891         u32 S514_mem_base_addr = 0;
1892         u32 ut_u32;
1893         struct pci_dev *pci_dev;
1894
1895
1896 #ifndef CONFIG_PCI
1897         printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname);
1898         return 0;
1899 #endif
1900
1901         /*
1902         The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
1903         slot number defined in 'router.conf' via the 'port' definition.
1904         */
1905         CPU_no = hw->S514_cpu_no[0];
1906         slot_no = hw->S514_slot_no;
1907         auto_slot_cfg = hw->auto_pci_cfg;
1908
1909         if (auto_slot_cfg){
1910                 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot=Auto\n",
1911                 modname, CPU_no);
1912
1913         }else{
1914                 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot #%d\n",
1915                 modname, CPU_no, slot_no);
1916         }
1917         
1918         /* check to see that CPU A or B has been selected in 'router.conf' */
1919         switch(CPU_no) {
1920                 case S514_CPU_A:
1921                 case S514_CPU_B:
1922                         break;
1923         
1924                 default:
1925                         printk(KERN_INFO "%s: S514 CPU definition invalid.\n", 
1926                                 modname);
1927                         printk(KERN_INFO "Must be 'A' or 'B'\n");
1928                         return 0;
1929         }
1930
1931         number_S514_cards = find_s514_adapter(hw, 0);
1932         if(!number_S514_cards)
1933                 return 0;
1934
1935         /* we are using a single S514 adapter with a slot of 0 so re-read the */        
1936         /* location of this adapter */
1937         if((number_S514_cards == 1) && auto_slot_cfg) { 
1938                 number_S514_cards = find_s514_adapter(hw, 1);
1939                 if(!number_S514_cards) {
1940                         printk(KERN_INFO "%s: Error finding PCI card\n",
1941                                 modname);
1942                         return 0;
1943                 }
1944         }
1945
1946         pci_dev = hw->pci_dev;
1947         /* read the physical memory base address */
1948         S514_mem_base_addr = (CPU_no == S514_CPU_A) ? 
1949                 (pci_dev->resource[1].start) :
1950                 (pci_dev->resource[2].start);
1951         
1952         printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n",
1953                 modname, S514_mem_base_addr);
1954         if(!S514_mem_base_addr) {
1955                 if(CPU_no == S514_CPU_B)
1956                         printk(KERN_INFO "%s: CPU #B not present on the card\n",                                modname);
1957                 else
1958                         printk(KERN_INFO "%s: No PCI memory allocated to card\n",                               modname);
1959                 return 0;
1960         }
1961
1962         /* enable the PCI memory */
1963         pci_read_config_dword(pci_dev, 
1964                 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1965                 &ut_u32);
1966         pci_write_config_dword(pci_dev,
1967                 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1968                 (ut_u32 | PCI_MEMORY_ENABLE));
1969
1970         /* check the IRQ allocated and enable IRQ usage */
1971         if(!(hw->irq = pci_dev->irq)) {
1972                 printk(KERN_INFO "%s: IRQ not allocated to S514 adapter\n",
1973                         modname);
1974                 return 0;
1975         }
1976
1977         /* BUG FIX : Mar 6 2000
1978          * On a initial loading of the card, we must check
1979          * and clear PCI interrupt bits, due to a reset
1980          * problem on some other boards.  i.e. An interrupt
1981          * might be pending, even after system bootup, 
1982          * in which case, when starting wanrouter the machine
1983          * would crash. 
1984          */
1985         if (init_pci_slot(hw))
1986                 return 0;
1987
1988         pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32);
1989         ut_u32 |= (CPU_no == S514_CPU_A) ?
1990                 PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B;
1991         pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32);
1992
1993         printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
1994                 modname, hw->irq);
1995
1996         /* map the physical PCI memory to virtual memory */
1997         (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
1998                 (unsigned long)MAX_SIZEOF_S514_MEMORY);
1999         /* map the physical control register memory to virtual memory */
2000         hw->vector = (unsigned long)ioremap(
2001                 (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE),
2002                 (unsigned long)16);
2003      
2004         if(!hw->dpmbase || !hw->vector) {
2005                 printk(KERN_INFO "%s: PCI virtual memory allocation failed\n",
2006                         modname);
2007                 return 0;
2008         }
2009
2010         /* halt the adapter */
2011         writeb (S514_CPU_HALT, hw->vector);     
2012
2013         return 1;
2014 }
2015
2016 /*============================================================================
2017  * Find the S514 PCI adapter in the PCI bus.
2018  *      Return the number of S514 adapters found (0 if no adapter found).
2019  */
2020 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
2021 {
2022         unsigned char slot_no;
2023         int number_S514_cards = 0;
2024         char S514_found_in_slot = 0;
2025         u16 PCI_subsys_vendor;
2026
2027         struct pci_dev *pci_dev = NULL;
2028  
2029        slot_no = hw->S514_slot_no;
2030   
2031         while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2032                 != NULL) {
2033                 
2034                 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2035                         &PCI_subsys_vendor);
2036                 
2037                 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2038                         continue;
2039                 
2040                 hw->pci_dev = pci_dev;
2041                 
2042                 if(find_first_S514_card)
2043                         return(1);
2044                 
2045                 number_S514_cards ++;
2046                 
2047                 printk(KERN_INFO
2048                         "%s: S514 card found, slot #%d (devfn 0x%X)\n",
2049                         modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2050                         pci_dev->devfn);
2051                 
2052                 if (hw->auto_pci_cfg){
2053                         hw->S514_slot_no = ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK);
2054                         slot_no = hw->S514_slot_no;
2055                         
2056                 }else if (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == slot_no){
2057                         S514_found_in_slot = 1;
2058                         break;
2059                 }
2060         }
2061
2062         /* if no S514 adapter has been found, then exit */
2063         if (!number_S514_cards) {
2064                 printk(KERN_INFO "%s: Error, no S514 adapters found\n", modname);
2065                 return 0;
2066         }
2067         /* if more than one S514 card has been found, then the user must have */        /* defined a slot number so that the correct adapter is used */
2068         else if ((number_S514_cards > 1) && hw->auto_pci_cfg) {
2069                 printk(KERN_INFO "%s: Error, PCI Slot autodetect Failed! \n"
2070                                  "%s:        More than one S514 adapter found.\n"
2071                                  "%s:        Disable the Autodetect feature and supply\n"
2072                                  "%s:        the PCISLOT numbers for each card.\n",
2073                         modname,modname,modname,modname);
2074                 return 0;
2075         }
2076         /* if the user has specified a slot number and the S514 adapter has */
2077         /* not been found in that slot, then exit */
2078         else if (!hw->auto_pci_cfg && !S514_found_in_slot) {
2079                 printk(KERN_INFO
2080                         "%s: Error, S514 card not found in specified slot #%d\n",
2081                         modname, slot_no);
2082                 return 0;
2083         }
2084
2085         return (number_S514_cards);
2086 }
2087
2088
2089
2090 /******* Miscellaneous ******************************************************/
2091
2092 /*============================================================================
2093  * Calibrate SDLA memory access delay.
2094  * Count number of idle loops made within 1 second and then calculate the
2095  * number of loops that should be made to achive desired delay.
2096  */
2097 static int calibrate_delay (int mks)
2098 {
2099         unsigned int delay;
2100         unsigned long stop;
2101
2102         for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
2103         return (delay/(1000000L/mks) + 1);
2104 }
2105
2106 /*============================================================================
2107  * Get option's index into the options list.
2108  *      Return option's index (1 .. N) or zero if option is invalid.
2109  */
2110 static int get_option_index (unsigned* optlist, unsigned optval)
2111 {
2112         int i;
2113
2114         for (i = 1; i <= optlist[0]; ++i)
2115                 if ( optlist[i] == optval)
2116                         return i;
2117         return 0;
2118 }
2119
2120 /*============================================================================
2121  * Check memory region to see if it's available. 
2122  * Return:      0       ok.
2123  */
2124 static unsigned check_memregion (void* ptr, unsigned len)
2125 {
2126         volatile unsigned char* p = ptr;
2127
2128         for (; len && (readb (p) == 0xFF); --len, ++p) {
2129                 writeb (0, p);          /* attempt to write 0 */
2130                 if (readb(p) != 0xFF) { /* still has to read 0xFF */
2131                         writeb (0xFF, p);/* restore original value */
2132                         break;          /* not good */
2133                 }
2134         }
2135
2136         return len;
2137 }
2138
2139 /*============================================================================
2140  * Test memory region.
2141  * Return:      size of the region that passed the test.
2142  * Note:        Region size must be multiple of 2 !
2143  */
2144 static unsigned test_memregion (void* ptr, unsigned len)
2145 {
2146         volatile unsigned short* w_ptr;
2147         unsigned len_w = len >> 1;      /* region len in words */
2148         unsigned i;
2149
2150         for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2151                 writew (0xAA55, w_ptr);
2152         
2153         for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2154                 if (readw (w_ptr) != 0xAA55) {
2155                         len_w = i;
2156                         break;
2157                 }
2158
2159         for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2160                 writew (0x55AA, w_ptr);
2161         
2162         for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2163                 if (readw(w_ptr) != 0x55AA) {
2164                         len_w = i;
2165                         break;
2166                 }
2167         
2168         for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2169                 writew (0, w_ptr);
2170
2171         return len_w << 1;
2172 }
2173
2174 /*============================================================================
2175  * Calculate 16-bit CRC using CCITT polynomial.
2176  */
2177 static unsigned short checksum (unsigned char* buf, unsigned len)
2178 {
2179         unsigned short crc = 0;
2180         unsigned mask, flag;
2181
2182         for (; len; --len, ++buf) {
2183                 for (mask = 0x80; mask; mask >>= 1) {
2184                         flag = (crc & 0x8000);
2185                         crc <<= 1;
2186                         crc |= ((*buf & mask) ? 1 : 0);
2187                         if (flag) crc ^= 0x1021;
2188                 }
2189         }
2190         return crc;
2191 }
2192
2193 static int init_pci_slot(sdlahw_t *hw)
2194 {
2195
2196         u32 int_status;
2197         int volatile found=0;
2198         int i=0;
2199
2200         /* Check if this is a very first load for a specific
2201          * pci card. If it is, clear the interrput bits, and
2202          * set the flag indicating that this card was initialized.
2203          */
2204         
2205         for (i=0; (i<MAX_S514_CARDS) && !found; i++){
2206                 if (pci_slot_ar[i] == hw->S514_slot_no){
2207                         found=1;
2208                         break;
2209                 }
2210                 if (pci_slot_ar[i] == 0xFF){
2211                         break;
2212                 }
2213         }
2214
2215         if (!found){
2216                 read_S514_int_stat(hw,&int_status);
2217                 S514_intack(hw,int_status);
2218                 if (i == MAX_S514_CARDS){
2219                         printk(KERN_INFO "%s: Critical Error !!!\n",modname);
2220                         printk(KERN_INFO 
2221                                 "%s: Number of Sangoma PCI cards exceeded maximum limit.\n",
2222                                         modname);
2223                         printk(KERN_INFO "Please contact Sangoma Technologies\n");
2224                         return 1;
2225                 }
2226                 pci_slot_ar[i] = hw->S514_slot_no;
2227         }
2228         return 0;
2229 }
2230
2231 static int pci_probe(sdlahw_t *hw)
2232 {
2233
2234         unsigned char slot_no;
2235         int number_S514_cards = 0;
2236         u16 PCI_subsys_vendor;
2237         u16 PCI_card_type;
2238
2239         struct pci_dev *pci_dev = NULL;
2240         struct pci_bus *bus = NULL;
2241  
2242        slot_no = 0;
2243   
2244         while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2245                 != NULL) {
2246                 
2247                 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2248                         &PCI_subsys_vendor);
2249                 
2250                 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2251                         continue;
2252
2253                 pci_read_config_word(pci_dev, PCI_CARD_TYPE,
2254                         &PCI_card_type);
2255         
2256                 bus = pci_dev->bus;
2257                 
2258                 /* A dual cpu card can support up to 4 physical connections,
2259                  * where a single cpu card can support up to 2 physical
2260                  * connections.  The FT1 card can only support a single 
2261                  * connection, however we cannot distinguish between a Single
2262                  * CPU card and an FT1 card. */
2263                 if (PCI_card_type == S514_DUAL_CPU){
2264                         number_S514_cards += 4;
2265                          printk(KERN_INFO
2266                                 "wanpipe: S514-PCI card found, cpu(s) 2, bus #%d, slot #%d, irq #%d\n",
2267                                 bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2268                                 pci_dev->irq);
2269                 }else{
2270                         number_S514_cards += 2;
2271                         printk(KERN_INFO
2272                                 "wanpipe: S514-PCI card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n",
2273                                 bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2274                                 pci_dev->irq);
2275                 }
2276         }
2277
2278         return number_S514_cards;
2279
2280 }
2281
2282
2283
2284 EXPORT_SYMBOL(wanpipe_hw_probe);
2285
2286 unsigned wanpipe_hw_probe(void)
2287 {
2288         sdlahw_t hw;
2289         unsigned* opt = s508_port_options; 
2290         unsigned cardno=0;
2291         int i;
2292         
2293         memset(&hw, 0, sizeof(hw));
2294         
2295         for (i = 1; i <= opt[0]; i++) {
2296                 if (detect_s508(opt[i])){
2297                         /* S508 card can support up to two physical links */
2298                         cardno+=2;
2299                         printk(KERN_INFO "wanpipe: S508-ISA card found, port 0x%x\n",opt[i]);
2300                 }
2301         }
2302
2303       #ifdef CONFIG_PCI
2304         hw.S514_slot_no = 0;
2305         cardno += pci_probe(&hw);
2306       #else
2307         printk(KERN_INFO "wanpipe: Warning, Kernel not compiled for PCI support!\n");
2308         printk(KERN_INFO "wanpipe: PCI Hardware Probe Failed!\n");
2309       #endif
2310
2311         return cardno;
2312 }
2313
2314 /****** End *****************************************************************/