Import 2.3.18pre1
[davej-history.git] / drivers / net / sdladrv.c
blob7182dff425d122af52b117afc26114d8845c5957
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>
9 * Copyright: (c) 1995-1996 Sangoma Technologies Inc.
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 * May 19, 1999 Arnaldo Melo wanpipe_init belongs to sdlamain.c
17 * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
18 * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
19 * Jun 12, 1996 Gene Kozin Added support for S503 card.
20 * Apr 30, 1996 Gene Kozin SDLA hardware interrupt is acknowledged before
21 * calling protocolspecific ISR.
22 * Register I/O ports with Linux kernel.
23 * Miscellaneous bug fixes.
24 * Dec 20, 1995 Gene Kozin Fixed a bug in interrupt routine.
25 * Oct 14, 1995 Gene Kozin Initial version.
26 *****************************************************************************/
28 /*****************************************************************************
29 * Notes:
30 * ------
31 * 1. This code is ment to be system-independent (as much as possible). To
32 * achive this, various macros are used to hide system-specific interfaces.
33 * To compile this code, one of the following constants must be defined:
35 * Platform Define
36 * -------- ------
37 * Linux _LINUX_
38 * SCO Unix _SCO_UNIX_
40 * 2. Supported adapter types:
42 * S502A
43 * ES502A (S502E)
44 * S503
45 * S507
46 * S508 (S509)
48 * 3. S502A Notes:
50 * There is no separate DPM window enable/disable control in S502A. It
51 * opens immediately after a window number it written to the HMCR
52 * register. To close the window, HMCR has to be written a value
53 * ????1111b (e.g. 0x0F or 0xFF).
55 * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
57 * There should be a delay of ??? before reading back S502A status
58 * register.
60 * 4. S502E Notes:
62 * S502E has a h/w bug: although default IRQ line state is HIGH, enabling
63 * interrupts by setting bit 1 of the control register (BASE) to '1'
64 * causes it to go LOW! Therefore, disabling interrupts by setting that
65 * bit to '0' causes low-to-high transition on IRQ line (ghosty
66 * interrupt). The same occurs when disabling CPU by resetting bit 0 of
67 * CPU control register (BASE+3) - see the next note.
69 * S502E CPU and DPM control is limited:
71 * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
72 * control register (BASE+3) shuts the board down entirely, including
73 * DPM;
75 * o DPM access cannot be controlled dynamically. Ones CPU is started,
76 * bit 1 of the control register (BASE) is used to enable/disable IRQ,
77 * so that access to shared memory cannot be disabled while CPU is
78 * running.
79 ****************************************************************************/
81 #define _LINUX_
83 #if defined(_LINUX_) /****** Linux *******************************/
85 #include <linux/kernel.h> /* printk(), and other useful stuff */
86 #include <linux/stddef.h> /* offsetof(), etc. */
87 #include <linux/errno.h> /* return codes */
88 #include <linux/string.h> /* inline memset(), etc. */
89 #include <linux/module.h> /* support for loadable modules */
90 #include <linux/sched.h> /* for jiffies, HZ, etc. */
91 #include <linux/sdladrv.h> /* API definitions */
92 #include <linux/sdlasfm.h> /* SDLA firmware module definitions */
93 #include <asm/io.h> /* for inb(), outb(), etc. */
94 #define _INB(port) (inb(port))
95 #define _OUTB(port, byte) (outb((byte),(port)))
96 #define SYSTEM_TICK jiffies
98 #elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
99 #if !defined(INKERNEL)
100 #error This code MUST be compiled in kernel mode!
101 #endif
102 #include <sys/sdladrv.h> /* API definitions */
103 #include <sys/sdlasfm.h> /* SDLA firmware module definitions */
104 #include <sys/inline.h> /* for inb(), outb(), etc. */
105 #define _INB(port) (inb(port))
106 #define _OUTB(port, byte) (outb((port),(byte)))
107 #define SYSTEM_TICK lbolt
109 #else
110 #error Unknown system type!
111 #endif
113 #define MOD_VERSION 3
114 #define MOD_RELEASE 0
116 #define SDLA_IODELAY 100 /* I/O Rd/Wr delay, 10 works for 486DX2-66 */
117 #define EXEC_DELAY 20 /* shared memory access delay, mks */
118 #define EXEC_TIMEOUT (HZ*2) /* command timeout, in ticks */
120 /* I/O port address range */
121 #define S502A_IORANGE 3
122 #define S502E_IORANGE 4
123 #define S503_IORANGE 3
124 #define S507_IORANGE 4
125 #define S508_IORANGE 4
127 /* Maximum amount of memory */
128 #define S502_MAXMEM 0x10000L
129 #define S503_MAXMEM 0x10000L
130 #define S507_MAXMEM 0x40000L
131 #define S508_MAXMEM 0x40000L
133 /* Minimum amount of memory */
134 #define S502_MINMEM 0x8000L
135 #define S503_MINMEM 0x8000L
136 #define S507_MINMEM 0x20000L
137 #define S508_MINMEM 0x20000L
139 /****** Function Prototypes *************************************************/
141 /* Module entry points. These are called by the OS and must be public. */
142 int init_module (void);
143 void cleanup_module (void);
145 /* Hardware-specific functions */
146 static int sdla_detect (sdlahw_t* hw);
147 static int sdla_autodpm (sdlahw_t* hw);
148 static int sdla_setdpm (sdlahw_t* hw);
149 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);
150 static int sdla_init (sdlahw_t* hw);
151 static unsigned long sdla_memtest (sdlahw_t* hw);
152 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
153 static unsigned char make_config_byte (sdlahw_t* hw);
154 static int sdla_start (sdlahw_t* hw, unsigned addr);
156 static int init_s502a (sdlahw_t* hw);
157 static int init_s502e (sdlahw_t* hw);
158 static int init_s503 (sdlahw_t* hw);
159 static int init_s507 (sdlahw_t* hw);
160 static int init_s508 (sdlahw_t* hw);
162 static int detect_s502a (int port);
163 static int detect_s502e (int port);
164 static int detect_s503 (int port);
165 static int detect_s507 (int port);
166 static int detect_s508 (int port);
168 /* Miscellaneous functions */
169 static int calibrate_delay (int mks);
170 static int get_option_index (unsigned* optlist, unsigned optval);
171 static unsigned check_memregion (void* ptr, unsigned len);
172 static unsigned test_memregion (void* ptr, unsigned len);
173 static unsigned short checksum (unsigned char* buf, unsigned len);
175 /****** Global Data **********************************************************
176 * Note: All data must be explicitly initialized!!!
179 /* private data */
180 static char modname[] = "sdladrv";
181 static char fullname[] = "SDLA Support Module";
182 static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc.";
183 static unsigned exec_idle;
185 /* Hardware configuration options.
186 * These are arrays of configuration options used by verification routines.
187 * The first element of each array is its size (i.e. number of options).
189 static unsigned s502_port_options[] =
190 { 4, 0x250, 0x300, 0x350, 0x360 }
192 static unsigned s503_port_options[] =
193 { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
195 static unsigned s508_port_options[] =
196 { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
199 static unsigned s502a_irq_options[] = { 0 };
200 static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
201 static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 };
202 static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
204 static unsigned s502a_dpmbase_options[] =
207 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
208 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
209 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
210 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
212 static unsigned s507_dpmbase_options[] =
215 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
216 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
217 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
218 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
220 static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */
223 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
224 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
225 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
226 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
230 static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
231 static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
232 static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
235 static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
236 static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
237 static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 };
238 static unsigned s507_pclk_options[] = { 1, 12288 };
239 static unsigned s508_pclk_options[] = { 1, 16000 };
241 /* Host memory control register masks */
242 static unsigned char s502a_hmcr[] =
244 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, /* A0000 - AC000 */
245 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, /* C0000 - CC000 */
246 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, /* D0000 - DC000 */
247 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, /* E0000 - EC000 */
249 static unsigned char s502e_hmcr[] =
251 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */
252 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */
253 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */
254 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */
256 static unsigned char s507_hmcr[] =
258 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */
259 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */
260 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */
261 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */
263 static unsigned char s508_hmcr[] =
265 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */
266 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */
267 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */
268 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */
271 static unsigned char s507_irqmask[] =
273 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
276 /******* Kernel Loadable Module Entry Points ********************************/
278 /*============================================================================
279 * Module 'insert' entry point.
280 * o print announcement
281 * o initialize static data
282 * o calibrate SDLA shared memory access delay.
284 * Return: 0 Ok
285 * < 0 error.
286 * Context: process
289 #ifdef MODULE
290 int init_module (void)
292 printk(KERN_INFO "%s v%u.%u %s\n",
293 fullname, MOD_VERSION, MOD_RELEASE, copyright);
294 exec_idle = calibrate_delay(EXEC_DELAY);
295 #ifdef WANDEBUG
296 printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
297 #endif
298 return 0;
301 /*============================================================================
302 * Module 'remove' entry point.
303 * o release all remaining system resources
305 void cleanup_module (void)
308 #endif
310 /******* Kernel APIs ********************************************************/
312 /*============================================================================
313 * Set up adapter.
314 * o detect adapter type
315 * o verify hardware configuration options
316 * o check for hardware conflicts
317 * o set up adapter shared memory
318 * o test adapter memory
319 * o load firmware
320 * Return: 0 ok.
321 * < 0 error
324 EXPORT_SYMBOL(sdla_setup);
326 int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
328 unsigned* irq_opt = NULL; /* IRQ options */
329 unsigned* dpmbase_opt = NULL; /* DPM window base options */
330 unsigned* pclk_opt = NULL; /* CPU clock rate options */
331 int err;
333 if (sdla_detect(hw))
335 printk(KERN_ERR "%s: adapter S%04u not found at port 0x%X!\n",
336 modname, hw->type, hw->port)
338 return -EINVAL;
340 printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
341 modname, hw->type, hw->port)
344 hw->dpmsize = SDLA_WINDOWSIZE;
345 switch (hw->type)
347 case SDLA_S502A:
348 hw->io_range = S502A_IORANGE;
349 irq_opt = s502a_irq_options;
350 dpmbase_opt = s502a_dpmbase_options;
351 pclk_opt = s502a_pclk_options;
352 break;
354 case SDLA_S502E:
355 hw->io_range = S502E_IORANGE;
356 irq_opt = s502e_irq_options;
357 dpmbase_opt = s508_dpmbase_options;
358 pclk_opt = s502e_pclk_options;
359 break;
361 case SDLA_S503:
362 hw->io_range = S503_IORANGE;
363 irq_opt = s503_irq_options;
364 dpmbase_opt = s508_dpmbase_options;
365 pclk_opt = s503_pclk_options;
366 break;
368 case SDLA_S507:
369 hw->io_range = S507_IORANGE;
370 irq_opt = s508_irq_options;
371 dpmbase_opt = s507_dpmbase_options;
372 pclk_opt = s507_pclk_options;
373 break;
375 case SDLA_S508:
376 hw->io_range = S508_IORANGE;
377 irq_opt = s508_irq_options;
378 dpmbase_opt = s508_dpmbase_options;
379 pclk_opt = s508_pclk_options;
380 break;
383 /* Verify IRQ configuration options */
384 if (!get_option_index(irq_opt, hw->irq))
386 printk(KERN_ERR "%s: IRQ %d is illegal!\n",
387 modname, hw->irq)
389 return -EINVAL;
392 /* Verify CPU clock rate configuration options */
393 if (hw->pclk == 0)
394 hw->pclk = pclk_opt[1] /* use default */
396 else if (!get_option_index(pclk_opt, hw->pclk))
398 printk(KERN_ERR "%s: CPU clock %u is illegal!\n",
399 modname, hw->pclk)
401 return -EINVAL;
403 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
404 modname, hw->pclk)
407 /* Setup adapter dual-port memory window and test memory */
408 if (hw->dpmbase == 0)
410 err = sdla_autodpm(hw);
411 if (err)
413 printk(KERN_ERR
414 "%s: can't find available memory region!\n",
415 modname)
417 return err;
420 else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase)))
422 printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n",
423 modname, virt_to_phys(hw->dpmbase))
425 return -EINVAL;
427 else if (sdla_setdpm(hw))
429 printk(KERN_ERR
430 "%s: 8K memory region at 0x%lX is not available!\n",
431 modname, virt_to_phys(hw->dpmbase));
432 return -EINVAL;
434 printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n",
435 modname, virt_to_phys(hw->dpmbase));
437 printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n",
438 modname, hw->memory / 1024);
440 /* Load firmware. If loader fails then shut down adapter */
441 err = sdla_load(hw, sfm, len);
442 if (err) sdla_down(hw); /* shutdown adapter */
443 return err;
446 /*============================================================================
447 * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
450 EXPORT_SYMBOL(sdla_down);
452 int sdla_down (sdlahw_t* hw)
454 unsigned port = hw->port;
455 int i;
457 if (!port) return -EFAULT;
459 switch (hw->type)
461 case SDLA_S502A:
462 _OUTB(port, 0x08); /* halt CPU */
463 _OUTB(port, 0x08);
464 _OUTB(port, 0x08);
465 hw->regs[0] = 0x08;
466 _OUTB(port + 1, 0xFF); /* close memory window */
467 hw->regs[1] = 0xFF;
468 break;
470 case SDLA_S502E:
471 _OUTB(port + 3, 0); /* stop CPU */
472 _OUTB(port, 0); /* reset board */
473 for (i = 0; i < S502E_IORANGE; ++i)
474 hw->regs[i] = 0
476 break;
478 case SDLA_S503:
479 case SDLA_S507:
480 case SDLA_S508:
481 _OUTB(port, 0); /* reset board logic */
482 hw->regs[0] = 0;
483 break;
485 default:
486 return -EINVAL;
488 return 0;
491 /*============================================================================
492 * Map shared memory window into SDLA address space.
495 EXPORT_SYMBOL(sdla_mapmem);
497 int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
499 unsigned port = hw->port;
500 register int tmp;
502 switch (hw->type)
504 case SDLA_S502A:
505 case SDLA_S502E:
506 if (addr < S502_MAXMEM) /* verify parameter */
508 tmp = addr >> 13; /* convert to register mask */
509 _OUTB(port + 2, tmp);
510 hw->regs[2] = tmp;
512 else return -EINVAL;
513 break;
515 case SDLA_S503:
516 if (addr < S503_MAXMEM) /* verify parameter */
518 tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
519 _OUTB(port, tmp);
520 hw->regs[0] = tmp;
522 else return -EINVAL;
523 break;
525 case SDLA_S507:
526 if (addr < S507_MAXMEM)
528 if (!(_INB(port) & 0x02))
529 return -EIO
531 tmp = addr >> 13; /* convert to register mask */
532 _OUTB(port + 2, tmp);
533 hw->regs[2] = tmp;
535 else return -EINVAL;
536 break;
538 case SDLA_S508:
539 if (addr < S508_MAXMEM)
541 tmp = addr >> 13; /* convert to register mask */
542 _OUTB(port + 2, tmp);
543 hw->regs[2] = tmp;
545 else return -EINVAL;
546 break;
548 default:
549 return -EINVAL;
551 hw->vector = addr & 0xFFFFE000L;
552 return 0;
555 /*============================================================================
556 * Enable interrupt generation.
559 EXPORT_SYMBOL(sdla_inten);
561 int sdla_inten (sdlahw_t* hw)
563 unsigned port = hw->port;
564 int tmp, i;
566 switch (hw->type)
568 case SDLA_S502E:
569 /* Note thar interrupt control operations on S502E are allowed
570 * only if CPU is enabled (bit 0 of status register is set).
572 if (_INB(port) & 0x01)
574 _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
575 _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
576 hw->regs[0] = 0x06;
578 else return -EIO;
579 break;
581 case SDLA_S503:
582 tmp = hw->regs[0] | 0x04;
583 _OUTB(port, tmp);
584 hw->regs[0] = tmp; /* update mirror */
585 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
586 if (!(_INB(port) & 0x02)) /* verify */
587 return -EIO
589 break;
591 case SDLA_S508:
592 tmp = hw->regs[0] | 0x10;
593 _OUTB(port, tmp);
594 hw->regs[0] = tmp; /* update mirror */
595 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
596 if (!(_INB(port + 1) & 0x10)) /* verify */
597 return -EIO
599 break;
601 case SDLA_S502A:
602 case SDLA_S507:
603 break;
605 default:
606 return -EINVAL;
609 return 0;
612 /*============================================================================
613 * Disable interrupt generation.
616 EXPORT_SYMBOL(sdla_intde);
618 int sdla_intde (sdlahw_t* hw)
620 unsigned port = hw->port;
621 int tmp, i;
623 switch (hw->type)
625 case SDLA_S502E:
626 /* Notes:
627 * 1) interrupt control operations are allowed only if CPU is
628 * enabled (bit 0 of status register is set).
629 * 2) disabling interrupts using bit 1 of control register
630 * causes IRQ line go high, therefore we are going to use
631 * 0x04 instead: lower it to inhibit interrupts to PC.
633 if (_INB(port) & 0x01)
635 _OUTB(port, hw->regs[0] & ~0x04);
636 hw->regs[0] &= ~0x04;
638 else return -EIO;
639 break;
641 case SDLA_S503:
642 tmp = hw->regs[0] & ~0x04;
643 _OUTB(port, tmp);
644 hw->regs[0] = tmp; /* update mirror */
645 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
646 if (_INB(port) & 0x02) /* verify */
647 return -EIO
649 break;
651 case SDLA_S508:
652 tmp = hw->regs[0] & ~0x10;
653 _OUTB(port, tmp);
654 hw->regs[0] = tmp; /* update mirror */
655 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
656 if (_INB(port) & 0x10) /* verify */
657 return -EIO
659 break;
661 case SDLA_S502A:
662 case SDLA_S507:
663 break;
665 default:
666 return -EINVAL;
668 return 0;
671 /*============================================================================
672 * Acknowledge SDLA hardware interrupt.
675 EXPORT_SYMBOL(sdla_intack);
677 int sdla_intack (sdlahw_t* hw)
679 unsigned port = hw->port;
680 int tmp;
682 switch (hw->type)
684 case SDLA_S502E:
685 /* To acknoledge hardware interrupt we have to toggle bit 3 of
686 * control register: \_/
687 * Note that interrupt control operations on S502E are allowed
688 * only if CPU is enabled (bit 1 of status register is set).
690 if (_INB(port) & 0x01)
692 tmp = hw->regs[0] & ~0x04;
693 _OUTB(port, tmp);
694 tmp |= 0x04;
695 _OUTB(port, tmp);
696 hw->regs[0] = tmp;
698 else return -EIO;
699 break;
701 case SDLA_S503:
702 if (_INB(port) & 0x04)
704 tmp = hw->regs[0] & ~0x08;
705 _OUTB(port, tmp);
706 tmp |= 0x08;
707 _OUTB(port, tmp);
708 hw->regs[0] = tmp;
710 break;
712 case SDLA_S502A:
713 case SDLA_S507:
714 case SDLA_S508:
715 break;
717 default:
718 return -EINVAL;
720 return 0;
723 /*============================================================================
724 * Generate an interrupt to adapter's CPU.
727 EXPORT_SYMBOL(sdla_intr);
729 int sdla_intr (sdlahw_t* hw)
731 unsigned port = hw->port;
733 switch (hw->type)
735 case SDLA_S502A:
736 if (!(_INB(port) & 0x40))
738 _OUTB(port, 0x10); /* issue NMI to CPU */
739 hw->regs[0] = 0x10;
741 else return -EIO;
742 break;
744 case SDLA_S507:
745 if ((_INB(port) & 0x06) == 0x06)
747 _OUTB(port + 3, 0);
749 else return -EIO;
750 break;
752 case SDLA_S508:
753 if (_INB(port + 1) & 0x02)
755 _OUTB(port, 0x08);
757 else return -EIO;
758 break;
760 case SDLA_S502E:
761 case SDLA_S503:
762 default:
763 return -EINVAL;
765 return 0;
768 /*============================================================================
769 * Execute Adapter Command.
770 * o Set exec flag.
771 * o Busy-wait until flag is reset.
772 * o Return number of loops made, or 0 if command timed out.
775 EXPORT_SYMBOL(sdla_exec);
777 int sdla_exec (void* opflag)
779 volatile unsigned char* flag = opflag;
780 unsigned long tstop;
781 int nloops;
783 if (*flag) return 0; /* ???? */
785 *flag = 1;
786 tstop = SYSTEM_TICK + EXEC_TIMEOUT;
787 for (nloops = 1; *flag; ++nloops)
789 unsigned delay = exec_idle;
790 while (--delay); /* delay */
791 if (SYSTEM_TICK > tstop) return 0; /* time is up! */
793 return nloops;
796 /*============================================================================
797 * Read absolute adapter memory.
798 * Transfer data from adapter's memory to data buffer.
800 * Note:
801 * Care should be taken when crossing dual-port memory window boundary.
802 * This function is not atomic, so caller must disable interrupt if
803 * interrupt routines are accessing adapter shared memory.
806 EXPORT_SYMBOL(sdla_peek);
808 int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
810 unsigned long oldvec = hw->vector;
811 unsigned winsize = hw->dpmsize;
812 unsigned curpos, curlen; /* current offset and block size */
813 unsigned long curvec; /* current DPM window vector */
814 int err = 0;
816 if (addr + len > hw->memory) /* verify arguments */
817 return -EINVAL
819 while (len && !err)
821 curpos = addr % winsize; /* current window offset */
822 curvec = addr - curpos; /* current window vector */
823 curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
825 /* Relocate window and copy block of data */
826 err = sdla_mapmem(hw, curvec);
827 memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen);
828 addr += curlen;
829 (char*)buf += curlen;
830 len -= curlen;
833 /* Restore DPM window position */
834 sdla_mapmem(hw, oldvec);
835 return err;
838 /*============================================================================
839 * Write Absolute Adapter Memory.
840 * Transfer data from data buffer to adapter's memory.
842 * Note:
843 * Care should be taken when crossing dual-port memory window boundary.
844 * This function is not atomic, so caller must disable interrupt if
845 * interrupt routines are accessing adapter shared memory.
848 EXPORT_SYMBOL(sdla_poke);
850 int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
852 unsigned long oldvec = hw->vector;
853 unsigned winsize = hw->dpmsize;
854 unsigned curpos, curlen; /* current offset and block size */
855 unsigned long curvec; /* current DPM window vector */
856 int err = 0;
858 if (addr + len > hw->memory) /* verify arguments */
859 return -EINVAL
861 while (len && !err)
863 curpos = addr % winsize; /* current window offset */
864 curvec = addr - curpos; /* current window vector */
865 curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
867 /* Relocate window and copy block of data */
868 sdla_mapmem(hw, curvec);
869 memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen);
870 addr += curlen;
871 (char*)buf += curlen;
872 len -= curlen;
875 /* Restore DPM window position */
876 sdla_mapmem(hw, oldvec);
877 return err;
880 #ifdef DONT_COMPIPLE_THIS
881 #endif /* DONT_COMPIPLE_THIS */
883 /****** Hardware-Specific Functions *****************************************/
885 /*============================================================================
886 * Detect adapter type.
887 * o if adapter type is specified then call detection routine for that adapter
888 * type. Otherwise call detection routines for every adapter types until
889 * adapter is detected.
891 * Notes:
892 * 1) Detection tests are destructive! Adapter will be left in shutdown state
893 * after the test.
895 static int sdla_detect (sdlahw_t* hw)
897 unsigned port = hw->port;
898 int err = 0;
900 if (!port)
901 return -EFAULT
903 switch (hw->type)
905 case SDLA_S502A:
906 if (!detect_s502a(port)) err = -ENODEV;
907 break;
909 case SDLA_S502E:
910 if (!detect_s502e(port)) err = -ENODEV;
911 break;
913 case SDLA_S503:
914 if (!detect_s503(port)) err = -ENODEV;
915 break;
917 case SDLA_S507:
918 if (!detect_s507(port)) err = -ENODEV;
919 break;
921 case SDLA_S508:
922 if (!detect_s508(port)) err = -ENODEV;
923 break;
925 default:
926 if (detect_s502a(port))
927 hw->type = SDLA_S502A
929 else if (detect_s502e(port))
930 hw->type = SDLA_S502E
932 else if (detect_s503(port))
933 hw->type = SDLA_S503
935 else if (detect_s507(port))
936 hw->type = SDLA_S507
938 else if (detect_s508(port))
939 hw->type = SDLA_S508
941 else err = -ENODEV;
943 return err;
946 /*============================================================================
947 * Autoselect memory region.
948 * o try all available DMP address options from the top down until success.
950 static int sdla_autodpm (sdlahw_t* hw)
952 int i, err = -EINVAL;
953 unsigned* opt;
955 switch (hw->type)
957 case SDLA_S502A:
958 opt = s502a_dpmbase_options;
959 break;
961 case SDLA_S502E:
962 case SDLA_S503:
963 case SDLA_S508:
964 opt = s508_dpmbase_options;
965 break;
967 case SDLA_S507:
968 opt = s507_dpmbase_options;
969 break;
971 default:
972 return -EINVAL;
975 for (i = opt[0]; i && err; --i)
977 hw->dpmbase = phys_to_virt(opt[i]);
978 err = sdla_setdpm(hw);
980 return err;
983 /*============================================================================
984 * Set up adapter dual-port memory window.
985 * o shut down adapter
986 * o make sure that no physical memory exists in this region, i.e entire
987 * region reads 0xFF and is not writable when adapter is shut down.
988 * o initialize adapter hardware
989 * o make sure that region is usable with SDLA card, i.e. we can write to it
990 * when adapter is configured.
992 static int sdla_setdpm (sdlahw_t* hw)
994 int err;
996 /* Shut down card and verify memory region */
997 sdla_down(hw);
998 if (check_memregion(hw->dpmbase, hw->dpmsize))
999 return -EINVAL
1002 /* Initialize adapter and test on-board memory segment by segment.
1003 * If memory size appears to be less than shared memory window size,
1004 * assume that memory region is unusable.
1006 err = sdla_init(hw);
1007 if (err) return err;
1009 if (sdla_memtest(hw) < hw->dpmsize) /* less than window size */
1011 sdla_down(hw);
1012 return -EIO;
1014 sdla_mapmem(hw, 0L); /* set window vector at bottom */
1015 return 0;
1018 /*============================================================================
1019 * Load adapter from the memory image of the SDLA firmware module.
1020 * o verify firmware integrity and compatibility
1021 * o start adapter up
1023 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1025 int i;
1027 /* Verify firmware signature */
1028 if (strcmp(sfm->signature, SFM_SIGNATURE))
1030 printk(KERN_ERR "%s: not SDLA firmware!\n",
1031 modname)
1033 return -EINVAL;
1036 /* Verify firmware module format version */
1037 if (sfm->version != SFM_VERSION)
1039 printk(KERN_ERR
1040 "%s: firmware format %u rejected! Expecting %u.\n",
1041 modname, sfm->version, SFM_VERSION)
1043 return -EINVAL;
1046 /* Verify firmware module length and checksum */
1047 if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
1048 (checksum((void*)&sfm->info,
1049 sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum))
1051 printk(KERN_ERR "%s: firmware corrupted!\n", modname);
1052 return -EINVAL;
1055 /* Announce */
1056 printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1057 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1058 sfm->info.codeid)
1061 /* Scan through the list of compatible adapters and make sure our
1062 * adapter type is listed.
1064 for (i = 0;
1065 (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1066 ++i)
1068 if (i == SFM_MAX_SDLA)
1070 printk(KERN_ERR "%s: firmware is not compatible with S%u!\n",
1071 modname, hw->type)
1073 return -EINVAL;
1076 /* Make sure there is enough on-board memory */
1077 if (hw->memory < sfm->info.memsize)
1079 printk(KERN_ERR
1080 "%s: firmware needs %lu bytes of on-board memory!\n",
1081 modname, sfm->info.memsize)
1083 return -EINVAL;
1086 /* Move code onto adapter */
1087 if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize))
1089 printk(KERN_ERR "%s: failed to load code segment!\n",
1090 modname)
1092 return -EIO;
1095 /* Prepare boot-time configuration data and kick-off CPU */
1096 sdla_bootcfg(hw, &sfm->info);
1097 if (sdla_start(hw, sfm->info.startoffs))
1099 printk(KERN_ERR "%s: Damn... Adapter won't start!\n",
1100 modname)
1102 return -EIO;
1105 /* position DPM window over the mailbox and enable interrupts */
1106 if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw))
1108 printk(KERN_ERR "%s: adapter hardware failure!\n",
1109 modname)
1111 return -EIO;
1113 hw->fwid = sfm->info.codeid; /* set firmware ID */
1114 return 0;
1117 /*============================================================================
1118 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1120 static int sdla_init (sdlahw_t* hw)
1122 int i;
1124 for (i = 0; i < SDLA_MAXIORANGE; ++i)
1125 hw->regs[i] = 0
1127 switch (hw->type)
1129 case SDLA_S502A: return init_s502a(hw);
1130 case SDLA_S502E: return init_s502e(hw);
1131 case SDLA_S503: return init_s503(hw);
1132 case SDLA_S507: return init_s507(hw);
1133 case SDLA_S508: return init_s508(hw);
1135 return -EINVAL;
1138 /*============================================================================
1139 * Test adapter on-board memory.
1140 * o slide DPM window from the bottom up and test adapter memory segment by
1141 * segment.
1142 * Return adapter memory size.
1144 static unsigned long sdla_memtest (sdlahw_t* hw)
1146 unsigned long memsize;
1147 unsigned winsize;
1149 for (memsize = 0, winsize = hw->dpmsize;
1150 !sdla_mapmem(hw, memsize) &&
1151 (test_memregion(hw->dpmbase, winsize) == winsize)
1153 memsize += winsize)
1155 hw->memory = memsize;
1156 return memsize;
1159 /*============================================================================
1160 * Prepare boot-time firmware configuration data.
1161 * o position DPM window
1162 * o initialize configuration data area
1164 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1166 unsigned char* data;
1168 if (!sfminfo->datasize) return 0; /* nothing to do */
1170 if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1171 return -EIO
1173 data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector));
1174 memset(data, 0, sfminfo->datasize);
1176 data[0x00] = make_config_byte(hw);
1177 switch (sfminfo->codeid)
1179 case SFID_X25_502:
1180 case SFID_X25_508:
1181 data[0x01] = 3; /* T1 timer */
1182 data[0x03] = 10; /* N2 */
1183 data[0x06] = 7; /* HDLC window size */
1184 data[0x0B] = 1; /* DTE */
1185 data[0x0C] = 2; /* X.25 packet window size */
1186 *(short*)&data[0x0D] = 128; /* default X.25 data size */
1187 *(short*)&data[0x0F] = 128; /* maximum X.25 data size */
1188 break;
1190 return 0;
1193 /*============================================================================
1194 * Prepare configuration byte identifying adapter type and CPU clock rate.
1196 static unsigned char make_config_byte (sdlahw_t* hw)
1198 unsigned char byte = 0;
1200 switch (hw->pclk)
1202 case 5000: byte = 0x01; break;
1203 case 7200: byte = 0x02; break;
1204 case 8000: byte = 0x03; break;
1205 case 10000: byte = 0x04; break;
1206 case 16000: byte = 0x05; break;
1208 switch (hw->type)
1210 case SDLA_S502E: byte |= 0x80; break;
1211 case SDLA_S503: byte |= 0x40; break;
1213 return byte;
1216 /*============================================================================
1217 * Start adapter's CPU.
1218 * o calculate a pointer to adapter's cold boot entry point
1219 * o position DPM window
1220 * o place boot instruction (jp addr) at cold boot entry point
1221 * o start CPU
1223 static int sdla_start (sdlahw_t* hw, unsigned addr)
1225 unsigned port = hw->port;
1226 unsigned char *bootp;
1227 int err, tmp, i;
1229 if (!port) return -EFAULT;
1231 switch (hw->type)
1233 case SDLA_S502A:
1234 bootp = hw->dpmbase;
1235 bootp += 0x66;
1236 break;
1238 case SDLA_S502E:
1239 case SDLA_S503:
1240 case SDLA_S507:
1241 case SDLA_S508:
1242 bootp = hw->dpmbase;
1243 break;
1245 default:
1246 return -EINVAL;
1249 err = sdla_mapmem(hw, 0);
1250 if (err) return err;
1252 *bootp = 0xC3; /* Z80: 'jp' opcode */
1253 bootp++;
1254 *((unsigned short*)(bootp)) = addr;
1256 switch (hw->type)
1258 case SDLA_S502A:
1259 _OUTB(port, 0x10); /* issue NMI to CPU */
1260 hw->regs[0] = 0x10;
1261 break;
1263 case SDLA_S502E:
1264 _OUTB(port + 3, 0x01); /* start CPU */
1265 hw->regs[3] = 0x01;
1266 for (i = 0; i < SDLA_IODELAY; ++i);
1267 if (_INB(port) & 0x01) /* verify */
1270 * Enabling CPU changes functionality of the
1271 * control register, so we have to reset its
1272 * mirror.
1274 _OUTB(port, 0); /* disable interrupts */
1275 hw->regs[0] = 0;
1277 else return -EIO;
1278 break;
1280 case SDLA_S503:
1281 tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */
1282 _OUTB(port, tmp);
1283 hw->regs[0] = tmp; /* update mirror */
1284 for (i = 0; i < SDLA_IODELAY; ++i);
1285 if (!(_INB(port) & 0x01)) /* verify */
1286 return -EIO
1288 break;
1290 case SDLA_S507:
1291 tmp = hw->regs[0] | 0x02;
1292 _OUTB(port, tmp);
1293 hw->regs[0] = tmp; /* update mirror */
1294 for (i = 0; i < SDLA_IODELAY; ++i);
1295 if (!(_INB(port) & 0x04)) /* verify */
1296 return -EIO
1298 break;
1300 case SDLA_S508:
1301 tmp = hw->regs[0] | 0x02;
1302 _OUTB(port, tmp);
1303 hw->regs[0] = tmp; /* update mirror */
1304 for (i = 0; i < SDLA_IODELAY; ++i);
1305 if (!(_INB(port + 1) & 0x02)) /* verify */
1306 return -EIO
1308 break;
1310 default:
1311 return -EINVAL;
1313 return 0;
1316 /*============================================================================
1317 * Initialize S502A adapter.
1319 static int init_s502a (sdlahw_t* hw)
1321 unsigned port = hw->port;
1322 int tmp, i;
1324 if (!detect_s502a(port))
1325 return -ENODEV
1327 hw->regs[0] = 0x08;
1328 hw->regs[1] = 0xFF;
1330 /* Verify configuration options */
1331 i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1332 if (i == 0)
1333 return -EINVAL
1336 tmp = s502a_hmcr[i - 1];
1337 switch (hw->dpmsize)
1339 case 0x2000:
1340 tmp |= 0x01;
1341 break;
1343 case 0x10000L:
1344 break;
1346 default:
1347 return -EINVAL;
1350 /* Setup dual-port memory window (this also enables memory access) */
1351 _OUTB(port + 1, tmp);
1352 hw->regs[1] = tmp;
1353 hw->regs[0] = 0x08;
1354 return 0;
1357 /*============================================================================
1358 * Initialize S502E adapter.
1360 static int init_s502e (sdlahw_t* hw)
1362 unsigned port = hw->port;
1363 int tmp, i;
1365 if (!detect_s502e(port))
1366 return -ENODEV
1369 /* Verify configuration options */
1370 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1371 if (i == 0)
1372 return -EINVAL
1375 tmp = s502e_hmcr[i - 1];
1376 switch (hw->dpmsize)
1378 case 0x2000:
1379 tmp |= 0x01;
1380 break;
1382 case 0x10000L:
1383 break;
1385 default:
1386 return -EINVAL;
1389 /* Setup dual-port memory window */
1390 _OUTB(port + 1, tmp);
1391 hw->regs[1] = tmp;
1393 /* Enable memory access */
1394 _OUTB(port, 0x02);
1395 hw->regs[0] = 0x02;
1396 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1397 return (_INB(port) & 0x02) ? 0 : -EIO;
1400 /*============================================================================
1401 * Initialize S503 adapter.
1402 * ---------------------------------------------------------------------------
1404 static int init_s503 (sdlahw_t* hw)
1406 unsigned port = hw->port;
1407 int tmp, i;
1409 if (!detect_s503(port))
1410 return -ENODEV
1413 /* Verify configuration options */
1414 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1415 if (i == 0)
1416 return -EINVAL
1419 tmp = s502e_hmcr[i - 1];
1420 switch (hw->dpmsize)
1422 case 0x2000:
1423 tmp |= 0x01;
1424 break;
1426 case 0x10000L:
1427 break;
1429 default:
1430 return -EINVAL;
1433 /* Setup dual-port memory window */
1434 _OUTB(port + 1, tmp);
1435 hw->regs[1] = tmp;
1437 /* Enable memory access */
1438 _OUTB(port, 0x02);
1439 hw->regs[0] = 0x02; /* update mirror */
1440 return 0;
1443 /*============================================================================
1444 * Initialize S507 adapter.
1446 static int init_s507 (sdlahw_t* hw)
1448 unsigned port = hw->port;
1449 int tmp, i;
1451 if (!detect_s507(port))
1452 return -ENODEV
1455 /* Verify configuration options */
1456 i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1457 if (i == 0)
1458 return -EINVAL
1461 tmp = s507_hmcr[i - 1];
1462 switch (hw->dpmsize)
1464 case 0x2000:
1465 tmp |= 0x01;
1466 break;
1468 case 0x10000L:
1469 break;
1471 default:
1472 return -EINVAL;
1475 /* Enable adapter's logic */
1476 _OUTB(port, 0x01);
1477 hw->regs[0] = 0x01;
1478 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1479 if (!(_INB(port) & 0x20))
1480 return -EIO
1483 /* Setup dual-port memory window */
1484 _OUTB(port + 1, tmp);
1485 hw->regs[1] = tmp;
1487 /* Enable memory access */
1488 tmp = hw->regs[0] | 0x04;
1489 if (hw->irq)
1491 i = get_option_index(s508_irq_options, hw->irq);
1492 if (i) tmp |= s507_irqmask[i - 1];
1494 _OUTB(port, tmp);
1495 hw->regs[0] = tmp; /* update mirror */
1496 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1497 return (_INB(port) & 0x08) ? 0 : -EIO;
1500 /*============================================================================
1501 * Initialize S508 adapter.
1503 static int init_s508 (sdlahw_t* hw)
1505 unsigned port = hw->port;
1506 int tmp, i;
1508 if (!detect_s508(port))
1509 return -ENODEV
1512 /* Verify configuration options */
1513 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1514 if (i == 0)
1515 return -EINVAL
1518 /* Setup memory configuration */
1519 tmp = s508_hmcr[i - 1];
1520 _OUTB(port + 1, tmp);
1521 hw->regs[1] = tmp;
1523 /* Enable memory access */
1524 _OUTB(port, 0x04);
1525 hw->regs[0] = 0x04; /* update mirror */
1526 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1527 return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1530 /*============================================================================
1531 * Detect S502A adapter.
1532 * Following tests are used to detect S502A adapter:
1533 * 1. All registers other than status (BASE) should read 0xFF
1534 * 2. After writing 00001000b to control register, status register should
1535 * read 01000000b.
1536 * 3. After writing 0 to control register, status register should still
1537 * read 01000000b.
1538 * 4. After writing 00000100b to control register, status register should
1539 * read 01000100b.
1540 * Return 1 if detected o.k. or 0 if failed.
1541 * Note: This test is destructive! Adapter will be left in shutdown
1542 * state after the test.
1544 static int detect_s502a (int port)
1546 int i, j;
1548 if (!get_option_index(s502_port_options, port))
1549 return 0
1551 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1553 if (_INB(port + j) != 0xFF)
1554 return 0
1556 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1559 _OUTB(port, 0x08); /* halt CPU */
1560 _OUTB(port, 0x08);
1561 _OUTB(port, 0x08);
1562 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1563 if (_INB(port) != 0x40)
1564 return 0
1566 _OUTB(port, 0x00);
1567 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1568 if (_INB(port) != 0x40)
1569 return 0
1571 _OUTB(port, 0x04);
1572 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1573 if (_INB(port) != 0x44)
1574 return 0
1577 /* Reset adapter */
1578 _OUTB(port, 0x08);
1579 _OUTB(port, 0x08);
1580 _OUTB(port, 0x08);
1581 _OUTB(port + 1, 0xFF);
1582 return 1;
1585 /*============================================================================
1586 * Detect S502E adapter.
1587 * Following tests are used to verify adapter presence:
1588 * 1. All registers other than status (BASE) should read 0xFF.
1589 * 2. After writing 0 to CPU control register (BASE+3), status register
1590 * (BASE) should read 11111000b.
1591 * 3. After writing 00000100b to port BASE (set bit 2), status register
1592 * (BASE) should read 11111100b.
1593 * Return 1 if detected o.k. or 0 if failed.
1594 * Note: This test is destructive! Adapter will be left in shutdown
1595 * state after the test.
1597 static int detect_s502e (int port)
1599 int i, j;
1601 if (!get_option_index(s502_port_options, port))
1602 return 0
1604 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1606 if (_INB(port + j) != 0xFF)
1607 return 0
1609 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1612 _OUTB(port + 3, 0); /* CPU control reg. */
1613 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1614 if (_INB(port) != 0xF8) /* read status */
1615 return 0
1617 _OUTB(port, 0x04); /* set bit 2 */
1618 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1619 if (_INB(port) != 0xFC) /* verify */
1620 return 0
1623 /* Reset adapter */
1624 _OUTB(port, 0);
1625 return 1;
1628 /*============================================================================
1629 * Detect s503 adapter.
1630 * Following tests are used to verify adapter presence:
1631 * 1. All registers other than status (BASE) should read 0xFF.
1632 * 2. After writing 0 to control register (BASE), status register (BASE)
1633 * should read 11110000b.
1634 * 3. After writing 00000100b (set bit 2) to control register (BASE),
1635 * status register should read 11110010b.
1636 * Return 1 if detected o.k. or 0 if failed.
1637 * Note: This test is destructive! Adapter will be left in shutdown
1638 * state after the test.
1640 static int detect_s503 (int port)
1642 int i, j;
1644 if (!get_option_index(s503_port_options, port))
1645 return 0
1647 for (j = 1; j < SDLA_MAXIORANGE; ++j)
1649 if (_INB(port + j) != 0xFF)
1650 return 0
1652 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1655 _OUTB(port, 0); /* reset control reg.*/
1656 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1657 if (_INB(port) != 0xF0) /* read status */
1658 return 0
1660 _OUTB(port, 0x04); /* set bit 2 */
1661 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1662 if (_INB(port) != 0xF2) /* verify */
1663 return 0
1666 /* Reset adapter */
1667 _OUTB(port, 0);
1668 return 1;
1671 /*============================================================================
1672 * Detect s507 adapter.
1673 * Following tests are used to detect s507 adapter:
1674 * 1. All ports should read the same value.
1675 * 2. After writing 0x00 to control register, status register should read
1676 * ?011000?b.
1677 * 3. After writing 0x01 to control register, status register should read
1678 * ?011001?b.
1679 * Return 1 if detected o.k. or 0 if failed.
1680 * Note: This test is destructive! Adapter will be left in shutdown
1681 * state after the test.
1683 static int detect_s507 (int port)
1685 int tmp, i, j;
1687 if (!get_option_index(s508_port_options, port))
1688 return 0
1690 tmp = _INB(port);
1691 for (j = 1; j < S507_IORANGE; ++j)
1693 if (_INB(port + j) != tmp)
1694 return 0
1696 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1699 _OUTB(port, 0x00);
1700 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1701 if ((_INB(port) & 0x7E) != 0x30)
1702 return 0
1704 _OUTB(port, 0x01);
1705 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1706 if ((_INB(port) & 0x7E) != 0x32)
1707 return 0
1710 /* Reset adapter */
1711 _OUTB(port, 0x00);
1712 return 1;
1715 /*============================================================================
1716 * Detect s508 adapter.
1717 * Following tests are used to detect s508 adapter:
1718 * 1. After writing 0x00 to control register, status register should read
1719 * ??000000b.
1720 * 2. After writing 0x10 to control register, status register should read
1721 * ??010000b
1722 * Return 1 if detected o.k. or 0 if failed.
1723 * Note: This test is destructive! Adapter will be left in shutdown
1724 * state after the test.
1726 static int detect_s508 (int port)
1728 int i;
1730 if (!get_option_index(s508_port_options, port))
1731 return 0
1733 _OUTB(port, 0x00);
1734 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1735 if ((_INB(port + 1) & 0x3F) != 0x00)
1736 return 0
1738 _OUTB(port, 0x10);
1739 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1740 if ((_INB(port + 1) & 0x3F) != 0x10)
1741 return 0
1744 /* Reset adapter */
1745 _OUTB(port, 0x00);
1746 return 1;
1749 /******* Miscellaneous ******************************************************/
1751 /*============================================================================
1752 * Calibrate SDLA memory access delay.
1753 * Count number of idle loops made within 1 second and then calculate the
1754 * number of loops that should be made to achive desired delay.
1756 static int calibrate_delay (int mks)
1758 unsigned int delay;
1759 unsigned long stop;
1761 for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
1762 return (delay/(1000000L/mks) + 1);
1765 /*============================================================================
1766 * Get option's index into the options list.
1767 * Return option's index (1 .. N) or zero if option is invalid.
1769 static int get_option_index (unsigned* optlist, unsigned optval)
1771 int i;
1773 for (i = 1; i <= optlist[0]; ++i)
1774 if ( optlist[i] == optval) return i
1776 return 0;
1779 /*============================================================================
1780 * Check memory region to see if it's available.
1781 * Return: 0 ok.
1783 static unsigned check_memregion (void* ptr, unsigned len)
1785 volatile unsigned char* p = ptr;
1787 for (; len && (*p == 0xFF); --len, ++p)
1789 *p = 0; /* attempt to write 0 */
1790 if (*p != 0xFF) /* still has to read 0xFF */
1792 *p = 0xFF; /* restore original value */
1793 break; /* not good */
1796 return len;
1799 /*============================================================================
1800 * Test memory region.
1801 * Return: size of the region that passed the test.
1802 * Note: Region size must be multiple of 2 !
1804 static unsigned test_memregion (void* ptr, unsigned len)
1806 volatile unsigned short* w_ptr;
1807 unsigned len_w = len >> 1; /* region len in words */
1808 unsigned i;
1810 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1811 *w_ptr = 0xAA55
1813 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1814 if (*w_ptr != 0xAA55)
1816 len_w = i;
1817 break;
1820 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1821 *w_ptr = 0x55AA
1823 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
1824 if (*w_ptr != 0x55AA)
1826 len_w = i;
1827 break;
1830 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) *w_ptr = 0;
1831 return len_w << 1;
1834 /*============================================================================
1835 * Calculate 16-bit CRC using CCITT polynomial.
1837 static unsigned short checksum (unsigned char* buf, unsigned len)
1839 unsigned short crc = 0;
1840 unsigned mask, flag;
1842 for (; len; --len, ++buf)
1844 for (mask = 0x80; mask; mask >>= 1)
1846 flag = (crc & 0x8000);
1847 crc <<= 1;
1848 crc |= ((*buf & mask) ? 1 : 0);
1849 if (flag) crc ^= 0x1021;
1852 return crc;
1856 /****** End *****************************************************************/