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