* better
[mascara-docs.git] / i386 / linux-2.3.21 / drivers / net / wan / sdladrv.c
blob5e1f6b99e9a0350287bf5cf7b397469a0dcfd0d4
1 /*****************************************************************************
2 * sdladrv.c SDLA Support Module. Main module.
4 * This module is a library of common hardware-specific functions
5 * used by all Sangoma drivers.
7 * Author: Gene Kozin <genek@compuserve.com>
8 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
10 * Copyright: (c) 1995-1996 Sangoma Technologies Inc.
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 * ============================================================================
17 * May 19, 1999 Arnaldo Melo wanpipe_init belongs to sdlamain.c
18 * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
19 * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
20 * Jun 12, 1996 Gene Kozin Added support for S503 card.
21 * Apr 30, 1996 Gene Kozin SDLA hardware interrupt is acknowledged before
22 * calling protocolspecific ISR.
23 * Register I/O ports with Linux kernel.
24 * Miscellaneous bug fixes.
25 * Dec 20, 1995 Gene Kozin Fixed a bug in interrupt routine.
26 * Oct 14, 1995 Gene Kozin Initial version.
27 *****************************************************************************/
29 /*****************************************************************************
30 * Notes:
31 * ------
32 * 1. This code is ment to be system-independent (as much as possible). To
33 * achive this, various macros are used to hide system-specific interfaces.
34 * To compile this code, one of the following constants must be defined:
36 * Platform Define
37 * -------- ------
38 * Linux _LINUX_
39 * SCO Unix _SCO_UNIX_
41 * 2. Supported adapter types:
43 * S502A
44 * ES502A (S502E)
45 * S503
46 * S507
47 * S508 (S509)
49 * 3. S502A Notes:
51 * There is no separate DPM window enable/disable control in S502A. It
52 * opens immediately after a window number it written to the HMCR
53 * register. To close the window, HMCR has to be written a value
54 * ????1111b (e.g. 0x0F or 0xFF).
56 * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
58 * There should be a delay of ??? before reading back S502A status
59 * register.
61 * 4. S502E Notes:
63 * S502E has a h/w bug: although default IRQ line state is HIGH, enabling
64 * interrupts by setting bit 1 of the control register (BASE) to '1'
65 * causes it to go LOW! Therefore, disabling interrupts by setting that
66 * bit to '0' causes low-to-high transition on IRQ line (ghosty
67 * interrupt). The same occurs when disabling CPU by resetting bit 0 of
68 * CPU control register (BASE+3) - see the next note.
70 * S502E CPU and DPM control is limited:
72 * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
73 * control register (BASE+3) shuts the board down entirely, including
74 * DPM;
76 * o DPM access cannot be controlled dynamically. Ones CPU is started,
77 * bit 1 of the control register (BASE) is used to enable/disable IRQ,
78 * so that access to shared memory cannot be disabled while CPU is
79 * running.
80 ****************************************************************************/
82 #define _LINUX_
84 #if defined(_LINUX_) /****** Linux *******************************/
86 #include <linux/kernel.h> /* printk(), and other useful stuff */
87 #include <linux/stddef.h> /* offsetof(), etc. */
88 #include <linux/errno.h> /* return codes */
89 #include <linux/string.h> /* inline memset(), etc. */
90 #include <linux/module.h> /* support for loadable modules */
91 #include <linux/sched.h> /* for jiffies, HZ, etc. */
92 #include <linux/sdladrv.h> /* API definitions */
93 #include <linux/sdlasfm.h> /* SDLA firmware module definitions */
94 #include <asm/io.h> /* for inb(), outb(), etc. */
95 #define _INB(port) (inb(port))
96 #define _OUTB(port, byte) (outb((byte),(port)))
97 #define SYSTEM_TICK jiffies
99 #elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
100 #if !defined(INKERNEL)
101 #error This code MUST be compiled in kernel mode!
102 #endif
103 #include <sys/sdladrv.h> /* API definitions */
104 #include <sys/sdlasfm.h> /* SDLA firmware module definitions */
105 #include <sys/inline.h> /* for inb(), outb(), etc. */
106 #define _INB(port) (inb(port))
107 #define _OUTB(port, byte) (outb((port),(byte)))
108 #define SYSTEM_TICK lbolt
110 #else
111 #error Unknown system type!
112 #endif
114 #define MOD_VERSION 3
115 #define MOD_RELEASE 0
117 #define SDLA_IODELAY 100 /* I/O Rd/Wr delay, 10 works for 486DX2-66 */
118 #define EXEC_DELAY 20 /* shared memory access delay, mks */
119 #define EXEC_TIMEOUT (HZ*2) /* command timeout, in ticks */
121 /* I/O port address range */
122 #define S502A_IORANGE 3
123 #define S502E_IORANGE 4
124 #define S503_IORANGE 3
125 #define S507_IORANGE 4
126 #define S508_IORANGE 4
128 /* Maximum amount of memory */
129 #define S502_MAXMEM 0x10000L
130 #define S503_MAXMEM 0x10000L
131 #define S507_MAXMEM 0x40000L
132 #define S508_MAXMEM 0x40000L
134 /* Minimum amount of memory */
135 #define S502_MINMEM 0x8000L
136 #define S503_MINMEM 0x8000L
137 #define S507_MINMEM 0x20000L
138 #define S508_MINMEM 0x20000L
140 /****** Function Prototypes *************************************************/
142 /* Module entry points. These are called by the OS and must be public. */
143 int init_module (void);
144 void cleanup_module (void);
146 /* Hardware-specific functions */
147 static int sdla_detect (sdlahw_t* hw);
148 static int sdla_autodpm (sdlahw_t* hw);
149 static int sdla_setdpm (sdlahw_t* hw);
150 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);
151 static int sdla_init (sdlahw_t* hw);
152 static unsigned long sdla_memtest (sdlahw_t* hw);
153 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
154 static unsigned char make_config_byte (sdlahw_t* hw);
155 static int sdla_start (sdlahw_t* hw, unsigned addr);
157 static int init_s502a (sdlahw_t* hw);
158 static int init_s502e (sdlahw_t* hw);
159 static int init_s503 (sdlahw_t* hw);
160 static int init_s507 (sdlahw_t* hw);
161 static int init_s508 (sdlahw_t* hw);
163 static int detect_s502a (int port);
164 static int detect_s502e (int port);
165 static int detect_s503 (int port);
166 static int detect_s507 (int port);
167 static int detect_s508 (int port);
169 /* Miscellaneous functions */
170 static int calibrate_delay (int mks);
171 static int get_option_index (unsigned* optlist, unsigned optval);
172 static unsigned check_memregion (void* ptr, unsigned len);
173 static unsigned test_memregion (void* ptr, unsigned len);
174 static unsigned short checksum (unsigned char* buf, unsigned len);
176 /****** Global Data **********************************************************
177 * Note: All data must be explicitly initialized!!!
180 /* private data */
181 static char modname[] = "sdladrv";
182 static char fullname[] = "SDLA Support Module";
183 static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc.";
184 static unsigned exec_idle;
186 /* Hardware configuration options.
187 * These are arrays of configuration options used by verification routines.
188 * The first element of each array is its size (i.e. number of options).
190 static unsigned s502_port_options[] =
191 { 4, 0x250, 0x300, 0x350, 0x360 }
193 static unsigned s503_port_options[] =
194 { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
196 static unsigned s508_port_options[] =
197 { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
200 static unsigned s502a_irq_options[] = { 0 };
201 static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
202 static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 };
203 static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
205 static unsigned s502a_dpmbase_options[] =
208 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
209 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
210 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
211 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
213 static unsigned s507_dpmbase_options[] =
216 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
217 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
218 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
219 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
221 static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */
224 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
225 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
226 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
227 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
231 static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
232 static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
233 static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
236 static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
237 static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
238 static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 };
239 static unsigned s507_pclk_options[] = { 1, 12288 };
240 static unsigned s508_pclk_options[] = { 1, 16000 };
242 /* Host memory control register masks */
243 static unsigned char s502a_hmcr[] =
245 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, /* A0000 - AC000 */
246 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, /* C0000 - CC000 */
247 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, /* D0000 - DC000 */
248 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, /* E0000 - EC000 */
250 static unsigned char s502e_hmcr[] =
252 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */
253 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */
254 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */
255 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */
257 static unsigned char s507_hmcr[] =
259 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */
260 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */
261 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */
262 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */
264 static unsigned char s508_hmcr[] =
266 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */
267 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */
268 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */
269 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */
272 static unsigned char s507_irqmask[] =
274 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
277 /******* Kernel Loadable Module Entry Points ********************************/
279 /*============================================================================
280 * Module 'insert' entry point.
281 * o print announcement
282 * o initialize static data
283 * o calibrate SDLA shared memory access delay.
285 * Return: 0 Ok
286 * < 0 error.
287 * Context: process
290 #ifdef MODULE
291 int init_module (void)
293 printk(KERN_INFO "%s v%u.%u %s\n",
294 fullname, MOD_VERSION, MOD_RELEASE, copyright);
295 exec_idle = calibrate_delay(EXEC_DELAY);
296 #ifdef WANDEBUG
297 printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
298 #endif
299 return 0;
302 /*============================================================================
303 * Module 'remove' entry point.
304 * o release all remaining system resources
306 void cleanup_module (void)
309 #endif
311 /******* Kernel APIs ********************************************************/
313 /*============================================================================
314 * Set up adapter.
315 * o detect adapter type
316 * o verify hardware configuration options
317 * o check for hardware conflicts
318 * o set up adapter shared memory
319 * o test adapter memory
320 * o load firmware
321 * Return: 0 ok.
322 * < 0 error
325 EXPORT_SYMBOL(sdla_setup);
327 int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
329 unsigned* irq_opt = NULL; /* IRQ options */
330 unsigned* dpmbase_opt = NULL; /* DPM window base options */
331 unsigned* pclk_opt = NULL; /* CPU clock rate options */
332 int err;
334 if (sdla_detect(hw))
336 printk(KERN_ERR "%s: adapter S%04u not found at port 0x%X!\n",
337 modname, hw->type, hw->port)
339 return -EINVAL;
341 printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
342 modname, hw->type, hw->port)
345 hw->dpmsize = SDLA_WINDOWSIZE;
346 switch (hw->type)
348 case SDLA_S502A:
349 hw->io_range = S502A_IORANGE;
350 irq_opt = s502a_irq_options;
351 dpmbase_opt = s502a_dpmbase_options;
352 pclk_opt = s502a_pclk_options;
353 break;
355 case SDLA_S502E:
356 hw->io_range = S502E_IORANGE;
357 irq_opt = s502e_irq_options;
358 dpmbase_opt = s508_dpmbase_options;
359 pclk_opt = s502e_pclk_options;
360 break;
362 case SDLA_S503:
363 hw->io_range = S503_IORANGE;
364 irq_opt = s503_irq_options;
365 dpmbase_opt = s508_dpmbase_options;
366 pclk_opt = s503_pclk_options;
367 break;
369 case SDLA_S507:
370 hw->io_range = S507_IORANGE;
371 irq_opt = s508_irq_options;
372 dpmbase_opt = s507_dpmbase_options;
373 pclk_opt = s507_pclk_options;
374 break;
376 case SDLA_S508:
377 hw->io_range = S508_IORANGE;
378 irq_opt = s508_irq_options;
379 dpmbase_opt = s508_dpmbase_options;
380 pclk_opt = s508_pclk_options;
381 break;
384 /* Verify IRQ configuration options */
385 if (!get_option_index(irq_opt, hw->irq))
387 printk(KERN_ERR "%s: IRQ %d is illegal!\n",
388 modname, hw->irq)
390 return -EINVAL;
393 /* Verify CPU clock rate configuration options */
394 if (hw->pclk == 0)
395 hw->pclk = pclk_opt[1] /* use default */
397 else if (!get_option_index(pclk_opt, hw->pclk))
399 printk(KERN_ERR "%s: CPU clock %u is illegal!\n",
400 modname, hw->pclk)
402 return -EINVAL;
404 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
405 modname, hw->pclk)
408 /* Setup adapter dual-port memory window and test memory */
409 if (hw->dpmbase == 0)
411 err = sdla_autodpm(hw);
412 if (err)
414 printk(KERN_ERR
415 "%s: can't find available memory region!\n",
416 modname)
418 return err;
421 else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase)))
423 printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n",
424 modname, virt_to_phys(hw->dpmbase))
426 return -EINVAL;
428 else if (sdla_setdpm(hw))
430 printk(KERN_ERR
431 "%s: 8K memory region at 0x%lX is not available!\n",
432 modname, virt_to_phys(hw->dpmbase));
433 return -EINVAL;
435 printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n",
436 modname, virt_to_phys(hw->dpmbase));
438 printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n",
439 modname, hw->memory / 1024);
441 /* Load firmware. If loader fails then shut down adapter */
442 err = sdla_load(hw, sfm, len);
443 if (err) sdla_down(hw); /* shutdown adapter */
444 return err;
447 /*============================================================================
448 * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
451 EXPORT_SYMBOL(sdla_down);
453 int sdla_down (sdlahw_t* hw)
455 unsigned port = hw->port;
456 int i;
458 if (!port) return -EFAULT;
460 switch (hw->type)
462 case SDLA_S502A:
463 _OUTB(port, 0x08); /* halt CPU */
464 _OUTB(port, 0x08);
465 _OUTB(port, 0x08);
466 hw->regs[0] = 0x08;
467 _OUTB(port + 1, 0xFF); /* close memory window */
468 hw->regs[1] = 0xFF;
469 break;
471 case SDLA_S502E:
472 _OUTB(port + 3, 0); /* stop CPU */
473 _OUTB(port, 0); /* reset board */
474 for (i = 0; i < S502E_IORANGE; ++i)
475 hw->regs[i] = 0
477 break;
479 case SDLA_S503:
480 case SDLA_S507:
481 case SDLA_S508:
482 _OUTB(port, 0); /* reset board logic */
483 hw->regs[0] = 0;
484 break;
486 default:
487 return -EINVAL;
489 return 0;
492 /*============================================================================
493 * Map shared memory window into SDLA address space.
496 EXPORT_SYMBOL(sdla_mapmem);
498 int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
500 unsigned port = hw->port;
501 register int tmp;
503 switch (hw->type)
505 case SDLA_S502A:
506 case SDLA_S502E:
507 if (addr < S502_MAXMEM) /* verify parameter */
509 tmp = addr >> 13; /* convert to register mask */
510 _OUTB(port + 2, tmp);
511 hw->regs[2] = tmp;
513 else return -EINVAL;
514 break;
516 case SDLA_S503:
517 if (addr < S503_MAXMEM) /* verify parameter */
519 tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
520 _OUTB(port, tmp);
521 hw->regs[0] = tmp;
523 else return -EINVAL;
524 break;
526 case SDLA_S507:
527 if (addr < S507_MAXMEM)
529 if (!(_INB(port) & 0x02))
530 return -EIO
532 tmp = addr >> 13; /* convert to register mask */
533 _OUTB(port + 2, tmp);
534 hw->regs[2] = tmp;
536 else return -EINVAL;
537 break;
539 case SDLA_S508:
540 if (addr < S508_MAXMEM)
542 tmp = addr >> 13; /* convert to register mask */
543 _OUTB(port + 2, tmp);
544 hw->regs[2] = tmp;
546 else return -EINVAL;
547 break;
549 default:
550 return -EINVAL;
552 hw->vector = addr & 0xFFFFE000L;
553 return 0;
556 /*============================================================================
557 * Enable interrupt generation.
560 EXPORT_SYMBOL(sdla_inten);
562 int sdla_inten (sdlahw_t* hw)
564 unsigned port = hw->port;
565 int tmp, i;
567 switch (hw->type)
569 case SDLA_S502E:
570 /* Note thar interrupt control operations on S502E are allowed
571 * only if CPU is enabled (bit 0 of status register is set).
573 if (_INB(port) & 0x01)
575 _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
576 _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
577 hw->regs[0] = 0x06;
579 else return -EIO;
580 break;
582 case SDLA_S503:
583 tmp = hw->regs[0] | 0x04;
584 _OUTB(port, tmp);
585 hw->regs[0] = tmp; /* update mirror */
586 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
587 if (!(_INB(port) & 0x02)) /* verify */
588 return -EIO
590 break;
592 case SDLA_S508:
593 tmp = hw->regs[0] | 0x10;
594 _OUTB(port, tmp);
595 hw->regs[0] = tmp; /* update mirror */
596 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
597 if (!(_INB(port + 1) & 0x10)) /* verify */
598 return -EIO
600 break;
602 case SDLA_S502A:
603 case SDLA_S507:
604 break;
606 default:
607 return -EINVAL;
610 return 0;
613 /*============================================================================
614 * Disable interrupt generation.
617 EXPORT_SYMBOL(sdla_intde);
619 int sdla_intde (sdlahw_t* hw)
621 unsigned port = hw->port;
622 int tmp, i;
624 switch (hw->type)
626 case SDLA_S502E:
627 /* Notes:
628 * 1) interrupt control operations are allowed only if CPU is
629 * enabled (bit 0 of status register is set).
630 * 2) disabling interrupts using bit 1 of control register
631 * causes IRQ line go high, therefore we are going to use
632 * 0x04 instead: lower it to inhibit interrupts to PC.
634 if (_INB(port) & 0x01)
636 _OUTB(port, hw->regs[0] & ~0x04);
637 hw->regs[0] &= ~0x04;
639 else return -EIO;
640 break;
642 case SDLA_S503:
643 tmp = hw->regs[0] & ~0x04;
644 _OUTB(port, tmp);
645 hw->regs[0] = tmp; /* update mirror */
646 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
647 if (_INB(port) & 0x02) /* verify */
648 return -EIO
650 break;
652 case SDLA_S508:
653 tmp = hw->regs[0] & ~0x10;
654 _OUTB(port, tmp);
655 hw->regs[0] = tmp; /* update mirror */
656 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
657 if (_INB(port) & 0x10) /* verify */
658 return -EIO
660 break;
662 case SDLA_S502A:
663 case SDLA_S507:
664 break;
666 default:
667 return -EINVAL;
669 return 0;
672 /*============================================================================
673 * Acknowledge SDLA hardware interrupt.
676 EXPORT_SYMBOL(sdla_intack);
678 int sdla_intack (sdlahw_t* hw)
680 unsigned port = hw->port;
681 int tmp;
683 switch (hw->type)
685 case SDLA_S502E:
686 /* To acknoledge hardware interrupt we have to toggle bit 3 of
687 * control register: \_/
688 * Note that interrupt control operations on S502E are allowed
689 * only if CPU is enabled (bit 1 of status register is set).
691 if (_INB(port) & 0x01)
693 tmp = hw->regs[0] & ~0x04;
694 _OUTB(port, tmp);
695 tmp |= 0x04;
696 _OUTB(port, tmp);
697 hw->regs[0] = tmp;
699 else return -EIO;
700 break;
702 case SDLA_S503:
703 if (_INB(port) & 0x04)
705 tmp = hw->regs[0] & ~0x08;
706 _OUTB(port, tmp);
707 tmp |= 0x08;
708 _OUTB(port, tmp);
709 hw->regs[0] = tmp;
711 break;
713 case SDLA_S502A:
714 case SDLA_S507:
715 case SDLA_S508:
716 break;
718 default:
719 return -EINVAL;
721 return 0;
724 /*============================================================================
725 * Generate an interrupt to adapter's CPU.
728 EXPORT_SYMBOL(sdla_intr);
730 int sdla_intr (sdlahw_t* hw)
732 unsigned port = hw->port;
734 switch (hw->type)
736 case SDLA_S502A:
737 if (!(_INB(port) & 0x40))
739 _OUTB(port, 0x10); /* issue NMI to CPU */
740 hw->regs[0] = 0x10;
742 else return -EIO;
743 break;
745 case SDLA_S507:
746 if ((_INB(port) & 0x06) == 0x06)
748 _OUTB(port + 3, 0);
750 else return -EIO;
751 break;
753 case SDLA_S508:
754 if (_INB(port + 1) & 0x02)
756 _OUTB(port, 0x08);
758 else return -EIO;
759 break;
761 case SDLA_S502E:
762 case SDLA_S503:
763 default:
764 return -EINVAL;
766 return 0;
769 /*============================================================================
770 * Execute Adapter Command.
771 * o Set exec flag.
772 * o Busy-wait until flag is reset.
773 * o Return number of loops made, or 0 if command timed out.
776 EXPORT_SYMBOL(sdla_exec);
778 int sdla_exec (void* opflag)
780 volatile unsigned char* flag = opflag;
781 unsigned long tstop;
782 int nloops;
784 if (*flag) return 0; /* ???? */
786 *flag = 1;
787 tstop = SYSTEM_TICK + EXEC_TIMEOUT;
788 for (nloops = 1; *flag; ++nloops)
790 unsigned delay = exec_idle;
791 while (--delay); /* delay */
792 if (SYSTEM_TICK > tstop) return 0; /* time is up! */
794 return nloops;
797 /*============================================================================
798 * Read absolute adapter memory.
799 * Transfer data from adapter's memory to data buffer.
801 * Note:
802 * Care should be taken when crossing dual-port memory window boundary.
803 * This function is not atomic, so caller must disable interrupt if
804 * interrupt routines are accessing adapter shared memory.
807 EXPORT_SYMBOL(sdla_peek);
809 int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
811 unsigned long oldvec = hw->vector;
812 unsigned winsize = hw->dpmsize;
813 unsigned curpos, curlen; /* current offset and block size */
814 unsigned long curvec; /* current DPM window vector */
815 int err = 0;
817 if (addr + len > hw->memory) /* verify arguments */
818 return -EINVAL
820 while (len && !err)
822 curpos = addr % winsize; /* current window offset */
823 curvec = addr - curpos; /* current window vector */
824 curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
826 /* Relocate window and copy block of data */
827 err = sdla_mapmem(hw, curvec);
828 memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen);
829 addr += curlen;
830 (char*)buf += curlen;
831 len -= curlen;
834 /* Restore DPM window position */
835 sdla_mapmem(hw, oldvec);
836 return err;
839 /*============================================================================
840 * Write Absolute Adapter Memory.
841 * Transfer data from data buffer to adapter's memory.
843 * Note:
844 * Care should be taken when crossing dual-port memory window boundary.
845 * This function is not atomic, so caller must disable interrupt if
846 * interrupt routines are accessing adapter shared memory.
849 EXPORT_SYMBOL(sdla_poke);
851 int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
853 unsigned long oldvec = hw->vector;
854 unsigned winsize = hw->dpmsize;
855 unsigned curpos, curlen; /* current offset and block size */
856 unsigned long curvec; /* current DPM window vector */
857 int err = 0;
859 if (addr + len > hw->memory) /* verify arguments */
860 return -EINVAL
862 while (len && !err)
864 curpos = addr % winsize; /* current window offset */
865 curvec = addr - curpos; /* current window vector */
866 curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
868 /* Relocate window and copy block of data */
869 sdla_mapmem(hw, curvec);
870 memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen);
871 addr += curlen;
872 (char*)buf += curlen;
873 len -= curlen;
876 /* Restore DPM window position */
877 sdla_mapmem(hw, oldvec);
878 return err;
881 #ifdef DONT_COMPIPLE_THIS
882 #endif /* DONT_COMPIPLE_THIS */
884 /****** Hardware-Specific Functions *****************************************/
886 /*============================================================================
887 * Detect adapter type.
888 * o if adapter type is specified then call detection routine for that adapter
889 * type. Otherwise call detection routines for every adapter types until
890 * adapter is detected.
892 * Notes:
893 * 1) Detection tests are destructive! Adapter will be left in shutdown state
894 * after the test.
896 static int sdla_detect (sdlahw_t* hw)
898 unsigned port = hw->port;
899 int err = 0;
901 if (!port)
902 return -EFAULT
904 switch (hw->type)
906 case SDLA_S502A:
907 if (!detect_s502a(port)) err = -ENODEV;
908 break;
910 case SDLA_S502E:
911 if (!detect_s502e(port)) err = -ENODEV;
912 break;
914 case SDLA_S503:
915 if (!detect_s503(port)) err = -ENODEV;
916 break;
918 case SDLA_S507:
919 if (!detect_s507(port)) err = -ENODEV;
920 break;
922 case SDLA_S508:
923 if (!detect_s508(port)) err = -ENODEV;
924 break;
926 default:
927 if (detect_s502a(port))
928 hw->type = SDLA_S502A
930 else if (detect_s502e(port))
931 hw->type = SDLA_S502E
933 else if (detect_s503(port))
934 hw->type = SDLA_S503
936 else if (detect_s507(port))
937 hw->type = SDLA_S507
939 else if (detect_s508(port))
940 hw->type = SDLA_S508
942 else err = -ENODEV;
944 return err;
947 /*============================================================================
948 * Autoselect memory region.
949 * o try all available DMP address options from the top down until success.
951 static int sdla_autodpm (sdlahw_t* hw)
953 int i, err = -EINVAL;
954 unsigned* opt;
956 switch (hw->type)
958 case SDLA_S502A:
959 opt = s502a_dpmbase_options;
960 break;
962 case SDLA_S502E:
963 case SDLA_S503:
964 case SDLA_S508:
965 opt = s508_dpmbase_options;
966 break;
968 case SDLA_S507:
969 opt = s507_dpmbase_options;
970 break;
972 default:
973 return -EINVAL;
976 for (i = opt[0]; i && err; --i)
978 hw->dpmbase = phys_to_virt(opt[i]);
979 err = sdla_setdpm(hw);
981 return err;
984 /*============================================================================
985 * Set up adapter dual-port memory window.
986 * o shut down adapter
987 * o make sure that no physical memory exists in this region, i.e entire
988 * region reads 0xFF and is not writable when adapter is shut down.
989 * o initialize adapter hardware
990 * o make sure that region is usable with SDLA card, i.e. we can write to it
991 * when adapter is configured.
993 static int sdla_setdpm (sdlahw_t* hw)
995 int err;
997 /* Shut down card and verify memory region */
998 sdla_down(hw);
999 if (check_memregion(hw->dpmbase, hw->dpmsize))
1000 return -EINVAL
1003 /* Initialize adapter and test on-board memory segment by segment.
1004 * If memory size appears to be less than shared memory window size,
1005 * assume that memory region is unusable.
1007 err = sdla_init(hw);
1008 if (err) return err;
1010 if (sdla_memtest(hw) < hw->dpmsize) /* less than window size */
1012 sdla_down(hw);
1013 return -EIO;
1015 sdla_mapmem(hw, 0L); /* set window vector at bottom */
1016 return 0;
1019 /*============================================================================
1020 * Load adapter from the memory image of the SDLA firmware module.
1021 * o verify firmware integrity and compatibility
1022 * o start adapter up
1024 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1026 int i;
1028 /* Verify firmware signature */
1029 if (strcmp(sfm->signature, SFM_SIGNATURE))
1031 printk(KERN_ERR "%s: not SDLA firmware!\n",
1032 modname)
1034 return -EINVAL;
1037 /* Verify firmware module format version */
1038 if (sfm->version != SFM_VERSION)
1040 printk(KERN_ERR
1041 "%s: firmware format %u rejected! Expecting %u.\n",
1042 modname, sfm->version, SFM_VERSION)
1044 return -EINVAL;
1047 /* Verify firmware module length and checksum */
1048 if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
1049 (checksum((void*)&sfm->info,
1050 sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum))
1052 printk(KERN_ERR "%s: firmware corrupted!\n", modname);
1053 return -EINVAL;
1056 /* Announce */
1057 printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1058 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1059 sfm->info.codeid)
1062 /* Scan through the list of compatible adapters and make sure our
1063 * adapter type is listed.
1065 for (i = 0;
1066 (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1067 ++i)
1069 if (i == SFM_MAX_SDLA)
1071 printk(KERN_ERR "%s: firmware is not compatible with S%u!\n",
1072 modname, hw->type)
1074 return -EINVAL;
1077 /* Make sure there is enough on-board memory */
1078 if (hw->memory < sfm->info.memsize)
1080 printk(KERN_ERR
1081 "%s: firmware needs %lu bytes of on-board memory!\n",
1082 modname, sfm->info.memsize)
1084 return -EINVAL;
1087 /* Move code onto adapter */
1088 if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize))
1090 printk(KERN_ERR "%s: failed to load code segment!\n",
1091 modname)
1093 return -EIO;
1096 /* Prepare boot-time configuration data and kick-off CPU */
1097 sdla_bootcfg(hw, &sfm->info);
1098 if (sdla_start(hw, sfm->info.startoffs))
1100 printk(KERN_ERR "%s: Damn... Adapter won't start!\n",
1101 modname)
1103 return -EIO;
1106 /* position DPM window over the mailbox and enable interrupts */
1107 if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw))
1109 printk(KERN_ERR "%s: adapter hardware failure!\n",
1110 modname)
1112 return -EIO;
1114 hw->fwid = sfm->info.codeid; /* set firmware ID */
1115 return 0;
1118 /*============================================================================
1119 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1121 static int sdla_init (sdlahw_t* hw)
1123 int i;
1125 for (i = 0; i < SDLA_MAXIORANGE; ++i)
1126 hw->regs[i] = 0
1128 switch (hw->type)
1130 case SDLA_S502A: return init_s502a(hw);
1131 case SDLA_S502E: return init_s502e(hw);
1132 case SDLA_S503: return init_s503(hw);
1133 case SDLA_S507: return init_s507(hw);
1134 case SDLA_S508: return init_s508(hw);
1136 return -EINVAL;
1139 /*============================================================================
1140 * Test adapter on-board memory.
1141 * o slide DPM window from the bottom up and test adapter memory segment by
1142 * segment.
1143 * Return adapter memory size.
1145 static unsigned long sdla_memtest (sdlahw_t* hw)
1147 unsigned long memsize;
1148 unsigned winsize;
1150 for (memsize = 0, winsize = hw->dpmsize;
1151 !sdla_mapmem(hw, memsize) &&
1152 (test_memregion(hw->dpmbase, winsize) == winsize)
1154 memsize += winsize)
1156 hw->memory = memsize;
1157 return memsize;
1160 /*============================================================================
1161 * Prepare boot-time firmware configuration data.
1162 * o position DPM window
1163 * o initialize configuration data area
1165 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1167 unsigned char* data;
1169 if (!sfminfo->datasize) return 0; /* nothing to do */
1171 if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1172 return -EIO
1174 data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector));
1175 memset(data, 0, sfminfo->datasize);
1177 data[0x00] = make_config_byte(hw);
1178 switch (sfminfo->codeid)
1180 case SFID_X25_502:
1181 case SFID_X25_508:
1182 data[0x01] = 3; /* T1 timer */
1183 data[0x03] = 10; /* N2 */
1184 data[0x06] = 7; /* HDLC window size */
1185 data[0x0B] = 1; /* DTE */
1186 data[0x0C] = 2; /* X.25 packet window size */
1187 *(short*)&data[0x0D] = 128; /* default X.25 data size */
1188 *(short*)&data[0x0F] = 128; /* maximum X.25 data size */
1189 break;
1191 return 0;
1194 /*============================================================================
1195 * Prepare configuration byte identifying adapter type and CPU clock rate.
1197 static unsigned char make_config_byte (sdlahw_t* hw)
1199 unsigned char byte = 0;
1201 switch (hw->pclk)
1203 case 5000: byte = 0x01; break;
1204 case 7200: byte = 0x02; break;
1205 case 8000: byte = 0x03; break;
1206 case 10000: byte = 0x04; break;
1207 case 16000: byte = 0x05; break;
1209 switch (hw->type)
1211 case SDLA_S502E: byte |= 0x80; break;
1212 case SDLA_S503: byte |= 0x40; break;
1214 return byte;
1217 /*============================================================================
1218 * Start adapter's CPU.
1219 * o calculate a pointer to adapter's cold boot entry point
1220 * o position DPM window
1221 * o place boot instruction (jp addr) at cold boot entry point
1222 * o start CPU
1224 static int sdla_start (sdlahw_t* hw, unsigned addr)
1226 unsigned port = hw->port;
1227 unsigned char *bootp;
1228 int err, tmp, i;
1230 if (!port) return -EFAULT;
1232 switch (hw->type)
1234 case SDLA_S502A:
1235 bootp = hw->dpmbase;
1236 bootp += 0x66;
1237 break;
1239 case SDLA_S502E:
1240 case SDLA_S503:
1241 case SDLA_S507:
1242 case SDLA_S508:
1243 bootp = hw->dpmbase;
1244 break;
1246 default:
1247 return -EINVAL;
1250 err = sdla_mapmem(hw, 0);
1251 if (err) return err;
1253 *bootp = 0xC3; /* Z80: 'jp' opcode */
1254 bootp++;
1255 *((unsigned short*)(bootp)) = addr;
1257 switch (hw->type)
1259 case SDLA_S502A:
1260 _OUTB(port, 0x10); /* issue NMI to CPU */
1261 hw->regs[0] = 0x10;
1262 break;
1264 case SDLA_S502E:
1265 _OUTB(port + 3, 0x01); /* start CPU */
1266 hw->regs[3] = 0x01;
1267 for (i = 0; i < SDLA_IODELAY; ++i);
1268 if (_INB(port) & 0x01) /* verify */
1271 * Enabling CPU changes functionality of the
1272 * control register, so we have to reset its
1273 * mirror.
1275 _OUTB(port, 0); /* disable interrupts */
1276 hw->regs[0] = 0;
1278 else return -EIO;
1279 break;
1281 case SDLA_S503:
1282 tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */
1283 _OUTB(port, tmp);
1284 hw->regs[0] = tmp; /* update mirror */
1285 for (i = 0; i < SDLA_IODELAY; ++i);
1286 if (!(_INB(port) & 0x01)) /* verify */
1287 return -EIO
1289 break;
1291 case SDLA_S507:
1292 tmp = hw->regs[0] | 0x02;
1293 _OUTB(port, tmp);
1294 hw->regs[0] = tmp; /* update mirror */
1295 for (i = 0; i < SDLA_IODELAY; ++i);
1296 if (!(_INB(port) & 0x04)) /* verify */
1297 return -EIO
1299 break;
1301 case SDLA_S508:
1302 tmp = hw->regs[0] | 0x02;
1303 _OUTB(port, tmp);
1304 hw->regs[0] = tmp; /* update mirror */
1305 for (i = 0; i < SDLA_IODELAY; ++i);
1306 if (!(_INB(port + 1) & 0x02)) /* verify */
1307 return -EIO
1309 break;
1311 default:
1312 return -EINVAL;
1314 return 0;
1317 /*============================================================================
1318 * Initialize S502A adapter.
1320 static int init_s502a (sdlahw_t* hw)
1322 unsigned port = hw->port;
1323 int tmp, i;
1325 if (!detect_s502a(port))
1326 return -ENODEV
1328 hw->regs[0] = 0x08;
1329 hw->regs[1] = 0xFF;
1331 /* Verify configuration options */
1332 i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1333 if (i == 0)
1334 return -EINVAL
1337 tmp = s502a_hmcr[i - 1];
1338 switch (hw->dpmsize)
1340 case 0x2000:
1341 tmp |= 0x01;
1342 break;
1344 case 0x10000L:
1345 break;
1347 default:
1348 return -EINVAL;
1351 /* Setup dual-port memory window (this also enables memory access) */
1352 _OUTB(port + 1, tmp);
1353 hw->regs[1] = tmp;
1354 hw->regs[0] = 0x08;
1355 return 0;
1358 /*============================================================================
1359 * Initialize S502E adapter.
1361 static int init_s502e (sdlahw_t* hw)
1363 unsigned port = hw->port;
1364 int tmp, i;
1366 if (!detect_s502e(port))
1367 return -ENODEV
1370 /* Verify configuration options */
1371 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1372 if (i == 0)
1373 return -EINVAL
1376 tmp = s502e_hmcr[i - 1];
1377 switch (hw->dpmsize)
1379 case 0x2000:
1380 tmp |= 0x01;
1381 break;
1383 case 0x10000L:
1384 break;
1386 default:
1387 return -EINVAL;
1390 /* Setup dual-port memory window */
1391 _OUTB(port + 1, tmp);
1392 hw->regs[1] = tmp;
1394 /* Enable memory access */
1395 _OUTB(port, 0x02);
1396 hw->regs[0] = 0x02;
1397 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1398 return (_INB(port) & 0x02) ? 0 : -EIO;
1401 /*============================================================================
1402 * Initialize S503 adapter.
1403 * ---------------------------------------------------------------------------
1405 static int init_s503 (sdlahw_t* hw)
1407 unsigned port = hw->port;
1408 int tmp, i;
1410 if (!detect_s503(port))
1411 return -ENODEV
1414 /* Verify configuration options */
1415 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1416 if (i == 0)
1417 return -EINVAL
1420 tmp = s502e_hmcr[i - 1];
1421 switch (hw->dpmsize)
1423 case 0x2000:
1424 tmp |= 0x01;
1425 break;
1427 case 0x10000L:
1428 break;
1430 default:
1431 return -EINVAL;
1434 /* Setup dual-port memory window */
1435 _OUTB(port + 1, tmp);
1436 hw->regs[1] = tmp;
1438 /* Enable memory access */
1439 _OUTB(port, 0x02);
1440 hw->regs[0] = 0x02; /* update mirror */
1441 return 0;
1444 /*============================================================================
1445 * Initialize S507 adapter.
1447 static int init_s507 (sdlahw_t* hw)
1449 unsigned port = hw->port;
1450 int tmp, i;
1452 if (!detect_s507(port))
1453 return -ENODEV
1456 /* Verify configuration options */
1457 i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1458 if (i == 0)
1459 return -EINVAL
1462 tmp = s507_hmcr[i - 1];
1463 switch (hw->dpmsize)
1465 case 0x2000:
1466 tmp |= 0x01;
1467 break;
1469 case 0x10000L:
1470 break;
1472 default:
1473 return -EINVAL;
1476 /* Enable adapter's logic */
1477 _OUTB(port, 0x01);
1478 hw->regs[0] = 0x01;
1479 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1480 if (!(_INB(port) & 0x20))
1481 return -EIO
1484 /* Setup dual-port memory window */
1485 _OUTB(port + 1, tmp);
1486 hw->regs[1] = tmp;
1488 /* Enable memory access */
1489 tmp = hw->regs[0] | 0x04;
1490 if (hw->irq)
1492 i = get_option_index(s508_irq_options, hw->irq);
1493 if (i) tmp |= s507_irqmask[i - 1];
1495 _OUTB(port, tmp);
1496 hw->regs[0] = tmp; /* update mirror */
1497 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1498 return (_INB(port) & 0x08) ? 0 : -EIO;
1501 /*============================================================================
1502 * Initialize S508 adapter.
1504 static int init_s508 (sdlahw_t* hw)
1506 unsigned port = hw->port;
1507 int tmp, i;
1509 if (!detect_s508(port))
1510 return -ENODEV
1513 /* Verify configuration options */
1514 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1515 if (i == 0)
1516 return -EINVAL
1519 /* Setup memory configuration */
1520 tmp = s508_hmcr[i - 1];
1521 _OUTB(port + 1, tmp);
1522 hw->regs[1] = tmp;
1524 /* Enable memory access */
1525 _OUTB(port, 0x04);
1526 hw->regs[0] = 0x04; /* update mirror */
1527 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1528 return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1531 /*============================================================================
1532 * Detect S502A adapter.
1533 * Following tests are used to detect S502A adapter:
1534 * 1. All registers other than status (BASE) should read 0xFF
1535 * 2. After writing 00001000b to control register, status register should
1536 * read 01000000b.
1537 * 3. After writing 0 to control register, status register should still
1538 * read 01000000b.
1539 * 4. After writing 00000100b to control register, status register should
1540 * read 01000100b.
1541 * Return 1 if detected o.k. or 0 if failed.
1542 * Note: This test is destructive! Adapter will be left in shutdown
1543 * state after the test.
1545 static int detect_s502a (int port)
1547 int i, j;
1549 if (!get_option_index(s502_port_options, port))
1550 return 0
1552 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1554 if (_INB(port + j) != 0xFF)
1555 return 0
1557 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1560 _OUTB(port, 0x08); /* halt CPU */
1561 _OUTB(port, 0x08);
1562 _OUTB(port, 0x08);
1563 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1564 if (_INB(port) != 0x40)
1565 return 0
1567 _OUTB(port, 0x00);
1568 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1569 if (_INB(port) != 0x40)
1570 return 0
1572 _OUTB(port, 0x04);
1573 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1574 if (_INB(port) != 0x44)
1575 return 0
1578 /* Reset adapter */
1579 _OUTB(port, 0x08);
1580 _OUTB(port, 0x08);
1581 _OUTB(port, 0x08);
1582 _OUTB(port + 1, 0xFF);
1583 return 1;
1586 /*============================================================================
1587 * Detect S502E adapter.
1588 * Following tests are used to verify adapter presence:
1589 * 1. All registers other than status (BASE) should read 0xFF.
1590 * 2. After writing 0 to CPU control register (BASE+3), status register
1591 * (BASE) should read 11111000b.
1592 * 3. After writing 00000100b to port BASE (set bit 2), status register
1593 * (BASE) should read 11111100b.
1594 * Return 1 if detected o.k. or 0 if failed.
1595 * Note: This test is destructive! Adapter will be left in shutdown
1596 * state after the test.
1598 static int detect_s502e (int port)
1600 int i, j;
1602 if (!get_option_index(s502_port_options, port))
1603 return 0
1605 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1607 if (_INB(port + j) != 0xFF)
1608 return 0
1610 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1613 _OUTB(port + 3, 0); /* CPU control reg. */
1614 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1615 if (_INB(port) != 0xF8) /* read status */
1616 return 0
1618 _OUTB(port, 0x04); /* set bit 2 */
1619 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1620 if (_INB(port) != 0xFC) /* verify */
1621 return 0
1624 /* Reset adapter */
1625 _OUTB(port, 0);
1626 return 1;
1629 /*============================================================================
1630 * Detect s503 adapter.
1631 * Following tests are used to verify adapter presence:
1632 * 1. All registers other than status (BASE) should read 0xFF.
1633 * 2. After writing 0 to control register (BASE), status register (BASE)
1634 * should read 11110000b.
1635 * 3. After writing 00000100b (set bit 2) to control register (BASE),
1636 * status register should read 11110010b.
1637 * Return 1 if detected o.k. or 0 if failed.
1638 * Note: This test is destructive! Adapter will be left in shutdown
1639 * state after the test.
1641 static int detect_s503 (int port)
1643 int i, j;
1645 if (!get_option_index(s503_port_options, port))
1646 return 0
1648 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1650 if (_INB(port + j) != 0xFF)
1651 return 0
1653 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1656 _OUTB(port, 0); /* reset control reg.*/
1657 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1658 if (_INB(port) != 0xF0) /* read status */
1659 return 0
1661 _OUTB(port, 0x04); /* set bit 2 */
1662 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1663 if (_INB(port) != 0xF2) /* verify */
1664 return 0
1667 /* Reset adapter */
1668 _OUTB(port, 0);
1669 return 1;
1672 /*============================================================================
1673 * Detect s507 adapter.
1674 * Following tests are used to detect s507 adapter:
1675 * 1. All ports should read the same value.
1676 * 2. After writing 0x00 to control register, status register should read
1677 * ?011000?b.
1678 * 3. After writing 0x01 to control register, status register should read
1679 * ?011001?b.
1680 * Return 1 if detected o.k. or 0 if failed.
1681 * Note: This test is destructive! Adapter will be left in shutdown
1682 * state after the test.
1684 static int detect_s507 (int port)
1686 int tmp, i, j;
1688 if (!get_option_index(s508_port_options, port))
1689 return 0
1691 tmp = _INB(port);
1692 for (j = 1; j < S507_IORANGE; ++j)
1694 if (_INB(port + j) != tmp)
1695 return 0
1697 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1700 _OUTB(port, 0x00);
1701 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1702 if ((_INB(port) & 0x7E) != 0x30)
1703 return 0
1705 _OUTB(port, 0x01);
1706 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1707 if ((_INB(port) & 0x7E) != 0x32)
1708 return 0
1711 /* Reset adapter */
1712 _OUTB(port, 0x00);
1713 return 1;
1716 /*============================================================================
1717 * Detect s508 adapter.
1718 * Following tests are used to detect s508 adapter:
1719 * 1. After writing 0x00 to control register, status register should read
1720 * ??000000b.
1721 * 2. After writing 0x10 to control register, status register should read
1722 * ??010000b
1723 * Return 1 if detected o.k. or 0 if failed.
1724 * Note: This test is destructive! Adapter will be left in shutdown
1725 * state after the test.
1727 static int detect_s508 (int port)
1729 int i;
1731 if (!get_option_index(s508_port_options, port))
1732 return 0
1734 _OUTB(port, 0x00);
1735 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1736 if ((_INB(port + 1) & 0x3F) != 0x00)
1737 return 0
1739 _OUTB(port, 0x10);
1740 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1741 if ((_INB(port + 1) & 0x3F) != 0x10)
1742 return 0
1745 /* Reset adapter */
1746 _OUTB(port, 0x00);
1747 return 1;
1750 /******* Miscellaneous ******************************************************/
1752 /*============================================================================
1753 * Calibrate SDLA memory access delay.
1754 * Count number of idle loops made within 1 second and then calculate the
1755 * number of loops that should be made to achive desired delay.
1757 static int calibrate_delay (int mks)
1759 unsigned int delay;
1760 unsigned long stop;
1762 for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
1763 return (delay/(1000000L/mks) + 1);
1766 /*============================================================================
1767 * Get option's index into the options list.
1768 * Return option's index (1 .. N) or zero if option is invalid.
1770 static int get_option_index (unsigned* optlist, unsigned optval)
1772 int i;
1774 for (i = 1; i <= optlist[0]; ++i)
1775 if ( optlist[i] == optval) return i
1777 return 0;
1780 /*============================================================================
1781 * Check memory region to see if it's available.
1782 * Return: 0 ok.
1784 static unsigned check_memregion (void* ptr, unsigned len)
1786 volatile unsigned char* p = ptr;
1788 for (; len && (*p == 0xFF); --len, ++p)
1790 *p = 0; /* attempt to write 0 */
1791 if (*p != 0xFF) /* still has to read 0xFF */
1793 *p = 0xFF; /* restore original value */
1794 break; /* not good */
1797 return len;
1800 /*============================================================================
1801 * Test memory region.
1802 * Return: size of the region that passed the test.
1803 * Note: Region size must be multiple of 2 !
1805 static unsigned test_memregion (void* ptr, unsigned len)
1807 volatile unsigned short* w_ptr;
1808 unsigned len_w = len >> 1; /* region len in words */
1809 unsigned i;
1811 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1812 *w_ptr = 0xAA55
1814 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1815 if (*w_ptr != 0xAA55)
1817 len_w = i;
1818 break;
1821 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1822 *w_ptr = 0x55AA
1824 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1825 if (*w_ptr != 0x55AA)
1827 len_w = i;
1828 break;
1831 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) *w_ptr = 0;
1832 return len_w << 1;
1835 /*============================================================================
1836 * Calculate 16-bit CRC using CCITT polynomial.
1838 static unsigned short checksum (unsigned char* buf, unsigned len)
1840 unsigned short crc = 0;
1841 unsigned mask, flag;
1843 for (; len; --len, ++buf)
1845 for (mask = 0x80; mask; mask >>= 1)
1847 flag = (crc & 0x8000);
1848 crc <<= 1;
1849 crc |= ((*buf & mask) ? 1 : 0);
1850 if (flag) crc ^= 0x1021;
1853 return crc;
1857 /****** End *****************************************************************/