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