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