xref: /freebsd/sys/dev/puc/pucdata.c (revision 5ff2bb52cc45a6c2c44a02bc68f373b9093ca219)
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 	{   0x1407, 0x0100, 0xffff, 0,
634 	    "Lava Computers Dual Serial",
635 	    DEFAULT_RCLK,
636 	    PUC_PORT_2S, 0x10, 4, 0,
637 	},
638 
639 	{   0x1407, 0x0101, 0xffff, 0,
640 	    "Lava Computers Quatro A",
641 	    DEFAULT_RCLK,
642 	    PUC_PORT_2S, 0x10, 4, 0,
643 	},
644 
645 	{   0x1407, 0x0102, 0xffff, 0,
646 	    "Lava Computers Quatro B",
647 	    DEFAULT_RCLK,
648 	    PUC_PORT_2S, 0x10, 4, 0,
649 	},
650 
651 	{   0x1407, 0x0120, 0xffff, 0,
652 	    "Lava Computers Quattro-PCI A",
653 	    DEFAULT_RCLK,
654 	    PUC_PORT_2S, 0x10, 4, 0,
655 	},
656 
657 	{   0x1407, 0x0121, 0xffff, 0,
658 	    "Lava Computers Quattro-PCI B",
659 	    DEFAULT_RCLK,
660 	    PUC_PORT_2S, 0x10, 4, 0,
661 	},
662 
663 	{   0x1407, 0x0180, 0xffff, 0,
664 	    "Lava Computers Octo A",
665 	    DEFAULT_RCLK,
666 	    PUC_PORT_4S, 0x10, 4, 0,
667 	},
668 
669 	{   0x1407, 0x0181, 0xffff, 0,
670 	    "Lava Computers Octo B",
671 	    DEFAULT_RCLK,
672 	    PUC_PORT_4S, 0x10, 4, 0,
673 	},
674 
675 	{   0x1409, 0x7268, 0xffff, 0,
676 	    "Sunix SUN1888",
677 	    0,
678 	    PUC_PORT_2P, 0x10, 0, 8,
679 	},
680 
681 	{   0x1409, 0x7168, 0xffff, 0,
682 	    NULL,
683 	    DEFAULT_RCLK * 8,
684 	    PUC_PORT_NONSTANDARD, 0x10, -1, -1,
685 	    .config_function = puc_config_timedia
686 	},
687 
688 	/*
689 	 * Boards with an Oxford Semiconductor chip.
690 	 *
691 	 * Oxford Semiconductor provides documentation for their chip at:
692 	 * <URL:http://www.plxtech.com/products/uart/>
693 	 *
694 	 * As sold by Kouwell <URL:http://www.kouwell.com/>.
695 	 * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports.
696 	 */
697 	{
698 		0x1415, 0x9501, 0x10fc ,0xc070,
699 		"I-O DATA RSA-PCI2/R",
700 		DEFAULT_RCLK * 8,
701 		PUC_PORT_2S, 0x10, 0, 8,
702 	},
703 
704 	{   0x1415, 0x9501, 0x131f, 0x2050,
705 	    "SIIG Cyber 4 PCI 16550",
706 	    DEFAULT_RCLK * 10,
707 	    PUC_PORT_4S, 0x10, 0, 8,
708 	},
709 
710 	{   0x1415, 0x9501, 0x131f, 0x2051,
711 	    "SIIG Cyber 4S PCI 16C650 (20x family)",
712 	    DEFAULT_RCLK * 10,
713 	    PUC_PORT_4S, 0x10, 0, 8,
714 	},
715 
716 	{   0x1415, 0x9501, 0x131f, 0x2052,
717 	    "SIIG Quartet Serial 850",
718 	    DEFAULT_RCLK * 10,
719 	    PUC_PORT_4S, 0x10, 0, 8,
720 	},
721 
722 	{   0x1415, 0x9501, 0x14db, 0x2150,
723 	    "Kuroutoshikou SERIAL4P-LPPCI2",
724 	    DEFAULT_RCLK * 10,
725 	    PUC_PORT_4S, 0x10, 0, 8,
726 	},
727 
728 	{   0x1415, 0x9501, 0xffff, 0,
729 	    "Oxford Semiconductor OX16PCI954 UARTs",
730 	    DEFAULT_RCLK,
731 	    PUC_PORT_4S, 0x10, 0, 8,
732 	},
733 
734 	{   0x1415, 0x950a, 0x131f, 0x2030,
735 	    "SIIG Cyber 2S PCIe",
736 	    DEFAULT_RCLK * 10,
737 	    PUC_PORT_2S, 0x10, 0, 8,
738 	},
739 
740 	{   0x1415, 0x950a, 0xffff, 0,
741 	    "Oxford Semiconductor OX16PCI954 UARTs",
742 	    DEFAULT_RCLK,
743 	    PUC_PORT_4S, 0x10, 0, 8,
744 	},
745 
746 	{   0x1415, 0x9511, 0xffff, 0,
747 	    "Oxford Semiconductor OX9160/OX16PCI954 UARTs (function 1)",
748 	    DEFAULT_RCLK,
749 	    PUC_PORT_4S, 0x10, 0, 8,
750 	},
751 
752 	{   0x1415, 0x9521, 0xffff, 0,
753 	    "Oxford Semiconductor OX16PCI952 UARTs",
754 	    DEFAULT_RCLK,
755 	    PUC_PORT_2S, 0x10, 4, 0,
756 	},
757 
758 	{   0x1415, 0x9538, 0xffff, 0,
759 	    "Oxford Semiconductor OX16PCI958 UARTs",
760 	    DEFAULT_RCLK * 10,
761 	    PUC_PORT_8S, 0x18, 0, 8,
762 	},
763 
764 	/*
765 	 * Perle boards use Oxford Semiconductor chips, but they store the
766 	 * Oxford Semiconductor device ID as a subvendor device ID and use
767 	 * their own device IDs.
768 	 */
769 
770 	{   0x155f, 0x0331, 0xffff, 0,
771 	    "Perle Speed4 LE",
772 	    DEFAULT_RCLK * 8,
773 	    PUC_PORT_4S, 0x10, 0, 8,
774 	},
775 
776 	/*
777 	 * Oxford Semiconductor PCI Express Expresso family
778 	 *
779 	 * Found in many 'native' PCI Express serial boards such as:
780 	 *
781 	 * eMegatech MP954ER4 (4 port) and MP958ER8 (8 port)
782 	 * <URL:http://www.emegatech.com.tw/pdrs232pcie.html>
783 	 *
784 	 * Lindy 51189 (4 port)
785 	 * <URL:http://www.lindy.com> <URL:http://tinyurl.com/lindy-51189>
786 	 *
787 	 * StarTech.com PEX4S952 (4 port) and PEX8S952 (8 port)
788 	 * <URL:http://www.startech.com>
789 	 */
790 
791 	{   0x1415, 0xc138, 0xffff, 0,
792 	    "Oxford Semiconductor OXPCIe952 UARTs",
793 	    DEFAULT_RCLK * 0x22,
794 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
795 	    .config_function = puc_config_oxford_pcie
796 	},
797 
798 	{   0x1415, 0xc158, 0xffff, 0,
799 	    "Oxford Semiconductor OXPCIe952 UARTs",
800 	    DEFAULT_RCLK * 0x22,
801 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
802 	    .config_function = puc_config_oxford_pcie
803 	},
804 
805 	{   0x1415, 0xc15d, 0xffff, 0,
806 	    "Oxford Semiconductor OXPCIe952 UARTs (function 1)",
807 	    DEFAULT_RCLK * 0x22,
808 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
809 	    .config_function = puc_config_oxford_pcie
810 	},
811 
812 	{   0x1415, 0xc208, 0xffff, 0,
813 	    "Oxford Semiconductor OXPCIe954 UARTs",
814 	    DEFAULT_RCLK * 0x22,
815 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
816 	    .config_function = puc_config_oxford_pcie
817 	},
818 
819 	{   0x1415, 0xc20d, 0xffff, 0,
820 	    "Oxford Semiconductor OXPCIe954 UARTs (function 1)",
821 	    DEFAULT_RCLK * 0x22,
822 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
823 	    .config_function = puc_config_oxford_pcie
824 	},
825 
826 	{   0x1415, 0xc308, 0xffff, 0,
827 	    "Oxford Semiconductor OXPCIe958 UARTs",
828 	    DEFAULT_RCLK * 0x22,
829 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
830 	    .config_function = puc_config_oxford_pcie
831 	},
832 
833 	{   0x1415, 0xc30d, 0xffff, 0,
834 	    "Oxford Semiconductor OXPCIe958 UARTs (function 1)",
835 	    DEFAULT_RCLK * 0x22,
836 	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
837 	    .config_function = puc_config_oxford_pcie
838 	},
839 
840 	{   0x14d2, 0x8010, 0xffff, 0,
841 	    "VScom PCI-100L",
842 	    DEFAULT_RCLK * 8,
843 	    PUC_PORT_1S, 0x14, 0, 0,
844 	},
845 
846 	{   0x14d2, 0x8020, 0xffff, 0,
847 	    "VScom PCI-200L",
848 	    DEFAULT_RCLK * 8,
849 	    PUC_PORT_2S, 0x14, 4, 0,
850 	},
851 
852 	{   0x14d2, 0x8028, 0xffff, 0,
853 	    "VScom 200Li",
854 	    DEFAULT_RCLK,
855 	    PUC_PORT_2S, 0x20, 0, 8,
856 	},
857 
858 	/*
859 	 * VScom (Titan?) PCI-800L.  More modern variant of the
860 	 * PCI-800.  Uses 6 discrete 16550 UARTs, plus another
861 	 * two of them obviously implemented as macro cells in
862 	 * the ASIC.  This causes the weird port access pattern
863 	 * below, where two of the IO port ranges each access
864 	 * one of the ASIC UARTs, and a block of IO addresses
865 	 * access the external UARTs.
866 	 */
867 	{   0x14d2, 0x8080, 0xffff, 0,
868 	    "Titan VScom PCI-800L",
869 	    DEFAULT_RCLK * 8,
870 	    PUC_PORT_8S, 0x14, -1, -1,
871 	    .config_function = puc_config_titan
872 	},
873 
874 	/*
875 	 * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers
876 	 * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has
877 	 * device ID 3 and PCI device 1 device ID 4.
878 	 */
879 	{   0x14d2, 0xa003, 0xffff, 0,
880 	    "Titan PCI-800H",
881 	    DEFAULT_RCLK * 8,
882 	    PUC_PORT_4S, 0x10, 0, 8,
883 	},
884 	{   0x14d2, 0xa004, 0xffff, 0,
885 	    "Titan PCI-800H",
886 	    DEFAULT_RCLK * 8,
887 	    PUC_PORT_4S, 0x10, 0, 8,
888 	},
889 
890 	{   0x14d2, 0xa005, 0xffff, 0,
891 	    "Titan PCI-200H",
892 	    DEFAULT_RCLK * 8,
893 	    PUC_PORT_2S, 0x10, 0, 8,
894 	},
895 
896 	{   0x14d2, 0xe020, 0xffff, 0,
897 	    "Titan VScom PCI-200HV2",
898 	    DEFAULT_RCLK * 8,
899 	    PUC_PORT_2S, 0x10, 4, 0,
900 	},
901 
902 	{   0x14d2, 0xa007, 0xffff, 0,
903 	    "Titan VScom PCIex-800H",
904 	    DEFAULT_RCLK * 8,
905 	    PUC_PORT_4S, 0x10, 0, 8,
906 	},
907 
908 	{   0x14d2, 0xa008, 0xffff, 0,
909 	    "Titan VScom PCIex-800H",
910 	    DEFAULT_RCLK * 8,
911 	    PUC_PORT_4S, 0x10, 0, 8,
912 	},
913 
914 	{   0x14db, 0x2130, 0xffff, 0,
915 	    "Avlab Technology, PCI IO 2S",
916 	    DEFAULT_RCLK,
917 	    PUC_PORT_2S, 0x10, 4, 0,
918 	},
919 
920 	{   0x14db, 0x2150, 0xffff, 0,
921 	    "Avlab Low Profile PCI 4 Serial",
922 	    DEFAULT_RCLK,
923 	    PUC_PORT_4S, 0x10, 4, 0,
924 	},
925 
926 	{   0x14db, 0x2152, 0xffff, 0,
927 	    "Avlab Low Profile PCI 4 Serial",
928 	    DEFAULT_RCLK,
929 	    PUC_PORT_4S, 0x10, 4, 0,
930 	},
931 
932 	{   0x1592, 0x0781, 0xffff, 0,
933 	    "Syba Tech Ltd. PCI-4S2P-550-ECP",
934 	    DEFAULT_RCLK,
935 	    PUC_PORT_4S1P, 0x10, 0, -1,
936 	    .config_function = puc_config_syba
937 	},
938 
939 	{   0x1fd4, 0x1999, 0xffff, 0,
940 	    "Sunix SER5437A",
941 	    DEFAULT_RCLK * 8,
942 	    PUC_PORT_2S, 0x10, 0, 8,
943 	},
944 
945 	{    0x5372, 0x6873, 0xffff, 0,
946 	     "Sun 1040 PCI Quad Serial",
947 	     DEFAULT_RCLK,
948 	     PUC_PORT_4S, 0x10, 4, 0,
949 	},
950 
951 	{   0x6666, 0x0001, 0xffff, 0,
952 	    "Decision Computer Inc, PCCOM 4-port serial",
953 	    DEFAULT_RCLK,
954 	    PUC_PORT_4S, 0x1c, 0, 8,
955 	},
956 
957 	{   0x6666, 0x0002, 0xffff, 0,
958 	    "Decision Computer Inc, PCCOM 8-port serial",
959 	    DEFAULT_RCLK,
960 	    PUC_PORT_8S, 0x1c, 0, 8,
961 	},
962 
963 	{   0x6666, 0x0004, 0xffff, 0,
964 	    "PCCOM dual port RS232/422/485",
965 	    DEFAULT_RCLK,
966 	    PUC_PORT_2S, 0x1c, 0, 8,
967 	},
968 
969 	{   0x9710, 0x9815, 0xffff, 0,
970 	    "NetMos NM9815 Dual 1284 Printer port",
971 	    0,
972 	    PUC_PORT_2P, 0x10, 8, 0,
973 	},
974 
975 	/*
976 	 * This is more specific than the generic NM9835 entry that follows, and
977 	 * is placed here to _prevent_ puc from claiming this single port card.
978 	 *
979 	 * uart(4) will claim this device.
980 	 */
981 	{   0x9710, 0x9835, 0x1000, 1,
982 	    "NetMos NM9835 based 1-port serial",
983 	    DEFAULT_RCLK,
984 	    PUC_PORT_1S, 0x10, 4, 0,
985 	},
986 
987 	{   0x9710, 0x9835, 0x1000, 2,
988 	    "NetMos NM9835 based 2-port serial",
989 	    DEFAULT_RCLK,
990 	    PUC_PORT_2S, 0x10, 4, 0,
991 	},
992 
993 	{   0x9710, 0x9835, 0xffff, 0,
994 	    "NetMos NM9835 Dual UART and 1284 Printer port",
995 	    DEFAULT_RCLK,
996 	    PUC_PORT_2S1P, 0x10, 4, 0,
997 	},
998 
999 	{   0x9710, 0x9845, 0x1000, 0x0006,
1000 	    "NetMos NM9845 6 Port UART",
1001 	    DEFAULT_RCLK,
1002 	    PUC_PORT_6S, 0x10, 4, 0,
1003 	},
1004 
1005 	{   0x9710, 0x9845, 0xffff, 0,
1006 	    "NetMos NM9845 Quad UART and 1284 Printer port",
1007 	    DEFAULT_RCLK,
1008 	    PUC_PORT_4S1P, 0x10, 4, 0,
1009 	},
1010 
1011 	{   0x9710, 0x9865, 0xa000, 0x3002,
1012 	    "NetMos NM9865 Dual UART",
1013 	    DEFAULT_RCLK,
1014 	    PUC_PORT_2S, 0x10, 4, 0,
1015 	},
1016 
1017 	{   0x9710, 0x9865, 0xa000, 0x3003,
1018 	    "NetMos NM9865 Triple UART",
1019 	    DEFAULT_RCLK,
1020 	    PUC_PORT_3S, 0x10, 4, 0,
1021 	},
1022 
1023 	{   0x9710, 0x9865, 0xa000, 0x3004,
1024 	    "NetMos NM9865 Quad UART",
1025 	    DEFAULT_RCLK,
1026 	    PUC_PORT_4S, 0x10, 4, 0,0
1027 	},
1028 
1029 	{   0x9710, 0x9865, 0xa000, 0x3011,
1030 	    "NetMos NM9865 Single UART and 1284 Printer port",
1031 	    DEFAULT_RCLK,
1032 	    PUC_PORT_1S1P, 0x10, 4, 0,
1033 	},
1034 
1035 	{   0x9710, 0x9865, 0xa000, 0x3012,
1036 	    "NetMos NM9865 Dual UART and 1284 Printer port",
1037 	    DEFAULT_RCLK,
1038 	    PUC_PORT_2S1P, 0x10, 4, 0,
1039 	},
1040 
1041 	{   0x9710, 0x9865, 0xa000, 0x3020,
1042 	    "NetMos NM9865 Dual 1284 Printer port",
1043 	    DEFAULT_RCLK,
1044 	    PUC_PORT_2P, 0x10, 4, 0,
1045 	},
1046 
1047 	{   0xb00c, 0x021c, 0xffff, 0,
1048 	    "IC Book Labs Gunboat x4 Lite",
1049 	    DEFAULT_RCLK,
1050 	    PUC_PORT_4S, 0x10, 0, 8,
1051 	    .config_function = puc_config_icbook
1052 	},
1053 
1054 	{   0xb00c, 0x031c, 0xffff, 0,
1055 	    "IC Book Labs Gunboat x4 Pro",
1056 	    DEFAULT_RCLK,
1057 	    PUC_PORT_4S, 0x10, 0, 8,
1058 	    .config_function = puc_config_icbook
1059 	},
1060 
1061 	{   0xb00c, 0x041c, 0xffff, 0,
1062 	    "IC Book Labs Ironclad x8 Lite",
1063 	    DEFAULT_RCLK,
1064 	    PUC_PORT_8S, 0x10, 0, 8,
1065 	    .config_function = puc_config_icbook
1066 	},
1067 
1068 	{   0xb00c, 0x051c, 0xffff, 0,
1069 	    "IC Book Labs Ironclad x8 Pro",
1070 	    DEFAULT_RCLK,
1071 	    PUC_PORT_8S, 0x10, 0, 8,
1072 	    .config_function = puc_config_icbook
1073 	},
1074 
1075 	{   0xb00c, 0x081c, 0xffff, 0,
1076 	    "IC Book Labs Dreadnought x16 Pro",
1077 	    DEFAULT_RCLK * 8,
1078 	    PUC_PORT_16S, 0x10, 0, 8,
1079 	    .config_function = puc_config_icbook
1080 	},
1081 
1082 	{   0xb00c, 0x091c, 0xffff, 0,
1083 	    "IC Book Labs Dreadnought x16 Lite",
1084 	    DEFAULT_RCLK,
1085 	    PUC_PORT_16S, 0x10, 0, 8,
1086 	    .config_function = puc_config_icbook
1087 	},
1088 
1089 	{   0xb00c, 0x0a1c, 0xffff, 0,
1090 	    "IC Book Labs Gunboat x2 Low Profile",
1091 	    DEFAULT_RCLK,
1092 	    PUC_PORT_2S, 0x10, 0, 8,
1093 	},
1094 
1095 	{   0xb00c, 0x0b1c, 0xffff, 0,
1096 	    "IC Book Labs Gunboat x4 Low Profile",
1097 	    DEFAULT_RCLK,
1098 	    PUC_PORT_4S, 0x10, 0, 8,
1099 	    .config_function = puc_config_icbook
1100 	},
1101 
1102 	{ 0xffff, 0, 0xffff, 0, NULL, 0 }
1103 };
1104 
1105 static int
1106 puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1107     intptr_t *res)
1108 {
1109 	switch (cmd) {
1110 	case PUC_CFG_GET_OFS:
1111 		*res = 8 * (port & 1);
1112 		return (0);
1113 	case PUC_CFG_GET_RID:
1114 		*res = 0x14 + (port >> 1) * 4;
1115 		return (0);
1116 	default:
1117 		break;
1118 	}
1119 	return (ENXIO);
1120 }
1121 
1122 static int
1123 puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1124     intptr_t *res)
1125 {
1126 	const struct puc_cfg *cfg = sc->sc_cfg;
1127 
1128 	if (cmd == PUC_CFG_GET_OFS) {
1129 		if (cfg->subdevice == 0x1282)		/* Everest SP */
1130 			port <<= 1;
1131 		else if (cfg->subdevice == 0x104b)	/* Maestro SP2 */
1132 			port = (port == 3) ? 4 : port;
1133 		*res = port * 8 + ((port > 2) ? 0x18 : 0);
1134 		return (0);
1135 	}
1136 	return (ENXIO);
1137 }
1138 
1139 static int
1140 puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1141     intptr_t *res)
1142 {
1143 	if (cmd == PUC_CFG_GET_OFS) {
1144 		*res = port * 0x200;
1145 		return (0);
1146 	}
1147 	return (ENXIO);
1148 }
1149 
1150 static int
1151 puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1152     intptr_t *res)
1153 {
1154 	if (cmd == PUC_CFG_GET_ILR) {
1155 		*res = PUC_ILR_DIGI;
1156 		return (0);
1157 	}
1158 	return (ENXIO);
1159 }
1160 
1161 static int
1162 puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1163     intptr_t *res)
1164 {
1165 	if (cmd == PUC_CFG_GET_OFS) {
1166 		const struct puc_cfg *cfg = sc->sc_cfg;
1167 
1168 		if (port == 3 && (cfg->device == 0x1045 || cfg->device == 0x1144))
1169 			port = 7;
1170 		*res = port * 0x200;
1171 
1172 		return 0;
1173 	}
1174 	return (ENXIO);
1175 }
1176 
1177 static int
1178 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1179     intptr_t *res)
1180 {
1181 	const struct puc_cfg *cfg = sc->sc_cfg;
1182 	struct puc_bar *bar;
1183 	uint8_t v0, v1;
1184 
1185 	switch (cmd) {
1186 	case PUC_CFG_SETUP:
1187 		/*
1188 		 * Check if the scratchpad register is enabled or if the
1189 		 * interrupt status and options registers are active.
1190 		 */
1191 		bar = puc_get_bar(sc, cfg->rid);
1192 		if (bar == NULL)
1193 			return (ENXIO);
1194 		/* Set DLAB in the LCR register of UART 0. */
1195 		bus_write_1(bar->b_res, 3, 0x80);
1196 		/* Write 0 to the SPR register of UART 0. */
1197 		bus_write_1(bar->b_res, 7, 0);
1198 		/* Read back the contents of the SPR register of UART 0. */
1199 		v0 = bus_read_1(bar->b_res, 7);
1200 		/* Write a specific value to the SPR register of UART 0. */
1201 		bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
1202 		/* Read back the contents of the SPR register of UART 0. */
1203 		v1 = bus_read_1(bar->b_res, 7);
1204 		/* Clear DLAB in the LCR register of UART 0. */
1205 		bus_write_1(bar->b_res, 3, 0);
1206 		/* Save the two values read-back from the SPR register. */
1207 		sc->sc_cfg_data = (v0 << 8) | v1;
1208 		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1209 			/*
1210 			 * The SPR register echoed the two values written
1211 			 * by us. This means that the SPAD jumper is set.
1212 			 */
1213 			device_printf(sc->sc_dev, "warning: extra features "
1214 			    "not usable -- SPAD compatibility enabled\n");
1215 			return (0);
1216 		}
1217 		if (v0 != 0) {
1218 			/*
1219 			 * The first value doesn't match. This can only mean
1220 			 * that the SPAD jumper is not set and that a non-
1221 			 * standard fixed clock multiplier jumper is set.
1222 			 */
1223 			if (bootverbose)
1224 				device_printf(sc->sc_dev, "fixed clock rate "
1225 				    "multiplier of %d\n", 1 << v0);
1226 			if (v0 < -cfg->clock)
1227 				device_printf(sc->sc_dev, "warning: "
1228 				    "suboptimal fixed clock rate multiplier "
1229 				    "setting\n");
1230 			return (0);
1231 		}
1232 		/*
1233 		 * The first value matched, but the second didn't. We know
1234 		 * that the SPAD jumper is not set. We also know that the
1235 		 * clock rate multiplier is software controlled *and* that
1236 		 * we just programmed it to the maximum allowed.
1237 		 */
1238 		if (bootverbose)
1239 			device_printf(sc->sc_dev, "clock rate multiplier of "
1240 			    "%d selected\n", 1 << -cfg->clock);
1241 		return (0);
1242 	case PUC_CFG_GET_CLOCK:
1243 		v0 = (sc->sc_cfg_data >> 8) & 0xff;
1244 		v1 = sc->sc_cfg_data & 0xff;
1245 		if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1246 			/*
1247 			 * XXX With the SPAD jumper applied, there's no
1248 			 * easy way of knowing if there's also a clock
1249 			 * rate multiplier jumper installed. Let's hope
1250 			 * not...
1251 			 */
1252 			*res = DEFAULT_RCLK;
1253 		} else if (v0 == 0) {
1254 			/*
1255 			 * No clock rate multiplier jumper installed,
1256 			 * so we programmed the board with the maximum
1257 			 * multiplier allowed as given to us in the
1258 			 * clock field of the config record (negated).
1259 			 */
1260 			*res = DEFAULT_RCLK << -cfg->clock;
1261 		} else
1262 			*res = DEFAULT_RCLK << v0;
1263 		return (0);
1264 	case PUC_CFG_GET_ILR:
1265 		v0 = (sc->sc_cfg_data >> 8) & 0xff;
1266 		v1 = sc->sc_cfg_data & 0xff;
1267 		*res = (v0 == 0 && v1 == 0x80 + -cfg->clock)
1268 		    ? PUC_ILR_NONE : PUC_ILR_QUATECH;
1269 		return (0);
1270 	default:
1271 		break;
1272 	}
1273 	return (ENXIO);
1274 }
1275 
1276 static int
1277 puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1278     intptr_t *res)
1279 {
1280 	static int base[] = { 0x251, 0x3f0, 0 };
1281 	const struct puc_cfg *cfg = sc->sc_cfg;
1282 	struct puc_bar *bar;
1283 	int efir, idx, ofs;
1284 	uint8_t v;
1285 
1286 	switch (cmd) {
1287 	case PUC_CFG_SETUP:
1288 		bar = puc_get_bar(sc, cfg->rid);
1289 		if (bar == NULL)
1290 			return (ENXIO);
1291 
1292 		/* configure both W83877TFs */
1293 		bus_write_1(bar->b_res, 0x250, 0x89);
1294 		bus_write_1(bar->b_res, 0x3f0, 0x87);
1295 		bus_write_1(bar->b_res, 0x3f0, 0x87);
1296 		idx = 0;
1297 		while (base[idx] != 0) {
1298 			efir = base[idx];
1299 			bus_write_1(bar->b_res, efir, 0x09);
1300 			v = bus_read_1(bar->b_res, efir + 1);
1301 			if ((v & 0x0f) != 0x0c)
1302 				return (ENXIO);
1303 			bus_write_1(bar->b_res, efir, 0x16);
1304 			v = bus_read_1(bar->b_res, efir + 1);
1305 			bus_write_1(bar->b_res, efir, 0x16);
1306 			bus_write_1(bar->b_res, efir + 1, v | 0x04);
1307 			bus_write_1(bar->b_res, efir, 0x16);
1308 			bus_write_1(bar->b_res, efir + 1, v & ~0x04);
1309 			ofs = base[idx] & 0x300;
1310 			bus_write_1(bar->b_res, efir, 0x23);
1311 			bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2);
1312 			bus_write_1(bar->b_res, efir, 0x24);
1313 			bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2);
1314 			bus_write_1(bar->b_res, efir, 0x25);
1315 			bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2);
1316 			bus_write_1(bar->b_res, efir, 0x17);
1317 			bus_write_1(bar->b_res, efir + 1, 0x03);
1318 			bus_write_1(bar->b_res, efir, 0x28);
1319 			bus_write_1(bar->b_res, efir + 1, 0x43);
1320 			idx++;
1321 		}
1322 		bus_write_1(bar->b_res, 0x250, 0xaa);
1323 		bus_write_1(bar->b_res, 0x3f0, 0xaa);
1324 		return (0);
1325 	case PUC_CFG_GET_OFS:
1326 		switch (port) {
1327 		case 0:
1328 			*res = 0x2f8;
1329 			return (0);
1330 		case 1:
1331 			*res = 0x2e8;
1332 			return (0);
1333 		case 2:
1334 			*res = 0x3f8;
1335 			return (0);
1336 		case 3:
1337 			*res = 0x3e8;
1338 			return (0);
1339 		case 4:
1340 			*res = 0x278;
1341 			return (0);
1342 		}
1343 		break;
1344 	default:
1345 		break;
1346 	}
1347 	return (ENXIO);
1348 }
1349 
1350 static int
1351 puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1352     intptr_t *res)
1353 {
1354 	const struct puc_cfg *cfg = sc->sc_cfg;
1355 
1356 	switch (cmd) {
1357 	case PUC_CFG_GET_OFS:
1358 		if (cfg->ports == PUC_PORT_8S) {
1359 			*res = (port > 4) ? 8 * (port - 4) : 0;
1360 			return (0);
1361 		}
1362 		break;
1363 	case PUC_CFG_GET_RID:
1364 		if (cfg->ports == PUC_PORT_8S) {
1365 			*res = 0x10 + ((port > 4) ? 0x10 : 4 * port);
1366 			return (0);
1367 		}
1368 		if (cfg->ports == PUC_PORT_2S1P) {
1369 			switch (port) {
1370 			case 0: *res = 0x10; return (0);
1371 			case 1: *res = 0x14; return (0);
1372 			case 2: *res = 0x1c; return (0);
1373 			}
1374 		}
1375 		break;
1376 	default:
1377 		break;
1378 	}
1379 	return (ENXIO);
1380 }
1381 
1382 static int
1383 puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1384     intptr_t *res)
1385 {
1386 	static uint16_t dual[] = {
1387 	    0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
1388 	    0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
1389 	    0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
1390 	    0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
1391 	    0xD079, 0
1392 	};
1393 	static uint16_t quad[] = {
1394 	    0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
1395 	    0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
1396 	    0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
1397 	    0xB157, 0
1398 	};
1399 	static uint16_t octa[] = {
1400 	    0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
1401 	    0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
1402 	};
1403 	static struct {
1404 		int ports;
1405 		uint16_t *ids;
1406 	} subdevs[] = {
1407 	    { 2, dual },
1408 	    { 4, quad },
1409 	    { 8, octa },
1410 	    { 0, NULL }
1411 	};
1412 	static char desc[64];
1413 	int dev, id;
1414 	uint16_t subdev;
1415 
1416 	switch (cmd) {
1417 	case PUC_CFG_GET_CLOCK:
1418 		if (port < 2)
1419 			*res = DEFAULT_RCLK * 8;
1420 		else
1421 			*res = DEFAULT_RCLK;
1422 		return (0);
1423 	case PUC_CFG_GET_DESC:
1424 		snprintf(desc, sizeof(desc),
1425 		    "Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
1426 		*res = (intptr_t)desc;
1427 		return (0);
1428 	case PUC_CFG_GET_NPORTS:
1429 		subdev = pci_get_subdevice(sc->sc_dev);
1430 		dev = 0;
1431 		while (subdevs[dev].ports != 0) {
1432 			id = 0;
1433 			while (subdevs[dev].ids[id] != 0) {
1434 				if (subdev == subdevs[dev].ids[id]) {
1435 					sc->sc_cfg_data = subdevs[dev].ports;
1436 					*res = sc->sc_cfg_data;
1437 					return (0);
1438 				}
1439 				id++;
1440 			}
1441 			dev++;
1442 		}
1443 		return (ENXIO);
1444 	case PUC_CFG_GET_OFS:
1445 		*res = (port == 1 || port == 3) ? 8 : 0;
1446 		return (0);
1447 	case PUC_CFG_GET_RID:
1448 		*res = 0x10 + ((port > 3) ? port - 2 : port >> 1) * 4;
1449 		return (0);
1450 	case PUC_CFG_GET_TYPE:
1451 		*res = PUC_TYPE_SERIAL;
1452 		return (0);
1453 	default:
1454 		break;
1455 	}
1456 	return (ENXIO);
1457 }
1458 
1459 static int
1460 puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1461     intptr_t *res)
1462 {
1463 	const struct puc_cfg *cfg = sc->sc_cfg;
1464 	int idx;
1465 	struct puc_bar *bar;
1466 	uint8_t value;
1467 
1468 	switch (cmd) {
1469 	case PUC_CFG_SETUP:
1470 		device_printf(sc->sc_dev, "%d UARTs detected\n",
1471 			sc->sc_nports);
1472 
1473 		/* Set UARTs to enhanced mode */
1474 		bar = puc_get_bar(sc, cfg->rid);
1475 		if (bar == NULL)
1476 			return (ENXIO);
1477 		for (idx = 0; idx < sc->sc_nports; idx++) {
1478 			value = bus_read_1(bar->b_res, 0x1000 + (idx << 9) +
1479 			    0x92);
1480 			bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
1481 			    value | 0x10);
1482 		}
1483 		return (0);
1484 	case PUC_CFG_GET_LEN:
1485 		*res = 0x200;
1486 		return (0);
1487 	case PUC_CFG_GET_NPORTS:
1488 		/*
1489 		 * Check if we are being called from puc_bfe_attach()
1490 		 * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
1491 		 * puc_get_bar(), so we return a value of 16. This has cosmetic
1492 		 * side-effects at worst; in PUC_CFG_GET_DESC,
1493 		 * (int)sc->sc_cfg_data will not contain the true number of
1494 		 * ports in PUC_CFG_GET_DESC, but we are not implementing that
1495 		 * call for this device family anyway.
1496 		 *
1497 		 * The check is for initialisation of sc->sc_bar[idx], which is
1498 		 * only done in puc_bfe_attach().
1499 		 */
1500 		idx = 0;
1501 		do {
1502 			if (sc->sc_bar[idx++].b_rid != -1) {
1503 				sc->sc_cfg_data = 16;
1504 				*res = sc->sc_cfg_data;
1505 				return (0);
1506 			}
1507 		} while (idx < PUC_PCI_BARS);
1508 
1509 		bar = puc_get_bar(sc, cfg->rid);
1510 		if (bar == NULL)
1511 			return (ENXIO);
1512 
1513 		value = bus_read_1(bar->b_res, 0x04);
1514 		if (value == 0)
1515 			return (ENXIO);
1516 
1517 		sc->sc_cfg_data = value;
1518 		*res = sc->sc_cfg_data;
1519 		return (0);
1520 	case PUC_CFG_GET_OFS:
1521 		*res = 0x1000 + (port << 9);
1522 		return (0);
1523 	case PUC_CFG_GET_TYPE:
1524 		*res = PUC_TYPE_SERIAL;
1525 		return (0);
1526 	default:
1527 		break;
1528 	}
1529 	return (ENXIO);
1530 }
1531 
1532 static int
1533 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1534     intptr_t *res)
1535 {
1536 	switch (cmd) {
1537 	case PUC_CFG_GET_OFS:
1538 		*res = (port < 3) ? 0 : (port - 2) << 3;
1539 		return (0);
1540 	case PUC_CFG_GET_RID:
1541 		*res = 0x14 + ((port >= 2) ? 0x0c : port << 2);
1542 		return (0);
1543 	default:
1544 		break;
1545 	}
1546 	return (ENXIO);
1547 }
1548