DM: virtio-gpio: return a valid length for GPIO request

When the backend completes a GPIO request, it returns a valid length
to ensure that response correct.

Tracked-On: #2512
Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Yuan Liu 2019-02-21 19:17:09 +08:00 committed by wenlingz
parent 8bc0e128a9
commit 780f520fc6

View File

@ -481,14 +481,14 @@ static struct virtio_ops virtio_gpio_ops = {
}; };
static void static int
virtio_gpio_proc(struct virtio_gpio *gpio, struct iovec *iov, int n) virtio_gpio_proc(struct virtio_gpio *gpio, struct iovec *iov, int n)
{ {
struct virtio_gpio_data *data; struct virtio_gpio_data *data;
struct virtio_gpio_request *req; struct virtio_gpio_request *req;
struct virtio_gpio_response *rsp; struct virtio_gpio_response *rsp;
struct gpio_line *line; struct gpio_line *line;
int i, len; int i, len, rc;
if (n == 1) { /* provide gpio names for front-end driver */ if (n == 1) { /* provide gpio names for front-end driver */
data = iov[0].iov_base; data = iov[0].iov_base;
@ -510,6 +510,7 @@ virtio_gpio_proc(struct virtio_gpio *gpio, struct iovec *iov, int n)
strncpy(data[i].name, line->name, strncpy(data[i].name, line->name,
sizeof(data[0].name) - 1); sizeof(data[0].name) - 1);
} }
rc = gpio->nvline;
} else if (n == 2) { /* handle gpio operations requests */ } else if (n == 2) { /* handle gpio operations requests */
req = iov[0].iov_base; req = iov[0].iov_base;
len = iov[0].iov_len; len = iov[0].iov_len;
@ -520,8 +521,13 @@ virtio_gpio_proc(struct virtio_gpio *gpio, struct iovec *iov, int n)
assert(len == sizeof(*rsp)); assert(len == sizeof(*rsp));
gpio_request_handler(gpio, req, rsp); gpio_request_handler(gpio, req, rsp);
} else rc = sizeof(*rsp);
} else {
DPRINTF("virtio gpio: number of buffer error %d\n", n); DPRINTF("virtio gpio: number of buffer error %d\n", n);
rc = 0;
}
return rc;
} }
static void static void
@ -530,18 +536,18 @@ virtio_gpio_notify(void *vdev, struct virtio_vq_info *vq)
struct iovec iov[2]; struct iovec iov[2];
struct virtio_gpio *gpio; struct virtio_gpio *gpio;
uint16_t idx; uint16_t idx;
int n; int n, len;
gpio = (struct virtio_gpio *)vdev; gpio = (struct virtio_gpio *)vdev;
if (vq_has_descs(vq)) { if (vq_has_descs(vq)) {
n = vq_getchain(vq, &idx, iov, 2, NULL); n = vq_getchain(vq, &idx, iov, 2, NULL);
assert(n < 3); assert(n < 3);
virtio_gpio_proc(gpio, iov, n); len = virtio_gpio_proc(gpio, iov, n);
/* /*
* Release this chain and handle more * Release this chain and handle more
*/ */
vq_relchain(vq, idx, 1); vq_relchain(vq, idx, len);
} }
} }