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