| 302 | } |
| 303 | |
| 304 | rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev) |
| 305 | { |
| 306 | rt_uint8_t pos; |
| 307 | rt_uint32_t class = 0; |
| 308 | struct rt_pci_host_bridge *host_bridge; |
| 309 | |
| 310 | if (!pdev) |
| 311 | { |
| 312 | return -RT_EINVAL; |
| 313 | } |
| 314 | |
| 315 | if (!(host_bridge = rt_pci_find_host_bridge(pdev->bus))) |
| 316 | { |
| 317 | return -RT_EINVAL; |
| 318 | } |
| 319 | |
| 320 | rt_pci_ofw_device_init(pdev); |
| 321 | |
| 322 | rt_pci_read_config_u32(pdev, PCIR_REVID, &class); |
| 323 | |
| 324 | pdev->revision = class & 0xff; |
| 325 | pdev->class = class >> 8; /* Upper 3 bytes */ |
| 326 | rt_pci_read_config_u8(pdev, PCIR_HDRTYPE, &pdev->hdr_type); |
| 327 | |
| 328 | /* Clear errors left from system firmware */ |
| 329 | rt_pci_write_config_u16(pdev, PCIR_STATUS, 0xffff); |
| 330 | |
| 331 | if (pdev->hdr_type & 0x80) |
| 332 | { |
| 333 | pdev->multi_function = RT_TRUE; |
| 334 | } |
| 335 | pdev->hdr_type &= PCIM_HDRTYPE; |
| 336 | |
| 337 | if (pci_intx_mask_broken(pdev)) |
| 338 | { |
| 339 | pdev->broken_intx_masking = RT_TRUE; |
| 340 | } |
| 341 | |
| 342 | rt_dm_dev_set_name(&pdev->parent, "%04x:%02x:%02x.%u", rt_pci_domain(pdev), |
| 343 | pdev->bus->number, RT_PCI_SLOT(pdev->devfn), RT_PCI_FUNC(pdev->devfn)); |
| 344 | |
| 345 | switch (pdev->hdr_type) |
| 346 | { |
| 347 | case PCIM_HDRTYPE_NORMAL: |
| 348 | if (class == PCIS_BRIDGE_PCI) |
| 349 | { |
| 350 | goto error; |
| 351 | } |
| 352 | pci_read_irq(pdev); |
| 353 | rt_pci_device_alloc_resource(host_bridge, pdev); |
| 354 | rt_pci_read_config_u16(pdev, PCIR_SUBVEND_0, &pdev->subsystem_vendor); |
| 355 | rt_pci_read_config_u16(pdev, PCIR_SUBDEV_0, &pdev->subsystem_device); |
| 356 | break; |
| 357 | |
| 358 | case PCIM_HDRTYPE_BRIDGE: |
| 359 | pci_read_irq(pdev); |
| 360 | rt_pci_device_alloc_resource(host_bridge, pdev); |
| 361 | pos = rt_pci_find_capability(pdev, PCIY_SUBVENDOR); |
no test coverage detected