1 /* 2 * QEMU Uninorth PCI host (for all Mac99 and newer machines) 3 * 4 * Copyright (c) 2006 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "hw/hw.h" 27 #include "hw/ppc/mac.h" 28 #include "qemu/module.h" 29 #include "hw/pci/pci.h" 30 #include "hw/pci/pci_host.h" 31 #include "hw/pci-host/uninorth.h" 32 #include "trace.h" 33 34 static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e }; 35 36 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) 37 { 38 return (irq_num + (pci_dev->devfn >> 3)) & 3; 39 } 40 41 static void pci_unin_set_irq(void *opaque, int irq_num, int level) 42 { 43 UNINHostState *s = opaque; 44 45 trace_unin_set_irq(unin_irq_line[irq_num], level); 46 qemu_set_irq(s->irqs[irq_num], level); 47 } 48 49 static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) 50 { 51 uint32_t retval; 52 53 if (reg & (1u << 31)) { 54 /* XXX OpenBIOS compatibility hack */ 55 retval = reg | (addr & 3); 56 } else if (reg & 1) { 57 /* CFA1 style */ 58 retval = (reg & ~7u) | (addr & 7); 59 } else { 60 uint32_t slot, func; 61 62 /* Grab CFA0 style values */ 63 slot = ctz32(reg & 0xfffff800); 64 if (slot == 32) { 65 slot = -1; /* XXX: should this be 0? */ 66 } 67 func = (reg >> 8) & 7; 68 69 /* ... and then convert them to x86 format */ 70 /* config pointer */ 71 retval = (reg & (0xff - 7)) | (addr & 7); 72 /* slot */ 73 retval |= slot << 11; 74 /* fn */ 75 retval |= func << 8; 76 } 77 78 trace_unin_get_config_reg(reg, addr, retval); 79 80 return retval; 81 } 82 83 static void unin_data_write(void *opaque, hwaddr addr, 84 uint64_t val, unsigned len) 85 { 86 UNINHostState *s = opaque; 87 PCIHostState *phb = PCI_HOST_BRIDGE(s); 88 trace_unin_data_write(addr, len, val); 89 pci_data_write(phb->bus, 90 unin_get_config_reg(phb->config_reg, addr), 91 val, len); 92 } 93 94 static uint64_t unin_data_read(void *opaque, hwaddr addr, 95 unsigned len) 96 { 97 UNINHostState *s = opaque; 98 PCIHostState *phb = PCI_HOST_BRIDGE(s); 99 uint32_t val; 100 101 val = pci_data_read(phb->bus, 102 unin_get_config_reg(phb->config_reg, addr), 103 len); 104 trace_unin_data_read(addr, len, val); 105 return val; 106 } 107 108 static const MemoryRegionOps unin_data_ops = { 109 .read = unin_data_read, 110 .write = unin_data_write, 111 .endianness = DEVICE_LITTLE_ENDIAN, 112 }; 113 114 static void pci_unin_init_irqs(UNINHostState *s) 115 { 116 int i; 117 118 for (i = 0; i < ARRAY_SIZE(s->irqs); i++) { 119 s->irqs[i] = qdev_get_gpio_in(DEVICE(s->pic), unin_irq_line[i]); 120 } 121 } 122 123 static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) 124 { 125 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); 126 127 return g_strdup_printf("%x", s->ofw_addr); 128 } 129 130 static void pci_unin_main_realize(DeviceState *dev, Error **errp) 131 { 132 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); 133 PCIHostState *h = PCI_HOST_BRIDGE(dev); 134 135 h->bus = pci_register_root_bus(dev, NULL, 136 pci_unin_set_irq, pci_unin_map_irq, 137 s, 138 &s->pci_mmio, 139 &s->pci_io, 140 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 141 142 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); 143 pci_unin_init_irqs(s); 144 145 /* DEC 21154 bridge */ 146 #if 0 147 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ 148 pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); 149 #endif 150 } 151 152 static void pci_unin_main_init(Object *obj) 153 { 154 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); 155 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 156 PCIHostState *h = PCI_HOST_BRIDGE(obj); 157 158 /* Use values found on a real PowerMac */ 159 /* Uninorth main bus */ 160 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 161 obj, "unin-pci-conf-idx", 0x1000); 162 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, 163 "unin-pci-conf-data", 0x1000); 164 165 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 166 0x100000000ULL); 167 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, 168 "unin-pci-isa-mmio", 0x00800000); 169 170 memory_region_init_alias(&s->pci_hole, OBJECT(s), 171 "unin-pci-hole", &s->pci_mmio, 172 0x80000000ULL, 0x10000000ULL); 173 174 object_property_add_link(obj, "pic", TYPE_OPENPIC, 175 (Object **) &s->pic, 176 qdev_prop_allow_set_link_before_realize, 177 0, NULL); 178 179 sysbus_init_mmio(sbd, &h->conf_mem); 180 sysbus_init_mmio(sbd, &h->data_mem); 181 sysbus_init_mmio(sbd, &s->pci_hole); 182 sysbus_init_mmio(sbd, &s->pci_io); 183 } 184 185 static void pci_u3_agp_realize(DeviceState *dev, Error **errp) 186 { 187 UNINHostState *s = U3_AGP_HOST_BRIDGE(dev); 188 PCIHostState *h = PCI_HOST_BRIDGE(dev); 189 190 h->bus = pci_register_root_bus(dev, NULL, 191 pci_unin_set_irq, pci_unin_map_irq, 192 s, 193 &s->pci_mmio, 194 &s->pci_io, 195 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 196 197 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); 198 pci_unin_init_irqs(s); 199 } 200 201 static void pci_u3_agp_init(Object *obj) 202 { 203 UNINHostState *s = U3_AGP_HOST_BRIDGE(obj); 204 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 205 PCIHostState *h = PCI_HOST_BRIDGE(obj); 206 207 /* Uninorth U3 AGP bus */ 208 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 209 obj, "unin-pci-conf-idx", 0x1000); 210 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, 211 "unin-pci-conf-data", 0x1000); 212 213 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 214 0x100000000ULL); 215 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, 216 "unin-pci-isa-mmio", 0x00800000); 217 218 memory_region_init_alias(&s->pci_hole, OBJECT(s), 219 "unin-pci-hole", &s->pci_mmio, 220 0x80000000ULL, 0x70000000ULL); 221 222 object_property_add_link(obj, "pic", TYPE_OPENPIC, 223 (Object **) &s->pic, 224 qdev_prop_allow_set_link_before_realize, 225 0, NULL); 226 227 sysbus_init_mmio(sbd, &h->conf_mem); 228 sysbus_init_mmio(sbd, &h->data_mem); 229 sysbus_init_mmio(sbd, &s->pci_hole); 230 sysbus_init_mmio(sbd, &s->pci_io); 231 } 232 233 static void pci_unin_agp_realize(DeviceState *dev, Error **errp) 234 { 235 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); 236 PCIHostState *h = PCI_HOST_BRIDGE(dev); 237 238 h->bus = pci_register_root_bus(dev, NULL, 239 pci_unin_set_irq, pci_unin_map_irq, 240 s, 241 &s->pci_mmio, 242 &s->pci_io, 243 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); 244 245 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); 246 pci_unin_init_irqs(s); 247 } 248 249 static void pci_unin_agp_init(Object *obj) 250 { 251 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); 252 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 253 PCIHostState *h = PCI_HOST_BRIDGE(obj); 254 255 /* Uninorth AGP bus */ 256 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 257 obj, "unin-agp-conf-idx", 0x1000); 258 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, 259 obj, "unin-agp-conf-data", 0x1000); 260 261 object_property_add_link(obj, "pic", TYPE_OPENPIC, 262 (Object **) &s->pic, 263 qdev_prop_allow_set_link_before_realize, 264 0, NULL); 265 266 sysbus_init_mmio(sbd, &h->conf_mem); 267 sysbus_init_mmio(sbd, &h->data_mem); 268 } 269 270 static void pci_unin_internal_realize(DeviceState *dev, Error **errp) 271 { 272 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); 273 PCIHostState *h = PCI_HOST_BRIDGE(dev); 274 275 h->bus = pci_register_root_bus(dev, NULL, 276 pci_unin_set_irq, pci_unin_map_irq, 277 s, 278 &s->pci_mmio, 279 &s->pci_io, 280 PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); 281 282 pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); 283 pci_unin_init_irqs(s); 284 } 285 286 static void pci_unin_internal_init(Object *obj) 287 { 288 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); 289 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 290 PCIHostState *h = PCI_HOST_BRIDGE(obj); 291 292 /* Uninorth internal bus */ 293 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, 294 obj, "unin-pci-conf-idx", 0x1000); 295 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, 296 obj, "unin-pci-conf-data", 0x1000); 297 298 object_property_add_link(obj, "pic", TYPE_OPENPIC, 299 (Object **) &s->pic, 300 qdev_prop_allow_set_link_before_realize, 301 0, NULL); 302 303 sysbus_init_mmio(sbd, &h->conf_mem); 304 sysbus_init_mmio(sbd, &h->data_mem); 305 } 306 307 static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) 308 { 309 /* cache_line_size */ 310 d->config[0x0C] = 0x08; 311 /* latency_timer */ 312 d->config[0x0D] = 0x10; 313 /* capabilities_pointer */ 314 d->config[0x34] = 0x00; 315 316 /* 317 * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI 318 * memory space with base 0x80000000, size 0x10000000 for Apple's 319 * AppleMacRiscPCI driver 320 */ 321 d->config[0x48] = 0x0; 322 d->config[0x49] = 0x0; 323 d->config[0x4a] = 0x0; 324 d->config[0x4b] = 0x1; 325 } 326 327 static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) 328 { 329 /* cache_line_size */ 330 d->config[0x0C] = 0x08; 331 /* latency_timer */ 332 d->config[0x0D] = 0x10; 333 /* capabilities_pointer 334 d->config[0x34] = 0x80; */ 335 } 336 337 static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) 338 { 339 /* cache line size */ 340 d->config[0x0C] = 0x08; 341 /* latency timer */ 342 d->config[0x0D] = 0x10; 343 } 344 345 static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp) 346 { 347 /* cache_line_size */ 348 d->config[0x0C] = 0x08; 349 /* latency_timer */ 350 d->config[0x0D] = 0x10; 351 /* capabilities_pointer */ 352 d->config[0x34] = 0x00; 353 } 354 355 static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) 356 { 357 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 358 DeviceClass *dc = DEVICE_CLASS(klass); 359 360 k->realize = unin_main_pci_host_realize; 361 k->vendor_id = PCI_VENDOR_ID_APPLE; 362 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; 363 k->revision = 0x00; 364 k->class_id = PCI_CLASS_BRIDGE_HOST; 365 /* 366 * PCI-facing part of the host bridge, not usable without the 367 * host-facing part, which can't be device_add'ed, yet. 368 */ 369 dc->user_creatable = false; 370 } 371 372 static const TypeInfo unin_main_pci_host_info = { 373 .name = "uni-north-pci", 374 .parent = TYPE_PCI_DEVICE, 375 .instance_size = sizeof(PCIDevice), 376 .class_init = unin_main_pci_host_class_init, 377 .interfaces = (InterfaceInfo[]) { 378 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 379 { }, 380 }, 381 }; 382 383 static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) 384 { 385 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 386 DeviceClass *dc = DEVICE_CLASS(klass); 387 388 k->realize = u3_agp_pci_host_realize; 389 k->vendor_id = PCI_VENDOR_ID_APPLE; 390 k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; 391 k->revision = 0x00; 392 k->class_id = PCI_CLASS_BRIDGE_HOST; 393 /* 394 * PCI-facing part of the host bridge, not usable without the 395 * host-facing part, which can't be device_add'ed, yet. 396 */ 397 dc->user_creatable = false; 398 } 399 400 static const TypeInfo u3_agp_pci_host_info = { 401 .name = "u3-agp", 402 .parent = TYPE_PCI_DEVICE, 403 .instance_size = sizeof(PCIDevice), 404 .class_init = u3_agp_pci_host_class_init, 405 .interfaces = (InterfaceInfo[]) { 406 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 407 { }, 408 }, 409 }; 410 411 static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) 412 { 413 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 414 DeviceClass *dc = DEVICE_CLASS(klass); 415 416 k->realize = unin_agp_pci_host_realize; 417 k->vendor_id = PCI_VENDOR_ID_APPLE; 418 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; 419 k->revision = 0x00; 420 k->class_id = PCI_CLASS_BRIDGE_HOST; 421 /* 422 * PCI-facing part of the host bridge, not usable without the 423 * host-facing part, which can't be device_add'ed, yet. 424 */ 425 dc->user_creatable = false; 426 } 427 428 static const TypeInfo unin_agp_pci_host_info = { 429 .name = "uni-north-agp", 430 .parent = TYPE_PCI_DEVICE, 431 .instance_size = sizeof(PCIDevice), 432 .class_init = unin_agp_pci_host_class_init, 433 .interfaces = (InterfaceInfo[]) { 434 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 435 { }, 436 }, 437 }; 438 439 static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) 440 { 441 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 442 DeviceClass *dc = DEVICE_CLASS(klass); 443 444 k->realize = unin_internal_pci_host_realize; 445 k->vendor_id = PCI_VENDOR_ID_APPLE; 446 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; 447 k->revision = 0x00; 448 k->class_id = PCI_CLASS_BRIDGE_HOST; 449 /* 450 * PCI-facing part of the host bridge, not usable without the 451 * host-facing part, which can't be device_add'ed, yet. 452 */ 453 dc->user_creatable = false; 454 } 455 456 static const TypeInfo unin_internal_pci_host_info = { 457 .name = "uni-north-internal-pci", 458 .parent = TYPE_PCI_DEVICE, 459 .instance_size = sizeof(PCIDevice), 460 .class_init = unin_internal_pci_host_class_init, 461 .interfaces = (InterfaceInfo[]) { 462 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 463 { }, 464 }, 465 }; 466 467 static Property pci_unin_main_pci_host_props[] = { 468 DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), 469 DEFINE_PROP_END_OF_LIST() 470 }; 471 472 static void pci_unin_main_class_init(ObjectClass *klass, void *data) 473 { 474 DeviceClass *dc = DEVICE_CLASS(klass); 475 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); 476 477 dc->realize = pci_unin_main_realize; 478 dc->props = pci_unin_main_pci_host_props; 479 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 480 dc->fw_name = "pci"; 481 sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; 482 } 483 484 static const TypeInfo pci_unin_main_info = { 485 .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE, 486 .parent = TYPE_PCI_HOST_BRIDGE, 487 .instance_size = sizeof(UNINHostState), 488 .instance_init = pci_unin_main_init, 489 .class_init = pci_unin_main_class_init, 490 }; 491 492 static void pci_u3_agp_class_init(ObjectClass *klass, void *data) 493 { 494 DeviceClass *dc = DEVICE_CLASS(klass); 495 496 dc->realize = pci_u3_agp_realize; 497 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 498 } 499 500 static const TypeInfo pci_u3_agp_info = { 501 .name = TYPE_U3_AGP_HOST_BRIDGE, 502 .parent = TYPE_PCI_HOST_BRIDGE, 503 .instance_size = sizeof(UNINHostState), 504 .instance_init = pci_u3_agp_init, 505 .class_init = pci_u3_agp_class_init, 506 }; 507 508 static void pci_unin_agp_class_init(ObjectClass *klass, void *data) 509 { 510 DeviceClass *dc = DEVICE_CLASS(klass); 511 512 dc->realize = pci_unin_agp_realize; 513 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 514 } 515 516 static const TypeInfo pci_unin_agp_info = { 517 .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE, 518 .parent = TYPE_PCI_HOST_BRIDGE, 519 .instance_size = sizeof(UNINHostState), 520 .instance_init = pci_unin_agp_init, 521 .class_init = pci_unin_agp_class_init, 522 }; 523 524 static void pci_unin_internal_class_init(ObjectClass *klass, void *data) 525 { 526 DeviceClass *dc = DEVICE_CLASS(klass); 527 528 dc->realize = pci_unin_internal_realize; 529 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 530 } 531 532 static const TypeInfo pci_unin_internal_info = { 533 .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE, 534 .parent = TYPE_PCI_HOST_BRIDGE, 535 .instance_size = sizeof(UNINHostState), 536 .instance_init = pci_unin_internal_init, 537 .class_init = pci_unin_internal_class_init, 538 }; 539 540 /* UniN device */ 541 static void unin_write(void *opaque, hwaddr addr, uint64_t value, 542 unsigned size) 543 { 544 trace_unin_write(addr, value); 545 } 546 547 static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) 548 { 549 uint32_t value; 550 551 switch (addr) { 552 case 0: 553 value = UNINORTH_VERSION_10A; 554 break; 555 default: 556 value = 0; 557 } 558 559 trace_unin_read(addr, value); 560 561 return value; 562 } 563 564 static const MemoryRegionOps unin_ops = { 565 .read = unin_read, 566 .write = unin_write, 567 .endianness = DEVICE_BIG_ENDIAN, 568 }; 569 570 static void unin_init(Object *obj) 571 { 572 UNINState *s = UNI_NORTH(obj); 573 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 574 575 memory_region_init_io(&s->mem, obj, &unin_ops, s, "unin", 0x1000); 576 577 sysbus_init_mmio(sbd, &s->mem); 578 } 579 580 static void unin_class_init(ObjectClass *klass, void *data) 581 { 582 DeviceClass *dc = DEVICE_CLASS(klass); 583 584 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 585 } 586 587 static const TypeInfo unin_info = { 588 .name = TYPE_UNI_NORTH, 589 .parent = TYPE_SYS_BUS_DEVICE, 590 .instance_size = sizeof(UNINState), 591 .instance_init = unin_init, 592 .class_init = unin_class_init, 593 }; 594 595 static void unin_register_types(void) 596 { 597 type_register_static(&unin_main_pci_host_info); 598 type_register_static(&u3_agp_pci_host_info); 599 type_register_static(&unin_agp_pci_host_info); 600 type_register_static(&unin_internal_pci_host_info); 601 602 type_register_static(&pci_unin_main_info); 603 type_register_static(&pci_u3_agp_info); 604 type_register_static(&pci_unin_agp_info); 605 type_register_static(&pci_unin_internal_info); 606 607 type_register_static(&unin_info); 608 } 609 610 type_init(unin_register_types) 611