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:
Cao jin 2016-01-17 20:13:12 +08:00 committed by Stefano Stabellini
parent f524bc3b3d
commit 376ba75f88
3 changed files with 68 additions and 52 deletions

View file

@ -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 */
#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;
char path[PATH_MAX];
@ -57,19 +57,18 @@ static int xen_host_pci_get_resource(XenHostPCIDevice *d)
fd = open(path, O_RDONLY);
if (fd == -1) {
XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
return -errno;
error_setg_file_open(errp, errno, path);
return;
}
do {
rc = read(fd, &buf, sizeof (buf) - 1);
rc = read(fd, &buf, sizeof(buf) - 1);
if (rc < 0 && errno != EINTR) {
rc = -errno;
error_setg_errno(errp, errno, "read err");
goto out;
}
} while (rc < 0);
buf[rc] = 0;
rc = 0;
s = buf;
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;
}
}
if (i != PCI_NUM_REGIONS) {
/* Invalid format or input to short */
rc = -ENODEV;
error_setg(errp, "Invalid format or input too short: %s", buf);
}
out:
close(fd);
return rc;
}
/* This size should be enough to read a long from a file */
#define XEN_HOST_PCI_GET_VALUE_BUFFER_SIZE 22
static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
unsigned int *pvalue, int base)
static void xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
unsigned int *pvalue, int base, Error **errp)
{
char path[PATH_MAX];
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);
if (fd == -1) {
XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
return -errno;
error_setg_file_open(errp, errno, path);
return;
}
do {
rc = read(fd, &buf, sizeof (buf) - 1);
rc = read(fd, &buf, sizeof(buf) - 1);
if (rc < 0 && errno != EINTR) {
rc = -errno;
error_setg_errno(errp, errno, "read err");
goto out;
}
} while (rc < 0);
buf[rc] = 0;
rc = qemu_strtoul(buf, &endptr, base, &value);
if (!rc) {
assert(value <= UINT_MAX);
*pvalue = value;
} else {
error_setg_errno(errp, -rc, "failed to parse value '%s'", buf);
}
out:
close(fd);
return rc;
}
static inline int xen_host_pci_get_hex_value(XenHostPCIDevice *d,
const char *name,
unsigned int *pvalue)
static inline void xen_host_pci_get_hex_value(XenHostPCIDevice *d,
const char *name,
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,
const char *name,
unsigned int *pvalue)
static inline void xen_host_pci_get_dec_value(XenHostPCIDevice *d,
const char *name,
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)
@ -192,17 +196,16 @@ static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
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];
xen_host_pci_sysfs_path(d, "config", path, sizeof(path));
d->config_fd = open(path, O_RDWR);
if (d->config_fd < 0) {
return -errno;
if (d->config_fd == -1) {
error_setg_file_open(errp, errno, path);
}
return 0;
}
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;
}
int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
uint8_t bus, uint8_t dev, uint8_t func)
void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
uint8_t bus, uint8_t dev, uint8_t func,
Error **errp)
{
unsigned int v;
int rc = 0;
Error *err = NULL;
d->config_fd = -1;
d->domain = domain;
@ -336,43 +340,51 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
d->dev = dev;
d->func = func;
rc = xen_host_pci_config_open(d);
if (rc) {
xen_host_pci_config_open(d, &err);
if (err) {
goto error;
}
rc = xen_host_pci_get_resource(d);
if (rc) {
xen_host_pci_get_resource(d, &err);
if (err) {
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;
}
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;
}
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;
}
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;
}
d->class_code = v;
d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
return 0;
return;
error:
error_propagate(errp, err);
if (d->config_fd >= 0) {
close(d->config_fd);
d->config_fd = -1;
}
return rc;
}
bool xen_host_pci_device_closed(XenHostPCIDevice *d)

View file

@ -36,8 +36,9 @@ typedef struct XenHostPCIDevice {
int config_fd;
} XenHostPCIDevice;
int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
uint8_t bus, uint8_t dev, uint8_t func);
void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
uint8_t bus, uint8_t dev, uint8_t func,
Error **errp);
void xen_host_pci_device_put(XenHostPCIDevice *pci_dev);
bool xen_host_pci_device_closed(XenHostPCIDevice *d);

View file

@ -767,6 +767,7 @@ static int xen_pt_initfn(PCIDevice *d)
uint8_t machine_irq = 0, scratch;
uint16_t cmd = 0;
int pirq = XEN_PT_UNASSIGNED_PIRQ;
Error *err = NULL;
/* register real device */
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->dev.devfn);
rc = xen_host_pci_device_get(&s->real_device,
s->hostaddr.domain, s->hostaddr.bus,
s->hostaddr.slot, s->hostaddr.function);
if (rc) {
XEN_PT_ERR(d, "Failed to \"open\" the real pci device. rc: %i\n", rc);
xen_host_pci_device_get(&s->real_device,
s->hostaddr.domain, s->hostaddr.bus,
s->hostaddr.slot, s->hostaddr.function,
&err);
if (err) {
error_append_hint(&err, "Failed to \"open\" the real pci device");
error_report_err(err);
return -1;
}