sdladrv.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:71k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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