]> CyberLeo.Net >> Repos - FreeBSD/releng/9.1.git/blob - sys/dev/puc/pucdata.c
MFC: r238933
[FreeBSD/releng/9.1.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, 0x1024, 0xffff, 0,
511             "Moxa Technologies, Smartio CP-102E/PCIe",
512             DEFAULT_RCLK * 8,
513             PUC_PORT_2S, 0x14, 0, -1,
514                 .config_function = puc_config_moxa
515         },
516
517         {   0x1393, 0x1025, 0xffff, 0,
518             "Moxa Technologies, Smartio CP-102EL/PCIe",
519             DEFAULT_RCLK * 8,
520             PUC_PORT_2S, 0x14, 0, -1,
521                 .config_function = puc_config_moxa
522         },
523
524         {   0x1393, 0x1040, 0xffff, 0,
525             "Moxa Technologies, Smartio C104H/PCI",
526             DEFAULT_RCLK * 8,
527             PUC_PORT_4S, 0x18, 0, 8,
528         },
529
530         {   0x1393, 0x1041, 0xffff, 0,
531             "Moxa Technologies, Smartio CP-104UL/PCI",
532             DEFAULT_RCLK * 8,
533             PUC_PORT_4S, 0x18, 0, 8,
534         },
535
536         {   0x1393, 0x1042, 0xffff, 0,
537             "Moxa Technologies, Smartio CP-104JU/PCI",
538             DEFAULT_RCLK * 8,
539             PUC_PORT_4S, 0x18, 0, 8,
540         },
541
542         {   0x1393, 0x1043, 0xffff, 0,
543             "Moxa Technologies, Smartio CP-104EL/PCIe",
544             DEFAULT_RCLK * 8,
545             PUC_PORT_4S, 0x18, 0, 8,
546         },
547
548         {   0x1393, 0x1045, 0xffff, 0,
549             "Moxa Technologies, Smartio CP-104EL-A/PCIe",
550             DEFAULT_RCLK * 8,
551             PUC_PORT_4S, 0x14, 0, -1,
552                 .config_function = puc_config_moxa
553         },
554
555         {   0x1393, 0x1120, 0xffff, 0,
556             "Moxa Technologies, CP-112UL",
557             DEFAULT_RCLK * 8,
558             PUC_PORT_2S, 0x18, 0, 8,
559         },
560
561         {   0x1393, 0x1141, 0xffff, 0,
562             "Moxa Technologies, Industio CP-114",
563             DEFAULT_RCLK * 8,
564             PUC_PORT_4S, 0x18, 0, 8,
565         },
566
567         {   0x1393, 0x1144, 0xffff, 0,
568             "Moxa Technologies, Smartio CP-114EL/PCIe",
569             DEFAULT_RCLK * 8,
570             PUC_PORT_4S, 0x14, 0, -1,
571                 .config_function = puc_config_moxa
572         },
573
574         {   0x1393, 0x1182, 0xffff, 0,
575             "Moxa Technologies, Smartio CP-118EL-A/PCIe",
576             DEFAULT_RCLK * 8,
577             PUC_PORT_8S, 0x14, 0, -1,
578                 .config_function = puc_config_moxa
579         },
580
581         {   0x1393, 0x1680, 0xffff, 0,
582             "Moxa Technologies, C168H/PCI",
583             DEFAULT_RCLK * 8,
584             PUC_PORT_8S, 0x18, 0, 8,
585         },
586
587         {   0x1393, 0x1681, 0xffff, 0,
588             "Moxa Technologies, C168U/PCI",
589             DEFAULT_RCLK * 8,
590             PUC_PORT_8S, 0x18, 0, 8,
591         },
592
593         {   0x1393, 0x1682, 0xffff, 0,
594             "Moxa Technologies, CP-168EL/PCIe",
595             DEFAULT_RCLK * 8,
596             PUC_PORT_8S, 0x18, 0, 8,
597         },
598
599         {   0x1393, 0x1683, 0xffff, 0,
600             "Moxa Technologies, Smartio CP-168EL-A/PCIe",
601             DEFAULT_RCLK * 8,
602             PUC_PORT_8S, 0x14, 0, -1,
603                 .config_function = puc_config_moxa
604         },
605
606         {   0x13a8, 0x0152, 0xffff, 0,
607             "Exar XR17C/D152",
608             DEFAULT_RCLK * 8,
609             PUC_PORT_2S, 0x10, 0, -1,
610             .config_function = puc_config_exar
611         },
612
613         {   0x13a8, 0x0154, 0xffff, 0,
614             "Exar XR17C154",
615             DEFAULT_RCLK * 8,
616             PUC_PORT_4S, 0x10, 0, -1,
617             .config_function = puc_config_exar
618         },
619
620         {   0x13a8, 0x0158, 0xffff, 0,
621             "Exar XR17C158",
622             DEFAULT_RCLK * 8,
623             PUC_PORT_8S, 0x10, 0, -1,
624             .config_function = puc_config_exar
625         },
626
627         {   0x13a8, 0x0258, 0xffff, 0,
628             "Exar XR17V258IV",
629             DEFAULT_RCLK * 8,
630             PUC_PORT_8S, 0x10, 0, -1,
631         },
632
633         {   0x1407, 0x0100, 0xffff, 0,
634             "Lava Computers Dual Serial",
635             DEFAULT_RCLK,
636             PUC_PORT_2S, 0x10, 4, 0,
637         },
638
639         {   0x1407, 0x0101, 0xffff, 0,
640             "Lava Computers Quatro A",
641             DEFAULT_RCLK,
642             PUC_PORT_2S, 0x10, 4, 0,
643         },
644
645         {   0x1407, 0x0102, 0xffff, 0,
646             "Lava Computers Quatro B",
647             DEFAULT_RCLK,
648             PUC_PORT_2S, 0x10, 4, 0,
649         },
650
651         {   0x1407, 0x0120, 0xffff, 0,
652             "Lava Computers Quattro-PCI A",
653             DEFAULT_RCLK,
654             PUC_PORT_2S, 0x10, 4, 0,
655         },
656
657         {   0x1407, 0x0121, 0xffff, 0,
658             "Lava Computers Quattro-PCI B",
659             DEFAULT_RCLK,
660             PUC_PORT_2S, 0x10, 4, 0,
661         },
662
663         {   0x1407, 0x0180, 0xffff, 0,
664             "Lava Computers Octo A",
665             DEFAULT_RCLK,
666             PUC_PORT_4S, 0x10, 4, 0,
667         },
668
669         {   0x1407, 0x0181, 0xffff, 0,
670             "Lava Computers Octo B",
671             DEFAULT_RCLK,
672             PUC_PORT_4S, 0x10, 4, 0,
673         },
674
675         {   0x1409, 0x7268, 0xffff, 0,
676             "Sunix SUN1888",
677             0,
678             PUC_PORT_2P, 0x10, 0, 8,
679         },
680
681         {   0x1409, 0x7168, 0xffff, 0,
682             NULL,
683             DEFAULT_RCLK * 8,
684             PUC_PORT_NONSTANDARD, 0x10, -1, -1,
685             .config_function = puc_config_timedia
686         },
687
688         /*
689          * Boards with an Oxford Semiconductor chip.
690          *
691          * Oxford Semiconductor provides documentation for their chip at:
692          * <URL:http://www.plxtech.com/products/uart/>
693          *
694          * As sold by Kouwell <URL:http://www.kouwell.com/>.
695          * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports.
696          */
697         {
698                 0x1415, 0x9501, 0x10fc ,0xc070,
699                 "I-O DATA RSA-PCI2/R",
700                 DEFAULT_RCLK * 8,
701                 PUC_PORT_2S, 0x10, 0, 8,
702         },
703
704         {   0x1415, 0x9501, 0x131f, 0x2050,
705             "SIIG Cyber 4 PCI 16550",
706             DEFAULT_RCLK * 10,
707             PUC_PORT_4S, 0x10, 0, 8,
708         },
709
710         {   0x1415, 0x9501, 0x131f, 0x2051,
711             "SIIG Cyber 4S PCI 16C650 (20x family)",
712             DEFAULT_RCLK * 10,
713             PUC_PORT_4S, 0x10, 0, 8,
714         },
715
716         {   0x1415, 0x9501, 0x131f, 0x2052,
717             "SIIG Quartet Serial 850",
718             DEFAULT_RCLK * 10,
719             PUC_PORT_4S, 0x10, 0, 8,
720         },
721
722         {   0x1415, 0x9501, 0x14db, 0x2150,
723             "Kuroutoshikou SERIAL4P-LPPCI2",
724             DEFAULT_RCLK * 10,
725             PUC_PORT_4S, 0x10, 0, 8,
726         },
727
728         {   0x1415, 0x9501, 0xffff, 0,
729             "Oxford Semiconductor OX16PCI954 UARTs",
730             DEFAULT_RCLK,
731             PUC_PORT_4S, 0x10, 0, 8,
732         },
733
734         {   0x1415, 0x950a, 0x131f, 0x2030,
735             "SIIG Cyber 2S PCIe",
736             DEFAULT_RCLK * 10,
737             PUC_PORT_2S, 0x10, 0, 8,
738         },
739
740         {   0x1415, 0x950a, 0xffff, 0,
741             "Oxford Semiconductor OX16PCI954 UARTs",
742             DEFAULT_RCLK,
743             PUC_PORT_4S, 0x10, 0, 8,
744         },
745
746         {   0x1415, 0x9511, 0xffff, 0,
747             "Oxford Semiconductor OX9160/OX16PCI954 UARTs (function 1)",
748             DEFAULT_RCLK,
749             PUC_PORT_4S, 0x10, 0, 8,
750         },
751
752         {   0x1415, 0x9521, 0xffff, 0,
753             "Oxford Semiconductor OX16PCI952 UARTs",
754             DEFAULT_RCLK,
755             PUC_PORT_2S, 0x10, 4, 0,
756         },
757
758         {   0x1415, 0x9538, 0xffff, 0,
759             "Oxford Semiconductor OX16PCI958 UARTs",
760             DEFAULT_RCLK * 10,
761             PUC_PORT_8S, 0x18, 0, 8,
762         },
763
764         /*
765          * Perle boards use Oxford Semiconductor chips, but they store the
766          * Oxford Semiconductor device ID as a subvendor device ID and use
767          * their own device IDs.
768          */
769
770         {   0x155f, 0x0331, 0xffff, 0,
771             "Perle Speed4 LE",
772             DEFAULT_RCLK * 8,
773             PUC_PORT_4S, 0x10, 0, 8,
774         },
775
776         /*
777          * Oxford Semiconductor PCI Express Expresso family
778          *
779          * Found in many 'native' PCI Express serial boards such as:
780          *
781          * eMegatech MP954ER4 (4 port) and MP958ER8 (8 port)
782          * <URL:http://www.emegatech.com.tw/pdrs232pcie.html>
783          *
784          * Lindy 51189 (4 port)
785          * <URL:http://www.lindy.com> <URL:http://tinyurl.com/lindy-51189>
786          * 
787          * StarTech.com PEX4S952 (4 port) and PEX8S952 (8 port)
788          * <URL:http://www.startech.com>
789          */
790
791         {   0x1415, 0xc138, 0xffff, 0,
792             "Oxford Semiconductor OXPCIe952 UARTs",
793             DEFAULT_RCLK * 0x22,
794             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
795             .config_function = puc_config_oxford_pcie
796         },
797
798         {   0x1415, 0xc158, 0xffff, 0,
799             "Oxford Semiconductor OXPCIe952 UARTs",
800             DEFAULT_RCLK * 0x22,
801             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
802             .config_function = puc_config_oxford_pcie
803         },
804
805         {   0x1415, 0xc15d, 0xffff, 0,
806             "Oxford Semiconductor OXPCIe952 UARTs (function 1)",
807             DEFAULT_RCLK * 0x22,
808             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
809             .config_function = puc_config_oxford_pcie
810         },
811
812         {   0x1415, 0xc208, 0xffff, 0,
813             "Oxford Semiconductor OXPCIe954 UARTs",
814             DEFAULT_RCLK * 0x22,
815             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
816             .config_function = puc_config_oxford_pcie
817         },
818
819         {   0x1415, 0xc20d, 0xffff, 0,
820             "Oxford Semiconductor OXPCIe954 UARTs (function 1)",
821             DEFAULT_RCLK * 0x22,
822             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
823             .config_function = puc_config_oxford_pcie
824         },
825
826         {   0x1415, 0xc308, 0xffff, 0,
827             "Oxford Semiconductor OXPCIe958 UARTs",
828             DEFAULT_RCLK * 0x22,
829             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
830             .config_function = puc_config_oxford_pcie
831         },
832
833         {   0x1415, 0xc30d, 0xffff, 0,
834             "Oxford Semiconductor OXPCIe958 UARTs (function 1)",
835             DEFAULT_RCLK * 0x22,
836             PUC_PORT_NONSTANDARD, 0x10, 0, -1,
837             .config_function = puc_config_oxford_pcie
838         },
839
840         {   0x14d2, 0x8010, 0xffff, 0,
841             "VScom PCI-100L",
842             DEFAULT_RCLK * 8,
843             PUC_PORT_1S, 0x14, 0, 0,
844         },
845
846         {   0x14d2, 0x8020, 0xffff, 0,
847             "VScom PCI-200L",
848             DEFAULT_RCLK * 8,
849             PUC_PORT_2S, 0x14, 4, 0,
850         },
851
852         {   0x14d2, 0x8028, 0xffff, 0,
853             "VScom 200Li",
854             DEFAULT_RCLK,
855             PUC_PORT_2S, 0x20, 0, 8,
856         },
857
858         /*
859          * VScom (Titan?) PCI-800L.  More modern variant of the
860          * PCI-800.  Uses 6 discrete 16550 UARTs, plus another
861          * two of them obviously implemented as macro cells in
862          * the ASIC.  This causes the weird port access pattern
863          * below, where two of the IO port ranges each access
864          * one of the ASIC UARTs, and a block of IO addresses
865          * access the external UARTs.
866          */
867         {   0x14d2, 0x8080, 0xffff, 0,
868             "Titan VScom PCI-800L",
869             DEFAULT_RCLK * 8,
870             PUC_PORT_8S, 0x14, -1, -1,
871             .config_function = puc_config_titan
872         },
873
874         /*
875          * VScom PCI-800H. Uses 8 16950 UART, behind a PCI chips that offers
876          * 4 com port on PCI device 0 and 4 on PCI device 1. PCI device 0 has
877          * device ID 3 and PCI device 1 device ID 4.
878          */
879         {   0x14d2, 0xa003, 0xffff, 0,
880             "Titan PCI-800H",
881             DEFAULT_RCLK * 8,
882             PUC_PORT_4S, 0x10, 0, 8,
883         },
884         {   0x14d2, 0xa004, 0xffff, 0,
885             "Titan PCI-800H",
886             DEFAULT_RCLK * 8,
887             PUC_PORT_4S, 0x10, 0, 8,
888         },
889
890         {   0x14d2, 0xa005, 0xffff, 0,
891             "Titan PCI-200H",
892             DEFAULT_RCLK * 8,
893             PUC_PORT_2S, 0x10, 0, 8,
894         },
895
896         {   0x14d2, 0xe020, 0xffff, 0,
897             "Titan VScom PCI-200HV2",
898             DEFAULT_RCLK * 8,
899             PUC_PORT_2S, 0x10, 4, 0,
900         },
901
902         {   0x14d2, 0xa007, 0xffff, 0,
903             "Titan VScom PCIex-800H",
904             DEFAULT_RCLK * 8,
905             PUC_PORT_4S, 0x10, 0, 8,
906         },
907
908         {   0x14d2, 0xa008, 0xffff, 0,
909             "Titan VScom PCIex-800H",
910             DEFAULT_RCLK * 8,
911             PUC_PORT_4S, 0x10, 0, 8,
912         },
913
914         {   0x14db, 0x2130, 0xffff, 0,
915             "Avlab Technology, PCI IO 2S",
916             DEFAULT_RCLK,
917             PUC_PORT_2S, 0x10, 4, 0,
918         },
919
920         {   0x14db, 0x2150, 0xffff, 0,
921             "Avlab Low Profile PCI 4 Serial",
922             DEFAULT_RCLK,
923             PUC_PORT_4S, 0x10, 4, 0,
924         },
925
926         {   0x14db, 0x2152, 0xffff, 0,
927             "Avlab Low Profile PCI 4 Serial",
928             DEFAULT_RCLK,
929             PUC_PORT_4S, 0x10, 4, 0,
930         },
931
932         {   0x1592, 0x0781, 0xffff, 0,
933             "Syba Tech Ltd. PCI-4S2P-550-ECP",
934             DEFAULT_RCLK,
935             PUC_PORT_4S1P, 0x10, 0, -1,
936             .config_function = puc_config_syba
937         },
938
939         {    0x5372, 0x6873, 0xffff, 0,
940              "Sun 1040 PCI Quad Serial",
941              DEFAULT_RCLK,
942              PUC_PORT_4S, 0x10, 4, 0,
943         },
944
945         {   0x6666, 0x0001, 0xffff, 0,
946             "Decision Computer Inc, PCCOM 4-port serial",
947             DEFAULT_RCLK,
948             PUC_PORT_4S, 0x1c, 0, 8,
949         },
950
951         {   0x6666, 0x0002, 0xffff, 0,
952             "Decision Computer Inc, PCCOM 8-port serial",
953             DEFAULT_RCLK,
954             PUC_PORT_8S, 0x1c, 0, 8,
955         },
956
957         {   0x6666, 0x0004, 0xffff, 0,
958             "PCCOM dual port RS232/422/485",
959             DEFAULT_RCLK,
960             PUC_PORT_2S, 0x1c, 0, 8,
961         },
962
963         {   0x9710, 0x9815, 0xffff, 0,
964             "NetMos NM9815 Dual 1284 Printer port", 
965             0,
966             PUC_PORT_2P, 0x10, 8, 0,
967         }, 
968
969         /*
970          * This is more specific than the generic NM9835 entry that follows, and
971          * is placed here to _prevent_ puc from claiming this single port card.
972          *
973          * uart(4) will claim this device.
974          */
975         {   0x9710, 0x9835, 0x1000, 1,
976             "NetMos NM9835 based 1-port serial",
977             DEFAULT_RCLK,
978             PUC_PORT_1S, 0x10, 4, 0,
979         },
980
981         {   0x9710, 0x9835, 0x1000, 2,
982             "NetMos NM9835 based 2-port serial",
983             DEFAULT_RCLK,
984             PUC_PORT_2S, 0x10, 4, 0,
985         },
986
987         {   0x9710, 0x9835, 0xffff, 0,
988             "NetMos NM9835 Dual UART and 1284 Printer port",
989             DEFAULT_RCLK,
990             PUC_PORT_2S1P, 0x10, 4, 0,
991         },
992
993         {   0x9710, 0x9845, 0x1000, 0x0006,
994             "NetMos NM9845 6 Port UART",
995             DEFAULT_RCLK,
996             PUC_PORT_6S, 0x10, 4, 0,
997         },
998
999         {   0x9710, 0x9845, 0xffff, 0,
1000             "NetMos NM9845 Quad UART and 1284 Printer port",
1001             DEFAULT_RCLK,
1002             PUC_PORT_4S1P, 0x10, 4, 0,
1003         },
1004
1005         {   0x9710, 0x9865, 0xa000, 0x3002,
1006             "NetMos NM9865 Dual UART",
1007             DEFAULT_RCLK,
1008             PUC_PORT_2S, 0x10, 4, 0,
1009         },
1010
1011         {   0x9710, 0x9865, 0xa000, 0x3003,
1012             "NetMos NM9865 Triple UART",
1013             DEFAULT_RCLK,
1014             PUC_PORT_3S, 0x10, 4, 0,
1015         },
1016
1017         {   0x9710, 0x9865, 0xa000, 0x3004,
1018             "NetMos NM9865 Quad UART",
1019             DEFAULT_RCLK,
1020             PUC_PORT_4S, 0x10, 4, 0,0
1021         },
1022
1023         {   0x9710, 0x9865, 0xa000, 0x3011,
1024             "NetMos NM9865 Single UART and 1284 Printer port",
1025             DEFAULT_RCLK,
1026             PUC_PORT_1S1P, 0x10, 4, 0,
1027         },
1028
1029         {   0x9710, 0x9865, 0xa000, 0x3012,
1030             "NetMos NM9865 Dual UART and 1284 Printer port",
1031             DEFAULT_RCLK,
1032             PUC_PORT_2S1P, 0x10, 4, 0,
1033         },
1034
1035         {   0x9710, 0x9865, 0xa000, 0x3020,
1036             "NetMos NM9865 Dual 1284 Printer port",
1037             DEFAULT_RCLK,
1038             PUC_PORT_2P, 0x10, 4, 0,
1039         },
1040
1041         {   0xb00c, 0x021c, 0xffff, 0,
1042             "IC Book Labs Gunboat x4 Lite",
1043             DEFAULT_RCLK,
1044             PUC_PORT_4S, 0x10, 0, 8,
1045             .config_function = puc_config_icbook
1046         },
1047
1048         {   0xb00c, 0x031c, 0xffff, 0,
1049             "IC Book Labs Gunboat x4 Pro",
1050             DEFAULT_RCLK,
1051             PUC_PORT_4S, 0x10, 0, 8,
1052             .config_function = puc_config_icbook
1053         },
1054
1055         {   0xb00c, 0x041c, 0xffff, 0,
1056             "IC Book Labs Ironclad x8 Lite",
1057             DEFAULT_RCLK,
1058             PUC_PORT_8S, 0x10, 0, 8,
1059             .config_function = puc_config_icbook
1060         },
1061
1062         {   0xb00c, 0x051c, 0xffff, 0,
1063             "IC Book Labs Ironclad x8 Pro",
1064             DEFAULT_RCLK,
1065             PUC_PORT_8S, 0x10, 0, 8,
1066             .config_function = puc_config_icbook
1067         },
1068
1069         {   0xb00c, 0x081c, 0xffff, 0,
1070             "IC Book Labs Dreadnought x16 Pro",
1071             DEFAULT_RCLK * 8,
1072             PUC_PORT_16S, 0x10, 0, 8,
1073             .config_function = puc_config_icbook
1074         },
1075
1076         {   0xb00c, 0x091c, 0xffff, 0,
1077             "IC Book Labs Dreadnought x16 Lite",
1078             DEFAULT_RCLK,
1079             PUC_PORT_16S, 0x10, 0, 8,
1080             .config_function = puc_config_icbook
1081         },
1082
1083         {   0xb00c, 0x0a1c, 0xffff, 0,
1084             "IC Book Labs Gunboat x2 Low Profile",
1085             DEFAULT_RCLK,
1086             PUC_PORT_2S, 0x10, 0, 8,
1087         },
1088
1089         {   0xb00c, 0x0b1c, 0xffff, 0,
1090             "IC Book Labs Gunboat x4 Low Profile",
1091             DEFAULT_RCLK,
1092             PUC_PORT_4S, 0x10, 0, 8,
1093             .config_function = puc_config_icbook
1094         },
1095
1096         { 0xffff, 0, 0xffff, 0, NULL, 0 }
1097 };
1098
1099 static int
1100 puc_config_amc(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1101     intptr_t *res)
1102 {
1103         switch (cmd) {
1104         case PUC_CFG_GET_OFS:
1105                 *res = 8 * (port & 1);
1106                 return (0);
1107         case PUC_CFG_GET_RID:
1108                 *res = 0x14 + (port >> 1) * 4;
1109                 return (0);
1110         default:
1111                 break;
1112         }
1113         return (ENXIO);
1114 }
1115
1116 static int
1117 puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1118     intptr_t *res)
1119 {
1120         const struct puc_cfg *cfg = sc->sc_cfg;
1121
1122         if (cmd == PUC_CFG_GET_OFS) {
1123                 if (cfg->subdevice == 0x1282)           /* Everest SP */
1124                         port <<= 1;
1125                 else if (cfg->subdevice == 0x104b)      /* Maestro SP2 */
1126                         port = (port == 3) ? 4 : port;
1127                 *res = port * 8 + ((port > 2) ? 0x18 : 0);
1128                 return (0);
1129         }
1130         return (ENXIO);
1131 }
1132
1133 static int
1134 puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1135     intptr_t *res)
1136 {
1137         if (cmd == PUC_CFG_GET_OFS) {
1138                 *res = port * 0x200;
1139                 return (0);
1140         }
1141         return (ENXIO);
1142 }
1143
1144 static int
1145 puc_config_icbook(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1146     intptr_t *res)
1147 {
1148         if (cmd == PUC_CFG_GET_ILR) {
1149                 *res = PUC_ILR_DIGI;
1150                 return (0);
1151         }
1152         return (ENXIO);
1153 }
1154
1155 static int
1156 puc_config_moxa(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1157     intptr_t *res)
1158 {
1159         if (cmd == PUC_CFG_GET_OFS) {
1160                 const struct puc_cfg *cfg = sc->sc_cfg;
1161
1162                 if (port == 3 && (cfg->device == 0x1045 || cfg->device == 0x1144))
1163                         port = 7;
1164                 *res = port * 0x200;
1165
1166                 return 0;
1167         }
1168         return (ENXIO);
1169 }
1170
1171 static int
1172 puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1173     intptr_t *res)
1174 {
1175         const struct puc_cfg *cfg = sc->sc_cfg;
1176         struct puc_bar *bar;
1177         uint8_t v0, v1;
1178
1179         switch (cmd) {
1180         case PUC_CFG_SETUP:
1181                 /*
1182                  * Check if the scratchpad register is enabled or if the
1183                  * interrupt status and options registers are active.
1184                  */
1185                 bar = puc_get_bar(sc, cfg->rid);
1186                 if (bar == NULL)
1187                         return (ENXIO);
1188                 /* Set DLAB in the LCR register of UART 0. */
1189                 bus_write_1(bar->b_res, 3, 0x80);
1190                 /* Write 0 to the SPR register of UART 0. */
1191                 bus_write_1(bar->b_res, 7, 0);
1192                 /* Read back the contents of the SPR register of UART 0. */
1193                 v0 = bus_read_1(bar->b_res, 7);
1194                 /* Write a specific value to the SPR register of UART 0. */
1195                 bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
1196                 /* Read back the contents of the SPR register of UART 0. */
1197                 v1 = bus_read_1(bar->b_res, 7);
1198                 /* Clear DLAB in the LCR register of UART 0. */
1199                 bus_write_1(bar->b_res, 3, 0);
1200                 /* Save the two values read-back from the SPR register. */
1201                 sc->sc_cfg_data = (v0 << 8) | v1;
1202                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1203                         /*
1204                          * The SPR register echoed the two values written
1205                          * by us. This means that the SPAD jumper is set.
1206                          */
1207                         device_printf(sc->sc_dev, "warning: extra features "
1208                             "not usable -- SPAD compatibility enabled\n");
1209                         return (0);
1210                 }
1211                 if (v0 != 0) {
1212                         /*
1213                          * The first value doesn't match. This can only mean
1214                          * that the SPAD jumper is not set and that a non-
1215                          * standard fixed clock multiplier jumper is set.
1216                          */
1217                         if (bootverbose)
1218                                 device_printf(sc->sc_dev, "fixed clock rate "
1219                                     "multiplier of %d\n", 1 << v0);
1220                         if (v0 < -cfg->clock)
1221                                 device_printf(sc->sc_dev, "warning: "
1222                                     "suboptimal fixed clock rate multiplier "
1223                                     "setting\n");
1224                         return (0);
1225                 }
1226                 /*
1227                  * The first value matched, but the second didn't. We know
1228                  * that the SPAD jumper is not set. We also know that the
1229                  * clock rate multiplier is software controlled *and* that
1230                  * we just programmed it to the maximum allowed.
1231                  */
1232                 if (bootverbose)
1233                         device_printf(sc->sc_dev, "clock rate multiplier of "
1234                             "%d selected\n", 1 << -cfg->clock);
1235                 return (0);
1236         case PUC_CFG_GET_CLOCK:
1237                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1238                 v1 = sc->sc_cfg_data & 0xff;
1239                 if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
1240                         /*
1241                          * XXX With the SPAD jumper applied, there's no
1242                          * easy way of knowing if there's also a clock
1243                          * rate multiplier jumper installed. Let's hope
1244                          * not...
1245                          */
1246                         *res = DEFAULT_RCLK;
1247                 } else if (v0 == 0) {
1248                         /*
1249                          * No clock rate multiplier jumper installed,
1250                          * so we programmed the board with the maximum
1251                          * multiplier allowed as given to us in the
1252                          * clock field of the config record (negated).
1253                          */
1254                         *res = DEFAULT_RCLK << -cfg->clock;
1255                 } else
1256                         *res = DEFAULT_RCLK << v0;
1257                 return (0);
1258         case PUC_CFG_GET_ILR:
1259                 v0 = (sc->sc_cfg_data >> 8) & 0xff;
1260                 v1 = sc->sc_cfg_data & 0xff;
1261                 *res = (v0 == 0 && v1 == 0x80 + -cfg->clock)
1262                     ? PUC_ILR_NONE : PUC_ILR_QUATECH;
1263                 return (0);
1264         default:
1265                 break;
1266         }
1267         return (ENXIO);
1268 }
1269
1270 static int
1271 puc_config_syba(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1272     intptr_t *res)
1273 {
1274         static int base[] = { 0x251, 0x3f0, 0 };
1275         const struct puc_cfg *cfg = sc->sc_cfg;
1276         struct puc_bar *bar;
1277         int efir, idx, ofs;
1278         uint8_t v;
1279
1280         switch (cmd) {
1281         case PUC_CFG_SETUP:
1282                 bar = puc_get_bar(sc, cfg->rid);
1283                 if (bar == NULL)
1284                         return (ENXIO);
1285
1286                 /* configure both W83877TFs */
1287                 bus_write_1(bar->b_res, 0x250, 0x89);
1288                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1289                 bus_write_1(bar->b_res, 0x3f0, 0x87);
1290                 idx = 0;
1291                 while (base[idx] != 0) {
1292                         efir = base[idx];
1293                         bus_write_1(bar->b_res, efir, 0x09);
1294                         v = bus_read_1(bar->b_res, efir + 1);
1295                         if ((v & 0x0f) != 0x0c)
1296                                 return (ENXIO);
1297                         bus_write_1(bar->b_res, efir, 0x16);
1298                         v = bus_read_1(bar->b_res, efir + 1);
1299                         bus_write_1(bar->b_res, efir, 0x16);
1300                         bus_write_1(bar->b_res, efir + 1, v | 0x04);
1301                         bus_write_1(bar->b_res, efir, 0x16);
1302                         bus_write_1(bar->b_res, efir + 1, v & ~0x04);
1303                         ofs = base[idx] & 0x300;
1304                         bus_write_1(bar->b_res, efir, 0x23);
1305                         bus_write_1(bar->b_res, efir + 1, (ofs + 0x78) >> 2);
1306                         bus_write_1(bar->b_res, efir, 0x24);
1307                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xf8) >> 2);
1308                         bus_write_1(bar->b_res, efir, 0x25);
1309                         bus_write_1(bar->b_res, efir + 1, (ofs + 0xe8) >> 2);
1310                         bus_write_1(bar->b_res, efir, 0x17);
1311                         bus_write_1(bar->b_res, efir + 1, 0x03);
1312                         bus_write_1(bar->b_res, efir, 0x28);
1313                         bus_write_1(bar->b_res, efir + 1, 0x43);
1314                         idx++;
1315                 }
1316                 bus_write_1(bar->b_res, 0x250, 0xaa);
1317                 bus_write_1(bar->b_res, 0x3f0, 0xaa);
1318                 return (0);
1319         case PUC_CFG_GET_OFS:
1320                 switch (port) {
1321                 case 0:
1322                         *res = 0x2f8;
1323                         return (0);
1324                 case 1:
1325                         *res = 0x2e8;
1326                         return (0);
1327                 case 2:
1328                         *res = 0x3f8;
1329                         return (0);
1330                 case 3:
1331                         *res = 0x3e8;
1332                         return (0);
1333                 case 4:
1334                         *res = 0x278;
1335                         return (0);
1336                 }
1337                 break;
1338         default:
1339                 break;
1340         }
1341         return (ENXIO);
1342 }
1343
1344 static int
1345 puc_config_siig(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1346     intptr_t *res)
1347 {
1348         const struct puc_cfg *cfg = sc->sc_cfg;
1349
1350         switch (cmd) {
1351         case PUC_CFG_GET_OFS:
1352                 if (cfg->ports == PUC_PORT_8S) {
1353                         *res = (port > 4) ? 8 * (port - 4) : 0;
1354                         return (0);
1355                 }
1356                 break;
1357         case PUC_CFG_GET_RID:
1358                 if (cfg->ports == PUC_PORT_8S) {
1359                         *res = 0x10 + ((port > 4) ? 0x10 : 4 * port);
1360                         return (0);
1361                 }
1362                 if (cfg->ports == PUC_PORT_2S1P) {
1363                         switch (port) {
1364                         case 0: *res = 0x10; return (0);
1365                         case 1: *res = 0x14; return (0);
1366                         case 2: *res = 0x1c; return (0);
1367                         }
1368                 }
1369                 break;
1370         default:
1371                 break;
1372         }
1373         return (ENXIO);
1374 }
1375
1376 static int
1377 puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1378     intptr_t *res)
1379 {
1380         static uint16_t dual[] = {
1381             0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
1382             0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 
1383             0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, 
1384             0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
1385             0xD079, 0
1386         };
1387         static uint16_t quad[] = {
1388             0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 
1389             0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 
1390             0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
1391             0xB157, 0
1392         };
1393         static uint16_t octa[] = {
1394             0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 
1395             0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
1396         };
1397         static struct {
1398                 int ports;
1399                 uint16_t *ids;
1400         } subdevs[] = {
1401             { 2, dual },
1402             { 4, quad },
1403             { 8, octa },
1404             { 0, NULL }
1405         };
1406         static char desc[64];
1407         int dev, id;
1408         uint16_t subdev;
1409
1410         switch (cmd) {
1411         case PUC_CFG_GET_CLOCK:
1412                 if (port < 2)
1413                         *res = DEFAULT_RCLK * 8;
1414                 else
1415                         *res = DEFAULT_RCLK;
1416                 return (0);
1417         case PUC_CFG_GET_DESC:
1418                 snprintf(desc, sizeof(desc),
1419                     "Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
1420                 *res = (intptr_t)desc;
1421                 return (0);
1422         case PUC_CFG_GET_NPORTS:
1423                 subdev = pci_get_subdevice(sc->sc_dev);
1424                 dev = 0;
1425                 while (subdevs[dev].ports != 0) {
1426                         id = 0;
1427                         while (subdevs[dev].ids[id] != 0) {
1428                                 if (subdev == subdevs[dev].ids[id]) {
1429                                         sc->sc_cfg_data = subdevs[dev].ports;
1430                                         *res = sc->sc_cfg_data;
1431                                         return (0);
1432                                 }
1433                                 id++;
1434                         }
1435                         dev++;
1436                 }
1437                 return (ENXIO);
1438         case PUC_CFG_GET_OFS:
1439                 *res = (port == 1 || port == 3) ? 8 : 0;
1440                 return (0);
1441         case PUC_CFG_GET_RID:
1442                 *res = 0x10 + ((port > 3) ? port - 2 : port >> 1) * 4;
1443                 return (0);
1444         case PUC_CFG_GET_TYPE:
1445                 *res = PUC_TYPE_SERIAL;
1446                 return (0);
1447         default:
1448                 break;
1449         }
1450         return (ENXIO);
1451 }
1452
1453 static int
1454 puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1455     intptr_t *res)
1456 {
1457         const struct puc_cfg *cfg = sc->sc_cfg;
1458         int idx;
1459         struct puc_bar *bar;
1460         uint8_t value;
1461
1462         switch (cmd) {
1463         case PUC_CFG_SETUP:
1464                 device_printf(sc->sc_dev, "%d UARTs detected\n",
1465                         sc->sc_nports);
1466
1467                 /* Set UARTs to enhanced mode */
1468                 bar = puc_get_bar(sc, cfg->rid);
1469                 if (bar == NULL)
1470                         return (ENXIO);
1471                 for (idx = 0; idx < sc->sc_nports; idx++) {
1472                         value = bus_read_1(bar->b_res, 0x1000 + (idx << 9) +
1473                             0x92);
1474                         bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
1475                             value | 0x10);
1476                 }
1477                 return (0);
1478         case PUC_CFG_GET_LEN:
1479                 *res = 0x200;
1480                 return (0);
1481         case PUC_CFG_GET_NPORTS:
1482                 /*
1483                  * Check if we are being called from puc_bfe_attach()
1484                  * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
1485                  * puc_get_bar(), so we return a value of 16. This has cosmetic
1486                  * side-effects at worst; in PUC_CFG_GET_DESC,
1487                  * (int)sc->sc_cfg_data will not contain the true number of
1488                  * ports in PUC_CFG_GET_DESC, but we are not implementing that
1489                  * call for this device family anyway.
1490                  *
1491                  * The check is for initialisation of sc->sc_bar[idx], which is
1492                  * only done in puc_bfe_attach().
1493                  */
1494                 idx = 0;
1495                 do {
1496                         if (sc->sc_bar[idx++].b_rid != -1) {
1497                                 sc->sc_cfg_data = 16;
1498                                 *res = sc->sc_cfg_data;
1499                                 return (0);
1500                         }
1501                 } while (idx < PUC_PCI_BARS);
1502
1503                 bar = puc_get_bar(sc, cfg->rid);
1504                 if (bar == NULL)
1505                         return (ENXIO);
1506
1507                 value = bus_read_1(bar->b_res, 0x04);
1508                 if (value == 0)
1509                         return (ENXIO);
1510
1511                 sc->sc_cfg_data = value;
1512                 *res = sc->sc_cfg_data;
1513                 return (0);
1514         case PUC_CFG_GET_OFS:
1515                 *res = 0x1000 + (port << 9);
1516                 return (0);
1517         case PUC_CFG_GET_TYPE:
1518                 *res = PUC_TYPE_SERIAL;
1519                 return (0);
1520         default:
1521                 break;
1522         }
1523         return (ENXIO);
1524 }
1525
1526 static int
1527 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
1528     intptr_t *res)
1529 {
1530         switch (cmd) {
1531         case PUC_CFG_GET_OFS:
1532                 *res = (port < 3) ? 0 : (port - 2) << 3;
1533                 return (0);
1534         case PUC_CFG_GET_RID:
1535                 *res = 0x14 + ((port >= 2) ? 0x0c : port << 2);
1536                 return (0);
1537         default:
1538                 break;
1539         }
1540         return (ENXIO);
1541 }