xref: /freebsd/sys/dev/puc/pucdata.c (revision f1f890804985a1043da42a5def13c79dc005f5e9)
1 /*-
2  * Copyright (c) 2006 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 /*
31  * PCI "universal" communications card driver configuration data (used to
32  * match/attach the cards).
33  */
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/bus.h>
39 
40 #include <machine/resource.h>
41 #include <machine/bus.h>
42 #include <sys/rman.h>
43 
44 #include <dev/pci/pcivar.h>
45 
46 #include <dev/puc/puc_bus.h>
47 #include <dev/puc/puc_cfg.h>
48 #include <dev/puc/puc_bfe.h>
49 
50 static puc_config_f puc_config_amc;
51 static puc_config_f puc_config_diva;
52 static puc_config_f puc_config_exar;
53 static puc_config_f puc_config_icbook;
54 static puc_config_f puc_config_moxa;
55 static puc_config_f puc_config_oxford_pcie;
56 static puc_config_f puc_config_quatech;
57 static puc_config_f puc_config_syba;
58 static puc_config_f puc_config_siig;
59 static puc_config_f puc_config_timedia;
60 static puc_config_f puc_config_titan;
61 
62 const struct puc_cfg puc_pci_devices[] = {
63 
64 	{   0x0009, 0x7168, 0xffff, 0,
65 	    "Sunix SUN1889",
66 	    DEFAULT_RCLK * 8,
67 	    PUC_PORT_2S, 0x10, 0, 8,
68 	},
69 
70 	{   0x103c, 0x1048, 0x103c, 0x1049,
71 	    "HP Diva Serial [GSP] Multiport UART - Tosca Console",
72 	    DEFAULT_RCLK,
73 	    PUC_PORT_3S, 0x10, 0, -1,
74 	    .config_function = puc_config_diva
75 	},
76 
77 	{   0x103c, 0x1048, 0x103c, 0x104a,
78 	    "HP Diva Serial [GSP] Multiport UART - Tosca Secondary",
79 	    DEFAULT_RCLK,
80 	    PUC_PORT_2S, 0x10, 0, -1,
81 	    .config_function = puc_config_diva
82 	},
83 
84 	{   0x103c, 0x1048, 0x103c, 0x104b,
85 	    "HP Diva Serial [GSP] Multiport UART - Maestro SP2",
86 	    DEFAULT_RCLK,
87 	    PUC_PORT_4S, 0x10, 0, -1,
88 	    .config_function = puc_config_diva
89 	},
90 
91 	{   0x103c, 0x1048, 0x103c, 0x1223,
92 	    "HP Diva Serial [GSP] Multiport UART - Superdome Console",
93 	    DEFAULT_RCLK,
94 	    PUC_PORT_3S, 0x10, 0, -1,
95 	    .config_function = puc_config_diva
96 	},
97 
98 	{   0x103c, 0x1048, 0x103c, 0x1226,
99 	    "HP Diva Serial [GSP] Multiport UART - Keystone SP2",
100 	    DEFAULT_RCLK,
101 	    PUC_PORT_3S, 0x10, 0, -1,
102 	    .config_function = puc_config_diva
103 	},
104 
105 	{   0x103c, 0x1048, 0x103c, 0x1282,
106 	    "HP Diva Serial [GSP] Multiport UART - Everest SP2",
107 	    DEFAULT_RCLK,
108 	    PUC_PORT_3S, 0x10, 0, -1,
109 	    .config_function = puc_config_diva
110 	},
111 
112 	{   0x10b5, 0x1076, 0x10b5, 0x1076,
113 	    "VScom PCI-800",
114 	    DEFAULT_RCLK * 8,
115 	    PUC_PORT_8S, 0x18, 0, 8,
116 	},
117 
118 	{   0x10b5, 0x1077, 0x10b5, 0x1077,
119 	    "VScom PCI-400",
120 	    DEFAULT_RCLK * 8,
121 	    PUC_PORT_4S, 0x18, 0, 8,
122 	},
123 
124 	{   0x10b5, 0x1103, 0x10b5, 0x1103,
125 	    "VScom PCI-200",
126 	    DEFAULT_RCLK * 8,
127 	    PUC_PORT_2S, 0x18, 4, 0,
128 	},
129 
130 	/*
131 	 * Boca Research Turbo Serial 658 (8 serial port) card.
132 	 * Appears to be the same as Chase Research PLC PCI-FAST8
133 	 * and Perle PCI-FAST8 Multi-Port serial cards.
134 	 */
135 	{   0x10b5, 0x9050, 0x12e0, 0x0021,
136 	    "Boca Research Turbo Serial 658",
137 	    DEFAULT_RCLK * 4,
138 	    PUC_PORT_8S, 0x18, 0, 8,
139 	},
140 
141 	{   0x10b5, 0x9050, 0x12e0, 0x0031,
142 	    "Boca Research Turbo Serial 654",
143 	    DEFAULT_RCLK * 4,
144 	    PUC_PORT_4S, 0x18, 0, 8,
145 	},
146 
147 	/*
148 	 * Dolphin Peripherals 4035 (dual serial port) card.  PLX 9050, with
149 	 * a seemingly-lame EEPROM setup that puts the Dolphin IDs
150 	 * into the subsystem fields, and claims that it's a
151 	 * network/misc (0x02/0x80) device.
152 	 */
153 	{   0x10b5, 0x9050, 0xd84d, 0x6808,
154 	    "Dolphin Peripherals 4035",
155 	    DEFAULT_RCLK,
156 	    PUC_PORT_2S, 0x18, 4, 0,
157 	},
158 
159 	/*
160 	 * Dolphin Peripherals 4014 (dual parallel port) card.  PLX 9050, with
161 	 * a seemingly-lame EEPROM setup that puts the Dolphin IDs
162 	 * into the subsystem fields, and claims that it's a
163 	 * network/misc (0x02/0x80) device.
164 	 */
165 	{   0x10b5, 0x9050, 0xd84d, 0x6810,
166 	    "Dolphin Peripherals 4014",
167 	    0,
168 	    PUC_PORT_2P, 0x20, 4, 0,
169 	},
170 
171 	{   0x10e8, 0x818e, 0xffff, 0,
172 	    "Applied Micro Circuits 8 Port UART",
173 	    DEFAULT_RCLK,
174 	    PUC_PORT_8S, 0x14, -1, -1,
175 	    .config_function = puc_config_amc
176 	},
177 
178 	{   0x11fe, 0x8010, 0xffff, 0,
179 	    "Comtrol RocketPort 550/8 RJ11 part A",
180 	    DEFAULT_RCLK * 4,
181 	    PUC_PORT_4S, 0x10, 0, 8,
182 	},
183 
184 	{   0x11fe, 0x8011, 0xffff, 0,
185 	    "Comtrol RocketPort 550/8 RJ11 part B",
186 	    DEFAULT_RCLK * 4,
187 	    PUC_PORT_4S, 0x10, 0, 8,
188 	},
189 
190 	{   0x11fe, 0x8012, 0xffff, 0,
191 	    "Comtrol RocketPort 550/8 Octa part A",
192 	    DEFAULT_RCLK * 4,
193 	    PUC_PORT_4S, 0x10, 0, 8,
194 	},
195 
196 	{   0x11fe, 0x8013, 0xffff, 0,
197 	    "Comtrol RocketPort 550/8 Octa part B",
198 	    DEFAULT_RCLK * 4,
199 	    PUC_PORT_4S, 0x10, 0, 8,
200 	},
201 
202 	{   0x11fe, 0x8014, 0xffff, 0,
203 	    "Comtrol RocketPort 550/4 RJ45",
204 	    DEFAULT_RCLK * 4,
205 	    PUC_PORT_4S, 0x10, 0, 8,
206 	},
207 
208 	{   0x11fe, 0x8015, 0xffff, 0,
209 	    "Comtrol RocketPort 550/Quad",
210 	    DEFAULT_RCLK * 4,
211 	    PUC_PORT_4S, 0x10, 0, 8,
212 	},
213 
214 	{   0x11fe, 0x8016, 0xffff, 0,
215 	    "Comtrol RocketPort 550/16 part A",
216 	    DEFAULT_RCLK * 4,
217 	    PUC_PORT_4S, 0x10, 0, 8,
218 	},
219 
220 	{   0x11fe, 0x8017, 0xffff, 0,
221 	    "Comtrol RocketPort 550/16 part B",
222 	    DEFAULT_RCLK * 4,
223 	    PUC_PORT_12S, 0x10, 0, 8,
224 	},
225 
226 	{   0x11fe, 0x8018, 0xffff, 0,
227 	    "Comtrol RocketPort 550/8 part A",
228 	    DEFAULT_RCLK * 4,
229 	    PUC_PORT_4S, 0x10, 0, 8,
230 	},
231 
232 	{   0x11fe, 0x8019, 0xffff, 0,
233 	    "Comtrol RocketPort 550/8 part B",
234 	    DEFAULT_RCLK * 4,
235 	    PUC_PORT_4S, 0x10, 0, 8,
236 	},
237 
238 	/*
239 	 * IBM SurePOS 300 Series (481033H) serial ports
240 	 * Details can be found on the IBM RSS websites
241 	 */
242 
243 	{   0x1014, 0x0297, 0xffff, 0,
244 	    "IBM SurePOS 300 Series (481033H) serial ports",
245 	    DEFAULT_RCLK,
246 	    PUC_PORT_4S, 0x10, 4, 0
247 	},
248 
249 	/*
250 	 * SIIG Boards.
251 	 *
252 	 * SIIG provides documentation for their boards at:
253 	 * <URL:http://www.siig.com/downloads.asp>
254 	 */
255 
256 	{   0x131f, 0x1010, 0xffff, 0,
257 	    "SIIG Cyber I/O PCI 16C550 (10x family)",
258 	    DEFAULT_RCLK,
259 	    PUC_PORT_1S1P, 0x18, 4, 0,
260 	},
261 
262 	{   0x131f, 0x1011, 0xffff, 0,
263 	    "SIIG Cyber I/O PCI 16C650 (10x family)",
264 	    DEFAULT_RCLK,
265 	    PUC_PORT_1S1P, 0x18, 4, 0,
266 	},
267 
268 	{   0x131f, 0x1012, 0xffff, 0,
269 	    "SIIG Cyber I/O PCI 16C850 (10x family)",
270 	    DEFAULT_RCLK,
271 	    PUC_PORT_1S1P, 0x18, 4, 0,
272 	},
273 
274 	{   0x131f, 0x1021, 0xffff, 0,
275 	    "SIIG Cyber Parallel Dual PCI (10x family)",
276 	    0,
277 	    PUC_PORT_2P, 0x18, 8, 0,
278 	},
279 
280 	{   0x131f, 0x1030, 0xffff, 0,
281 	    "SIIG Cyber Serial Dual PCI 16C550 (10x family)",
282 	    DEFAULT_RCLK,
283 	    PUC_PORT_2S, 0x18, 4, 0,
284 	},
285 
286 	{   0x131f, 0x1031, 0xffff, 0,
287 	    "SIIG Cyber Serial Dual PCI 16C650 (10x family)",
288 	    DEFAULT_RCLK,
289 	    PUC_PORT_2S, 0x18, 4, 0,
290 	},
291 
292 	{   0x131f, 0x1032, 0xffff, 0,
293 	    "SIIG Cyber Serial Dual PCI 16C850 (10x family)",
294 	    DEFAULT_RCLK,
295 	    PUC_PORT_2S, 0x18, 4, 0,
296 	},
297 
298 	{   0x131f, 0x1034, 0xffff, 0,	/* XXX really? */
299 	    "SIIG Cyber 2S1P PCI 16C550 (10x family)",
300 	    DEFAULT_RCLK,
301 	    PUC_PORT_2S1P, 0x18, 4, 0,
302 	},
303 
304 	{   0x131f, 0x1035, 0xffff, 0,	/* XXX really? */
305 	    "SIIG Cyber 2S1P PCI 16C650 (10x family)",
306 	    DEFAULT_RCLK,
307 	    PUC_PORT_2S1P, 0x18, 4, 0,
308 	},
309 
310 	{   0x131f, 0x1036, 0xffff, 0,	/* XXX really? */
311 	    "SIIG Cyber 2S1P PCI 16C850 (10x family)",
312 	    DEFAULT_RCLK,
313 	    PUC_PORT_2S1P, 0x18, 4, 0,
314 	},
315 
316 	{   0x131f, 0x1050, 0xffff, 0,
317 	    "SIIG Cyber 4S PCI 16C550 (10x family)",
318 	    DEFAULT_RCLK,
319 	    PUC_PORT_4S, 0x18, 4, 0,
320 	},
321 
322 	{   0x131f, 0x1051, 0xffff, 0,
323 	    "SIIG Cyber 4S PCI 16C650 (10x family)",
324 	    DEFAULT_RCLK,
325 	    PUC_PORT_4S, 0x18, 4, 0,
326 	},
327 
328 	{   0x131f, 0x1052, 0xffff, 0,
329 	    "SIIG Cyber 4S PCI 16C850 (10x family)",
330 	    DEFAULT_RCLK,
331 	    PUC_PORT_4S, 0x18, 4, 0,
332 	},
333 
334 	{   0x131f, 0x2010, 0xffff, 0,
335 	    "SIIG Cyber I/O PCI 16C550 (20x family)",
336 	    DEFAULT_RCLK,
337 	    PUC_PORT_1S1P, 0x10, 4, 0,
338 	},
339 
340 	{   0x131f, 0x2011, 0xffff, 0,
341 	    "SIIG Cyber I/O PCI 16C650 (20x family)",
342 	    DEFAULT_RCLK,
343 	    PUC_PORT_1S1P, 0x10, 4, 0,
344 	},
345 
346 	{   0x131f, 0x2012, 0xffff, 0,
347 	    "SIIG Cyber I/O PCI 16C850 (20x family)",
348 	    DEFAULT_RCLK,
349 	    PUC_PORT_1S1P, 0x10, 4, 0,
350 	},
351 
352 	{   0x131f, 0x2021, 0xffff, 0,
353 	    "SIIG Cyber Parallel Dual PCI (20x family)",
354 	    0,
355 	    PUC_PORT_2P, 0x10, 8, 0,
356 	},
357 
358 	{   0x131f, 0x2030, 0xffff, 0,
359 	    "SIIG Cyber Serial Dual PCI 16C550 (20x family)",
360 	    DEFAULT_RCLK,
361 	    PUC_PORT_2S, 0x10, 4, 0,
362 	},
363 
364 	{   0x131f, 0x2031, 0xffff, 0,
365 	    "SIIG Cyber Serial Dual PCI 16C650 (20x family)",
366 	    DEFAULT_RCLK,
367 	    PUC_PORT_2S, 0x10, 4, 0,
368 	},
369 
370 	{   0x131f, 0x2032, 0xffff, 0,
371 	    "SIIG Cyber Serial Dual PCI 16C850 (20x family)",
372 	    DEFAULT_RCLK,
373 	    PUC_PORT_2S, 0x10, 4, 0,
374 	},
375 
376 	{   0x131f, 0x2040, 0xffff, 0,
377 	    "SIIG Cyber 2P1S PCI 16C550 (20x family)",
378 	    DEFAULT_RCLK,
379 	    PUC_PORT_1S2P, 0x10, -1, 0,
380 	    .config_function = puc_config_siig
381 	},
382 
383 	{   0x131f, 0x2041, 0xffff, 0,
384 	    "SIIG Cyber 2P1S PCI 16C650 (20x family)",
385 	    DEFAULT_RCLK,
386 	    PUC_PORT_1S2P, 0x10, -1, 0,
387 	    .config_function = puc_config_siig
388 	},
389 
390 	{   0x131f, 0x2042, 0xffff, 0,
391 	    "SIIG Cyber 2P1S PCI 16C850 (20x family)",
392 	    DEFAULT_RCLK,
393 	    PUC_PORT_1S2P, 0x10, -1, 0,
394 	    .config_function = puc_config_siig
395 	},
396 
397 	{   0x131f, 0x2050, 0xffff, 0,
398 	    "SIIG Cyber 4S PCI 16C550 (20x family)",
399 	    DEFAULT_RCLK,
400 	    PUC_PORT_4S, 0x10, 4, 0,
401 	},
402 
403 	{   0x131f, 0x2051, 0xffff, 0,
404 	    "SIIG Cyber 4S PCI 16C650 (20x family)",
405 	    DEFAULT_RCLK,
406 	    PUC_PORT_4S, 0x10, 4, 0,
407 	},
408 
409 	{   0x131f, 0x2052, 0xffff, 0,
410 	    "SIIG Cyber 4S PCI 16C850 (20x family)",
411 	    DEFAULT_RCLK,
412 	    PUC_PORT_4S, 0x10, 4, 0,
413 	},
414 
415 	{   0x131f, 0x2060, 0xffff, 0,
416 	    "SIIG Cyber 2S1P PCI 16C550 (20x family)",
417 	    DEFAULT_RCLK,
418 	    PUC_PORT_2S1P, 0x10, 4, 0,
419 	},
420 
421 	{   0x131f, 0x2061, 0xffff, 0,
422 	    "SIIG Cyber 2S1P PCI 16C650 (20x family)",
423 	    DEFAULT_RCLK,
424 	    PUC_PORT_2S1P, 0x10, 4, 0,
425 	},
426 
427 	{   0x131f, 0x2062, 0xffff, 0,
428 	    "SIIG Cyber 2S1P PCI 16C850 (20x family)",
429 	    DEFAULT_RCLK,
430 	    PUC_PORT_2S1P, 0x10, 4, 0,
431 	},
432 
433 	{   0x131f, 0x2081, 0xffff, 0,
434 	    "SIIG PS8000 8S PCI 16C650 (20x family)",
435 	    DEFAULT_RCLK,
436 	    PUC_PORT_8S, 0x10, -1, -1,
437 	    .config_function = puc_config_siig
438 	},
439 
440 	{   0x135c, 0x0010, 0xffff, 0,
441 	    "Quatech QSC-100",
442 	    -3,	/* max 8x clock rate */
443 	    PUC_PORT_4S, 0x14, 0, 8,
444 	    .config_function = puc_config_quatech
445 	},
446 
447 	{   0x135c, 0x0020, 0xffff, 0,
448 	    "Quatech DSC-100",
449 	    -1, /* max 2x clock rate */
450 	    PUC_PORT_2S, 0x14, 0, 8,
451 	    .config_function = puc_config_quatech
452 	},
453 
454 	{   0x135c, 0x0030, 0xffff, 0,
455 	    "Quatech DSC-200/300",
456 	    -1, /* max 2x clock rate */
457 	    PUC_PORT_2S, 0x14, 0, 8,
458 	    .config_function = puc_config_quatech
459 	},
460 
461 	{   0x135c, 0x0040, 0xffff, 0,
462 	    "Quatech QSC-200/300",
463 	    -3, /* max 8x clock rate */
464 	    PUC_PORT_4S, 0x14, 0, 8,
465 	    .config_function = puc_config_quatech
466 	},
467 
468 	{   0x135c, 0x0050, 0xffff, 0,
469 	    "Quatech ESC-100D",
470 	    -3, /* max 8x clock rate */
471 	    PUC_PORT_8S, 0x14, 0, 8,
472 	    .config_function = puc_config_quatech
473 	},
474 
475 	{   0x135c, 0x0060, 0xffff, 0,
476 	    "Quatech ESC-100M",
477 	    -3, /* max 8x clock rate */
478 	    PUC_PORT_8S, 0x14, 0, 8,
479 	    .config_function = puc_config_quatech
480 	},
481 
482 	{   0x135c, 0x0170, 0xffff, 0,
483 	    "Quatech QSCLP-100",
484 	    -1, /* max 2x clock rate */
485 	    PUC_PORT_4S, 0x18, 0, 8,
486 	    .config_function = puc_config_quatech
487 	},
488 
489 	{   0x135c, 0x0180, 0xffff, 0,
490 	    "Quatech DSCLP-100",
491 	    -1, /* max 3x clock rate */
492 	    PUC_PORT_2S, 0x18, 0, 8,
493 	    .config_function = puc_config_quatech
494 	},
495 
496 	{   0x135c, 0x01b0, 0xffff, 0,
497 	    "Quatech DSCLP-200/300",
498 	    -1, /* max 2x clock rate */
499 	    PUC_PORT_2S, 0x18, 0, 8,
500 	    .config_function = puc_config_quatech
501 	},
502 
503 	{   0x135c, 0x01e0, 0xffff, 0,
504 	    "Quatech ESCLP-100",
505 	    -3, /* max 8x clock rate */
506 	    PUC_PORT_8S, 0x10, 0, 8,
507 	    .config_function = puc_config_quatech
508 	},
509 
510 	{   0x1393, 0x1024, 0xffff, 0,
511 	    "Moxa Technologies, Smartio CP-102E/PCIe",
512 	    DEFAULT_RCLK * 8,
513 	    PUC_PORT_2S, 0x14, 0, -1,
514 	        .config_function = puc_config_moxa
515 	},
516 
517 	{   0x1393, 0x1025, 0xffff, 0,
518 	    "Moxa Technologies, Smartio CP-102EL/PCIe",
519 	    DEFAULT_RCLK * 8,
520 	    PUC_PORT_2S, 0x14, 0, -1,
521 	        .config_function = puc_config_moxa
522 	},
523 
524 	{   0x1393, 0x1040, 0xffff, 0,
525 	    "Moxa Technologies, Smartio C104H/PCI",
526 	    DEFAULT_RCLK * 8,
527 	    PUC_PORT_4S, 0x18, 0, 8,
528 	},
529 
530 	{   0x1393, 0x1041, 0xffff, 0,
531 	    "Moxa Technologies, Smartio CP-104UL/PCI",
532 	    DEFAULT_RCLK * 8,
533 	    PUC_PORT_4S, 0x18, 0, 8,
534 	},
535 
536 	{   0x1393, 0x1042, 0xffff, 0,
537 	    "Moxa Technologies, Smartio CP-104JU/PCI",
538 	    DEFAULT_RCLK * 8,
539 	    PUC_PORT_4S, 0x18, 0, 8,
540 	},
541 
542 	{   0x1393, 0x1043, 0xffff, 0,
543 	    "Moxa Technologies, Smartio CP-104EL/PCIe",
544 	    DEFAULT_RCLK * 8,
545 	    PUC_PORT_4S, 0x18, 0, 8,
546 	},
547 
548 	{   0x1393, 0x1045, 0xffff, 0,
549 	    "Moxa Technologies, Smartio CP-104EL-A/PCIe",
550 	    DEFAULT_RCLK * 8,
551 	    PUC_PORT_4S, 0x14, 0, -1,
552 		.config_function = puc_config_moxa
553 	},
554 
555 	{   0x1393, 0x1120, 0xffff, 0,
556 	    "Moxa Technologies, CP-112UL",
557 	    DEFAULT_RCLK * 8,
558 	    PUC_PORT_2S, 0x18, 0, 8,
559 	},
560 
561 	{   0x1393, 0x1141, 0xffff, 0,
562 	    "Moxa Technologies, Industio CP-114",
563 	    DEFAULT_RCLK * 8,
564 	    PUC_PORT_4S, 0x18, 0, 8,
565 	},
566 
567 	{   0x1393, 0x1144, 0xffff, 0,
568 	    "Moxa Technologies, Smartio CP-114EL/PCIe",
569 	    DEFAULT_RCLK * 8,
570 	    PUC_PORT_4S, 0x14, 0, -1,
571 		.config_function = puc_config_moxa
572 	},
573 
574 	{   0x1393, 0x1182, 0xffff, 0,
575 	    "Moxa Technologies, Smartio CP-118EL-A/PCIe",
576 	    DEFAULT_RCLK * 8,
577 	    PUC_PORT_8S, 0x14, 0, -1,
578 		.config_function = puc_config_moxa
579 	},
580 
581 	{   0x1393, 0x1680, 0xffff, 0,
582 	    "Moxa Technologies, C168H/PCI",
583 	    DEFAULT_RCLK * 8,
584 	    PUC_PORT_8S, 0x18, 0, 8,
585 	},
586 
587 	{   0x1393, 0x1681, 0xffff, 0,
588 	    "Moxa Technologies, C168U/PCI",
589 	    DEFAULT_RCLK * 8,
590 	    PUC_PORT_8S, 0x18, 0, 8,
591 	},
592 
593 	{   0x1393, 0x1682, 0xffff, 0,
594 	    "Moxa Technologies, CP-168EL/PCIe",
595 	    DEFAULT_RCLK * 8,
596 	    PUC_PORT_8S, 0x18, 0, 8,
597 	},
598 
599 	{   0x1393, 0x1683, 0xffff, 0,
600 	    "Moxa Technologies, Smartio CP-168EL-A/PCIe",
601 	    DEFAULT_RCLK * 8,
602 	    PUC_PORT_8S, 0x14, 0, -1,
603 		.config_function = puc_config_moxa
604 	},
605 
606 	{   0x13a8, 0x0152, 0xffff, 0,
607 	    "Exar XR17C/D152",
608 	    DEFAULT_RCLK * 8,
609 	    PUC_PORT_2S, 0x10, 0, -1,
610 	    .config_function = puc_config_exar
611 	},
612 
613 	{   0x13a8, 0x0154, 0xffff, 0,
614 	    "Exar XR17C154",
615 	    DEFAULT_RCLK * 8,
616 	    PUC_PORT_4S, 0x10, 0, -1,
617 	    .config_function = puc_config_exar
618 	},
619 
620 	{   0x13a8, 0x0158, 0xffff, 0,
621 	    "Exar XR17C158",
622 	    DEFAULT_RCLK * 8,
623 	    PUC_PORT_8S, 0x10, 0, -1,
624 	    .config_function = puc_config_exar
625 	},
626 
627 	{   0x13a8, 0x0258, 0xffff, 0,
628 	    "Exar XR17V258IV",
629 	    DEFAULT_RCLK * 8,
630 	    PUC_PORT_8S, 0x10, 0, -1,
631 	},
632 
633 	{   0x13fe, 0x1600, 0x1602, 0x0002,
634 	    "Advantech PCI-1602",
635 	    DEFAULT_RCLK * 8,
636 	    PUC_PORT_2S, 0x10, 0, 8,
637 	},
638 
639 	{   0x1407, 0x0100, 0xffff, 0,
640 	    "Lava Computers Dual Serial",
641 	    DEFAULT_RCLK,
642 	    PUC_PORT_2S, 0x10, 4, 0,
643 	},
644 
645 	{   0x1407, 0x0101, 0xffff, 0,
646 	    "Lava Computers Quatro A",
647 	    DEFAULT_RCLK,
648 	    PUC_PORT_2S, 0x10, 4, 0,
649 	},
650 
651 	{   0x1407, 0x0102, 0xffff, 0,
652 	    "Lava Computers Quatro B",
653 	    DEFAULT_RCLK,
654 	    PUC_PORT_2S, 0x10, 4, 0,
655 	},
656 
657 	{   0x1407, 0x0120, 0xffff, 0,
658 	    "Lava Computers Quattro-PCI A",
659 	    DEFAULT_RCLK,
660 	    PUC_PORT_2S, 0x10, 4, 0,
661 	},
662 
663 	{   0x1407, 0x0121, 0xffff, 0,
664 	    "Lava Computers Quattro-PCI B",
665 	    DEFAULT_RCLK,
666 	    PUC_PORT_2S, 0x10, 4, 0,
667 	},
668 
669 	{   0x1407, 0x0180, 0xffff, 0,
670 	    "Lava Computers Octo A",
671 	    DEFAULT_RCLK,
672 	    PUC_PORT_4S, 0x10, 4, 0,
673 	},
674 
675 	{   0x1407, 0x0181, 0xffff, 0,
676 	    "Lava Computers Octo B",
677 	    DEFAULT_RCLK,
678 	    PUC_PORT_4S, 0x10, 4, 0,
679 	},
680 
681 	{   0x1409, 0x7268, 0xffff, 0,
682 	    "Sunix SUN1888",
683 	    0,
684 	    PUC_PORT_2P, 0x10, 0, 8,
685 	},
686 
687 	{   0x1409, 0x7168, 0xffff, 0,
688 	    NULL,
689 	    DEFAULT_RCLK * 8,
690 	    PUC_PORT_NONSTANDARD, 0x10, -1, -1,
691 	    .config_function = puc_config_timedia
692 	},
693 
694 	/*
695 	 * Boards with an Oxford Semiconductor chip.
696 	 *
697 	 * Oxford Semiconductor provides documentation for their chip at:
698 	 * <URL:http://www.plxtech.com/products/uart/>
699 	 *
700 	 * As sold by Kouwell <URL:http://www.kouwell.com/>.
701 	 * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports.
702 	 */
703 	{
704 		0x1415, 0x9501, 0x10fc ,0xc070,
705 		"I-O DATA RSA-PCI2/R",
706 		DEFAULT_RCLK * 8,
707 		PUC_PORT_2S, 0x10, 0, 8,
708 	},
709 
710 	{   0x1415, 0x9501, 0x131f, 0x2050,
711 	    "SIIG Cyber 4 PCI 16550",
712 	    DEFAULT_RCLK * 10,
713 	    PUC_PORT_4S, 0x10, 0, 8,
714 	},
715 
716 	{   0x1415, 0x9501, 0x131f, 0x2051,
717 	    "SIIG Cyber 4S PCI 16C650 (20x family)",
718 	    DEFAULT_RCLK * 10,
719 	    PUC_PORT_4S, 0x10, 0, 8,
720 	},
721 
722 	{   0x1415, 0x9501, 0x131f, 0x2052,
723 	    "SIIG Quartet Serial 850",
724 	    DEFAULT_RCLK * 10,
725 	    PUC_PORT_4S, 0x10, 0, 8,
726 	},
727 
728 	{   0x1415, 0x9501, 0x14db, 0x2150,
729 	    "Kuroutoshikou SERIAL4P-LPPCI2",
730 	    DEFAULT_RCLK * 10,
731 	    PUC_PORT_4S, 0x10, 0, 8,
732 	},
733 
734 	{   0x1415, 0x9501, 0xffff, 0,
735 	    "Oxford Semiconductor OX16PCI954 UARTs",
736 	    DEFAULT_RCLK,
737 	    PUC_PORT_4S, 0x10, 0, 8,
738 	},
739 
740 	{   0x1415, 0x950a, 0x131f, 0x2030,
741 	    "SIIG Cyber 2S PCIe",
742 	    DEFAULT_RCLK * 10,
743 	    PUC_PORT_2S, 0x10, 0, 8,
744 	},
745 
746 	{   0x1415, 0x950a, 0x131f, 0x2032,
747 	    "SIIG Cyber Serial Dual PCI 16C850",
748 	    DEFAULT_RCLK * 10,
749 	    PUC_PORT_4S, 0x10, 0, 8,
750 	},
751 
752 	{   0x1415, 0x950a, 0xffff, 0,
753 	    "Oxford Semiconductor OX16PCI954 UARTs",
754 	    DEFAULT_RCLK,
755 	    PUC_PORT_4S, 0x10, 0, 8,
756 	},
757 
758 	{   0x1415, 0x9511, 0xffff, 0,
759 	    "Oxford Semiconductor OX9160/OX16PCI954 UARTs (function 1)",
760 	    DEFAULT_RCLK,
761 	    PUC_PORT_4S, 0x10, 0, 8,
762 	},
763 
764 	{   0x1415, 0x9521, 0xffff, 0,
765 	    "Oxford Semiconductor OX16PCI952 UARTs",
766 	    DEFAULT_RCLK,
767 	    PUC_PORT_2S, 0x10, 4, 0,
768 	},
769 
770 	{   0x1415, 0x9538, 0xffff, 0,
771 	    "Oxford Semiconductor OX16PCI958 UARTs",
772 	    DEFAULT_RCLK,
773 	    PUC_PORT_8S, 0x18, 0, 8,
774 	},
775 
776 	/*
777 	 * Perle boards use Oxford Semiconductor chips, but they store the
778 	 * Oxford Semiconductor device ID as a subvendor device ID and use
779 	 * their own device IDs.
780 	 */
781 
782 	{   0x155f, 0x0331, 0xffff, 0,
783 	    "Perle Ultraport4 Express",
784 	    DEFAULT_RCLK * 8,
785 	    PUC_PORT_4S, 0x10, 0, 8,
786 	},
787 
788 	{   0x155f, 0xB012, 0xffff, 0,
789 	    "Perle Speed2 LE",
790 	    DEFAULT_RCLK * 8,
791 	    PUC_PORT_2S, 0x10, 0, 8,
792 	},
793 
794 	{   0x155f, 0xB022, 0xffff, 0,
795 	    "Perle Speed2 LE",
796 	    DEFAULT_RCLK * 8,
797 	    PUC_PORT_2S, 0x10, 0, 8,
798 	},
799 
800 	{   0x155f, 0xB004, 0xffff, 0,
801 	    "Perle Speed4 LE",
802 	    DEFAULT_RCLK * 8,
803 	    PUC_PORT_4S, 0x10, 0, 8,
804 	},
805 
806 	{   0x155f, 0xB008, 0xffff, 0,
807 	    "Perle Speed8 LE",
808 	    DEFAULT_RCLK * 8,
809 	    PUC_PORT_8S, 0x10, 0, 8,
810 	},
811 
812 
813 	/*
814 	 * Oxford Semiconductor PCI Express Expresso family
815 	 *
816 	 * Found in many 'native' PCI Express serial boards such as:
817 	 *
818 	 * eMegatech MP954ER4 (4 port) and MP958ER8 (8 port)
819 	 * <URL:http://www.emegatech.com.tw/pdrs232pcie.html>
820 	 *
821 	 * Lindy 51189 (4 port)
822 	 * <URL:http://www.lindy.com> <URL:http://tinyurl.com/lindy-51189>
823 	 *
824 	 * StarTech.com PEX4S952 (4 port) and PEX8S952 (8 port)
825 	 * <URL:http://www.startech.com>
826 	 */
827 
828 	{   0x1415, 0xc138, 0xffff, 0,
829 	    "Oxford Semiconductor OXPCIe952 UARTs",
830 	    DEFAULT_RCLK * 0x22,
831 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
832 	    .config_function = puc_config_oxford_pcie
833 	},
834 
835 	{   0x1415, 0xc158, 0xffff, 0,
836 	    "Oxford Semiconductor OXPCIe952 UARTs",
837 	    DEFAULT_RCLK * 0x22,
838 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
839 	    .config_function = puc_config_oxford_pcie
840 	},
841 
842 	{   0x1415, 0xc15d, 0xffff, 0,
843 	    "Oxford Semiconductor OXPCIe952 UARTs (function 1)",
844 	    DEFAULT_RCLK * 0x22,
845 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
846 	    .config_function = puc_config_oxford_pcie
847 	},
848 
849 	{   0x1415, 0xc208, 0xffff, 0,
850 	    "Oxford Semiconductor OXPCIe954 UARTs",
851 	    DEFAULT_RCLK * 0x22,
852 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
853 	    .config_function = puc_config_oxford_pcie
854 	},
855 
856 	{   0x1415, 0xc20d, 0xffff, 0,
857 	    "Oxford Semiconductor OXPCIe954 UARTs (function 1)",
858 	    DEFAULT_RCLK * 0x22,
859 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
860 	    .config_function = puc_config_oxford_pcie
861 	},
862 
863 	{   0x1415, 0xc308, 0xffff, 0,
864 	    "Oxford Semiconductor OXPCIe958 UARTs",
865 	    DEFAULT_RCLK * 0x22,
866 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
867 	    .config_function = puc_config_oxford_pcie
868 	},
869 
870 	{   0x1415, 0xc30d, 0xffff, 0,
871 	    "Oxford Semiconductor OXPCIe958 UARTs (function 1)",
872 	    DEFAULT_RCLK * 0x22,
873 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
874 	    .config_function = puc_config_oxford_pcie
875 	},
876 
877 	{   0x14d2, 0x8010, 0xffff, 0,
878 	    "VScom PCI-100L",
879 	    DEFAULT_RCLK * 8,
880 	    PUC_PORT_1S, 0x14, 0, 0,
881 	},
882 
883 	{   0x14d2, 0x8020, 0xffff, 0,
884 	    "VScom PCI-200L",
885 	    DEFAULT_RCLK * 8,
886 	    PUC_PORT_2S, 0x14, 4, 0,
887 	},
888 
889 	{   0x14d2, 0x8028, 0xffff, 0,
890 	    "VScom 200Li",
891 	    DEFAULT_RCLK,
892 	    PUC_PORT_2S, 0x20, 0, 8,
893 	},
894 
895 	/*
896 	 * VScom (Titan?) PCI-800L.  More modern variant of the
897 	 * PCI-800.  Uses 6 discrete 16550 UARTs, plus another
898 	 * two of them obviously implemented as macro cells in
899 	 * the ASIC.  This causes the weird port access pattern
900 	 * below, where two of the IO port ranges each access
901 	 * one of the ASIC UARTs, and a block of IO addresses
902 	 * access the external UARTs.
903 	 */
904 	{   0x14d2, 0x8080, 0xffff, 0,
905 	    "Titan VScom PCI-800L",
906 	    DEFAULT_RCLK * 8,
907 	    PUC_PORT_8S, 0x14, -1, -1,
908 	    .config_function = puc_config_titan
909 	},
910 
911 	/*
912 	 * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers
913 	 * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has
914 	 * device ID 3 and PCI device 1 device ID 4.
915 	 */
916 	{   0x14d2, 0xa003, 0xffff, 0,
917 	    "Titan PCI-800H",
918 	    DEFAULT_RCLK * 8,
919 	    PUC_PORT_4S, 0x10, 0, 8,
920 	},
921 
922 	{   0x14d2, 0xa004, 0xffff, 0,
923 	    "Titan PCI-800H",
924 	    DEFAULT_RCLK * 8,
925 	    PUC_PORT_4S, 0x10, 0, 8,
926 	},
927 
928 	{   0x14d2, 0xa005, 0xffff, 0,
929 	    "Titan PCI-200H",
930 	    DEFAULT_RCLK * 8,
931 	    PUC_PORT_2S, 0x10, 0, 8,
932 	},
933 
934 	{   0x14d2, 0xe020, 0xffff, 0,
935 	    "Titan VScom PCI-200HV2",
936 	    DEFAULT_RCLK * 8,
937 	    PUC_PORT_2S, 0x10, 4, 0,
938 	},
939 
940 	{   0x14d2, 0xa007, 0xffff, 0,
941 	    "Titan VScom PCIex-800H",
942 	    DEFAULT_RCLK * 8,
943 	    PUC_PORT_4S, 0x10, 0, 8,
944 	},
945 
946 	{   0x14d2, 0xa008, 0xffff, 0,
947 	    "Titan VScom PCIex-800H",
948 	    DEFAULT_RCLK * 8,
949 	    PUC_PORT_4S, 0x10, 0, 8,
950 	},
951 
952 	{   0x14db, 0x2130, 0xffff, 0,
953 	    "Avlab Technology, PCI IO 2S",
954 	    DEFAULT_RCLK,
955 	    PUC_PORT_2S, 0x10, 4, 0,
956 	},
957 
958 	{   0x14db, 0x2150, 0xffff, 0,
959 	    "Avlab Low Profile PCI 4 Serial",
960 	    DEFAULT_RCLK,
961 	    PUC_PORT_4S, 0x10, 4, 0,
962 	},
963 
964 	{   0x14db, 0x2152, 0xffff, 0,
965 	    "Avlab Low Profile PCI 4 Serial",
966 	    DEFAULT_RCLK,
967 	    PUC_PORT_4S, 0x10, 4, 0,
968 	},
969 
970 	{   0x1592, 0x0781, 0xffff, 0,
971 	    "Syba Tech Ltd. PCI-4S2P-550-ECP",
972 	    DEFAULT_RCLK,
973 	    PUC_PORT_4S1P, 0x10, 0, -1,
974 	    .config_function = puc_config_syba
975 	},
976 
977 	{   0x1fd4, 0x1999, 0xffff, 0,
978 	    "Sunix SER5437A",
979 	    DEFAULT_RCLK * 8,
980 	    PUC_PORT_2S, 0x10, 0, 8,
981 	},
982 
983 	{    0x5372, 0x6873, 0xffff, 0,
984 	     "Sun 1040 PCI Quad Serial",
985 	     DEFAULT_RCLK,
986 	     PUC_PORT_4S, 0x10, 4, 0,
987 	},
988 
989 	{   0x6666, 0x0001, 0xffff, 0,
990 	    "Decision Computer Inc, PCCOM 4-port serial",
991 	    DEFAULT_RCLK,
992 	    PUC_PORT_4S, 0x1c, 0, 8,
993 	},
994 
995 	{   0x6666, 0x0002, 0xffff, 0,
996 	    "Decision Computer Inc, PCCOM 8-port serial",
997 	    DEFAULT_RCLK,
998 	    PUC_PORT_8S, 0x1c, 0, 8,
999 	},
1000 
1001 	{   0x6666, 0x0004, 0xffff, 0,
1002 	    "PCCOM dual port RS232/422/485",
1003 	    DEFAULT_RCLK,
1004 	    PUC_PORT_2S, 0x1c, 0, 8,
1005 	},
1006 
1007 	{   0x9710, 0x9815, 0xffff, 0,
1008 	    "NetMos NM9815 Dual 1284 Printer port",
1009 	    0,
1010 	    PUC_PORT_2P, 0x10, 8, 0,
1011 	},
1012 
1013 	/*
1014 	 * This is more specific than the generic NM9835 entry that follows, and
1015 	 * is placed here to _prevent_ puc from claiming this single port card.
1016 	 *
1017 	 * uart(4) will claim this device.
1018 	 */
1019 	{   0x9710, 0x9835, 0x1000, 1,
1020 	    "NetMos NM9835 based 1-port serial",
1021 	    DEFAULT_RCLK,
1022 	    PUC_PORT_1S, 0x10, 4, 0,
1023 	},
1024 
1025 	{   0x9710, 0x9835, 0x1000, 2,
1026 	    "NetMos NM9835 based 2-port serial",
1027 	    DEFAULT_RCLK,
1028 	    PUC_PORT_2S, 0x10, 4, 0,
1029 	},
1030 
1031 	{   0x9710, 0x9835, 0xffff, 0,
1032 	    "NetMos NM9835 Dual UART and 1284 Printer port",
1033 	    DEFAULT_RCLK,
1034 	    PUC_PORT_2S1P, 0x10, 4, 0,
1035 	},
1036 
1037 	{   0x9710, 0x9845, 0x1000, 0x0006,
1038 	    "NetMos NM9845 6 Port UART",
1039 	    DEFAULT_RCLK,
1040 	    PUC_PORT_6S, 0x10, 4, 0,
1041 	},
1042 
1043 	{   0x9710, 0x9845, 0xffff, 0,
1044 	    "NetMos NM9845 Quad UART and 1284 Printer port",
1045 	    DEFAULT_RCLK,
1046 	    PUC_PORT_4S1P, 0x10, 4, 0,
1047 	},
1048 
1049 	{   0x9710, 0x9865, 0xa000, 0x3002,
1050 	    "NetMos NM9865 Dual UART",
1051 	    DEFAULT_RCLK,
1052 	    PUC_PORT_2S, 0x10, 4, 0,
1053 	},
1054 
1055 	{   0x9710, 0x9865, 0xa000, 0x3003,
1056 	    "NetMos NM9865 Triple UART",
1057 	    DEFAULT_RCLK,
1058 	    PUC_PORT_3S, 0x10, 4, 0,
1059 	},
1060 
1061 	{   0x9710, 0x9865, 0xa000, 0x3004,
1062 	    "NetMos NM9865 Quad UART",
1063 	    DEFAULT_RCLK,
1064 	    PUC_PORT_4S, 0x10, 4, 0,
1065 	},
1066 
1067 	{   0x9710, 0x9865, 0xa000, 0x3011,
1068 	    "NetMos NM9865 Single UART and 1284 Printer port",
1069 	    DEFAULT_RCLK,
1070 	    PUC_PORT_1S1P, 0x10, 4, 0,
1071 	},
1072 
1073 	{   0x9710, 0x9865, 0xa000, 0x3012,
1074 	    "NetMos NM9865 Dual UART and 1284 Printer port",
1075 	    DEFAULT_RCLK,
1076 	    PUC_PORT_2S1P, 0x10, 4, 0,
1077 	},
1078 
1079 	{   0x9710, 0x9865, 0xa000, 0x3020,
1080 	    "NetMos NM9865 Dual 1284 Printer port",
1081 	    DEFAULT_RCLK,
1082 	    PUC_PORT_2P, 0x10, 4, 0,
1083 	},
1084 
1085 	{   0xb00c, 0x021c, 0xffff, 0,
1086 	    "IC Book Labs Gunboat x4 Lite",
1087 	    DEFAULT_RCLK,
1088 	    PUC_PORT_4S, 0x10, 0, 8,
1089 	    .config_function = puc_config_icbook
1090 	},
1091 
1092 	{   0xb00c, 0x031c, 0xffff, 0,
1093 	    "IC Book Labs Gunboat x4 Pro",
1094 	    DEFAULT_RCLK,
1095 	    PUC_PORT_4S, 0x10, 0, 8,
1096 	    .config_function = puc_config_icbook
1097 	},
1098 
1099 	{   0xb00c, 0x041c, 0xffff, 0,
1100 	    "IC Book Labs Ironclad x8 Lite",
1101 	    DEFAULT_RCLK,
1102 	    PUC_PORT_8S, 0x10, 0, 8,
1103 	    .config_function = puc_config_icbook
1104 	},
1105 
1106 	{   0xb00c, 0x051c, 0xffff, 0,
1107 	    "IC Book Labs Ironclad x8 Pro",
1108 	    DEFAULT_RCLK,
1109 	    PUC_PORT_8S, 0x10, 0, 8,
1110 	    .config_function = puc_config_icbook
1111 	},
1112 
1113 	{   0xb00c, 0x081c, 0xffff, 0,
1114 	    "IC Book Labs Dreadnought x16 Pro",
1115 	    DEFAULT_RCLK * 8,
1116 	    PUC_PORT_16S, 0x10, 0, 8,
1117 	    .config_function = puc_config_icbook
1118 	},
1119 
1120 	{   0xb00c, 0x091c, 0xffff, 0,
1121 	    "IC Book Labs Dreadnought x16 Lite",
1122 	    DEFAULT_RCLK,
1123 	    PUC_PORT_16S, 0x10, 0, 8,
1124 	    .config_function = puc_config_icbook
1125 	},
1126 
1127 	{   0xb00c, 0x0a1c, 0xffff, 0,
1128 	    "IC Book Labs Gunboat x2 Low Profile",
1129 	    DEFAULT_RCLK,
1130 	    PUC_PORT_2S, 0x10, 0, 8,
1131 	},
1132 
1133 	{   0xb00c, 0x0b1c, 0xffff, 0,
1134 	    "IC Book Labs Gunboat x4 Low Profile",
1135 	    DEFAULT_RCLK,
1136 	    PUC_PORT_4S, 0x10, 0, 8,
1137 	    .config_function = puc_config_icbook
1138 	},
1139 
1140 	{ 0xffff, 0, 0xffff, 0, NULL, 0 }
1141 };
1142 
1143 static int
1144 puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1145     intptr_t *res)
1146 {
1147 	switch (cmd) {
1148 	case PUC_CFG_GET_OFS:
1149 		*res = 8 * (port & 1);
1150 		return (0);
1151 	case PUC_CFG_GET_RID:
1152 		*res = 0x14 + (port >> 1) * 4;
1153 		return (0);
1154 	default:
1155 		break;
1156 	}
1157 	return (ENXIO);
1158 }
1159 
1160 static int
1161 puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1162     intptr_t *res)
1163 {
1164 	const struct puc_cfg *cfg = sc->sc_cfg;
1165 
1166 	if (cmd == PUC_CFG_GET_OFS) {
1167 		if (cfg->subdevice == 0x1282)		/* Everest SP */
1168 			port <<= 1;
1169 		else if (cfg->subdevice == 0x104b)	/* Maestro SP2 */
1170 			port = (port == 3) ? 4 : port;
1171 		*res = port * 8 + ((port > 2) ? 0x18 : 0);
1172 		return (0);
1173 	}
1174 	return (ENXIO);
1175 }
1176 
1177 static int
1178 puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1179     intptr_t *res)
1180 {
1181 	if (cmd == PUC_CFG_GET_OFS) {
1182 		*res = port * 0x200;
1183 		return (0);
1184 	}
1185 	return (ENXIO);
1186 }
1187 
1188 static int
1189 puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1190     intptr_t *res)
1191 {
1192 	if (cmd == PUC_CFG_GET_ILR) {
1193 		*res = PUC_ILR_DIGI;
1194 		return (0);
1195 	}
1196 	return (ENXIO);
1197 }
1198 
1199 static int
1200 puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1201     intptr_t *res)
1202 {
1203 	if (cmd == PUC_CFG_GET_OFS) {
1204 		const struct puc_cfg *cfg = sc->sc_cfg;
1205 
1206 		if (port == 3 && (cfg->device == 0x1045 || cfg->device == 0x1144))
1207 			port = 7;
1208 		*res = port * 0x200;
1209 
1210 		return 0;
1211 	}
1212 	return (ENXIO);
1213 }
1214 
1215 static int
1216 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1217     intptr_t *res)
1218 {
1219 	const struct puc_cfg *cfg = sc->sc_cfg;
1220 	struct puc_bar *bar;
1221 	uint8_t v0, v1;
1222 
1223 	switch (cmd) {
1224 	case PUC_CFG_SETUP:
1225 		/*
1226 		 * Check if the scratchpad register is enabled or if the
1227 		 * interrupt status and options registers are active.
1228 		 */
1229 		bar = puc_get_bar(sc, cfg->rid);
1230 		if (bar == NULL)
1231 			return (ENXIO);
1232 		/* Set DLAB in the LCR register of UART 0. */
1233 		bus_write_1(bar->b_res, 3, 0x80);
1234 		/* Write 0 to the SPR register of UART 0. */
1235 		bus_write_1(bar->b_res, 7, 0);
1236 		/* Read back the contents of the SPR register of UART 0. */
1237 		v0 = bus_read_1(bar->b_res, 7);
1238 		/* Write a specific value to the SPR register of UART 0. */
1239 		bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
1240 		/* Read back the contents of the SPR register of UART 0. */
1241 		v1 = bus_read_1(bar->b_res, 7);
1242 		/* Clear DLAB in the LCR register of UART 0. */
1243 		bus_write_1(bar->b_res, 3, 0);
1244 		/* Save the two values read-back from the SPR register. */
1245 		sc->sc_cfg_data = (v0 << 8) | v1;
1246 		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1247 			/*
1248 			 * The SPR register echoed the two values written
1249 			 * by us. This means that the SPAD jumper is set.
1250 			 */
1251 			device_printf(sc->sc_dev, "warning: extra features "
1252 			    "not usable -- SPAD compatibility enabled\n");
1253 			return (0);
1254 		}
1255 		if (v0 != 0) {
1256 			/*
1257 			 * The first value doesn't match. This can only mean
1258 			 * that the SPAD jumper is not set and that a non-
1259 			 * standard fixed clock multiplier jumper is set.
1260 			 */
1261 			if (bootverbose)
1262 				device_printf(sc->sc_dev, "fixed clock rate "
1263 				    "multiplier of %d\n", 1 << v0);
1264 			if (v0 < -cfg->clock)
1265 				device_printf(sc->sc_dev, "warning: "
1266 				    "suboptimal fixed clock rate multiplier "
1267 				    "setting\n");
1268 			return (0);
1269 		}
1270 		/*
1271 		 * The first value matched, but the second didn't. We know
1272 		 * that the SPAD jumper is not set. We also know that the
1273 		 * clock rate multiplier is software controlled *and* that
1274 		 * we just programmed it to the maximum allowed.
1275 		 */
1276 		if (bootverbose)
1277 			device_printf(sc->sc_dev, "clock rate multiplier of "
1278 			    "%d selected\n", 1 << -cfg->clock);
1279 		return (0);
1280 	case PUC_CFG_GET_CLOCK:
1281 		v0 = (sc->sc_cfg_data >> 8) & 0xff;
1282 		v1 = sc->sc_cfg_data & 0xff;
1283 		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1284 			/*
1285 			 * XXX With the SPAD jumper applied, there's no
1286 			 * easy way of knowing if there's also a clock
1287 			 * rate multiplier jumper installed. Let's hope
1288 			 * not...
1289 			 */
1290 			*res = DEFAULT_RCLK;
1291 		} else if (v0 == 0) {
1292 			/*
1293 			 * No clock rate multiplier jumper installed,
1294 			 * so we programmed the board with the maximum
1295 			 * multiplier allowed as given to us in the
1296 			 * clock field of the config record (negated).
1297 			 */
1298 			*res = DEFAULT_RCLK << -cfg->clock;
1299 		} else
1300 			*res = DEFAULT_RCLK << v0;
1301 		return (0);
1302 	case PUC_CFG_GET_ILR:
1303 		v0 = (sc->sc_cfg_data >> 8) & 0xff;
1304 		v1 = sc->sc_cfg_data & 0xff;
1305 		*res = (v0 == 0 && v1 == 0x80 + -cfg->clock)
1306 		    ? PUC_ILR_NONE : PUC_ILR_QUATECH;
1307 		return (0);
1308 	default:
1309 		break;
1310 	}
1311 	return (ENXIO);
1312 }
1313 
1314 static int
1315 puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1316     intptr_t *res)
1317 {
1318 	static int base[] = { 0x251, 0x3f0, 0 };
1319 	const struct puc_cfg *cfg = sc->sc_cfg;
1320 	struct puc_bar *bar;
1321 	int efir, idx, ofs;
1322 	uint8_t v;
1323 
1324 	switch (cmd) {
1325 	case PUC_CFG_SETUP:
1326 		bar = puc_get_bar(sc, cfg->rid);
1327 		if (bar == NULL)
1328 			return (ENXIO);
1329 
1330 		/* configure both W83877TFs */
1331 		bus_write_1(bar->b_res, 0x250, 0x89);
1332 		bus_write_1(bar->b_res, 0x3f0, 0x87);
1333 		bus_write_1(bar->b_res, 0x3f0, 0x87);
1334 		idx = 0;
1335 		while (base[idx] != 0) {
1336 			efir = base[idx];
1337 			bus_write_1(bar->b_res, efir, 0x09);
1338 			v = bus_read_1(bar->b_res, efir + 1);
1339 			if ((v & 0x0f) != 0x0c)
1340 				return (ENXIO);
1341 			bus_write_1(bar->b_res, efir, 0x16);
1342 			v = bus_read_1(bar->b_res, efir + 1);
1343 			bus_write_1(bar->b_res, efir, 0x16);
1344 			bus_write_1(bar->b_res, efir + 1, v | 0x04);
1345 			bus_write_1(bar->b_res, efir, 0x16);
1346 			bus_write_1(bar->b_res, efir + 1, v & ~0x04);
1347 			ofs = base[idx] & 0x300;
1348 			bus_write_1(bar->b_res, efir, 0x23);
1349 			bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2);
1350 			bus_write_1(bar->b_res, efir, 0x24);
1351 			bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2);
1352 			bus_write_1(bar->b_res, efir, 0x25);
1353 			bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2);
1354 			bus_write_1(bar->b_res, efir, 0x17);
1355 			bus_write_1(bar->b_res, efir + 1, 0x03);
1356 			bus_write_1(bar->b_res, efir, 0x28);
1357 			bus_write_1(bar->b_res, efir + 1, 0x43);
1358 			idx++;
1359 		}
1360 		bus_write_1(bar->b_res, 0x250, 0xaa);
1361 		bus_write_1(bar->b_res, 0x3f0, 0xaa);
1362 		return (0);
1363 	case PUC_CFG_GET_OFS:
1364 		switch (port) {
1365 		case 0:
1366 			*res = 0x2f8;
1367 			return (0);
1368 		case 1:
1369 			*res = 0x2e8;
1370 			return (0);
1371 		case 2:
1372 			*res = 0x3f8;
1373 			return (0);
1374 		case 3:
1375 			*res = 0x3e8;
1376 			return (0);
1377 		case 4:
1378 			*res = 0x278;
1379 			return (0);
1380 		}
1381 		break;
1382 	default:
1383 		break;
1384 	}
1385 	return (ENXIO);
1386 }
1387 
1388 static int
1389 puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1390     intptr_t *res)
1391 {
1392 	const struct puc_cfg *cfg = sc->sc_cfg;
1393 
1394 	switch (cmd) {
1395 	case PUC_CFG_GET_OFS:
1396 		if (cfg->ports == PUC_PORT_8S) {
1397 			*res = (port > 4) ? 8 * (port - 4) : 0;
1398 			return (0);
1399 		}
1400 		break;
1401 	case PUC_CFG_GET_RID:
1402 		if (cfg->ports == PUC_PORT_8S) {
1403 			*res = 0x10 + ((port > 4) ? 0x10 : 4 * port);
1404 			return (0);
1405 		}
1406 		if (cfg->ports == PUC_PORT_2S1P) {
1407 			switch (port) {
1408 			case 0: *res = 0x10; return (0);
1409 			case 1: *res = 0x14; return (0);
1410 			case 2: *res = 0x1c; return (0);
1411 			}
1412 		}
1413 		break;
1414 	default:
1415 		break;
1416 	}
1417 	return (ENXIO);
1418 }
1419 
1420 static int
1421 puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1422     intptr_t *res)
1423 {
1424 	static const uint16_t dual[] = {
1425 	    0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
1426 	    0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
1427 	    0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
1428 	    0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
1429 	    0xD079, 0
1430 	};
1431 	static const uint16_t quad[] = {
1432 	    0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
1433 	    0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
1434 	    0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
1435 	    0xB157, 0
1436 	};
1437 	static const uint16_t octa[] = {
1438 	    0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
1439 	    0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
1440 	};
1441 	static const struct {
1442 		int ports;
1443 		const uint16_t *ids;
1444 	} subdevs[] = {
1445 	    { 2, dual },
1446 	    { 4, quad },
1447 	    { 8, octa },
1448 	    { 0, NULL }
1449 	};
1450 	static char desc[64];
1451 	int dev, id;
1452 	uint16_t subdev;
1453 
1454 	switch (cmd) {
1455 	case PUC_CFG_GET_CLOCK:
1456 		if (port < 2)
1457 			*res = DEFAULT_RCLK * 8;
1458 		else
1459 			*res = DEFAULT_RCLK;
1460 		return (0);
1461 	case PUC_CFG_GET_DESC:
1462 		snprintf(desc, sizeof(desc),
1463 		    "Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
1464 		*res = (intptr_t)desc;
1465 		return (0);
1466 	case PUC_CFG_GET_NPORTS:
1467 		subdev = pci_get_subdevice(sc->sc_dev);
1468 		dev = 0;
1469 		while (subdevs[dev].ports != 0) {
1470 			id = 0;
1471 			while (subdevs[dev].ids[id] != 0) {
1472 				if (subdev == subdevs[dev].ids[id]) {
1473 					sc->sc_cfg_data = subdevs[dev].ports;
1474 					*res = sc->sc_cfg_data;
1475 					return (0);
1476 				}
1477 				id++;
1478 			}
1479 			dev++;
1480 		}
1481 		return (ENXIO);
1482 	case PUC_CFG_GET_OFS:
1483 		*res = (port == 1 || port == 3) ? 8 : 0;
1484 		return (0);
1485 	case PUC_CFG_GET_RID:
1486 		*res = 0x10 + ((port > 3) ? port - 2 : port >> 1) * 4;
1487 		return (0);
1488 	case PUC_CFG_GET_TYPE:
1489 		*res = PUC_TYPE_SERIAL;
1490 		return (0);
1491 	default:
1492 		break;
1493 	}
1494 	return (ENXIO);
1495 }
1496 
1497 static int
1498 puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1499     intptr_t *res)
1500 {
1501 	const struct puc_cfg *cfg = sc->sc_cfg;
1502 	int idx;
1503 	struct puc_bar *bar;
1504 	uint8_t value;
1505 
1506 	switch (cmd) {
1507 	case PUC_CFG_SETUP:
1508 		device_printf(sc->sc_dev, "%d UARTs detected\n",
1509 			sc->sc_nports);
1510 
1511 		/* Set UARTs to enhanced mode */
1512 		bar = puc_get_bar(sc, cfg->rid);
1513 		if (bar == NULL)
1514 			return (ENXIO);
1515 		for (idx = 0; idx < sc->sc_nports; idx++) {
1516 			value = bus_read_1(bar->b_res, 0x1000 + (idx << 9) +
1517 			    0x92);
1518 			bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
1519 			    value | 0x10);
1520 		}
1521 		return (0);
1522 	case PUC_CFG_GET_LEN:
1523 		*res = 0x200;
1524 		return (0);
1525 	case PUC_CFG_GET_NPORTS:
1526 		/*
1527 		 * Check if we are being called from puc_bfe_attach()
1528 		 * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
1529 		 * puc_get_bar(), so we return a value of 16. This has cosmetic
1530 		 * side-effects at worst; in PUC_CFG_GET_DESC,
1531 		 * (int)sc->sc_cfg_data will not contain the true number of
1532 		 * ports in PUC_CFG_GET_DESC, but we are not implementing that
1533 		 * call for this device family anyway.
1534 		 *
1535 		 * The check is for initialisation of sc->sc_bar[idx], which is
1536 		 * only done in puc_bfe_attach().
1537 		 */
1538 		idx = 0;
1539 		do {
1540 			if (sc->sc_bar[idx++].b_rid != -1) {
1541 				sc->sc_cfg_data = 16;
1542 				*res = sc->sc_cfg_data;
1543 				return (0);
1544 			}
1545 		} while (idx < PUC_PCI_BARS);
1546 
1547 		bar = puc_get_bar(sc, cfg->rid);
1548 		if (bar == NULL)
1549 			return (ENXIO);
1550 
1551 		value = bus_read_1(bar->b_res, 0x04);
1552 		if (value == 0)
1553 			return (ENXIO);
1554 
1555 		sc->sc_cfg_data = value;
1556 		*res = sc->sc_cfg_data;
1557 		return (0);
1558 	case PUC_CFG_GET_OFS:
1559 		*res = 0x1000 + (port << 9);
1560 		return (0);
1561 	case PUC_CFG_GET_TYPE:
1562 		*res = PUC_TYPE_SERIAL;
1563 		return (0);
1564 	default:
1565 		break;
1566 	}
1567 	return (ENXIO);
1568 }
1569 
1570 static int
1571 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1572     intptr_t *res)
1573 {
1574 	switch (cmd) {
1575 	case PUC_CFG_GET_OFS:
1576 		*res = (port < 3) ? 0 : (port - 2) << 3;
1577 		return (0);
1578 	case PUC_CFG_GET_RID:
1579 		*res = 0x14 + ((port >= 2) ? 0x0c : port << 2);
1580 		return (0);
1581 	default:
1582 		break;
1583 	}
1584 	return (ENXIO);
1585 }
1586