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