diff --git a/server/include/gtfpga.h b/server/include/gtfpga.h index d1cc54378..444c46a50 100644 --- a/server/include/gtfpga.h +++ b/server/include/gtfpga.h @@ -11,13 +11,14 @@ #include -#define GTFPGA_BAR 0 +#define GTFPGA_BAR 0 /**< The Base Address Register which is mmap()ed to the User Space */ -#define GTFPGA_MAX_TX 64 -#define GTFPGA_MAX_RX 64 +#define GTFPGA_MAX_TX 64 /**< The amount of values which is supported by the GTFPGA card */ +#define GTFPGA_MAX_RX 64 /**< The amount of values which is supported by the GTFPGA card */ + +#define GTFPGA_VID 0x10ee /**< The default vendor ID of the GTFPGA card */ +#define GTFPGA_DID 0x0007 /**< The default device ID of the GTFPGA card */ -#define GTFPGA_VID 0x10ee -#define GTFPGA_DID 0x0007 struct gtfpga { struct pci_filter filter; @@ -25,10 +26,23 @@ struct gtfpga { int fd_mmap, fd_uio; void *map; - struct pci_access *pacc; struct pci_dev *dev; }; +int gtfpga_init(int argc, char * argv[]); + +int gtfpga_deinit(); + +/** Parse node connection details for GTFPGA type + * + * @param cfg A libconfig object pointing to the node. + * @param n A pointer to the node structure which should be parsed. + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ +int gtfpga_parse(config_setting_t *cfg, struct node *n); + +int gtfpga_print(struct node *n, char *buf, int len); int gtfpga_open(struct node *n); diff --git a/server/include/node.h b/server/include/node.h index d96759624..97becd91d 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -41,7 +41,7 @@ enum node_type { TCPD, /* BSD socket: AF_INET SOCK_STREAM bind + listen + accept */ TCP, /* BSD socket: AF_INET SOCK_STREAM bind + connect */ OPAL_ASYNC, /* OPAL-RT Asynchronous Process Api */ -// GTFPGA, /* Xilinx ML507 GTFPGA card */ + GTFPGA, /* Xilinx ML507 GTFPGA card */ INVALID }; diff --git a/server/src/gtfpga.c b/server/src/gtfpga.c index 314f6d2c3..107f05d44 100644 --- a/server/src/gtfpga.c +++ b/server/src/gtfpga.c @@ -10,26 +10,100 @@ #define SYSFS_PATH "/sys/bus/pci" -static int gtfpga_load_driver(struct node *n) -{ +static pci_access *pacc; +int gtfpga_init(int argc, char *argv[]) +{ + pacc = pci_alloc(); /* Get the pci_access structure */ + pci_init(pacc); /* Initialize the PCI library */ + + pacc->error = error; /* Replace logging and debug functions */ + pacc->warning = warn; + pacc->debug = debug; + + pci_scan_bus(pacc); /* We want to get the list of devices */ } -static struct pci_dev * gtfpga_find_device(struct node *n) +int gtfpga_deinit() { - struct gtfpga *g = n->gtfpga; + pci_cleanup(pacc); +} - struct pci_dev *dev; +int gtfpga_parse(config_setting_t *cfg, struct node *n) +{ + char *slot, *id; + config_setting_t *cfg_slot, *cfg_id; + struct gtfpga *g = alloc(sizeof(struct gtfpga)); - pacc = pci_alloc(); /* Get the pci_access structure */ + pci_filter_init(NULL, &g->filter); - pci_init(pacc); /* Initialize the PCI library */ - pci_scan_bus(pacc); /* We want to get the list of devices */ + if (cfg_slot = config_setting_get_member(cfg, "slot")) { + if (slot = config_setting_get_string(cfg_slot)) { + if ((err = pci_filter_parse_slot(&g->filter, slot)) + cerror(cfg_slot, "%s", err); + } + else + cerror(cfg_slot, "Invalid slot format"); + } + + if (cfg_id = config_setting_get_member(cfg, "id")) { + if (id = config_setting_get_string(cfg_id)) { + if ((err = pci_filter_parse_id(&g->filter, id)) + cerror(cfg_id, "%s", err); + } + else + cerror(cfg_slot, "Invalid id format"); + } + + + return 0; +} + +int gtfpga_print(struct node *n, char *buf, int len) +{ + +} + +static int gtfpga_load_driver(struct pci_dev *d) +{ + FILE *f; + char slot[16]; + int ret; + + /* Prepare slot identifier */ + snprintf(slot, sizeof(slot), "%04x:%02x:%02x.%x", + d->domain, d->bus, d->slot, d->func); + + /* Load uio_pci_generic module */ + ret = system2("modprobe uio_pci_generic"); + if (ret) + serror("Failed to load module"); + + /* Add new ID to uio_pci_generic */ + f = fopen(SYSFS_PATH "/drivers/uio_pci_generic/new_id", "w"); + if (!f) + serror("Failed to add PCI id to uio_pci_generic driver"); + + fprintf(f, "%04x %04x", d->vendor_id, d->device_id); + fclose(f); + + /* Bind to uio_pci_generic */ + f = fopen(SYSFS_PATH "/drivers/uio_pci_generic/bind", "w"); + if (!f) + serror("Failed to add PCI id to uio_pci_generic driver"); + + fprintf(f, "%s\n", slot); + fclose(f); +} + +static struct pci_dev * gtfpga_find_device(struct pci_filter *f) +{ + struct pci_dev *d; /* Iterate over all devices */ - for (dev = pacc->devices; dev; dev = dev->next) { - if (pci_filter_match(&filter, dev)) - return dev; + for (d = pacc->devices; d; d = d->next) { + if (pci_filter_match(&f, d)) + return d; } return NULL; @@ -90,7 +164,8 @@ int gtfpga_close(struct node *n) { struct gtfpga *g = n->gtfpga; - munmap(g->map, g->dev->size[GTFPGA_BAR]); + if (g->map) + munmap(g->map, g->dev->size[GTFPGA_BAR]); close(g->fd_mmap); close(g->fd_uio); @@ -98,6 +173,7 @@ int gtfpga_close(struct node *n) return 0; } +/** @todo implement */ int gtfpga_read(struct node *n, struct msg *m) { struct gtfpga *g = n->gtfpga; @@ -105,6 +181,7 @@ int gtfpga_read(struct node *n, struct msg *m) return 0; } +/** @todo implement */ int gtfpga_write(struct node *n, struct msg *m) { struct gtfpga *g = n->gtfpga;