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