mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Accept interface name and PCIe BDF when connecting to device
This commit is contained in:
parent
23f635f273
commit
eba32ce8a5
@ -347,13 +347,13 @@ int file_type_from_ext(const char *file_name)
|
||||
return FILE_TYPE_BIN;
|
||||
}
|
||||
|
||||
int pcie_hot_reset(const char *pcie_port_path)
|
||||
int pcie_hot_reset(const char *pci_port_path)
|
||||
{
|
||||
int fd;
|
||||
char path[PATH_MAX+32];
|
||||
char buf[32];
|
||||
|
||||
snprintf(path, sizeof(path), "%s/config", pcie_port_path);
|
||||
snprintf(path, sizeof(path), "%s/config", pci_port_path);
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
|
||||
@ -381,14 +381,14 @@ int pcie_hot_reset(const char *pcie_port_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcie_disable_fatal_err(const char *pcie_port_path)
|
||||
int pcie_disable_fatal_err(const char *pci_port_path)
|
||||
{
|
||||
int fd;
|
||||
char path[PATH_MAX+32];
|
||||
char buf[32];
|
||||
int offset;
|
||||
|
||||
snprintf(path, sizeof(path), "%s/config", pcie_port_path);
|
||||
snprintf(path, sizeof(path), "%s/config", pci_port_path);
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
|
||||
@ -451,8 +451,8 @@ int main(int argc, char *argv[])
|
||||
FILE *write_file = NULL;
|
||||
|
||||
char path[PATH_MAX+32];
|
||||
char device_path[PATH_MAX];
|
||||
char port_path[PATH_MAX];
|
||||
char pci_device_path[PATH_MAX];
|
||||
char pci_port_path[PATH_MAX];
|
||||
char *ptr;
|
||||
|
||||
int slot = -1;
|
||||
@ -526,47 +526,24 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
// determine sysfs path of PCIe device
|
||||
// first, try to find via miscdevice
|
||||
ptr = strrchr(device, '/');
|
||||
ptr = ptr ? ptr+1 : device;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/misc/%s/device", ptr);
|
||||
|
||||
if (!realpath(path, device_path))
|
||||
if (!dev->pci_device_path[0])
|
||||
{
|
||||
// that failed, perhaps it was a PCIe resource
|
||||
strcpy(path, device);
|
||||
ptr = strrchr(path, '/');
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
|
||||
if (!realpath(path, device_path))
|
||||
{
|
||||
perror("failed to determine device path");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// PCIe device will have a config space, so check for that
|
||||
snprintf(path, sizeof(path), "%s/config", device_path);
|
||||
|
||||
if (access(path, F_OK))
|
||||
{
|
||||
perror("failed to determine device path");
|
||||
fprintf(stderr, "Failed to determine PCIe device path\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
// snprintf(device_path, sizeof(device_path), dev->device_path)
|
||||
snprintf(pci_device_path, sizeof(pci_device_path), "%s", dev->pci_device_path);
|
||||
|
||||
// determine sysfs path of upstream port
|
||||
strcpy(port_path, device_path);
|
||||
ptr = strrchr(port_path, '/');
|
||||
snprintf(pci_port_path, sizeof(pci_port_path), "%s", pci_device_path);
|
||||
ptr = strrchr(pci_port_path, '/');
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
|
||||
printf("PCIe ID (device): %s\n", strrchr(device_path, '/')+1);
|
||||
printf("PCIe ID (upstream port): %s\n", strrchr(port_path, '/')+1);
|
||||
printf("PCIe ID (device): %s\n", strrchr(pci_device_path, '/')+1);
|
||||
printf("PCIe ID (upstream port): %s\n", strrchr(pci_port_path, '/')+1);
|
||||
|
||||
uint32_t flash_format = 0;
|
||||
const char *fpga_part = get_fpga_part(dev->fpga_id);
|
||||
@ -1216,27 +1193,23 @@ skip_flash:
|
||||
|
||||
// disable fatal error reporting on port (to prevent IPMI-triggered reboot)
|
||||
printf("Disabling PCIe fatal error reporting on port...\n");
|
||||
pcie_disable_fatal_err(port_path);
|
||||
pcie_disable_fatal_err(pci_port_path);
|
||||
|
||||
// disconnect from device
|
||||
mqnic_close(dev);
|
||||
dev = NULL;
|
||||
|
||||
// attempt to disconnect driver
|
||||
ptr = strrchr(device_path, '/');
|
||||
if (ptr)
|
||||
{
|
||||
snprintf(path, sizeof(path), "%s/driver/unbind", device_path);
|
||||
snprintf(path, sizeof(path), "%s/driver/unbind", pci_device_path);
|
||||
|
||||
if (access(path, F_OK) == 0)
|
||||
{
|
||||
printf("Unbinding driver...\n");
|
||||
write_str_to_file(path, ptr+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No driver bound\n");
|
||||
}
|
||||
if (access(path, F_OK) == 0)
|
||||
{
|
||||
printf("Unbinding driver...\n");
|
||||
write_str_to_file(path, ptr+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No driver bound\n");
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
@ -1245,7 +1218,7 @@ skip_flash:
|
||||
if (action_boot)
|
||||
{
|
||||
// reconnect directly to device
|
||||
snprintf(path, sizeof(path), "%s/resource0", device_path);
|
||||
snprintf(path, sizeof(path), "%s/resource0", pci_device_path);
|
||||
dev = mqnic_open(path);
|
||||
|
||||
if (!dev)
|
||||
@ -1269,7 +1242,7 @@ skip_flash:
|
||||
// remove PCIe device
|
||||
printf("Removing device...\n");
|
||||
|
||||
snprintf(path, sizeof(path), "%s/remove", device_path);
|
||||
snprintf(path, sizeof(path), "%s/remove", pci_device_path);
|
||||
|
||||
if (write_1_to_file(path))
|
||||
{
|
||||
@ -1289,13 +1262,13 @@ skip_flash:
|
||||
for (int tries = 5; tries > 0; tries--)
|
||||
{
|
||||
printf("Performing hot reset on upstream port...\n");
|
||||
pcie_hot_reset(port_path);
|
||||
pcie_hot_reset(pci_port_path);
|
||||
|
||||
sleep(2);
|
||||
|
||||
printf("Rescanning on upstream port...\n");
|
||||
|
||||
snprintf(path, sizeof(path), "%s/rescan", port_path);
|
||||
snprintf(path, sizeof(path), "%s/rescan", pci_port_path);
|
||||
|
||||
if (write_1_to_file(path))
|
||||
{
|
||||
@ -1305,7 +1278,7 @@ skip_flash:
|
||||
}
|
||||
|
||||
// PCIe device will have a config space, so check for that
|
||||
snprintf(path, sizeof(path), "%s/config", device_path);
|
||||
snprintf(path, sizeof(path), "%s/config", pci_device_path);
|
||||
|
||||
if (access(path, F_OK) == 0)
|
||||
{
|
||||
|
160
utils/mqnic.c
160
utils/mqnic.c
@ -33,8 +33,10 @@ either expressed or implied, of The Regents of the University of California.
|
||||
|
||||
#include "mqnic.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -43,18 +45,29 @@ either expressed or implied, of The Regents of the University of California.
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct mqnic *mqnic_open(const char *dev_name)
|
||||
static int mqnic_try_open(struct mqnic *dev, const char *fmt, ...)
|
||||
{
|
||||
struct mqnic *dev = calloc(1, sizeof(struct mqnic));
|
||||
va_list ap;
|
||||
char path[PATH_MAX+32];
|
||||
struct stat st;
|
||||
char *ptr;
|
||||
|
||||
if (!dev)
|
||||
{
|
||||
perror("memory allocation failed");
|
||||
goto fail_alloc;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(dev->device_path, sizeof(dev->device_path), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
dev->fd = open(dev_name, O_RDWR);
|
||||
dev->pci_device_path[0] = 0;
|
||||
|
||||
if (access(dev->device_path, W_OK))
|
||||
return -1;
|
||||
|
||||
if (stat(dev->device_path, &st))
|
||||
return -1;
|
||||
|
||||
if (S_ISDIR(st.st_mode))
|
||||
return -1;
|
||||
|
||||
dev->fd = open(dev->device_path, O_RDWR);
|
||||
|
||||
if (dev->fd < 0)
|
||||
{
|
||||
@ -82,6 +95,35 @@ struct mqnic *mqnic_open(const char *dev_name)
|
||||
dev->regs_size = info.regs_size;
|
||||
}
|
||||
|
||||
// determine sysfs path of PCIe device
|
||||
// first, try to find via miscdevice
|
||||
ptr = strrchr(dev->device_path, '/');
|
||||
ptr = ptr ? ptr+1 : dev->device_path;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/misc/%s/device", ptr);
|
||||
|
||||
if (!realpath(path, dev->pci_device_path))
|
||||
{
|
||||
// that failed, perhaps it was a PCIe resource
|
||||
snprintf(path, sizeof(path), "%s", dev->device_path);
|
||||
ptr = strrchr(path, '/');
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
|
||||
if (!realpath(path, dev->pci_device_path))
|
||||
dev->pci_device_path[0] = 0;
|
||||
}
|
||||
|
||||
// PCIe device will have a config space, so check for that
|
||||
if (dev->pci_device_path[0])
|
||||
{
|
||||
snprintf(path, sizeof(path), "%s/config", dev->pci_device_path);
|
||||
|
||||
if (access(path, F_OK))
|
||||
dev->pci_device_path[0] = 0;
|
||||
}
|
||||
|
||||
// map registers
|
||||
dev->regs = (volatile uint8_t *)mmap(NULL, dev->regs_size, PROT_READ | PROT_WRITE, MAP_SHARED, dev->fd, 0);
|
||||
if (dev->regs == MAP_FAILED)
|
||||
{
|
||||
@ -89,20 +131,12 @@ struct mqnic *mqnic_open(const char *dev_name)
|
||||
goto fail_mmap_regs;
|
||||
}
|
||||
|
||||
if (mqnic_reg_read32(dev->regs, 4) == 0xffffffff)
|
||||
if (dev->pci_device_path[0] && mqnic_reg_read32(dev->regs, 4) == 0xffffffff)
|
||||
{
|
||||
// if we were given a PCIe resource, then we may need to enable the device
|
||||
char path[PATH_MAX+32];
|
||||
char *ptr;
|
||||
snprintf(path, sizeof(path), "%s/enable", dev->pci_device_path);
|
||||
|
||||
strcpy(path, dev_name);
|
||||
ptr = strrchr(path, '/');
|
||||
if (ptr)
|
||||
{
|
||||
strcpy(++ptr, "enable");
|
||||
}
|
||||
|
||||
if (access(path, F_OK) == 0)
|
||||
if (access(path, W_OK) == 0)
|
||||
{
|
||||
FILE *fp = fopen(path, "w");
|
||||
|
||||
@ -137,6 +171,85 @@ struct mqnic *mqnic_open(const char *dev_name)
|
||||
goto fail_enum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_enum:
|
||||
if (dev->rb_list)
|
||||
free_reg_block_list(dev->rb_list);
|
||||
fail_reset:
|
||||
munmap((void *)dev->regs, dev->regs_size);
|
||||
fail_mmap_regs:
|
||||
fail_ioctl:
|
||||
fail_fstat:
|
||||
close(dev->fd);
|
||||
fail_open:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mqnic_try_open_if_name(struct mqnic *dev, const char *if_name)
|
||||
{
|
||||
DIR *folder;
|
||||
struct dirent *entry;
|
||||
char path[PATH_MAX];
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/net/%s/device/misc/", if_name);
|
||||
|
||||
folder = opendir(path);
|
||||
if (!folder)
|
||||
return -1;
|
||||
|
||||
while ((entry = readdir(folder)))
|
||||
{
|
||||
if (entry->d_name[0] != '.')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
closedir(folder);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "/dev/%s", entry->d_name);
|
||||
|
||||
closedir(folder);
|
||||
|
||||
return mqnic_try_open(dev, "%s", path);
|
||||
}
|
||||
|
||||
struct mqnic *mqnic_open(const char *dev_name)
|
||||
{
|
||||
struct mqnic *dev = calloc(1, sizeof(struct mqnic));
|
||||
|
||||
if (!dev)
|
||||
{
|
||||
perror("memory allocation failed");
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
// absolute path
|
||||
if (mqnic_try_open(dev, "%s", dev_name) == 0)
|
||||
goto open;
|
||||
|
||||
// network interface
|
||||
if (mqnic_try_open_if_name(dev, dev_name) == 0)
|
||||
goto open;
|
||||
|
||||
// PCIe sysfs path
|
||||
if (mqnic_try_open(dev, "%s/resource0", dev_name) == 0)
|
||||
goto open;
|
||||
|
||||
// PCIe BDF (dddd:xx:yy.z)
|
||||
if (mqnic_try_open(dev, "/sys/bus/pci/devices/%s/resource0", dev_name) == 0)
|
||||
goto open;
|
||||
|
||||
// PCIe BDF (xx:yy.z)
|
||||
if (mqnic_try_open(dev, "/sys/bus/pci/devices/0000:%s/resource0", dev_name) == 0)
|
||||
goto open;
|
||||
|
||||
goto fail_open;
|
||||
|
||||
open:
|
||||
dev->fpga_id = mqnic_reg_read32(dev->fw_id_rb->regs, MQNIC_RB_FW_ID_REG_FPGA_ID);
|
||||
dev->fw_id = mqnic_reg_read32(dev->fw_id_rb->regs, MQNIC_RB_FW_ID_REG_FW_ID);
|
||||
dev->fw_ver = mqnic_reg_read32(dev->fw_id_rb->regs, MQNIC_RB_FW_ID_REG_FW_VER);
|
||||
@ -186,15 +299,6 @@ struct mqnic *mqnic_open(const char *dev_name)
|
||||
skip_interface:
|
||||
return dev;
|
||||
|
||||
fail:
|
||||
fail_enum:
|
||||
fail_reset:
|
||||
mqnic_close(dev);
|
||||
return NULL;
|
||||
fail_mmap_regs:
|
||||
fail_ioctl:
|
||||
fail_fstat:
|
||||
close(dev->fd);
|
||||
fail_open:
|
||||
free(dev);
|
||||
fail_alloc:
|
||||
|
@ -34,6 +34,7 @@ either expressed or implied, of The Regents of the University of California.
|
||||
#ifndef MQNIC_H
|
||||
#define MQNIC_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -152,6 +153,9 @@ struct mqnic {
|
||||
char build_date_str[32];
|
||||
|
||||
struct mqnic_if *interfaces[MQNIC_MAX_IF];
|
||||
|
||||
char device_path[PATH_MAX];
|
||||
char pci_device_path[PATH_MAX];
|
||||
};
|
||||
|
||||
struct mqnic *mqnic_open(const char *dev_name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user