]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/puc/pucdata.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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, 0xc11b, 0xffff, 0,
842             "Oxford Semiconductor OXPCIe952 1S1P",
843             DEFAULT_RCLK * 0x22,
844             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
845             .config_function = puc_config_oxford_pcie
846         },
847
848         {   0x1415, 0xc138, 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, 0xc158, 0xffff, 0,
856             "Oxford Semiconductor OXPCIe952 UARTs",
857             DEFAULT_RCLK * 0x22,
858             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
859             .config_function = puc_config_oxford_pcie
860         },
861
862         {   0x1415, 0xc15d, 0xffff, 0,
863             "Oxford Semiconductor OXPCIe952 UARTs (function 1)",
864             DEFAULT_RCLK * 0x22,
865             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
866             .config_function = puc_config_oxford_pcie
867         },
868
869         {   0x1415, 0xc208, 0xffff, 0,
870             "Oxford Semiconductor OXPCIe954 UARTs",
871             DEFAULT_RCLK * 0x22,
872             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
873             .config_function = puc_config_oxford_pcie
874         },
875
876         {   0x1415, 0xc20d, 0xffff, 0,
877             "Oxford Semiconductor OXPCIe954 UARTs (function 1)",
878             DEFAULT_RCLK * 0x22,
879             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
880             .config_function = puc_config_oxford_pcie
881         },
882
883         {   0x1415, 0xc308, 0xffff, 0,
884             "Oxford Semiconductor OXPCIe958 UARTs",
885             DEFAULT_RCLK * 0x22,
886             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
887             .config_function = puc_config_oxford_pcie
888         },
889
890         {   0x1415, 0xc30d, 0xffff, 0,
891             "Oxford Semiconductor OXPCIe958 UARTs (function 1)",
892             DEFAULT_RCLK * 0x22,
893             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
894             .config_function = puc_config_oxford_pcie
895         },
896
897         {   0x14d2, 0x8010, 0xffff, 0,
898             "VScom PCI-100L",
899             DEFAULT_RCLK * 8,
900             PUC_PORT_1S, 0x14, 0, 0,
901         },
902
903         {   0x14d2, 0x8020, 0xffff, 0,
904             "VScom PCI-200L",
905             DEFAULT_RCLK * 8,
906             PUC_PORT_2S, 0x14, 4, 0,
907         },
908
909         {   0x14d2, 0x8028, 0xffff, 0,
910             "VScom 200Li",
911             DEFAULT_RCLK,
912             PUC_PORT_2S, 0x20, 0, 8,
913         },
914
915         /*
916          * VScom (Titan?) PCI-800L.  More modern variant of the
917          * PCI-800.  Uses 6 discrete 16550 UARTs, plus another
918          * two of them obviously implemented as macro cells in
919          * the ASIC.  This causes the weird port access pattern
920          * below, where two of the IO port ranges each access
921          * one of the ASIC UARTs, and a block of IO addresses
922          * access the external UARTs.
923          */
924         {   0x14d2, 0x8080, 0xffff, 0,
925             "Titan VScom PCI-800L",
926             DEFAULT_RCLK * 8,
927             PUC_PORT_8S, 0x14, -1, -1,
928             .config_function = puc_config_titan
929         },
930
931         /*
932          * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers
933          * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has
934          * device ID 3 and PCI device 1 device ID 4.
935          */
936         {   0x14d2, 0xa003, 0xffff, 0,
937             "Titan PCI-800H",
938             DEFAULT_RCLK * 8,
939             PUC_PORT_4S, 0x10, 0, 8,
940         },
941
942         {   0x14d2, 0xa004, 0xffff, 0,
943             "Titan PCI-800H",
944             DEFAULT_RCLK * 8,
945             PUC_PORT_4S, 0x10, 0, 8,
946         },
947
948         {   0x14d2, 0xa005, 0xffff, 0,
949             "Titan PCI-200H",
950             DEFAULT_RCLK * 8,
951             PUC_PORT_2S, 0x10, 0, 8,
952         },
953
954         {   0x14d2, 0xe020, 0xffff, 0,
955             "Titan VScom PCI-200HV2",
956             DEFAULT_RCLK * 8,
957             PUC_PORT_2S, 0x10, 4, 0,
958         },
959
960         {   0x14d2, 0xa007, 0xffff, 0,
961             "Titan VScom PCIex-800H",
962             DEFAULT_RCLK * 8,
963             PUC_PORT_4S, 0x10, 0, 8,
964         },
965
966         {   0x14d2, 0xa008, 0xffff, 0,
967             "Titan VScom PCIex-800H",
968             DEFAULT_RCLK * 8,
969             PUC_PORT_4S, 0x10, 0, 8,
970         },
971
972         {   0x14db, 0x2130, 0xffff, 0,
973             "Avlab Technology, PCI IO 2S",
974             DEFAULT_RCLK,
975             PUC_PORT_2S, 0x10, 4, 0,
976         },
977
978         {   0x14db, 0x2150, 0xffff, 0,
979             "Avlab Low Profile PCI 4 Serial",
980             DEFAULT_RCLK,
981             PUC_PORT_4S, 0x10, 4, 0,
982         },
983
984         {   0x14db, 0x2152, 0xffff, 0,
985             "Avlab Low Profile PCI 4 Serial",
986             DEFAULT_RCLK,
987             PUC_PORT_4S, 0x10, 4, 0,
988         },
989
990         {   0x1592, 0x0781, 0xffff, 0,
991             "Syba Tech Ltd. PCI-4S2P-550-ECP",
992             DEFAULT_RCLK,
993             PUC_PORT_4S1P, 0x10, 0, -1,
994             .config_function = puc_config_syba
995         },
996
997         {   0x1fd4, 0x1999, 0x1fd4, 0x0002,
998             "Sunix SER5xxxx 2-port serial",
999             DEFAULT_RCLK * 8,
1000             PUC_PORT_2S, 0x10, 0, 8,
1001         },
1002
1003         {   0x1fd4, 0x1999, 0x1fd4, 0x0004,
1004             "Sunix SER5xxxx 4-port serial",
1005             DEFAULT_RCLK * 8,
1006             PUC_PORT_4S, 0x10, 0, 8,
1007         },
1008
1009         {   0x1fd4, 0x1999, 0x1fd4, 0x0008,
1010             "Sunix SER5xxxx 8-port serial",
1011             DEFAULT_RCLK * 8,
1012             PUC_PORT_8S, -1, -1, -1,
1013             .config_function = puc_config_sunix
1014         },
1015
1016         {   0x1fd4, 0x1999, 0x1fd4, 0x0101,
1017             "Sunix MIO5xxxx 1-port serial and 1284 Printer port",
1018             DEFAULT_RCLK * 8,
1019             PUC_PORT_1S1P, -1, -1, -1,
1020             .config_function = puc_config_sunix
1021         },
1022
1023         {   0x1fd4, 0x1999, 0x1fd4, 0x0102,
1024             "Sunix MIO5xxxx 2-port serial and 1284 Printer port",
1025             DEFAULT_RCLK * 8,
1026             PUC_PORT_2S1P, -1, -1, -1,
1027             .config_function = puc_config_sunix
1028         },
1029
1030         {   0x1fd4, 0x1999, 0x1fd4, 0x0104,
1031             "Sunix MIO5xxxx 4-port serial and 1284 Printer port",
1032             DEFAULT_RCLK * 8,
1033             PUC_PORT_4S1P, -1, -1, -1,
1034             .config_function = puc_config_sunix
1035         },
1036
1037         {   0x5372, 0x6872, 0xffff, 0,
1038             "Feasso PCI FPP-02 2S1P",
1039             DEFAULT_RCLK,
1040             PUC_PORT_2S1P, 0x10, 4, 0,
1041         },
1042
1043         {   0x5372, 0x6873, 0xffff, 0,
1044             "Sun 1040 PCI Quad Serial",
1045             DEFAULT_RCLK,
1046             PUC_PORT_4S, 0x10, 4, 0,
1047         },
1048
1049         {   0x6666, 0x0001, 0xffff, 0,
1050             "Decision Computer Inc, PCCOM 4-port serial",
1051             DEFAULT_RCLK,
1052             PUC_PORT_4S, 0x1c, 0, 8,
1053         },
1054
1055         {   0x6666, 0x0002, 0xffff, 0,
1056             "Decision Computer Inc, PCCOM 8-port serial",
1057             DEFAULT_RCLK,
1058             PUC_PORT_8S, 0x1c, 0, 8,
1059         },
1060
1061         {   0x6666, 0x0004, 0xffff, 0,
1062             "PCCOM dual port RS232/422/485",
1063             DEFAULT_RCLK,
1064             PUC_PORT_2S, 0x1c, 0, 8,
1065         },
1066
1067         {   0x9710, 0x9815, 0xffff, 0,
1068             "NetMos NM9815 Dual 1284 Printer port",
1069             0,
1070             PUC_PORT_2P, 0x10, 8, 0,
1071         },
1072
1073         /*
1074          * This is more specific than the generic NM9835 entry, and is placed
1075          * here to _prevent_ puc(4) from claiming this single port card.
1076          *
1077          * uart(4) will claim this device.
1078          */
1079         {   0x9710, 0x9835, 0x1000, 1,
1080             "NetMos NM9835 based 1-port serial",
1081             DEFAULT_RCLK,
1082             PUC_PORT_1S, 0x10, 4, 0,
1083         },
1084
1085         {   0x9710, 0x9835, 0x1000, 2,
1086             "NetMos NM9835 based 2-port serial",
1087             DEFAULT_RCLK,
1088             PUC_PORT_2S, 0x10, 4, 0,
1089         },
1090
1091         {   0x9710, 0x9835, 0xffff, 0,
1092             "NetMos NM9835 Dual UART and 1284 Printer port",
1093             DEFAULT_RCLK,
1094             PUC_PORT_2S1P, 0x10, 4, 0,
1095         },
1096
1097         {   0x9710, 0x9845, 0x1000, 0x0006,
1098             "NetMos NM9845 6 Port UART",
1099             DEFAULT_RCLK,
1100             PUC_PORT_6S, 0x10, 4, 0,
1101         },
1102
1103         {   0x9710, 0x9845, 0xffff, 0,
1104             "NetMos NM9845 Quad UART and 1284 Printer port",
1105             DEFAULT_RCLK,
1106             PUC_PORT_4S1P, 0x10, 4, 0,
1107         },
1108
1109         {   0x9710, 0x9865, 0xa000, 0x3002,
1110             "NetMos NM9865 Dual UART",
1111             DEFAULT_RCLK,
1112             PUC_PORT_2S, 0x10, 4, 0,
1113         },
1114
1115         {   0x9710, 0x9865, 0xa000, 0x3003,
1116             "NetMos NM9865 Triple UART",
1117             DEFAULT_RCLK,
1118             PUC_PORT_3S, 0x10, 4, 0,
1119         },
1120
1121         {   0x9710, 0x9865, 0xa000, 0x3004,
1122             "NetMos NM9865 Quad UART",
1123             DEFAULT_RCLK,
1124             PUC_PORT_4S, 0x10, 4, 0,
1125         },
1126
1127         {   0x9710, 0x9865, 0xa000, 0x3011,
1128             "NetMos NM9865 Single UART and 1284 Printer port",
1129             DEFAULT_RCLK,
1130             PUC_PORT_1S1P, 0x10, 4, 0,
1131         },
1132
1133         {   0x9710, 0x9865, 0xa000, 0x3012,
1134             "NetMos NM9865 Dual UART and 1284 Printer port",
1135             DEFAULT_RCLK,
1136             PUC_PORT_2S1P, 0x10, 4, 0,
1137         },
1138
1139         {   0x9710, 0x9865, 0xa000, 0x3020,
1140             "NetMos NM9865 Dual 1284 Printer port",
1141             DEFAULT_RCLK,
1142             PUC_PORT_2P, 0x10, 4, 0,
1143         },
1144
1145         {   0xb00c, 0x021c, 0xffff, 0,
1146             "IC Book Labs Gunboat x4 Lite",
1147             DEFAULT_RCLK,
1148             PUC_PORT_4S, 0x10, 0, 8,
1149             .config_function = puc_config_icbook
1150         },
1151
1152         {   0xb00c, 0x031c, 0xffff, 0,
1153             "IC Book Labs Gunboat x4 Pro",
1154             DEFAULT_RCLK,
1155             PUC_PORT_4S, 0x10, 0, 8,
1156             .config_function = puc_config_icbook
1157         },
1158
1159         {   0xb00c, 0x041c, 0xffff, 0,
1160             "IC Book Labs Ironclad x8 Lite",
1161             DEFAULT_RCLK,
1162             PUC_PORT_8S, 0x10, 0, 8,
1163             .config_function = puc_config_icbook
1164         },
1165
1166         {   0xb00c, 0x051c, 0xffff, 0,
1167             "IC Book Labs Ironclad x8 Pro",
1168             DEFAULT_RCLK,
1169             PUC_PORT_8S, 0x10, 0, 8,
1170             .config_function = puc_config_icbook
1171         },
1172
1173         {   0xb00c, 0x081c, 0xffff, 0,
1174             "IC Book Labs Dreadnought x16 Pro",
1175             DEFAULT_RCLK * 8,
1176             PUC_PORT_16S, 0x10, 0, 8,
1177             .config_function = puc_config_icbook
1178         },
1179
1180         {   0xb00c, 0x091c, 0xffff, 0,
1181             "IC Book Labs Dreadnought x16 Lite",
1182             DEFAULT_RCLK,
1183             PUC_PORT_16S, 0x10, 0, 8,
1184             .config_function = puc_config_icbook
1185         },
1186
1187         {   0xb00c, 0x0a1c, 0xffff, 0,
1188             "IC Book Labs Gunboat x2 Low Profile",
1189             DEFAULT_RCLK,
1190             PUC_PORT_2S, 0x10, 0, 8,
1191         },
1192
1193         {   0xb00c, 0x0b1c, 0xffff, 0,
1194             "IC Book Labs Gunboat x4 Low Profile",
1195             DEFAULT_RCLK,
1196             PUC_PORT_4S, 0x10, 0, 8,
1197             .config_function = puc_config_icbook
1198         },
1199
1200         { 0xffff, 0, 0xffff, 0, NULL, 0 }
1201 };
1202
1203 static int
1204 puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1205     intptr_t *res)
1206 {
1207         switch (cmd) {
1208         case PUC_CFG_GET_OFS:
1209                 *res = 8 * (port & 1);
1210                 return (0);
1211         case PUC_CFG_GET_RID:
1212                 *res = 0x14 + (port >> 1) * 4;
1213                 return (0);
1214         default:
1215                 break;
1216         }
1217         return (ENXIO);
1218 }
1219
1220 static int
1221 puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1222     intptr_t *res)
1223 {
1224         const struct puc_cfg *cfg = sc->sc_cfg;
1225
1226         if (cmd == PUC_CFG_GET_OFS) {
1227                 if (cfg->subdevice == 0x1282)           /* Everest SP */
1228                         port <<= 1;
1229                 else if (cfg->subdevice == 0x104b)      /* Maestro SP2 */
1230                         port = (port == 3) ? 4 : port;
1231                 *res = port * 8 + ((port > 2) ? 0x18 : 0);
1232                 return (0);
1233         }
1234         return (ENXIO);
1235 }
1236
1237 static int
1238 puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1239     intptr_t *res)
1240 {
1241         if (cmd == PUC_CFG_GET_OFS) {
1242                 *res = port * 0x200;
1243                 return (0);
1244         }
1245         return (ENXIO);
1246 }
1247
1248 static int
1249 puc_config_exar_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1250     intptr_t *res)
1251 {
1252         if (cmd == PUC_CFG_GET_OFS) {
1253                 *res = port * 0x400;
1254                 return (0);
1255         }
1256         return (ENXIO);
1257 }
1258
1259 static int
1260 puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1261     intptr_t *res)
1262 {
1263         if (cmd == PUC_CFG_GET_ILR) {
1264                 *res = PUC_ILR_DIGI;
1265                 return (0);
1266         }
1267         return (ENXIO);
1268 }
1269
1270 static int
1271 puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1272     intptr_t *res)
1273 {
1274         if (cmd == PUC_CFG_GET_OFS) {
1275                 const struct puc_cfg *cfg = sc->sc_cfg;
1276
1277                 if (port == 3 && (cfg->device == 0x1045 || cfg->device == 0x1144))
1278                         port = 7;
1279                 *res = port * 0x200;
1280
1281                 return 0;
1282         }
1283         return (ENXIO);
1284 }
1285
1286 static int
1287 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1288     intptr_t *res)
1289 {
1290         const struct puc_cfg *cfg = sc->sc_cfg;
1291         struct puc_bar *bar;
1292         uint8_t v0, v1;
1293
1294         switch (cmd) {
1295         case PUC_CFG_SETUP:
1296                 /*
1297                  * Check if the scratchpad register is enabled or if the
1298                  * interrupt status and options registers are active.
1299                  */
1300                 bar = puc_get_bar(sc, cfg->rid);
1301                 if (bar == NULL)
1302                         return (ENXIO);
1303                 /* Set DLAB in the LCR register of UART 0. */
1304                 bus_write_1(bar->b_res, 3, 0x80);
1305                 /* Write 0 to the SPR register of UART 0. */
1306                 bus_write_1(bar->b_res, 7, 0);
1307                 /* Read back the contents of the SPR register of UART 0. */
1308                 v0 = bus_read_1(bar->b_res, 7);
1309                 /* Write a specific value to the SPR register of UART 0. */
1310                 bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
1311                 /* Read back the contents of the SPR register of UART 0. */
1312                 v1 = bus_read_1(bar->b_res, 7);
1313                 /* Clear DLAB in the LCR register of UART 0. */
1314                 bus_write_1(bar->b_res, 3, 0);
1315                 /* Save the two values read-back from the SPR register. */
1316                 sc->sc_cfg_data = (v0 << 8) | v1;
1317                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1318                         /*
1319                          * The SPR register echoed the two values written
1320                          * by us. This means that the SPAD jumper is set.
1321                          */
1322                         device_printf(sc->sc_dev, "warning: extra features "
1323                             "not usable -- SPAD compatibility enabled\n");
1324                         return (0);
1325                 }
1326                 if (v0 != 0) {
1327                         /*
1328                          * The first value doesn't match. This can only mean
1329                          * that the SPAD jumper is not set and that a non-
1330                          * standard fixed clock multiplier jumper is set.
1331                          */
1332                         if (bootverbose)
1333                                 device_printf(sc->sc_dev, "fixed clock rate "
1334                                     "multiplier of %d\n", 1 << v0);
1335                         if (v0 < -cfg->clock)
1336                                 device_printf(sc->sc_dev, "warning: "
1337                                     "suboptimal fixed clock rate multiplier "
1338                                     "setting\n");
1339                         return (0);
1340                 }
1341                 /*
1342                  * The first value matched, but the second didn't. We know
1343                  * that the SPAD jumper is not set. We also know that the
1344                  * clock rate multiplier is software controlled *and* that
1345                  * we just programmed it to the maximum allowed.
1346                  */
1347                 if (bootverbose)
1348                         device_printf(sc->sc_dev, "clock rate multiplier of "
1349                             "%d selected\n", 1 << -cfg->clock);
1350                 return (0);
1351         case PUC_CFG_GET_CLOCK:
1352                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1353                 v1 = sc->sc_cfg_data & 0xff;
1354                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1355                         /*
1356                          * XXX With the SPAD jumper applied, there's no
1357                          * easy way of knowing if there's also a clock
1358                          * rate multiplier jumper installed. Let's hope
1359                          * not...
1360                          */
1361                         *res = DEFAULT_RCLK;
1362                 } else if (v0 == 0) {
1363                         /*
1364                          * No clock rate multiplier jumper installed,
1365                          * so we programmed the board with the maximum
1366                          * multiplier allowed as given to us in the
1367                          * clock field of the config record (negated).
1368                          */
1369                         *res = DEFAULT_RCLK << -cfg->clock;
1370                 } else
1371                         *res = DEFAULT_RCLK << v0;
1372                 return (0);
1373         case PUC_CFG_GET_ILR:
1374                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1375                 v1 = sc->sc_cfg_data & 0xff;
1376                 *res = (v0 == 0 && v1 == 0x80 + -cfg->clock)
1377                     ? PUC_ILR_NONE : PUC_ILR_QUATECH;
1378                 return (0);
1379         default:
1380                 break;
1381         }
1382         return (ENXIO);
1383 }
1384
1385 static int
1386 puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1387     intptr_t *res)
1388 {
1389         static int base[] = { 0x251, 0x3f0, 0 };
1390         const struct puc_cfg *cfg = sc->sc_cfg;
1391         struct puc_bar *bar;
1392         int efir, idx, ofs;
1393         uint8_t v;
1394
1395         switch (cmd) {
1396         case PUC_CFG_SETUP:
1397                 bar = puc_get_bar(sc, cfg->rid);
1398                 if (bar == NULL)
1399                         return (ENXIO);
1400
1401                 /* configure both W83877TFs */
1402                 bus_write_1(bar->b_res, 0x250, 0x89);
1403                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1404                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1405                 idx = 0;
1406                 while (base[idx] != 0) {
1407                         efir = base[idx];
1408                         bus_write_1(bar->b_res, efir, 0x09);
1409                         v = bus_read_1(bar->b_res, efir + 1);
1410                         if ((v & 0x0f) != 0x0c)
1411                                 return (ENXIO);
1412                         bus_write_1(bar->b_res, efir, 0x16);
1413                         v = bus_read_1(bar->b_res, efir + 1);
1414                         bus_write_1(bar->b_res, efir, 0x16);
1415                         bus_write_1(bar->b_res, efir + 1, v | 0x04);
1416                         bus_write_1(bar->b_res, efir, 0x16);
1417                         bus_write_1(bar->b_res, efir + 1, v & ~0x04);
1418                         ofs = base[idx] & 0x300;
1419                         bus_write_1(bar->b_res, efir, 0x23);
1420                         bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2);
1421                         bus_write_1(bar->b_res, efir, 0x24);
1422                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2);
1423                         bus_write_1(bar->b_res, efir, 0x25);
1424                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2);
1425                         bus_write_1(bar->b_res, efir, 0x17);
1426                         bus_write_1(bar->b_res, efir + 1, 0x03);
1427                         bus_write_1(bar->b_res, efir, 0x28);
1428                         bus_write_1(bar->b_res, efir + 1, 0x43);
1429                         idx++;
1430                 }
1431                 bus_write_1(bar->b_res, 0x250, 0xaa);
1432                 bus_write_1(bar->b_res, 0x3f0, 0xaa);
1433                 return (0);
1434         case PUC_CFG_GET_OFS:
1435                 switch (port) {
1436                 case 0:
1437                         *res = 0x2f8;
1438                         return (0);
1439                 case 1:
1440                         *res = 0x2e8;
1441                         return (0);
1442                 case 2:
1443                         *res = 0x3f8;
1444                         return (0);
1445                 case 3:
1446                         *res = 0x3e8;
1447                         return (0);
1448                 case 4:
1449                         *res = 0x278;
1450                         return (0);
1451                 }
1452                 break;
1453         default:
1454                 break;
1455         }
1456         return (ENXIO);
1457 }
1458
1459 static int
1460 puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1461     intptr_t *res)
1462 {
1463         const struct puc_cfg *cfg = sc->sc_cfg;
1464
1465         switch (cmd) {
1466         case PUC_CFG_GET_OFS:
1467                 if (cfg->ports == PUC_PORT_8S) {
1468                         *res = (port > 4) ? 8 * (port - 4) : 0;
1469                         return (0);
1470                 }
1471                 break;
1472         case PUC_CFG_GET_RID:
1473                 if (cfg->ports == PUC_PORT_8S) {
1474                         *res = 0x10 + ((port > 4) ? 0x10 : 4 * port);
1475                         return (0);
1476                 }
1477                 if (cfg->ports == PUC_PORT_2S1P) {
1478                         switch (port) {
1479                         case 0: *res = 0x10; return (0);
1480                         case 1: *res = 0x14; return (0);
1481                         case 2: *res = 0x1c; return (0);
1482                         }
1483                 }
1484                 break;
1485         default:
1486                 break;
1487         }
1488         return (ENXIO);
1489 }
1490
1491 static int
1492 puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1493     intptr_t *res)
1494 {
1495         static const uint16_t dual[] = {
1496             0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
1497             0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
1498             0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
1499             0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
1500             0xD079, 0
1501         };
1502         static const uint16_t quad[] = {
1503             0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
1504             0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
1505             0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
1506             0xB157, 0
1507         };
1508         static const uint16_t octa[] = {
1509             0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
1510             0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
1511         };
1512         static const struct {
1513                 int ports;
1514                 const uint16_t *ids;
1515         } subdevs[] = {
1516             { 2, dual },
1517             { 4, quad },
1518             { 8, octa },
1519             { 0, NULL }
1520         };
1521         static char desc[64];
1522         int dev, id;
1523         uint16_t subdev;
1524
1525         switch (cmd) {
1526         case PUC_CFG_GET_CLOCK:
1527                 if (port < 2)
1528                         *res = DEFAULT_RCLK * 8;
1529                 else
1530                         *res = DEFAULT_RCLK;
1531                 return (0);
1532         case PUC_CFG_GET_DESC:
1533                 snprintf(desc, sizeof(desc),
1534                     "Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
1535                 *res = (intptr_t)desc;
1536                 return (0);
1537         case PUC_CFG_GET_NPORTS:
1538                 subdev = pci_get_subdevice(sc->sc_dev);
1539                 dev = 0;
1540                 while (subdevs[dev].ports != 0) {
1541                         id = 0;
1542                         while (subdevs[dev].ids[id] != 0) {
1543                                 if (subdev == subdevs[dev].ids[id]) {
1544                                         sc->sc_cfg_data = subdevs[dev].ports;
1545                                         *res = sc->sc_cfg_data;
1546                                         return (0);
1547                                 }
1548                                 id++;
1549                         }
1550                         dev++;
1551                 }
1552                 return (ENXIO);
1553         case PUC_CFG_GET_OFS:
1554                 *res = (port == 1 || port == 3) ? 8 : 0;
1555                 return (0);
1556         case PUC_CFG_GET_RID:
1557                 *res = 0x10 + ((port > 3) ? port - 2 : port >> 1) * 4;
1558                 return (0);
1559         case PUC_CFG_GET_TYPE:
1560                 *res = PUC_TYPE_SERIAL;
1561                 return (0);
1562         default:
1563                 break;
1564         }
1565         return (ENXIO);
1566 }
1567
1568 static int
1569 puc_config_oxford_pci954(struct puc_softc *sc, enum puc_cfg_cmd cmd,
1570     int port __unused, intptr_t *res)
1571 {
1572
1573         switch (cmd) {
1574         case PUC_CFG_GET_CLOCK:
1575                 /*
1576                  * OXu16PCI954 use a 14.7456 MHz clock by default while
1577                  * OX16PCI954 and OXm16PCI954 employ a 1.8432 MHz one.
1578                  */
1579                 if (pci_get_revid(sc->sc_dev) == 1)
1580                         *res = DEFAULT_RCLK * 8;
1581                 else
1582                         *res = DEFAULT_RCLK;
1583                 return (0);
1584         default:
1585                 break;
1586         }
1587         return (ENXIO);
1588 }
1589
1590 static int
1591 puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1592     intptr_t *res)
1593 {
1594         const struct puc_cfg *cfg = sc->sc_cfg;
1595         int idx;
1596         struct puc_bar *bar;
1597         uint8_t value;
1598
1599         switch (cmd) {
1600         case PUC_CFG_SETUP:
1601                 device_printf(sc->sc_dev, "%d UARTs detected\n",
1602                         sc->sc_nports);
1603
1604                 /* Set UARTs to enhanced mode */
1605                 bar = puc_get_bar(sc, cfg->rid);
1606                 if (bar == NULL)
1607                         return (ENXIO);
1608                 for (idx = 0; idx < sc->sc_nports; idx++) {
1609                         value = bus_read_1(bar->b_res, 0x1000 + (idx << 9) +
1610                             0x92);
1611                         bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
1612                             value | 0x10);
1613                 }
1614                 return (0);
1615         case PUC_CFG_GET_LEN:
1616                 *res = 0x200;
1617                 return (0);
1618         case PUC_CFG_GET_NPORTS:
1619                 /*
1620                  * Check if we are being called from puc_bfe_attach()
1621                  * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
1622                  * puc_get_bar(), so we return a value of 16. This has cosmetic
1623                  * side-effects at worst; in PUC_CFG_GET_DESC,
1624                  * (int)sc->sc_cfg_data will not contain the true number of
1625                  * ports in PUC_CFG_GET_DESC, but we are not implementing that
1626                  * call for this device family anyway.
1627                  *
1628                  * The check is for initialisation of sc->sc_bar[idx], which is
1629                  * only done in puc_bfe_attach().
1630                  */
1631                 idx = 0;
1632                 do {
1633                         if (sc->sc_bar[idx++].b_rid != -1) {
1634                                 sc->sc_cfg_data = 16;
1635                                 *res = sc->sc_cfg_data;
1636                                 return (0);
1637                         }
1638                 } while (idx < PUC_PCI_BARS);
1639
1640                 bar = puc_get_bar(sc, cfg->rid);
1641                 if (bar == NULL)
1642                         return (ENXIO);
1643
1644                 value = bus_read_1(bar->b_res, 0x04);
1645                 if (value == 0)
1646                         return (ENXIO);
1647
1648                 sc->sc_cfg_data = value;
1649                 *res = sc->sc_cfg_data;
1650                 return (0);
1651         case PUC_CFG_GET_OFS:
1652                 *res = 0x1000 + (port << 9);
1653                 return (0);
1654         case PUC_CFG_GET_TYPE:
1655                 *res = PUC_TYPE_SERIAL;
1656                 return (0);
1657         default:
1658                 break;
1659         }
1660         return (ENXIO);
1661 }
1662
1663 static int
1664 puc_config_sunix(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1665     intptr_t *res)
1666 {
1667         int error;
1668
1669         switch (cmd) {
1670         case PUC_CFG_GET_OFS:
1671                 error = puc_config(sc, PUC_CFG_GET_TYPE, port, res);
1672                 if (error != 0)
1673                         return (error);
1674                 *res = (*res == PUC_TYPE_SERIAL) ? (port & 3) * 8 : 0;
1675                 return (0);
1676         case PUC_CFG_GET_RID:
1677                 error = puc_config(sc, PUC_CFG_GET_TYPE, port, res);
1678                 if (error != 0)
1679                         return (error);
1680                 *res = (*res == PUC_TYPE_SERIAL && port <= 3) ? 0x10 : 0x14;
1681                 return (0);
1682         default:
1683                 break;
1684         }
1685         return (ENXIO);
1686 }
1687
1688 static int
1689 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1690     intptr_t *res)
1691 {
1692         switch (cmd) {
1693         case PUC_CFG_GET_OFS:
1694                 *res = (port < 3) ? 0 : (port - 2) << 3;
1695                 return (0);
1696         case PUC_CFG_GET_RID:
1697                 *res = 0x14 + ((port >= 2) ? 0x0c : port << 2);
1698                 return (0);
1699         default:
1700                 break;
1701         }
1702         return (ENXIO);
1703 }