1 /* 2 * QEMU TEWS TPCI200 IndustryPack carrier emulation 3 * 4 * Copyright (C) 2012 Igalia, S.L. 5 * Author: Alberto Garcia <berto@igalia.com> 6 * 7 * This code is licensed under the GNU GPL v2 or (at your option) any 8 * later version. 9 */ 10 11 #include "qemu/osdep.h" 12 #include "qemu/units.h" 13 #include "hw/ipack/ipack.h" 14 #include "hw/irq.h" 15 #include "hw/pci/pci.h" 16 #include "migration/vmstate.h" 17 #include "qemu/bitops.h" 18 #include "qemu/module.h" 19 #include "qom/object.h" 20 21 /* #define DEBUG_TPCI */ 22 23 #ifdef DEBUG_TPCI 24 #define DPRINTF(fmt, ...) \ 25 do { fprintf(stderr, "TPCI200: " fmt, ## __VA_ARGS__); } while (0) 26 #else 27 #define DPRINTF(fmt, ...) do { } while (0) 28 #endif 29 30 #define N_MODULES 4 31 32 #define IP_ID_SPACE 2 33 #define IP_INT_SPACE 3 34 #define IP_IO_SPACE_ADDR_MASK 0x7F 35 #define IP_ID_SPACE_ADDR_MASK 0x3F 36 #define IP_INT_SPACE_ADDR_MASK 0x3F 37 38 #define STATUS_INT(IP, INTNO) BIT((IP) * 2 + (INTNO)) 39 #define STATUS_TIME(IP) BIT((IP) + 12) 40 #define STATUS_ERR_ANY 0xF00 41 42 #define CTRL_CLKRATE BIT(0) 43 #define CTRL_RECOVER BIT(1) 44 #define CTRL_TIME_INT BIT(2) 45 #define CTRL_ERR_INT BIT(3) 46 #define CTRL_INT_EDGE(INTNO) BIT(4 + (INTNO)) 47 #define CTRL_INT(INTNO) BIT(6 + (INTNO)) 48 49 #define REG_REV_ID 0x00 50 #define REG_IP_A_CTRL 0x02 51 #define REG_IP_B_CTRL 0x04 52 #define REG_IP_C_CTRL 0x06 53 #define REG_IP_D_CTRL 0x08 54 #define REG_RESET 0x0A 55 #define REG_STATUS 0x0C 56 #define IP_N_FROM_REG(REG) ((REG) / 2 - 1) 57 58 struct TPCI200State { 59 PCIDevice dev; 60 IPackBus bus; 61 MemoryRegion mmio; 62 MemoryRegion io; 63 MemoryRegion las0; 64 MemoryRegion las1; 65 MemoryRegion las2; 66 MemoryRegion las3; 67 bool big_endian[3]; 68 uint8_t ctrl[N_MODULES]; 69 uint16_t status; 70 uint8_t int_set; 71 }; 72 typedef struct TPCI200State TPCI200State; 73 74 #define TYPE_TPCI200 "tpci200" 75 76 DECLARE_INSTANCE_CHECKER(TPCI200State, TPCI200, 77 TYPE_TPCI200) 78 79 static const uint8_t local_config_regs[] = { 80 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x00, 81 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 82 0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 83 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x60, 0x41, 0xD4, 84 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x01, 85 0x14, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x08, 0x01, 0x02, 86 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x02, 0x41, 87 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x00, 0x52, 0x92, 0x24, 0x02 88 }; 89 90 static void adjust_addr(bool big_endian, hwaddr *addr, unsigned size) 91 { 92 /* During 8 bit access in big endian mode, 93 odd and even addresses are swapped */ 94 if (big_endian && size == 1) { 95 *addr ^= 1; 96 } 97 } 98 99 static uint64_t adjust_value(bool big_endian, uint64_t *val, unsigned size) 100 { 101 /* Local spaces only support 8/16 bit access, 102 * so there's no need to care for sizes > 2 */ 103 if (big_endian && size == 2) { 104 *val = bswap16(*val); 105 } 106 return *val; 107 } 108 109 static void tpci200_set_irq(void *opaque, int intno, int level) 110 { 111 IPackDevice *ip = opaque; 112 IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(DEVICE(ip))); 113 PCIDevice *pcidev = PCI_DEVICE(BUS(bus)->parent); 114 TPCI200State *dev = TPCI200(pcidev); 115 unsigned ip_n = ip->slot; 116 uint16_t prev_status = dev->status; 117 118 assert(ip->slot >= 0 && ip->slot < N_MODULES); 119 120 /* The requested interrupt must be enabled in the IP CONTROL 121 * register */ 122 if (!(dev->ctrl[ip_n] & CTRL_INT(intno))) { 123 return; 124 } 125 126 /* Update the interrupt status in the IP STATUS register */ 127 if (level) { 128 dev->status |= STATUS_INT(ip_n, intno); 129 } else { 130 dev->status &= ~STATUS_INT(ip_n, intno); 131 } 132 133 /* Return if there are no changes */ 134 if (dev->status == prev_status) { 135 return; 136 } 137 138 DPRINTF("IP %u INT%u#: %u\n", ip_n, intno, level); 139 140 /* Check if the interrupt is edge sensitive */ 141 if (dev->ctrl[ip_n] & CTRL_INT_EDGE(intno)) { 142 if (level) { 143 pci_set_irq(&dev->dev, !dev->int_set); 144 pci_set_irq(&dev->dev, dev->int_set); 145 } 146 } else { 147 unsigned i, j; 148 uint16_t level_status = dev->status; 149 150 /* Check if there are any level sensitive interrupts set by 151 removing the ones that are edge sensitive from the status 152 register */ 153 for (i = 0; i < N_MODULES; i++) { 154 for (j = 0; j < 2; j++) { 155 if (dev->ctrl[i] & CTRL_INT_EDGE(j)) { 156 level_status &= ~STATUS_INT(i, j); 157 } 158 } 159 } 160 161 if (level_status && !dev->int_set) { 162 pci_irq_assert(&dev->dev); 163 dev->int_set = 1; 164 } else if (!level_status && dev->int_set) { 165 pci_irq_deassert(&dev->dev); 166 dev->int_set = 0; 167 } 168 } 169 } 170 171 static uint64_t tpci200_read_cfg(void *opaque, hwaddr addr, unsigned size) 172 { 173 TPCI200State *s = opaque; 174 uint8_t ret = 0; 175 if (addr < ARRAY_SIZE(local_config_regs)) { 176 ret = local_config_regs[addr]; 177 } 178 /* Endianness is stored in the first bit of these registers */ 179 if ((addr == 0x2b && s->big_endian[0]) || 180 (addr == 0x2f && s->big_endian[1]) || 181 (addr == 0x33 && s->big_endian[2])) { 182 ret |= 1; 183 } 184 DPRINTF("Read from LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) ret); 185 return ret; 186 } 187 188 static void tpci200_write_cfg(void *opaque, hwaddr addr, uint64_t val, 189 unsigned size) 190 { 191 TPCI200State *s = opaque; 192 /* Endianness is stored in the first bit of these registers */ 193 if (addr == 0x2b || addr == 0x2f || addr == 0x33) { 194 unsigned las = (addr - 0x2b) / 4; 195 s->big_endian[las] = val & 1; 196 DPRINTF("LAS%u big endian mode: %u\n", las, (unsigned) val & 1); 197 } else { 198 DPRINTF("Write to LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) val); 199 } 200 } 201 202 static uint64_t tpci200_read_las0(void *opaque, hwaddr addr, unsigned size) 203 { 204 TPCI200State *s = opaque; 205 uint64_t ret = 0; 206 207 switch (addr) { 208 209 case REG_REV_ID: 210 DPRINTF("Read REVISION ID\n"); /* Current value is 0x00 */ 211 break; 212 213 case REG_IP_A_CTRL: 214 case REG_IP_B_CTRL: 215 case REG_IP_C_CTRL: 216 case REG_IP_D_CTRL: 217 { 218 unsigned ip_n = IP_N_FROM_REG(addr); 219 ret = s->ctrl[ip_n]; 220 DPRINTF("Read IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) ret); 221 } 222 break; 223 224 case REG_RESET: 225 DPRINTF("Read RESET\n"); /* Not implemented */ 226 break; 227 228 case REG_STATUS: 229 ret = s->status; 230 DPRINTF("Read STATUS: 0x%x\n", (unsigned) ret); 231 break; 232 233 /* Reserved */ 234 default: 235 DPRINTF("Unsupported read from LAS0 0x%x\n", (unsigned) addr); 236 break; 237 } 238 239 return adjust_value(s->big_endian[0], &ret, size); 240 } 241 242 static void tpci200_write_las0(void *opaque, hwaddr addr, uint64_t val, 243 unsigned size) 244 { 245 TPCI200State *s = opaque; 246 247 adjust_value(s->big_endian[0], &val, size); 248 249 switch (addr) { 250 251 case REG_REV_ID: 252 DPRINTF("Write Revision ID: 0x%x\n", (unsigned) val); /* No effect */ 253 break; 254 255 case REG_IP_A_CTRL: 256 case REG_IP_B_CTRL: 257 case REG_IP_C_CTRL: 258 case REG_IP_D_CTRL: 259 { 260 unsigned ip_n = IP_N_FROM_REG(addr); 261 s->ctrl[ip_n] = val; 262 DPRINTF("Write IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) val); 263 } 264 break; 265 266 case REG_RESET: 267 DPRINTF("Write RESET: 0x%x\n", (unsigned) val); /* Not implemented */ 268 break; 269 270 case REG_STATUS: 271 { 272 unsigned i; 273 274 for (i = 0; i < N_MODULES; i++) { 275 IPackDevice *ip = ipack_device_find(&s->bus, i); 276 277 if (ip != NULL) { 278 if (val & STATUS_INT(i, 0)) { 279 DPRINTF("Clear IP %c INT0# status\n", 'A' + i); 280 qemu_irq_lower(ip->irq[0]); 281 } 282 if (val & STATUS_INT(i, 1)) { 283 DPRINTF("Clear IP %c INT1# status\n", 'A' + i); 284 qemu_irq_lower(ip->irq[1]); 285 } 286 } 287 288 if (val & STATUS_TIME(i)) { 289 DPRINTF("Clear IP %c timeout\n", 'A' + i); 290 s->status &= ~STATUS_TIME(i); 291 } 292 } 293 294 if (val & STATUS_ERR_ANY) { 295 DPRINTF("Unexpected write to STATUS register: 0x%x\n", 296 (unsigned) val); 297 } 298 } 299 break; 300 301 /* Reserved */ 302 default: 303 DPRINTF("Unsupported write to LAS0 0x%x: 0x%x\n", 304 (unsigned) addr, (unsigned) val); 305 break; 306 } 307 } 308 309 static uint64_t tpci200_read_las1(void *opaque, hwaddr addr, unsigned size) 310 { 311 TPCI200State *s = opaque; 312 IPackDevice *ip; 313 uint64_t ret = 0; 314 unsigned ip_n, space; 315 uint8_t offset; 316 317 adjust_addr(s->big_endian[1], &addr, size); 318 319 /* 320 * The address is divided into the IP module number (0-4), the IP 321 * address space (I/O, ID, INT) and the offset within that space. 322 */ 323 ip_n = addr >> 8; 324 space = (addr >> 6) & 3; 325 ip = ipack_device_find(&s->bus, ip_n); 326 327 if (ip == NULL) { 328 DPRINTF("Read LAS1: IP module %u not installed\n", ip_n); 329 } else { 330 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 331 switch (space) { 332 333 case IP_ID_SPACE: 334 offset = addr & IP_ID_SPACE_ADDR_MASK; 335 if (k->id_read) { 336 ret = k->id_read(ip, offset); 337 } 338 break; 339 340 case IP_INT_SPACE: 341 offset = addr & IP_INT_SPACE_ADDR_MASK; 342 343 /* Read address 0 to ACK IP INT0# and address 2 to ACK IP INT1# */ 344 if (offset == 0 || offset == 2) { 345 unsigned intno = offset / 2; 346 bool int_set = s->status & STATUS_INT(ip_n, intno); 347 bool int_edge_sensitive = s->ctrl[ip_n] & CTRL_INT_EDGE(intno); 348 if (int_set && !int_edge_sensitive) { 349 qemu_irq_lower(ip->irq[intno]); 350 } 351 } 352 353 if (k->int_read) { 354 ret = k->int_read(ip, offset); 355 } 356 break; 357 358 default: 359 offset = addr & IP_IO_SPACE_ADDR_MASK; 360 if (k->io_read) { 361 ret = k->io_read(ip, offset); 362 } 363 break; 364 } 365 } 366 367 return adjust_value(s->big_endian[1], &ret, size); 368 } 369 370 static void tpci200_write_las1(void *opaque, hwaddr addr, uint64_t val, 371 unsigned size) 372 { 373 TPCI200State *s = opaque; 374 IPackDevice *ip; 375 unsigned ip_n, space; 376 uint8_t offset; 377 378 adjust_addr(s->big_endian[1], &addr, size); 379 adjust_value(s->big_endian[1], &val, size); 380 381 /* 382 * The address is divided into the IP module number, the IP 383 * address space (I/O, ID, INT) and the offset within that space. 384 */ 385 ip_n = addr >> 8; 386 space = (addr >> 6) & 3; 387 ip = ipack_device_find(&s->bus, ip_n); 388 389 if (ip == NULL) { 390 DPRINTF("Write LAS1: IP module %u not installed\n", ip_n); 391 } else { 392 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 393 switch (space) { 394 395 case IP_ID_SPACE: 396 offset = addr & IP_ID_SPACE_ADDR_MASK; 397 if (k->id_write) { 398 k->id_write(ip, offset, val); 399 } 400 break; 401 402 case IP_INT_SPACE: 403 offset = addr & IP_INT_SPACE_ADDR_MASK; 404 if (k->int_write) { 405 k->int_write(ip, offset, val); 406 } 407 break; 408 409 default: 410 offset = addr & IP_IO_SPACE_ADDR_MASK; 411 if (k->io_write) { 412 k->io_write(ip, offset, val); 413 } 414 break; 415 } 416 } 417 } 418 419 static uint64_t tpci200_read_las2(void *opaque, hwaddr addr, unsigned size) 420 { 421 TPCI200State *s = opaque; 422 IPackDevice *ip; 423 uint64_t ret = 0; 424 unsigned ip_n; 425 uint32_t offset; 426 427 adjust_addr(s->big_endian[2], &addr, size); 428 429 /* 430 * The address is divided into the IP module number and the offset 431 * within the IP module MEM space. 432 */ 433 ip_n = addr >> 23; 434 offset = addr & 0x7fffff; 435 ip = ipack_device_find(&s->bus, ip_n); 436 437 if (ip == NULL) { 438 DPRINTF("Read LAS2: IP module %u not installed\n", ip_n); 439 } else { 440 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 441 if (k->mem_read16) { 442 ret = k->mem_read16(ip, offset); 443 } 444 } 445 446 return adjust_value(s->big_endian[2], &ret, size); 447 } 448 449 static void tpci200_write_las2(void *opaque, hwaddr addr, uint64_t val, 450 unsigned size) 451 { 452 TPCI200State *s = opaque; 453 IPackDevice *ip; 454 unsigned ip_n; 455 uint32_t offset; 456 457 adjust_addr(s->big_endian[2], &addr, size); 458 adjust_value(s->big_endian[2], &val, size); 459 460 /* 461 * The address is divided into the IP module number and the offset 462 * within the IP module MEM space. 463 */ 464 ip_n = addr >> 23; 465 offset = addr & 0x7fffff; 466 ip = ipack_device_find(&s->bus, ip_n); 467 468 if (ip == NULL) { 469 DPRINTF("Write LAS2: IP module %u not installed\n", ip_n); 470 } else { 471 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 472 if (k->mem_write16) { 473 k->mem_write16(ip, offset, val); 474 } 475 } 476 } 477 478 static uint64_t tpci200_read_las3(void *opaque, hwaddr addr, unsigned size) 479 { 480 TPCI200State *s = opaque; 481 IPackDevice *ip; 482 uint64_t ret = 0; 483 /* 484 * The address is divided into the IP module number and the offset 485 * within the IP module MEM space. 486 */ 487 unsigned ip_n = addr >> 22; 488 uint32_t offset = addr & 0x3fffff; 489 490 ip = ipack_device_find(&s->bus, ip_n); 491 492 if (ip == NULL) { 493 DPRINTF("Read LAS3: IP module %u not installed\n", ip_n); 494 } else { 495 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 496 if (k->mem_read8) { 497 ret = k->mem_read8(ip, offset); 498 } 499 } 500 501 return ret; 502 } 503 504 static void tpci200_write_las3(void *opaque, hwaddr addr, uint64_t val, 505 unsigned size) 506 { 507 TPCI200State *s = opaque; 508 IPackDevice *ip; 509 /* 510 * The address is divided into the IP module number and the offset 511 * within the IP module MEM space. 512 */ 513 unsigned ip_n = addr >> 22; 514 uint32_t offset = addr & 0x3fffff; 515 516 ip = ipack_device_find(&s->bus, ip_n); 517 518 if (ip == NULL) { 519 DPRINTF("Write LAS3: IP module %u not installed\n", ip_n); 520 } else { 521 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 522 if (k->mem_write8) { 523 k->mem_write8(ip, offset, val); 524 } 525 } 526 } 527 528 static const MemoryRegionOps tpci200_cfg_ops = { 529 .read = tpci200_read_cfg, 530 .write = tpci200_write_cfg, 531 .endianness = DEVICE_NATIVE_ENDIAN, 532 .valid = { 533 .min_access_size = 1, 534 .max_access_size = 4 535 }, 536 .impl = { 537 .min_access_size = 1, 538 .max_access_size = 1 539 } 540 }; 541 542 static const MemoryRegionOps tpci200_las0_ops = { 543 .read = tpci200_read_las0, 544 .write = tpci200_write_las0, 545 .endianness = DEVICE_NATIVE_ENDIAN, 546 .valid = { 547 .min_access_size = 2, 548 .max_access_size = 2 549 } 550 }; 551 552 static const MemoryRegionOps tpci200_las1_ops = { 553 .read = tpci200_read_las1, 554 .write = tpci200_write_las1, 555 .endianness = DEVICE_NATIVE_ENDIAN, 556 .valid = { 557 .min_access_size = 1, 558 .max_access_size = 2 559 } 560 }; 561 562 static const MemoryRegionOps tpci200_las2_ops = { 563 .read = tpci200_read_las2, 564 .write = tpci200_write_las2, 565 .endianness = DEVICE_NATIVE_ENDIAN, 566 .valid = { 567 .min_access_size = 1, 568 .max_access_size = 2 569 } 570 }; 571 572 static const MemoryRegionOps tpci200_las3_ops = { 573 .read = tpci200_read_las3, 574 .write = tpci200_write_las3, 575 .endianness = DEVICE_NATIVE_ENDIAN, 576 .valid = { 577 .min_access_size = 1, 578 .max_access_size = 1 579 } 580 }; 581 582 static void tpci200_realize(PCIDevice *pci_dev, Error **errp) 583 { 584 TPCI200State *s = TPCI200(pci_dev); 585 uint8_t *c = s->dev.config; 586 587 pci_set_word(c + PCI_COMMAND, 0x0003); 588 pci_set_word(c + PCI_STATUS, 0x0280); 589 590 pci_set_byte(c + PCI_INTERRUPT_PIN, 0x01); /* Interrupt pin A */ 591 592 pci_set_byte(c + PCI_CAPABILITY_LIST, 0x40); 593 pci_set_long(c + 0x40, 0x48014801); 594 pci_set_long(c + 0x48, 0x00024C06); 595 pci_set_long(c + 0x4C, 0x00000003); 596 597 memory_region_init_io(&s->mmio, OBJECT(s), &tpci200_cfg_ops, 598 s, "tpci200_mmio", 128); 599 memory_region_init_io(&s->io, OBJECT(s), &tpci200_cfg_ops, 600 s, "tpci200_io", 128); 601 memory_region_init_io(&s->las0, OBJECT(s), &tpci200_las0_ops, 602 s, "tpci200_las0", 256); 603 memory_region_init_io(&s->las1, OBJECT(s), &tpci200_las1_ops, 604 s, "tpci200_las1", 1024); 605 memory_region_init_io(&s->las2, OBJECT(s), &tpci200_las2_ops, 606 s, "tpci200_las2", 32 * MiB); 607 memory_region_init_io(&s->las3, OBJECT(s), &tpci200_las3_ops, 608 s, "tpci200_las3", 16 * MiB); 609 pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); 610 pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); 611 pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las0); 612 pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las1); 613 pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2); 614 pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3); 615 616 ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL, 617 N_MODULES, tpci200_set_irq); 618 } 619 620 static const VMStateDescription vmstate_tpci200 = { 621 .name = "tpci200", 622 .version_id = 1, 623 .minimum_version_id = 1, 624 .fields = (VMStateField[]) { 625 VMSTATE_PCI_DEVICE(dev, TPCI200State), 626 VMSTATE_BOOL_ARRAY(big_endian, TPCI200State, 3), 627 VMSTATE_UINT8_ARRAY(ctrl, TPCI200State, N_MODULES), 628 VMSTATE_UINT16(status, TPCI200State), 629 VMSTATE_UINT8(int_set, TPCI200State), 630 VMSTATE_END_OF_LIST() 631 } 632 }; 633 634 static void tpci200_class_init(ObjectClass *klass, void *data) 635 { 636 DeviceClass *dc = DEVICE_CLASS(klass); 637 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 638 639 k->realize = tpci200_realize; 640 k->vendor_id = PCI_VENDOR_ID_TEWS; 641 k->device_id = PCI_DEVICE_ID_TEWS_TPCI200; 642 k->class_id = PCI_CLASS_BRIDGE_OTHER; 643 k->subsystem_vendor_id = PCI_VENDOR_ID_TEWS; 644 k->subsystem_id = 0x300A; 645 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 646 dc->desc = "TEWS TPCI200 IndustryPack carrier"; 647 dc->vmsd = &vmstate_tpci200; 648 } 649 650 static const TypeInfo tpci200_info = { 651 .name = TYPE_TPCI200, 652 .parent = TYPE_PCI_DEVICE, 653 .instance_size = sizeof(TPCI200State), 654 .class_init = tpci200_class_init, 655 .interfaces = (InterfaceInfo[]) { 656 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 657 { }, 658 }, 659 }; 660 661 static void tpci200_register_types(void) 662 { 663 type_register_static(&tpci200_info); 664 } 665 666 type_init(tpci200_register_types) 667