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