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