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 /*****************************************************************************
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:
41 * 2. Supported adapter types:
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
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
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
80 ****************************************************************************/
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!
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
111 #error Unknown system type!
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!!!
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.
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
);
297 printk(KERN_DEBUG
"%s: exec_idle = %d\n", modname
, exec_idle
);
302 /*============================================================================
303 * Module 'remove' entry point.
304 * o release all remaining system resources
306 void cleanup_module (void)
311 /******* Kernel APIs ********************************************************/
313 /*============================================================================
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
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 */
336 printk(KERN_ERR
"%s: adapter S%04u not found at port 0x%X!\n",
337 modname
, hw
->type
, hw
->port
)
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
;
349 hw
->io_range
= S502A_IORANGE
;
350 irq_opt
= s502a_irq_options
;
351 dpmbase_opt
= s502a_dpmbase_options
;
352 pclk_opt
= s502a_pclk_options
;
356 hw
->io_range
= S502E_IORANGE
;
357 irq_opt
= s502e_irq_options
;
358 dpmbase_opt
= s508_dpmbase_options
;
359 pclk_opt
= s502e_pclk_options
;
363 hw
->io_range
= S503_IORANGE
;
364 irq_opt
= s503_irq_options
;
365 dpmbase_opt
= s508_dpmbase_options
;
366 pclk_opt
= s503_pclk_options
;
370 hw
->io_range
= S507_IORANGE
;
371 irq_opt
= s508_irq_options
;
372 dpmbase_opt
= s507_dpmbase_options
;
373 pclk_opt
= s507_pclk_options
;
377 hw
->io_range
= S508_IORANGE
;
378 irq_opt
= s508_irq_options
;
379 dpmbase_opt
= s508_dpmbase_options
;
380 pclk_opt
= s508_pclk_options
;
384 /* Verify IRQ configuration options */
385 if (!get_option_index(irq_opt
, hw
->irq
))
387 printk(KERN_ERR
"%s: IRQ %d is illegal!\n",
393 /* Verify CPU clock rate configuration options */
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",
404 printk(KERN_INFO
"%s: assuming CPU clock rate of %u kHz.\n",
408 /* Setup adapter dual-port memory window and test memory */
409 if (hw
->dpmbase
== 0)
411 err
= sdla_autodpm(hw
);
415 "%s: can't find available memory region!\n",
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
))
428 else if (sdla_setdpm(hw
))
431 "%s: 8K memory region at 0x%lX is not available!\n",
432 modname
, virt_to_phys(hw
->dpmbase
));
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 */
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
;
458 if (!port
) return -EFAULT
;
463 _OUTB(port
, 0x08); /* halt CPU */
467 _OUTB(port
+ 1, 0xFF); /* close memory window */
472 _OUTB(port
+ 3, 0); /* stop CPU */
473 _OUTB(port
, 0); /* reset board */
474 for (i
= 0; i
< S502E_IORANGE
; ++i
)
482 _OUTB(port
, 0); /* reset board logic */
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
;
507 if (addr
< S502_MAXMEM
) /* verify parameter */
509 tmp
= addr
>> 13; /* convert to register mask */
510 _OUTB(port
+ 2, tmp
);
517 if (addr
< S503_MAXMEM
) /* verify parameter */
519 tmp
= (hw
->regs
[0] & 0x8F) | ((addr
>> 9) & 0x70);
527 if (addr
< S507_MAXMEM
)
529 if (!(_INB(port
) & 0x02))
532 tmp
= addr
>> 13; /* convert to register mask */
533 _OUTB(port
+ 2, tmp
);
540 if (addr
< S508_MAXMEM
)
542 tmp
= addr
>> 13; /* convert to register mask */
543 _OUTB(port
+ 2, tmp
);
552 hw
->vector
= addr
& 0xFFFFE000L
;
556 /*============================================================================
557 * Enable interrupt generation.
560 EXPORT_SYMBOL(sdla_inten
);
562 int sdla_inten (sdlahw_t
* hw
)
564 unsigned port
= hw
->port
;
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 */
583 tmp
= hw
->regs
[0] | 0x04;
585 hw
->regs
[0] = tmp
; /* update mirror */
586 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
587 if (!(_INB(port
) & 0x02)) /* verify */
593 tmp
= hw
->regs
[0] | 0x10;
595 hw
->regs
[0] = tmp
; /* update mirror */
596 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
597 if (!(_INB(port
+ 1) & 0x10)) /* verify */
613 /*============================================================================
614 * Disable interrupt generation.
617 EXPORT_SYMBOL(sdla_intde
);
619 int sdla_intde (sdlahw_t
* hw
)
621 unsigned port
= hw
->port
;
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;
643 tmp
= hw
->regs
[0] & ~0x04;
645 hw
->regs
[0] = tmp
; /* update mirror */
646 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
647 if (_INB(port
) & 0x02) /* verify */
653 tmp
= hw
->regs
[0] & ~0x10;
655 hw
->regs
[0] = tmp
; /* update mirror */
656 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
657 if (_INB(port
) & 0x10) /* verify */
672 /*============================================================================
673 * Acknowledge SDLA hardware interrupt.
676 EXPORT_SYMBOL(sdla_intack
);
678 int sdla_intack (sdlahw_t
* hw
)
680 unsigned port
= hw
->port
;
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;
703 if (_INB(port
) & 0x04)
705 tmp
= hw
->regs
[0] & ~0x08;
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
;
737 if (!(_INB(port
) & 0x40))
739 _OUTB(port
, 0x10); /* issue NMI to CPU */
746 if ((_INB(port
) & 0x06) == 0x06)
754 if (_INB(port
+ 1) & 0x02)
769 /*============================================================================
770 * Execute Adapter Command.
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
;
784 if (*flag
) return 0; /* ???? */
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! */
797 /*============================================================================
798 * Read absolute adapter memory.
799 * Transfer data from adapter's memory to data buffer.
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 */
817 if (addr
+ len
> hw
->memory
) /* verify arguments */
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
);
830 (char*)buf
+= curlen
;
834 /* Restore DPM window position */
835 sdla_mapmem(hw
, oldvec
);
839 /*============================================================================
840 * Write Absolute Adapter Memory.
841 * Transfer data from data buffer to adapter's memory.
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 */
859 if (addr
+ len
> hw
->memory
) /* verify arguments */
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
);
872 (char*)buf
+= curlen
;
876 /* Restore DPM window position */
877 sdla_mapmem(hw
, oldvec
);
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.
893 * 1) Detection tests are destructive! Adapter will be left in shutdown state
896 static int sdla_detect (sdlahw_t
* hw
)
898 unsigned port
= hw
->port
;
907 if (!detect_s502a(port
)) err
= -ENODEV
;
911 if (!detect_s502e(port
)) err
= -ENODEV
;
915 if (!detect_s503(port
)) err
= -ENODEV
;
919 if (!detect_s507(port
)) err
= -ENODEV
;
923 if (!detect_s508(port
)) err
= -ENODEV
;
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
))
936 else if (detect_s507(port
))
939 else if (detect_s508(port
))
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
;
959 opt
= s502a_dpmbase_options
;
965 opt
= s508_dpmbase_options
;
969 opt
= s507_dpmbase_options
;
976 for (i
= opt
[0]; i
&& err
; --i
)
978 hw
->dpmbase
= phys_to_virt(opt
[i
]);
979 err
= sdla_setdpm(hw
);
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
)
997 /* Shut down card and verify memory region */
999 if (check_memregion(hw
->dpmbase
, hw
->dpmsize
))
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 */
1015 sdla_mapmem(hw
, 0L); /* set window vector at bottom */
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
)
1028 /* Verify firmware signature */
1029 if (strcmp(sfm
->signature
, SFM_SIGNATURE
))
1031 printk(KERN_ERR
"%s: not SDLA firmware!\n",
1037 /* Verify firmware module format version */
1038 if (sfm
->version
!= SFM_VERSION
)
1041 "%s: firmware format %u rejected! Expecting %u.\n",
1042 modname
, sfm
->version
, SFM_VERSION
)
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
);
1057 printk(KERN_INFO
"%s: loading %s (ID=%u)...\n", modname
,
1058 (sfm
->descr
[0] != '\0') ? sfm
->descr
: "unknown firmware",
1062 /* Scan through the list of compatible adapters and make sure our
1063 * adapter type is listed.
1066 (i
< SFM_MAX_SDLA
) && (sfm
->info
.adapter
[i
] != hw
->type
);
1069 if (i
== SFM_MAX_SDLA
)
1071 printk(KERN_ERR
"%s: firmware is not compatible with S%u!\n",
1077 /* Make sure there is enough on-board memory */
1078 if (hw
->memory
< sfm
->info
.memsize
)
1081 "%s: firmware needs %lu bytes of on-board memory!\n",
1082 modname
, sfm
->info
.memsize
)
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",
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",
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",
1114 hw
->fwid
= sfm
->info
.codeid
; /* set firmware ID */
1118 /*============================================================================
1119 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1121 static int sdla_init (sdlahw_t
* hw
)
1125 for (i
= 0; i
< SDLA_MAXIORANGE
; ++i
)
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
);
1139 /*============================================================================
1140 * Test adapter on-board memory.
1141 * o slide DPM window from the bottom up and test adapter memory segment by
1143 * Return adapter memory size.
1145 static unsigned long sdla_memtest (sdlahw_t
* hw
)
1147 unsigned long memsize
;
1150 for (memsize
= 0, winsize
= hw
->dpmsize
;
1151 !sdla_mapmem(hw
, memsize
) &&
1152 (test_memregion(hw
->dpmbase
, winsize
) == winsize
)
1156 hw
->memory
= 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)
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
)
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 */
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;
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;
1211 case SDLA_S502E
: byte
|= 0x80; break;
1212 case SDLA_S503
: byte
|= 0x40; break;
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
1224 static int sdla_start (sdlahw_t
* hw
, unsigned addr
)
1226 unsigned port
= hw
->port
;
1227 unsigned char *bootp
;
1230 if (!port
) return -EFAULT
;
1235 bootp
= hw
->dpmbase
;
1243 bootp
= hw
->dpmbase
;
1250 err
= sdla_mapmem(hw
, 0);
1251 if (err
) return err
;
1253 *bootp
= 0xC3; /* Z80: 'jp' opcode */
1255 *((unsigned short*)(bootp
)) = addr
;
1260 _OUTB(port
, 0x10); /* issue NMI to CPU */
1265 _OUTB(port
+ 3, 0x01); /* start CPU */
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
1275 _OUTB(port
, 0); /* disable interrupts */
1282 tmp
= hw
->regs
[0] | 0x09; /* set bits 0 and 3 */
1284 hw
->regs
[0] = tmp
; /* update mirror */
1285 for (i
= 0; i
< SDLA_IODELAY
; ++i
);
1286 if (!(_INB(port
) & 0x01)) /* verify */
1292 tmp
= hw
->regs
[0] | 0x02;
1294 hw
->regs
[0] = tmp
; /* update mirror */
1295 for (i
= 0; i
< SDLA_IODELAY
; ++i
);
1296 if (!(_INB(port
) & 0x04)) /* verify */
1302 tmp
= hw
->regs
[0] | 0x02;
1304 hw
->regs
[0] = tmp
; /* update mirror */
1305 for (i
= 0; i
< SDLA_IODELAY
; ++i
);
1306 if (!(_INB(port
+ 1) & 0x02)) /* verify */
1317 /*============================================================================
1318 * Initialize S502A adapter.
1320 static int init_s502a (sdlahw_t
* hw
)
1322 unsigned port
= hw
->port
;
1325 if (!detect_s502a(port
))
1331 /* Verify configuration options */
1332 i
= get_option_index(s502a_dpmbase_options
, virt_to_phys(hw
->dpmbase
));
1337 tmp
= s502a_hmcr
[i
- 1];
1338 switch (hw
->dpmsize
)
1351 /* Setup dual-port memory window (this also enables memory access) */
1352 _OUTB(port
+ 1, tmp
);
1358 /*============================================================================
1359 * Initialize S502E adapter.
1361 static int init_s502e (sdlahw_t
* hw
)
1363 unsigned port
= hw
->port
;
1366 if (!detect_s502e(port
))
1370 /* Verify configuration options */
1371 i
= get_option_index(s508_dpmbase_options
, virt_to_phys(hw
->dpmbase
));
1376 tmp
= s502e_hmcr
[i
- 1];
1377 switch (hw
->dpmsize
)
1390 /* Setup dual-port memory window */
1391 _OUTB(port
+ 1, tmp
);
1394 /* Enable memory access */
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
;
1410 if (!detect_s503(port
))
1414 /* Verify configuration options */
1415 i
= get_option_index(s508_dpmbase_options
, virt_to_phys(hw
->dpmbase
));
1420 tmp
= s502e_hmcr
[i
- 1];
1421 switch (hw
->dpmsize
)
1434 /* Setup dual-port memory window */
1435 _OUTB(port
+ 1, tmp
);
1438 /* Enable memory access */
1440 hw
->regs
[0] = 0x02; /* update mirror */
1444 /*============================================================================
1445 * Initialize S507 adapter.
1447 static int init_s507 (sdlahw_t
* hw
)
1449 unsigned port
= hw
->port
;
1452 if (!detect_s507(port
))
1456 /* Verify configuration options */
1457 i
= get_option_index(s507_dpmbase_options
, virt_to_phys(hw
->dpmbase
));
1462 tmp
= s507_hmcr
[i
- 1];
1463 switch (hw
->dpmsize
)
1476 /* Enable adapter's logic */
1479 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1480 if (!(_INB(port
) & 0x20))
1484 /* Setup dual-port memory window */
1485 _OUTB(port
+ 1, tmp
);
1488 /* Enable memory access */
1489 tmp
= hw
->regs
[0] | 0x04;
1492 i
= get_option_index(s508_irq_options
, hw
->irq
);
1493 if (i
) tmp
|= s507_irqmask
[i
- 1];
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
;
1509 if (!detect_s508(port
))
1513 /* Verify configuration options */
1514 i
= get_option_index(s508_dpmbase_options
, virt_to_phys(hw
->dpmbase
));
1519 /* Setup memory configuration */
1520 tmp
= s508_hmcr
[i
- 1];
1521 _OUTB(port
+ 1, tmp
);
1524 /* Enable memory access */
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
1537 * 3. After writing 0 to control register, status register should still
1539 * 4. After writing 00000100b to control register, status register should
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
)
1549 if (!get_option_index(s502_port_options
, port
))
1552 for (j
= 1; j
< SDLA_MAXIORANGE
; ++j
)
1554 if (_INB(port
+ j
) != 0xFF)
1557 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1560 _OUTB(port
, 0x08); /* halt CPU */
1563 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1564 if (_INB(port
) != 0x40)
1568 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1569 if (_INB(port
) != 0x40)
1573 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1574 if (_INB(port
) != 0x44)
1582 _OUTB(port
+ 1, 0xFF);
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
)
1602 if (!get_option_index(s502_port_options
, port
))
1605 for (j
= 1; j
< SDLA_MAXIORANGE
; ++j
)
1607 if (_INB(port
+ j
) != 0xFF)
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 */
1618 _OUTB(port
, 0x04); /* set bit 2 */
1619 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1620 if (_INB(port
) != 0xFC) /* verify */
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
)
1645 if (!get_option_index(s503_port_options
, port
))
1648 for (j
= 1; j
< SDLA_MAXIORANGE
; ++j
)
1650 if (_INB(port
+ j
) != 0xFF)
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 */
1661 _OUTB(port
, 0x04); /* set bit 2 */
1662 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1663 if (_INB(port
) != 0xF2) /* verify */
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
1678 * 3. After writing 0x01 to control register, status register should read
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
)
1688 if (!get_option_index(s508_port_options
, port
))
1692 for (j
= 1; j
< S507_IORANGE
; ++j
)
1694 if (_INB(port
+ j
) != tmp
)
1697 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1701 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1702 if ((_INB(port
) & 0x7E) != 0x30)
1706 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1707 if ((_INB(port
) & 0x7E) != 0x32)
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
1721 * 2. After writing 0x10 to control register, status register should read
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
)
1731 if (!get_option_index(s508_port_options
, port
))
1735 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1736 if ((_INB(port
+ 1) & 0x3F) != 0x00)
1740 for (i
= 0; i
< SDLA_IODELAY
; ++i
); /* delay */
1741 if ((_INB(port
+ 1) & 0x3F) != 0x10)
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
)
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
)
1774 for (i
= 1; i
<= optlist
[0]; ++i
)
1775 if ( optlist
[i
] == optval
) return i
1780 /*============================================================================
1781 * Check memory region to see if it's available.
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 */
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 */
1811 for (i
= 0, w_ptr
= ptr
; i
< len_w
; ++i
, ++w_ptr
)
1814 for (i
= 0, w_ptr
= ptr
; i
< len_w
; ++i
, ++w_ptr
)
1815 if (*w_ptr
!= 0xAA55)
1821 for (i
= 0, w_ptr
= ptr
; i
< len_w
; ++i
, ++w_ptr
)
1824 for (i
= 0, w_ptr
= ptr
; i
< len_w
; ++i
, ++w_ptr
)
1825 if (*w_ptr
!= 0x55AA)
1831 for (i
= 0, w_ptr
= ptr
; i
< len_w
; ++i
, ++w_ptr
) *w_ptr
= 0;
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);
1849 crc
|= ((*buf
& mask
) ? 1 : 0);
1850 if (flag
) crc
^= 0x1021;
1857 /****** End *****************************************************************/