Add Error **errp for xen_host_pci_device_get()
To catch the error message. Also modify the caller Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
f524bc3b3d
commit
376ba75f88
@ -44,7 +44,7 @@ static void xen_host_pci_sysfs_path(const XenHostPCIDevice *d,
|
|||||||
|
|
||||||
/* This size should be enough to read the first 7 lines of a resource file */
|
/* This size should be enough to read the first 7 lines of a resource file */
|
||||||
#define XEN_HOST_PCI_RESOURCE_BUFFER_SIZE 400
|
#define XEN_HOST_PCI_RESOURCE_BUFFER_SIZE 400
|
||||||
static int xen_host_pci_get_resource(XenHostPCIDevice *d)
|
static void xen_host_pci_get_resource(XenHostPCIDevice *d, Error **errp)
|
||||||
{
|
{
|
||||||
int i, rc, fd;
|
int i, rc, fd;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
@ -57,19 +57,18 @@ static int xen_host_pci_get_resource(XenHostPCIDevice *d)
|
|||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
|
error_setg_file_open(errp, errno, path);
|
||||||
return -errno;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = read(fd, &buf, sizeof (buf) - 1);
|
rc = read(fd, &buf, sizeof(buf) - 1);
|
||||||
if (rc < 0 && errno != EINTR) {
|
if (rc < 0 && errno != EINTR) {
|
||||||
rc = -errno;
|
error_setg_errno(errp, errno, "read err");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} while (rc < 0);
|
} while (rc < 0);
|
||||||
buf[rc] = 0;
|
buf[rc] = 0;
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
s = buf;
|
s = buf;
|
||||||
for (i = 0; i < PCI_NUM_REGIONS; i++) {
|
for (i = 0; i < PCI_NUM_REGIONS; i++) {
|
||||||
@ -122,20 +121,19 @@ static int xen_host_pci_get_resource(XenHostPCIDevice *d)
|
|||||||
d->rom.bus_flags = flags & IORESOURCE_BITS;
|
d->rom.bus_flags = flags & IORESOURCE_BITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != PCI_NUM_REGIONS) {
|
if (i != PCI_NUM_REGIONS) {
|
||||||
/* Invalid format or input to short */
|
error_setg(errp, "Invalid format or input too short: %s", buf);
|
||||||
rc = -ENODEV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This size should be enough to read a long from a file */
|
/* This size should be enough to read a long from a file */
|
||||||
#define XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE 22
|
#define XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE 22
|
||||||
static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
|
static void xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
|
||||||
unsigned int *pvalue, int base)
|
unsigned int *pvalue, int base, Error **errp)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char buf[XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE];
|
char buf[XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE];
|
||||||
@ -147,39 +145,45 @@ static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
|
|||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
|
error_setg_file_open(errp, errno, path);
|
||||||
return -errno;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = read(fd, &buf, sizeof (buf) - 1);
|
rc = read(fd, &buf, sizeof(buf) - 1);
|
||||||
if (rc < 0 && errno != EINTR) {
|
if (rc < 0 && errno != EINTR) {
|
||||||
rc = -errno;
|
error_setg_errno(errp, errno, "read err");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} while (rc < 0);
|
} while (rc < 0);
|
||||||
|
|
||||||
buf[rc] = 0;
|
buf[rc] = 0;
|
||||||
rc = qemu_strtoul(buf, &endptr, base, &value);
|
rc = qemu_strtoul(buf, &endptr, base, &value);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
assert(value <= UINT_MAX);
|
assert(value <= UINT_MAX);
|
||||||
*pvalue = value;
|
*pvalue = value;
|
||||||
|
} else {
|
||||||
|
error_setg_errno(errp, -rc, "failed to parse value '%s'", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xen_host_pci_get_hex_value(XenHostPCIDevice *d,
|
static inline void xen_host_pci_get_hex_value(XenHostPCIDevice *d,
|
||||||
const char *name,
|
const char *name,
|
||||||
unsigned int *pvalue)
|
unsigned int *pvalue,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
return xen_host_pci_get_value(d, name, pvalue, 16);
|
xen_host_pci_get_value(d, name, pvalue, 16, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int xen_host_pci_get_dec_value(XenHostPCIDevice *d,
|
static inline void xen_host_pci_get_dec_value(XenHostPCIDevice *d,
|
||||||
const char *name,
|
const char *name,
|
||||||
unsigned int *pvalue)
|
unsigned int *pvalue,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
return xen_host_pci_get_value(d, name, pvalue, 10);
|
xen_host_pci_get_value(d, name, pvalue, 10, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
|
static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
|
||||||
@ -192,17 +196,16 @@ static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
|
|||||||
return !stat(path, &buf);
|
return !stat(path, &buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_host_pci_config_open(XenHostPCIDevice *d)
|
static void xen_host_pci_config_open(XenHostPCIDevice *d, Error **errp)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
xen_host_pci_sysfs_path(d, "config", path, sizeof(path));
|
xen_host_pci_sysfs_path(d, "config", path, sizeof(path));
|
||||||
|
|
||||||
d->config_fd = open(path, O_RDWR);
|
d->config_fd = open(path, O_RDWR);
|
||||||
if (d->config_fd < 0) {
|
if (d->config_fd == -1) {
|
||||||
return -errno;
|
error_setg_file_open(errp, errno, path);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_host_pci_config_read(XenHostPCIDevice *d,
|
static int xen_host_pci_config_read(XenHostPCIDevice *d,
|
||||||
@ -324,11 +327,12 @@ int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *d, uint32_t cap)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
|
void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
|
||||||
uint8_t bus, uint8_t dev, uint8_t func)
|
uint8_t bus, uint8_t dev, uint8_t func,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
unsigned int v;
|
unsigned int v;
|
||||||
int rc = 0;
|
Error *err = NULL;
|
||||||
|
|
||||||
d->config_fd = -1;
|
d->config_fd = -1;
|
||||||
d->domain = domain;
|
d->domain = domain;
|
||||||
@ -336,43 +340,51 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
|
|||||||
d->dev = dev;
|
d->dev = dev;
|
||||||
d->func = func;
|
d->func = func;
|
||||||
|
|
||||||
rc = xen_host_pci_config_open(d);
|
xen_host_pci_config_open(d, &err);
|
||||||
if (rc) {
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rc = xen_host_pci_get_resource(d);
|
|
||||||
if (rc) {
|
xen_host_pci_get_resource(d, &err);
|
||||||
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rc = xen_host_pci_get_hex_value(d, "vendor", &v);
|
|
||||||
if (rc) {
|
xen_host_pci_get_hex_value(d, "vendor", &v, &err);
|
||||||
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d->vendor_id = v;
|
d->vendor_id = v;
|
||||||
rc = xen_host_pci_get_hex_value(d, "device", &v);
|
|
||||||
if (rc) {
|
xen_host_pci_get_hex_value(d, "device", &v, &err);
|
||||||
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d->device_id = v;
|
d->device_id = v;
|
||||||
rc = xen_host_pci_get_dec_value(d, "irq", &v);
|
|
||||||
if (rc) {
|
xen_host_pci_get_dec_value(d, "irq", &v, &err);
|
||||||
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d->irq = v;
|
d->irq = v;
|
||||||
rc = xen_host_pci_get_hex_value(d, "class", &v);
|
|
||||||
if (rc) {
|
xen_host_pci_get_hex_value(d, "class", &v, &err);
|
||||||
|
if (err) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d->class_code = v;
|
d->class_code = v;
|
||||||
|
|
||||||
d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
|
d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
error_propagate(errp, err);
|
||||||
|
|
||||||
if (d->config_fd >= 0) {
|
if (d->config_fd >= 0) {
|
||||||
close(d->config_fd);
|
close(d->config_fd);
|
||||||
d->config_fd = -1;
|
d->config_fd = -1;
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xen_host_pci_device_closed(XenHostPCIDevice *d)
|
bool xen_host_pci_device_closed(XenHostPCIDevice *d)
|
||||||
|
@ -36,8 +36,9 @@ typedef struct XenHostPCIDevice {
|
|||||||
int config_fd;
|
int config_fd;
|
||||||
} XenHostPCIDevice;
|
} XenHostPCIDevice;
|
||||||
|
|
||||||
int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
|
void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
|
||||||
uint8_t bus, uint8_t dev, uint8_t func);
|
uint8_t bus, uint8_t dev, uint8_t func,
|
||||||
|
Error **errp);
|
||||||
void xen_host_pci_device_put(XenHostPCIDevice *pci_dev);
|
void xen_host_pci_device_put(XenHostPCIDevice *pci_dev);
|
||||||
bool xen_host_pci_device_closed(XenHostPCIDevice *d);
|
bool xen_host_pci_device_closed(XenHostPCIDevice *d);
|
||||||
|
|
||||||
|
@ -767,6 +767,7 @@ static int xen_pt_initfn(PCIDevice *d)
|
|||||||
uint8_t machine_irq = 0, scratch;
|
uint8_t machine_irq = 0, scratch;
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
int pirq = XEN_PT_UNASSIGNED_PIRQ;
|
int pirq = XEN_PT_UNASSIGNED_PIRQ;
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
/* register real device */
|
/* register real device */
|
||||||
XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d"
|
XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d"
|
||||||
@ -774,11 +775,13 @@ static int xen_pt_initfn(PCIDevice *d)
|
|||||||
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
|
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
|
||||||
s->dev.devfn);
|
s->dev.devfn);
|
||||||
|
|
||||||
rc = xen_host_pci_device_get(&s->real_device,
|
xen_host_pci_device_get(&s->real_device,
|
||||||
s->hostaddr.domain, s->hostaddr.bus,
|
s->hostaddr.domain, s->hostaddr.bus,
|
||||||
s->hostaddr.slot, s->hostaddr.function);
|
s->hostaddr.slot, s->hostaddr.function,
|
||||||
if (rc) {
|
&err);
|
||||||
XEN_PT_ERR(d, "Failed to \"open\" the real pci device. rc: %i\n", rc);
|
if (err) {
|
||||||
|
error_append_hint(&err, "Failed to \"open\" the real pci device");
|
||||||
|
error_report_err(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user