in SDAccel/userspace/src/scan.h [243:447]
int scan(bool print) {
pci_device device;
int domain = 0;
int bus = 0, dev = 0, func = 0;
std::string dirname;
dirname = ROOT_DIR;
dirname += "/devices/";
#ifdef INTERNAL_TESTING
DIR *dir;
struct dirent *entry;
if ( !print_system_info() ) {
std::cout << "Unable to determine system info " << std::endl;
}
std::cout << "--- " << std::endl;
if ( !print_paths() ) {
std::cout << "Unable to determine PATH/LD_LIBRARY_PATH info " << std::endl;
}
std::cout << "--- " << std::endl;
dir = opendir(dirname.c_str());
if ( !dir ) {
std::cout << "Cannot open " << dirname << std::endl;
return -1;
}
while ((entry = readdir(dir))) {
if ( entry->d_name[0] == '.')
continue;
if ( sscanf(entry->d_name, "%x:%x:%x.%d", &domain, &bus, &dev, &func) < 4) {
std::cout << "scan: Couldn't parse entry name " << entry->d_name << std::endl;
}
std::string subdir = dirname + entry->d_name;
std::string subdir2 = dirname + entry->d_name;
//On Pegasus: 0 is userPF & 2 is mgmtPG.
//On Pegasus & F1: userPF is for Device 1d0f:1042
//if (func == 0 || func == 2) {
//}
//Using device id to only find userPF info
device.domain = domain;
device.bus = bus;
device.dev = dev;
device.func = func;
device.vendor_id = get_val_int(subdir, "vendor");
device.device_id = get_val_int(subdir, "device");
device.subsystem_id = get_val_int(subdir, "subsystem_device");
if (device.vendor_id != XILINX_ID)
continue;
if (device.device_id != AWS_UserPF_DEVICE_ID && device.device_id != AWS_MgmtPF_DEVICE_ID && device.device_id != AWS_UserPF_DEVICE_ID_SDx)
continue;
if ( device.func != 0 && device.func != 2)
continue;
//std::cout << "scan: Xilinx AWS device entry name " << entry->d_name << std::endl;
//Get the driver name.
char driverName[DRIVER_BUF_SIZE];
memset(driverName, 0, DRIVER_BUF_SIZE);
subdir += "/driver";
int err = readlink(subdir.c_str(), driverName, DRIVER_BUF_SIZE);
if ( err < 0 ) {
add_device(device);
continue;
}
if ( err >= DRIVER_BUF_SIZE ) {
std::cout << "Driver name is too big " << std::endl;
return -1;
}
device.driver_name = driverName;
size_t found = device.driver_name.find_last_of("/");
if ( found != std::string::npos ) {
device.driver_name = device.driver_name.substr(found + 1);
}
//Get driver version
subdir += "/module/";
std::string version = get_val_string(subdir, "version");
version.erase(std::remove(version.begin(), version.end(), '\n'), version.end());
device.driver_version = version;
if(device.func == 2) {//mgmtPF on Pegasus; mgmtPF not visible on AWS F1
device.instance = get_val_int(subdir2, "instance");
} else if (device.func == 0) {//userPF on Pegasus (AWS)
std::string drm_dir = subdir2;
drm_dir += "/drm";
device.instance = get_render_value(drm_dir);
}
device.device_name = entry->d_name;
if ( !add_device(device) )
return -1;
}
//std::cout << "scan: Create device list" << std::endl;
add_to_device_list();
if(print)
return print_pci_info() ? 0 : -1;
else
return 0;
#else
uint16_t vendor_id = 0, device_id = 0; // only used without INTERNAL_TESTING
if (fpga_mgmt_init() || fpga_pci_init() ) {
std::cout << "ERROR: xclProbe-scan failed to initialized fpga libraries" << std::endl;
return -1;
}
fpga_slot_spec spec_array[16];
std::memset(spec_array, 0, sizeof(fpga_slot_spec) * 16);
if (fpga_pci_get_all_slot_specs(spec_array, 16)) {
std::cout << "ERROR: xclProbe-scan failed at fpga_pci_get_all_slot_specs" << std::endl;
return -1;
}
for (unsigned short i = 0; i < 16; i++) {
if (spec_array[i].map[FPGA_APP_PF].vendor_id == 0)
break;
domain = spec_array[i].map[FPGA_APP_PF].domain;
bus = spec_array[i].map[FPGA_APP_PF].bus;
dev = spec_array[i].map[FPGA_APP_PF].dev;
func = spec_array[i].map[FPGA_APP_PF].func;
vendor_id = spec_array[i].map[FPGA_APP_PF].vendor_id;
device_id = spec_array[i].map[FPGA_APP_PF].device_id;
//On Pegasus: func=0 is userPF & func=2 is mgmtPG.
//On Pegasus & F1: userPF is for Device 1d0f:1042
if (vendor_id != XILINX_ID)
continue;
if (device_id != AWS_UserPF_DEVICE_ID && device_id != AWS_MgmtPF_DEVICE_ID && device_id != AWS_UserPF_DEVICE_ID_SDx)
continue;
if (func != 0) //userPF func == 0; mgmtPF not visible on AWS F1
continue;
//userPF func == 0; mgmtPF not visible on AWS F1
std::stringstream domain_str;
std::stringstream bus_str;
std::stringstream dev_str;
//Note: Below works with stringstream only for integers and not for uint8, etc.
domain_str << std::setw(4) << std::setfill('0') << domain;
bus_str << std::setw(2) << std::setfill('0') << std::hex << bus;
dev_str << std::setw(2) << std::setfill('0') << std::hex << dev;
std::string func_str = std::to_string(func);//stringstream is giving minimum of two chars
device.device_name = domain_str.str() + ":" + bus_str.str() + ":" + dev_str.str() + "." + func_str + "\0";
std::string subdir2 = dirname + device.device_name;
device.domain = domain;
device.bus = bus;
device.dev = dev;
device.func = func;
device.vendor_id = vendor_id;
device.device_id = device_id;
device.subsystem_id = spec_array[i].map[FPGA_APP_PF].subsystem_device_id;
//Get the driver name.
char driverName[DRIVER_BUF_SIZE];
memset(driverName, 0, DRIVER_BUF_SIZE);
std::string driver_dir = subdir2;
driver_dir += "/driver";
int err = readlink(driver_dir.c_str(), driverName, DRIVER_BUF_SIZE);
if ( err < 0) {
add_device(device);
continue;
}
if (err >= DRIVER_BUF_SIZE) {
std::cout << "ERROR: Driver name is too big " << std::endl;
return -1;
}
device.driver_name = driverName;
size_t found = device.driver_name.find_last_of("/");
if ( found != std::string::npos) {
device.driver_name = device.driver_name.substr(found + 1);
}
//Get driver version
std::string module_dir = driver_dir;
module_dir += "/module/";
std::string version = get_val_string(module_dir, "version");
version.erase(std::remove(version.begin(), version.end(), '\n'), version.end());
device.driver_version = version;
if (func == 0) {//userPF on Pegasus & F1
std::string drm_dir = subdir2;
drm_dir += "/drm";
device.instance = get_render_value(drm_dir);
}
if (!add_device(device))
return -1;
}
//std::cout << "scan: Create device list" << std::endl;
add_to_device_list();
if(print)
return print_f1_pci_info() ? 0 : -1;
else
return 0;
#endif
}