HelenOS sources
This source file includes following definitions.
- main
- syntax_print
- pci_list
- pci_list_bridge
- pci_list_bridge_id
#include <devman.h>
#include <errno.h>
#include <io/table.h>
#include <loc.h>
#include <pci.h>
#include <stdio.h>
#include <stdlib.h>
#include <str.h>
#define NAME "mkext4"
#define MAX_NAME_LENGTH 1024
static void syntax_print(void);
static errno_t pci_list(void);
static errno_t pci_list_bridge(const char *);
static errno_t pci_list_bridge_id(service_id_t);
int main(int argc, char **argv)
{
errno_t rc;
const char *bridge = NULL;
--argc;
++argv;
while (argc > 0 && argv[0][0] == '-') {
if (str_cmp(argv[0], "--bridge") == 0) {
--argc;
++argv;
if (argc < 1) {
printf("Option argument missing.\n");
return 1;
}
bridge = argv[0];
--argc;
++argv;
} else {
syntax_print();
return 1;
}
}
if (argc != 0) {
syntax_print();
return 1;
}
if (bridge != NULL)
rc = pci_list_bridge(bridge);
else
rc = pci_list();
if (rc != EOK)
return 1;
return 0;
}
static void syntax_print(void)
{
printf("syntax: pci [<options>]\n");
printf("options:\n"
"\t--bridge <svc-name> Only devices under host bridge <svc-name>\n");
}
static errno_t pci_list(void)
{
errno_t rc;
category_id_t pci_cat_id;
service_id_t *svc_ids = NULL;
size_t svc_cnt;
size_t i;
rc = loc_category_get_id("pci", &pci_cat_id, 0);
if (rc != EOK) {
printf("Error getting 'pci' category ID.\n");
goto error;
}
rc = loc_category_get_svcs(pci_cat_id, &svc_ids, &svc_cnt);
if (rc != EOK) {
printf("Error getting list of PCI services.\n");
goto error;
}
for (i = 0; i < svc_cnt; i++) {
if (i > 0)
putchar('\n');
rc = pci_list_bridge_id(svc_ids[i]);
if (rc != EOK)
goto error;
}
free(svc_ids);
return EOK;
error:
if (svc_ids != NULL)
free(svc_ids);
return rc;
}
static errno_t pci_list_bridge(const char *svc_name)
{
errno_t rc;
service_id_t svc_id;
rc = loc_service_get_id(svc_name, &svc_id, 0);
if (rc != EOK) {
printf("Error looking up host bridge '%s'.\n", svc_name);
return rc;
}
return pci_list_bridge_id(svc_id);
}
static errno_t pci_list_bridge_id(service_id_t svc_id)
{
errno_t rc;
devman_handle_t *dev_ids = NULL;
size_t dev_cnt;
pci_dev_info_t dev_info;
size_t i;
pci_t *pci = NULL;
char *svc_name = NULL;
char *drv_name = NULL;
table_t *table = NULL;
drv_name = malloc(MAX_NAME_LENGTH);
if (drv_name == NULL) {
printf("Out of memory.\n");
rc = ENOMEM;
goto error;
}
rc = table_create(&table);
if (rc != EOK) {
printf("Out of memory.\n");
rc = ENOMEM;
goto error;
}
table_header_row(table);
table_printf(table, "Address\t" "Type\t" "Driver\n");
rc = loc_service_get_name(svc_id, &svc_name);
if (rc != EOK) {
printf("Error getting service name.\n");
goto error;
}
rc = pci_open(svc_id, &pci);
if (rc != EOK) {
printf("Error opening PCI service '%s'.\n", svc_name);
goto error;
}
rc = pci_get_devices(pci, &dev_ids, &dev_cnt);
if (rc != EOK) {
printf("Error getting PCI device list.\n");
goto error;
}
for (i = 0; i < dev_cnt; i++) {
rc = pci_dev_get_info(pci, dev_ids[i], &dev_info);
if (rc != EOK) {
printf("Error getting PCI device info.\n");
goto error;
}
rc = devman_fun_get_driver_name(dev_info.dev_handle,
drv_name, MAX_NAME_LENGTH);
if (rc != EOK && rc != EINVAL) {
printf("Error getting driver name.\n");
goto error;
}
if (rc == EINVAL)
drv_name[0] = '\0';
table_printf(table, "%02x.%02x.%x\t" "%04x:%04x\t"
"%s\n", dev_info.bus_num, dev_info.dev_num,
dev_info.fn_num, dev_info.vendor_id,
dev_info.device_id, drv_name);
}
printf("Device listing for host bridge %s:\n\n", svc_name);
rc = table_print_out(table, stdout);
if (rc != EOK) {
printf("Error printing table.\n");
goto error;
}
table_destroy(table);
table = NULL;
free(dev_ids);
dev_ids = NULL;
pci_close(pci);
pci = NULL;
free(svc_name);
svc_name = NULL;
free(drv_name);
return EOK;
error:
if (drv_name != NULL)
free(drv_name);
if (table != NULL)
table_destroy(table);
if (pci != NULL)
pci_close(pci);
if (svc_name != NULL)
free(svc_name);
if (dev_ids != NULL)
free(dev_ids);
return rc;
}
HelenOS homepage, sources at GitHub