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