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