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