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, 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, 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 1101 static int 1102 puc_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 1118 static int 1119 puc_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 1135 static int 1136 puc_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 1146 static int 1147 puc_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 1157 static int 1158 puc_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 1168 static int 1169 puc_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 1267 static int 1268 puc_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 1341 static int 1342 puc_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 1373 static int 1374 puc_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 1450 static int 1451 puc_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 1523 static int 1524 puc_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 } 1539