/** * pciinfo() - Show a list of devices on the PCI bus * * Show information about devices on PCI bus. Depending on @short_pci_listing * the output will be more or less exhaustive. * * @bus_num: The number of the bus to be scanned * @short_pci_listing: true to use short form, showing only a brief header * for each device */ void pciinfo(int bus_num, int short_pci_listing) { struct pci_controller *hose = pci_bus_to_hose(bus_num); int device; int function; unsigned char header_type; unsigned short vendor_id; pci_dev_t dev; int ret; if (!hose) return; pciinfo_header(bus_num, short_pci_listing); for (device = 0; device < PCI_MAX_PCI_DEVICES; device++) { header_type = 0; vendor_id = 0; for (function = 0; function < PCI_MAX_PCI_FUNCTIONS; function++) { /* * If this is not a multi-function device, we skip * the rest. */ if (function && !(header_type & 0x80)) break; dev = PCI_BDF(bus_num, device, function); if (pci_skip_dev(hose, dev)) continue; ret = pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id); if (ret) goto error; if ((vendor_id == 0xFFFF) || (vendor_id == 0x0000)) continue; if (!function) { pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); } if (short_pci_listing) { printf("%02x.%02x.%02x ", bus_num, device, function); pci_header_show_brief(dev); } else { printf("\nFound PCI device %02x.%02x.%02x:\n", bus_num, device, function); pci_header_show(dev); } } } return; error: printf("Cannot read bus configuration: %d\n", ret); }
/* * Subroutine: pciinfo * * Description: Show information about devices on PCI bus. * Depending on the define CONFIG_SYS_SHORT_PCI_LISTING * the output will be more or less exhaustive. * * Inputs: bus_no the number of the bus to be scanned. * * Return: None * */ void pciinfo(u32 BusNum) { int Device; int Function; unsigned char HeaderType; unsigned short VendorID; pci_dev_t dev; int ShortPCIListing; printf("Scanning PCI devices on bus %d\r\n", BusNum); ShortPCIListing = 0; if (ShortPCIListing) { printf("BusDevFun VendorId DeviceId Device Class Sub-Class\r\n"); printf("_____________________________________________________________\r\n"); } for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) { HeaderType = 0; VendorID = 0; for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) { /* * If this is not a multi-function device, we skip the rest. */ if (Function && !(HeaderType & 0x80)) break; dev = PCI_BDF(BusNum, Device, Function); pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID); if ((VendorID == 0xFFFF) || (VendorID == 0x0000)) continue; if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType); if (ShortPCIListing) { printf("%02x %02x %02x ", BusNum, Device, Function); pci_header_show_brief(dev); } else { printf("\nFound PCI device %02x %02x %02x:\r\n", BusNum, Device, Function); pci_header_show(dev); } } } }
static void pciinfo(struct udevice *bus, bool short_listing) { struct udevice *dev; pciinfo_header(bus->seq, short_listing); for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev)) { struct pci_child_platdata *pplat; pplat = dev_get_parent_platdata(dev); if (short_listing) { printf("%02x.%02x.%02x ", bus->seq, PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn)); pci_header_show_brief(dev); } else { printf("\nFound PCI device %02x.%02x.%02x:\n", bus->seq, PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn)); pci_header_show(dev); } } }
/* * Subroutine: pciinfo * * Description: Show information about devices on PCI bus. * Depending on the define CONFIG_SYS_SHORT_PCI_LISTING * the output will be more or less exhaustive. * * Inputs: bus_no the number of the bus to be scanned. * * Return: None * */ void pciinfo(int BusNum, int ShortPCIListing) { struct pci_controller *hose = pci_bus_to_hose(BusNum); int Device; int Function; unsigned char HeaderType; unsigned short VendorID; pci_dev_t dev; int ret; if (!hose) return; printf("Scanning PCI devices on bus %d\n", BusNum); if (ShortPCIListing) { printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n"); printf("_____________________________________________________________\n"); } for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) { HeaderType = 0; VendorID = 0; for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) { /* * If this is not a multi-function device, we skip the rest. */ if (Function && !(HeaderType & 0x80)) break; dev = PCI_BDF(BusNum, Device, Function); if (pci_skip_dev(hose, dev)) continue; ret = pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID); if (ret) goto error; if ((VendorID == 0xFFFF) || (VendorID == 0x0000)) continue; if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType); if (ShortPCIListing) { printf("%02x.%02x.%02x ", BusNum, Device, Function); pci_header_show_brief(dev); } else { printf("\nFound PCI device %02x.%02x.%02x:\n", BusNum, Device, Function); pci_header_show(dev); } } } return; error: printf("Cannot read bus configuration: %d\n", ret); }
/* PCI Configuration Space access commands * * Syntax: * pci display[.b, .w, .l] bus.device.function} [addr] [len] * pci next[.b, .w, .l] bus.device.function [addr] * pci modify[.b, .w, .l] bus.device.function [addr] * pci write[.b, .w, .l] bus.device.function addr value */ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr = 0, value = 0, size = 0; pci_dev_t bdf = 0; char cmd = 's'; if (argc > 1) cmd = argv[1][0]; switch (cmd) { case 'd': /* display */ case 'n': /* next */ case 'm': /* modify */ case 'w': /* write */ /* Check for a size specification. */ size = cmd_get_data_size(argv[1], 4); if (argc > 3) addr = simple_strtoul(argv[3], NULL, 16); if (argc > 4) value = simple_strtoul(argv[4], NULL, 16); case 'h': /* header */ if (argc < 3) goto usage; if ((bdf = get_pci_dev(argv[2])) == -1) return 1; break; #ifdef CONFIG_CMD_PCI_ENUM case 'e': break; #endif default: /* scan bus */ value = 1; /* short listing */ bdf = 0; /* bus number */ if (argc > 1) { if (argv[argc-1][0] == 'l') { value = 0; argc--; } if (argc > 1) bdf = simple_strtoul(argv[1], NULL, 16); } pciinfo(bdf, value); return 0; } switch (argv[1][0]) { case 'h': /* header */ pci_header_show(bdf); return 0; case 'd': /* display */ return pci_cfg_display(bdf, addr, size, value); #ifdef CONFIG_CMD_PCI_ENUM case 'e': pci_init(); return 0; #endif case 'n': /* next */ if (argc < 4) goto usage; return pci_cfg_modify(bdf, addr, size, value, 0); case 'm': /* modify */ if (argc < 4) goto usage; return pci_cfg_modify(bdf, addr, size, value, 1); case 'w': /* write */ if (argc < 5) goto usage; return pci_cfg_write(bdf, addr, size, value); } return 1; usage: return CMD_RET_USAGE; }
/* PCI Configuration Space access commands * * Syntax: * pci display[.b, .w, .l] bus.device.function} [addr] [len] * pci next[.b, .w, .l] bus.device.function [addr] * pci modify[.b, .w, .l] bus.device.function [addr] * pci write[.b, .w, .l] bus.device.function addr value */ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr = 0, value = 0, cmd_size = 0; enum pci_size_t size = PCI_SIZE_32; #ifdef CONFIG_DM_PCI struct udevice *dev, *bus; #else pci_dev_t dev; #endif int busnum = 0; pci_dev_t bdf = 0; char cmd = 's'; int ret = 0; if (argc > 1) cmd = argv[1][0]; switch (cmd) { case 'd': /* display */ case 'n': /* next */ case 'm': /* modify */ case 'w': /* write */ /* Check for a size specification. */ cmd_size = cmd_get_data_size(argv[1], 4); size = (cmd_size == 4) ? PCI_SIZE_32 : cmd_size - 1; if (argc > 3) addr = simple_strtoul(argv[3], NULL, 16); if (argc > 4) value = simple_strtoul(argv[4], NULL, 16); case 'h': /* header */ #ifdef CONFIG_DM_PCI case 'b': /* bars */ #endif if (argc < 3) goto usage; if ((bdf = get_pci_dev(argv[2])) == -1) return 1; break; #if defined(CONFIG_DM_PCI) case 'e': pci_init(); return 0; #endif case 'r': /* no break */ default: /* scan bus */ value = 1; /* short listing */ if (argc > 1) { if (cmd != 'r' && argv[argc-1][0] == 'l') { value = 0; argc--; } if (argc > 1) busnum = simple_strtoul(argv[1], NULL, 16); } #ifdef CONFIG_DM_PCI ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus); if (ret) { printf("No such bus\n"); return CMD_RET_FAILURE; } if (cmd == 'r') pci_show_regions(bus); else pciinfo(bus, value); #else pciinfo(busnum, value); #endif return 0; } #ifdef CONFIG_DM_PCI ret = dm_pci_bus_find_bdf(bdf, &dev); if (ret) { printf("No such device\n"); return CMD_RET_FAILURE; } #else dev = bdf; #endif switch (argv[1][0]) { case 'h': /* header */ pci_header_show(dev); break; case 'd': /* display */ return pci_cfg_display(dev, addr, size, value); case 'n': /* next */ if (argc < 4) goto usage; ret = pci_cfg_modify(dev, addr, size, value, 0); break; case 'm': /* modify */ if (argc < 4) goto usage; ret = pci_cfg_modify(dev, addr, size, value, 1); break; case 'w': /* write */ if (argc < 5) goto usage; #ifdef CONFIG_DM_PCI ret = dm_pci_write_config(dev, addr, value, size); #else ret = pci_cfg_write(dev, addr, size, value); #endif break; #ifdef CONFIG_DM_PCI case 'b': /* bars */ return pci_bar_show(dev); #endif default: ret = CMD_RET_USAGE; break; } return ret; usage: return CMD_RET_USAGE; }