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