]> CyberLeo.Net >> Repos - FreeBSD/releng/9.1.git/blob - sys/dev/puc/pucdata.c
Copy stable/9 to releng/9.1 as part of the 9.1-RELEASE release process.
[FreeBSD/releng/9.1.git] / sys / dev / puc / pucdata.c
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         {    0x5372, 0x6873, 0xffff, 0,
936              "Sun 1040 PCI Quad Serial",
937              DEFAULT_RCLK,
938              PUC_PORT_4S, 0x10, 4, 0,
939         },
940
941         {   0x6666, 0x0001, 0xffff, 0,
942             "Decision Computer Inc, PCCOM 4-port serial",
943             DEFAULT_RCLK,
944             PUC_PORT_4S, 0x1c, 0, 8,
945         },
946
947         {   0x6666, 0x0002, 0xffff, 0,
948             "Decision Computer Inc, PCCOM 8-port serial",
949             DEFAULT_RCLK,
950             PUC_PORT_8S, 0x1c, 0, 8,
951         },
952
953         {   0x6666, 0x0004, 0xffff, 0,
954             "PCCOM dual port RS232/422/485",
955             DEFAULT_RCLK,
956             PUC_PORT_2S, 0x1c, 0, 8,
957         },
958
959         {   0x9710, 0x9815, 0xffff, 0,
960             "NetMos NM9815 Dual 1284 Printer port", 
961             0,
962             PUC_PORT_2P, 0x10, 8, 0,
963         }, 
964
965         /*
966          * This is more specific than the generic NM9835 entry that follows, and
967          * is placed here to _prevent_ puc from claiming this single port card.
968          *
969          * uart(4) will claim this device.
970          */
971         {   0x9710, 0x9835, 0x1000, 1,
972             "NetMos NM9835 based 1-port serial",
973             DEFAULT_RCLK,
974             PUC_PORT_1S, 0x10, 4, 0,
975         },
976
977         {   0x9710, 0x9835, 0x1000, 2,
978             "NetMos NM9835 based 2-port serial",
979             DEFAULT_RCLK,
980             PUC_PORT_2S, 0x10, 4, 0,
981         },
982
983         {   0x9710, 0x9835, 0xffff, 0,
984             "NetMos NM9835 Dual UART and 1284 Printer port",
985             DEFAULT_RCLK,
986             PUC_PORT_2S1P, 0x10, 4, 0,
987         },
988
989         {   0x9710, 0x9845, 0x1000, 0x0006,
990             "NetMos NM9845 6 Port UART",
991             DEFAULT_RCLK,
992             PUC_PORT_6S, 0x10, 4, 0,
993         },
994
995         {   0x9710, 0x9845, 0xffff, 0,
996             "NetMos NM9845 Quad UART and 1284 Printer port",
997             DEFAULT_RCLK,
998             PUC_PORT_4S1P, 0x10, 4, 0,
999         },
1000
1001         {   0x9710, 0x9865, 0xa000, 0x3002,
1002             "NetMos NM9865 Dual UART",
1003             DEFAULT_RCLK,
1004             PUC_PORT_2S, 0x10, 4, 0,
1005         },
1006
1007         {   0x9710, 0x9865, 0xa000, 0x3003,
1008             "NetMos NM9865 Triple UART",
1009             DEFAULT_RCLK,
1010             PUC_PORT_3S, 0x10, 4, 0,
1011         },
1012
1013         {   0x9710, 0x9865, 0xa000, 0x3004,
1014             "NetMos NM9865 Quad UART",
1015             DEFAULT_RCLK,
1016             PUC_PORT_4S, 0x10, 4, 0,0
1017         },
1018
1019         {   0x9710, 0x9865, 0xa000, 0x3011,
1020             "NetMos NM9865 Single UART and 1284 Printer port",
1021             DEFAULT_RCLK,
1022             PUC_PORT_1S1P, 0x10, 4, 0,
1023         },
1024
1025         {   0x9710, 0x9865, 0xa000, 0x3012,
1026             "NetMos NM9865 Dual UART and 1284 Printer port",
1027             DEFAULT_RCLK,
1028             PUC_PORT_2S1P, 0x10, 4, 0,
1029         },
1030
1031         {   0x9710, 0x9865, 0xa000, 0x3020,
1032             "NetMos NM9865 Dual 1284 Printer port",
1033             DEFAULT_RCLK,
1034             PUC_PORT_2P, 0x10, 4, 0,
1035         },
1036
1037         {   0xb00c, 0x021c, 0xffff, 0,
1038             "IC Book Labs Gunboat x4 Lite",
1039             DEFAULT_RCLK,
1040             PUC_PORT_4S, 0x10, 0, 8,
1041             .config_function = puc_config_icbook
1042         },
1043
1044         {   0xb00c, 0x031c, 0xffff, 0,
1045             "IC Book Labs Gunboat x4 Pro",
1046             DEFAULT_RCLK,
1047             PUC_PORT_4S, 0x10, 0, 8,
1048             .config_function = puc_config_icbook
1049         },
1050
1051         {   0xb00c, 0x041c, 0xffff, 0,
1052             "IC Book Labs Ironclad x8 Lite",
1053             DEFAULT_RCLK,
1054             PUC_PORT_8S, 0x10, 0, 8,
1055             .config_function = puc_config_icbook
1056         },
1057
1058         {   0xb00c, 0x051c, 0xffff, 0,
1059             "IC Book Labs Ironclad x8 Pro",
1060             DEFAULT_RCLK,
1061             PUC_PORT_8S, 0x10, 0, 8,
1062             .config_function = puc_config_icbook
1063         },
1064
1065         {   0xb00c, 0x081c, 0xffff, 0,
1066             "IC Book Labs Dreadnought x16 Pro",
1067             DEFAULT_RCLK * 8,
1068             PUC_PORT_16S, 0x10, 0, 8,
1069             .config_function = puc_config_icbook
1070         },
1071
1072         {   0xb00c, 0x091c, 0xffff, 0,
1073             "IC Book Labs Dreadnought x16 Lite",
1074             DEFAULT_RCLK,
1075             PUC_PORT_16S, 0x10, 0, 8,
1076             .config_function = puc_config_icbook
1077         },
1078
1079         {   0xb00c, 0x0a1c, 0xffff, 0,
1080             "IC Book Labs Gunboat x2 Low Profile",
1081             DEFAULT_RCLK,
1082             PUC_PORT_2S, 0x10, 0, 8,
1083         },
1084
1085         {   0xb00c, 0x0b1c, 0xffff, 0,
1086             "IC Book Labs Gunboat x4 Low Profile",
1087             DEFAULT_RCLK,
1088             PUC_PORT_4S, 0x10, 0, 8,
1089             .config_function = puc_config_icbook
1090         },
1091
1092         { 0xffff, 0, 0xffff, 0, NULL, 0 }
1093 };
1094
1095 static int
1096 puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1097     intptr_t *res)
1098 {
1099         switch (cmd) {
1100         case PUC_CFG_GET_OFS:
1101                 *res = 8 * (port & 1);
1102                 return (0);
1103         case PUC_CFG_GET_RID:
1104                 *res = 0x14 + (port >> 1) * 4;
1105                 return (0);
1106         default:
1107                 break;
1108         }
1109         return (ENXIO);
1110 }
1111
1112 static int
1113 puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1114     intptr_t *res)
1115 {
1116         const struct puc_cfg *cfg = sc->sc_cfg;
1117
1118         if (cmd == PUC_CFG_GET_OFS) {
1119                 if (cfg->subdevice == 0x1282)           /* Everest SP */
1120                         port <<= 1;
1121                 else if (cfg->subdevice == 0x104b)      /* Maestro SP2 */
1122                         port = (port == 3) ? 4 : port;
1123                 *res = port * 8 + ((port > 2) ? 0x18 : 0);
1124                 return (0);
1125         }
1126         return (ENXIO);
1127 }
1128
1129 static int
1130 puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1131     intptr_t *res)
1132 {
1133         if (cmd == PUC_CFG_GET_OFS) {
1134                 *res = port * 0x200;
1135                 return (0);
1136         }
1137         return (ENXIO);
1138 }
1139
1140 static int
1141 puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1142     intptr_t *res)
1143 {
1144         if (cmd == PUC_CFG_GET_ILR) {
1145                 *res = PUC_ILR_DIGI;
1146                 return (0);
1147         }
1148         return (ENXIO);
1149 }
1150
1151 static int
1152 puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1153     intptr_t *res)
1154 {
1155         if (cmd == PUC_CFG_GET_OFS) {
1156                 *res = ((port == 3) ? 7 : port) * 0x200;
1157                 return 0;
1158         }
1159         return (ENXIO);
1160 }
1161
1162 static int
1163 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1164     intptr_t *res)
1165 {
1166         const struct puc_cfg *cfg = sc->sc_cfg;
1167         struct puc_bar *bar;
1168         uint8_t v0, v1;
1169
1170         switch (cmd) {
1171         case PUC_CFG_SETUP:
1172                 /*
1173                  * Check if the scratchpad register is enabled or if the
1174                  * interrupt status and options registers are active.
1175                  */
1176                 bar = puc_get_bar(sc, cfg->rid);
1177                 if (bar == NULL)
1178                         return (ENXIO);
1179                 /* Set DLAB in the LCR register of UART 0. */
1180                 bus_write_1(bar->b_res, 3, 0x80);
1181                 /* Write 0 to the SPR register of UART 0. */
1182                 bus_write_1(bar->b_res, 7, 0);
1183                 /* Read back the contents of the SPR register of UART 0. */
1184                 v0 = bus_read_1(bar->b_res, 7);
1185                 /* Write a specific value to the SPR register of UART 0. */
1186                 bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
1187                 /* Read back the contents of the SPR register of UART 0. */
1188                 v1 = bus_read_1(bar->b_res, 7);
1189                 /* Clear DLAB in the LCR register of UART 0. */
1190                 bus_write_1(bar->b_res, 3, 0);
1191                 /* Save the two values read-back from the SPR register. */
1192                 sc->sc_cfg_data = (v0 << 8) | v1;
1193                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1194                         /*
1195                          * The SPR register echoed the two values written
1196                          * by us. This means that the SPAD jumper is set.
1197                          */
1198                         device_printf(sc->sc_dev, "warning: extra features "
1199                             "not usable -- SPAD compatibility enabled\n");
1200                         return (0);
1201                 }
1202                 if (v0 != 0) {
1203                         /*
1204                          * The first value doesn't match. This can only mean
1205                          * that the SPAD jumper is not set and that a non-
1206                          * standard fixed clock multiplier jumper is set.
1207                          */
1208                         if (bootverbose)
1209                                 device_printf(sc->sc_dev, "fixed clock rate "
1210                                     "multiplier of %d\n", 1 << v0);
1211                         if (v0 < -cfg->clock)
1212                                 device_printf(sc->sc_dev, "warning: "
1213                                     "suboptimal fixed clock rate multiplier "
1214                                     "setting\n");
1215                         return (0);
1216                 }
1217                 /*
1218                  * The first value matched, but the second didn't. We know
1219                  * that the SPAD jumper is not set. We also know that the
1220                  * clock rate multiplier is software controlled *and* that
1221                  * we just programmed it to the maximum allowed.
1222                  */
1223                 if (bootverbose)
1224                         device_printf(sc->sc_dev, "clock rate multiplier of "
1225                             "%d selected\n", 1 << -cfg->clock);
1226                 return (0);
1227         case PUC_CFG_GET_CLOCK:
1228                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1229                 v1 = sc->sc_cfg_data & 0xff;
1230                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1231                         /*
1232                          * XXX With the SPAD jumper applied, there's no
1233                          * easy way of knowing if there's also a clock
1234                          * rate multiplier jumper installed. Let's hope
1235                          * not...
1236                          */
1237                         *res = DEFAULT_RCLK;
1238                 } else if (v0 == 0) {
1239                         /*
1240                          * No clock rate multiplier jumper installed,
1241                          * so we programmed the board with the maximum
1242                          * multiplier allowed as given to us in the
1243                          * clock field of the config record (negated).
1244                          */
1245                         *res = DEFAULT_RCLK << -cfg->clock;
1246                 } else
1247                         *res = DEFAULT_RCLK << v0;
1248                 return (0);
1249         case PUC_CFG_GET_ILR:
1250                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1251                 v1 = sc->sc_cfg_data & 0xff;
1252                 *res = (v0 == 0 && v1 == 0x80 + -cfg->clock)
1253                     ? PUC_ILR_NONE : PUC_ILR_QUATECH;
1254                 return (0);
1255         default:
1256                 break;
1257         }
1258         return (ENXIO);
1259 }
1260
1261 static int
1262 puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1263     intptr_t *res)
1264 {
1265         static int base[] = { 0x251, 0x3f0, 0 };
1266         const struct puc_cfg *cfg = sc->sc_cfg;
1267         struct puc_bar *bar;
1268         int efir, idx, ofs;
1269         uint8_t v;
1270
1271         switch (cmd) {
1272         case PUC_CFG_SETUP:
1273                 bar = puc_get_bar(sc, cfg->rid);
1274                 if (bar == NULL)
1275                         return (ENXIO);
1276
1277                 /* configure both W83877TFs */
1278                 bus_write_1(bar->b_res, 0x250, 0x89);
1279                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1280                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1281                 idx = 0;
1282                 while (base[idx] != 0) {
1283                         efir = base[idx];
1284                         bus_write_1(bar->b_res, efir, 0x09);
1285                         v = bus_read_1(bar->b_res, efir + 1);
1286                         if ((v & 0x0f) != 0x0c)
1287                                 return (ENXIO);
1288                         bus_write_1(bar->b_res, efir, 0x16);
1289                         v = bus_read_1(bar->b_res, efir + 1);
1290                         bus_write_1(bar->b_res, efir, 0x16);
1291                         bus_write_1(bar->b_res, efir + 1, v | 0x04);
1292                         bus_write_1(bar->b_res, efir, 0x16);
1293                         bus_write_1(bar->b_res, efir + 1, v & ~0x04);
1294                         ofs = base[idx] & 0x300;
1295                         bus_write_1(bar->b_res, efir, 0x23);
1296                         bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2);
1297                         bus_write_1(bar->b_res, efir, 0x24);
1298                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2);
1299                         bus_write_1(bar->b_res, efir, 0x25);
1300                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2);
1301                         bus_write_1(bar->b_res, efir, 0x17);
1302                         bus_write_1(bar->b_res, efir + 1, 0x03);
1303                         bus_write_1(bar->b_res, efir, 0x28);
1304                         bus_write_1(bar->b_res, efir + 1, 0x43);
1305                         idx++;
1306                 }
1307                 bus_write_1(bar->b_res, 0x250, 0xaa);
1308                 bus_write_1(bar->b_res, 0x3f0, 0xaa);
1309                 return (0);
1310         case PUC_CFG_GET_OFS:
1311                 switch (port) {
1312                 case 0:
1313                         *res = 0x2f8;
1314                         return (0);
1315                 case 1:
1316                         *res = 0x2e8;
1317                         return (0);
1318                 case 2:
1319                         *res = 0x3f8;
1320                         return (0);
1321                 case 3:
1322                         *res = 0x3e8;
1323                         return (0);
1324                 case 4:
1325                         *res = 0x278;
1326                         return (0);
1327                 }
1328                 break;
1329         default:
1330                 break;
1331         }
1332         return (ENXIO);
1333 }
1334
1335 static int
1336 puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1337     intptr_t *res)
1338 {
1339         const struct puc_cfg *cfg = sc->sc_cfg;
1340
1341         switch (cmd) {
1342         case PUC_CFG_GET_OFS:
1343                 if (cfg->ports == PUC_PORT_8S) {
1344                         *res = (port > 4) ? 8 * (port - 4) : 0;
1345                         return (0);
1346                 }
1347                 break;
1348         case PUC_CFG_GET_RID:
1349                 if (cfg->ports == PUC_PORT_8S) {
1350                         *res = 0x10 + ((port > 4) ? 0x10 : 4 * port);
1351                         return (0);
1352                 }
1353                 if (cfg->ports == PUC_PORT_2S1P) {
1354                         switch (port) {
1355                         case 0: *res = 0x10; return (0);
1356                         case 1: *res = 0x14; return (0);
1357                         case 2: *res = 0x1c; return (0);
1358                         }
1359                 }
1360                 break;
1361         default:
1362                 break;
1363         }
1364         return (ENXIO);
1365 }
1366
1367 static int
1368 puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1369     intptr_t *res)
1370 {
1371         static uint16_t dual[] = {
1372             0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
1373             0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 
1374             0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, 
1375             0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
1376             0xD079, 0
1377         };
1378         static uint16_t quad[] = {
1379             0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 
1380             0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 
1381             0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
1382             0xB157, 0
1383         };
1384         static uint16_t octa[] = {
1385             0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 
1386             0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
1387         };
1388         static struct {
1389                 int ports;
1390                 uint16_t *ids;
1391         } subdevs[] = {
1392             { 2, dual },
1393             { 4, quad },
1394             { 8, octa },
1395             { 0, NULL }
1396         };
1397         static char desc[64];
1398         int dev, id;
1399         uint16_t subdev;
1400
1401         switch (cmd) {
1402         case PUC_CFG_GET_CLOCK:
1403                 if (port < 2)
1404                         *res = DEFAULT_RCLK * 8;
1405                 else
1406                         *res = DEFAULT_RCLK;
1407                 return (0);
1408         case PUC_CFG_GET_DESC:
1409                 snprintf(desc, sizeof(desc),
1410                     "Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
1411                 *res = (intptr_t)desc;
1412                 return (0);
1413         case PUC_CFG_GET_NPORTS:
1414                 subdev = pci_get_subdevice(sc->sc_dev);
1415                 dev = 0;
1416                 while (subdevs[dev].ports != 0) {
1417                         id = 0;
1418                         while (subdevs[dev].ids[id] != 0) {
1419                                 if (subdev == subdevs[dev].ids[id]) {
1420                                         sc->sc_cfg_data = subdevs[dev].ports;
1421                                         *res = sc->sc_cfg_data;
1422                                         return (0);
1423                                 }
1424                                 id++;
1425                         }
1426                         dev++;
1427                 }
1428                 return (ENXIO);
1429         case PUC_CFG_GET_OFS:
1430                 *res = (port == 1 || port == 3) ? 8 : 0;
1431                 return (0);
1432         case PUC_CFG_GET_RID:
1433                 *res = 0x10 + ((port > 3) ? port - 2 : port >> 1) * 4;
1434                 return (0);
1435         case PUC_CFG_GET_TYPE:
1436                 *res = PUC_TYPE_SERIAL;
1437                 return (0);
1438         default:
1439                 break;
1440         }
1441         return (ENXIO);
1442 }
1443
1444 static int
1445 puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1446     intptr_t *res)
1447 {
1448         const struct puc_cfg *cfg = sc->sc_cfg;
1449         int idx;
1450         struct puc_bar *bar;
1451         uint8_t value;
1452
1453         switch (cmd) {
1454         case PUC_CFG_SETUP:
1455                 device_printf(sc->sc_dev, "%d UARTs detected\n",
1456                         sc->sc_nports);
1457
1458                 /* Set UARTs to enhanced mode */
1459                 bar = puc_get_bar(sc, cfg->rid);
1460                 if (bar == NULL)
1461                         return (ENXIO);
1462                 for (idx = 0; idx < sc->sc_nports; idx++) {
1463                         value = bus_read_1(bar->b_res, 0x1000 + (idx << 9) +
1464                             0x92);
1465                         bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
1466                             value | 0x10);
1467                 }
1468                 return (0);
1469         case PUC_CFG_GET_LEN:
1470                 *res = 0x200;
1471                 return (0);
1472         case PUC_CFG_GET_NPORTS:
1473                 /*
1474                  * Check if we are being called from puc_bfe_attach()
1475                  * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
1476                  * puc_get_bar(), so we return a value of 16. This has cosmetic
1477                  * side-effects at worst; in PUC_CFG_GET_DESC,
1478                  * (int)sc->sc_cfg_data will not contain the true number of
1479                  * ports in PUC_CFG_GET_DESC, but we are not implementing that
1480                  * call for this device family anyway.
1481                  *
1482                  * The check is for initialisation of sc->sc_bar[idx], which is
1483                  * only done in puc_bfe_attach().
1484                  */
1485                 idx = 0;
1486                 do {
1487                         if (sc->sc_bar[idx++].b_rid != -1) {
1488                                 sc->sc_cfg_data = 16;
1489                                 *res = sc->sc_cfg_data;
1490                                 return (0);
1491                         }
1492                 } while (idx < PUC_PCI_BARS);
1493
1494                 bar = puc_get_bar(sc, cfg->rid);
1495                 if (bar == NULL)
1496                         return (ENXIO);
1497
1498                 value = bus_read_1(bar->b_res, 0x04);
1499                 if (value == 0)
1500                         return (ENXIO);
1501
1502                 sc->sc_cfg_data = value;
1503                 *res = sc->sc_cfg_data;
1504                 return (0);
1505         case PUC_CFG_GET_OFS:
1506                 *res = 0x1000 + (port << 9);
1507                 return (0);
1508         case PUC_CFG_GET_TYPE:
1509                 *res = PUC_TYPE_SERIAL;
1510                 return (0);
1511         default:
1512                 break;
1513         }
1514         return (ENXIO);
1515 }
1516
1517 static int
1518 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1519     intptr_t *res)
1520 {
1521         switch (cmd) {
1522         case PUC_CFG_GET_OFS:
1523                 *res = (port < 3) ? 0 : (port - 2) << 3;
1524                 return (0);
1525         case PUC_CFG_GET_RID:
1526                 *res = 0x14 + ((port >= 2) ? 0x0c : port << 2);
1527                 return (0);
1528         default:
1529                 break;
1530         }
1531         return (ENXIO);
1532 }