From 341df5f859294503d81a416e3efa9d2f297a6410 Mon Sep 17 00:00:00 2001 From: Jakub Jermar Date: Sat, 5 May 2018 22:07:00 +0200 Subject: [PATCH] Factor our generic virtio device initialization --- uspace/drv/nic/virtio-net/virtio-net.c | 60 +++++------------------------ uspace/drv/nic/virtio-net/virtio-net.h | 10 ++--- uspace/lib/virtio/virtio-pci.c | 69 ++++++++++++++++++++++++++++++++++ uspace/lib/virtio/virtio-pci.h | 6 +++ 4 files changed, 88 insertions(+), 57 deletions(-) diff --git a/uspace/drv/nic/virtio-net/virtio-net.c b/uspace/drv/nic/virtio-net/virtio-net.c index 121c58f05..4e0117912 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.c +++ b/uspace/drv/nic/virtio-net/virtio-net.c @@ -74,53 +74,13 @@ static errno_t virtio_net_initialize(ddf_dev_t *dev) virtio_pci_common_cfg_t *cfg = virtio_net->virtio_dev.common_cfg; virtio_net_cfg_t *netcfg = virtio_net->virtio_dev.device_cfg; - /* - * Perform device initialization as described in section 3.1.1 of the - * specification. - */ - - /* 1. Reset the device */ - uint8_t status = VIRTIO_DEV_STATUS_RESET; - pio_write_8(&cfg->device_status, status); - - /* 2. Acknowledge we found the device */ - status |= VIRTIO_DEV_STATUS_ACKNOWLEDGE; - pio_write_8(&cfg->device_status, status); - - /* 3. We know how to drive the device */ - status |= VIRTIO_DEV_STATUS_DRIVER; - pio_write_8(&cfg->device_status, status); - - /* 4. Read the offered feature flags */ - pio_write_32(&cfg->device_feature_select, VIRTIO_NET_F_SELECT_PAGE_0); - uint32_t features = pio_read_32(&cfg->device_feature); - - ddf_msg(LVL_NOTE, "offered features %x", features); - features &= (1U << VIRTIO_NET_F_MAC) | (1U << VIRTIO_NET_F_CTRL_VQ); - - if (!features) { - rc = ENOTSUP; - goto fail; - } - - /* 4. Write the accepted feature flags */ - pio_write_32(&cfg->driver_feature_select, VIRTIO_NET_F_SELECT_PAGE_0); - pio_write_32(&cfg->driver_feature, features); - - ddf_msg(LVL_NOTE, "accepted features %x", features); - - /* 5. Set FEATURES_OK */ - status |= VIRTIO_DEV_STATUS_FEATURES_OK; - pio_write_8(&cfg->device_status, status); - - /* 6. Test if the device supports our feature subset */ - status = pio_read_8(&cfg->device_status); - if (!(status & VIRTIO_DEV_STATUS_FEATURES_OK)) { - rc = ENOTSUP; + /* Reset the device and negotiate the feature bits */ + rc = virtio_device_setup_start(vdev, + VIRTIO_NET_F_MAC | VIRTIO_NET_F_CTRL_VQ); + if (rc != EOK) goto fail; - } - /* 7. Perform device-specific setup */ + /* Perform device-specific setup */ /* * Discover and configure the virtqueues @@ -163,16 +123,14 @@ static errno_t virtio_net_initialize(ddf_dev_t *dev) nic_addr.address[0], nic_addr.address[1], nic_addr.address[2], nic_addr.address[3], nic_addr.address[4], nic_addr.address[5]); - /* 8. Go live */ - status |= VIRTIO_DEV_STATUS_DRIVER_OK; - pio_write_8(&cfg->device_status, status); + /* Go live */ + virtio_device_setup_finalize(vdev); return EOK; fail: - status |= VIRTIO_DEV_STATUS_FAILED; - pio_write_8(&cfg->device_status, status); - virtio_pci_dev_cleanup(&virtio_net->virtio_dev); + virtio_device_setup_fail(vdev); + virtio_pci_dev_cleanup(vdev); return rc; } diff --git a/uspace/drv/nic/virtio-net/virtio-net.h b/uspace/drv/nic/virtio-net/virtio-net.h index 80d7362d9..c9a31b1b1 100644 --- a/uspace/drv/nic/virtio-net/virtio-net.h +++ b/uspace/drv/nic/virtio-net/virtio-net.h @@ -31,16 +31,14 @@ #include -#define VIRTIO_NET_F_SELECT_PAGE_0 0 - /** Device handles packets with partial checksum. */ -#define VIRTIO_NET_F_CSUM 0 +#define VIRTIO_NET_F_CSUM (1U << 0) /** Driver handles packets with partial checksum. */ -#define VIRTIO_NET_F_GUEST_CSUM 2 +#define VIRTIO_NET_F_GUEST_CSUM (1U << 2) /** Device has given MAC address. */ -#define VIRTIO_NET_F_MAC 5 +#define VIRTIO_NET_F_MAC (1U << 5) /** Control channel is available */ -#define VIRTIO_NET_F_CTRL_VQ 17 +#define VIRTIO_NET_F_CTRL_VQ (1U << 17) typedef struct { uint8_t mac[6]; diff --git a/uspace/lib/virtio/virtio-pci.c b/uspace/lib/virtio/virtio-pci.c index c5a1ee80f..3991b389a 100644 --- a/uspace/lib/virtio/virtio-pci.c +++ b/uspace/lib/virtio/virtio-pci.c @@ -271,6 +271,75 @@ void virtio_virtq_teardown(virtio_dev_t *vdev, uint16_t num) free(q->buffers); } +/** + * Perform device initialization as described in section 3.1.1 of the + * specification, steps 1 - 6. + */ +errno_t virtio_device_setup_start(virtio_dev_t *vdev, uint32_t features) +{ + virtio_pci_common_cfg_t *cfg = vdev->common_cfg; + + /* 1. Reset the device */ + uint8_t status = VIRTIO_DEV_STATUS_RESET; + pio_write_8(&cfg->device_status, status); + + /* 2. Acknowledge we found the device */ + status |= VIRTIO_DEV_STATUS_ACKNOWLEDGE; + pio_write_8(&cfg->device_status, status); + + /* 3. We know how to drive the device */ + status |= VIRTIO_DEV_STATUS_DRIVER; + pio_write_8(&cfg->device_status, status); + + /* 4. Read the offered feature flags */ + pio_write_32(&cfg->device_feature_select, VIRTIO_FEATURES_0_31); + uint32_t device_features = pio_read_32(&cfg->device_feature); + + ddf_msg(LVL_NOTE, "offered features %x", device_features); + features &= device_features; + + if (!features) + return ENOTSUP; + + /* 4. Write the accepted feature flags */ + pio_write_32(&cfg->driver_feature_select, VIRTIO_FEATURES_0_31); + pio_write_32(&cfg->driver_feature, features); + + ddf_msg(LVL_NOTE, "accepted features %x", features); + + /* 5. Set FEATURES_OK */ + status |= VIRTIO_DEV_STATUS_FEATURES_OK; + pio_write_8(&cfg->device_status, status); + + /* 6. Test if the device supports our feature subset */ + status = pio_read_8(&cfg->device_status); + if (!(status & VIRTIO_DEV_STATUS_FEATURES_OK)) + return ENOTSUP; + + return EOK; +} + +/** + * Perform device initialization as described in section 3.1.1 of the + * specification, step 8 (go live). + */ +void virtio_device_setup_finalize(virtio_dev_t *vdev) +{ + virtio_pci_common_cfg_t *cfg = vdev->common_cfg; + + /* 8. Go live */ + uint8_t status = pio_read_8(&cfg->device_status); + pio_write_8(&cfg->device_status, status | VIRTIO_DEV_STATUS_DRIVER_OK); +} + +void virtio_device_setup_fail(virtio_dev_t *vdev) +{ + virtio_pci_common_cfg_t *cfg = vdev->common_cfg; + + uint8_t status = pio_read_8(&cfg->device_status); + pio_write_8(&cfg->device_status, status | VIRTIO_DEV_STATUS_FAILED); +} + errno_t virtio_pci_dev_initialize(ddf_dev_t *dev, virtio_dev_t *vdev) { memset(vdev, 0, sizeof(virtio_dev_t)); diff --git a/uspace/lib/virtio/virtio-pci.h b/uspace/lib/virtio/virtio-pci.h index c1f5cff72..678cebf06 100644 --- a/uspace/lib/virtio/virtio-pci.h +++ b/uspace/lib/virtio/virtio-pci.h @@ -57,6 +57,8 @@ #define VIRTIO_DEV_STATUS_DEVICE_NEEDS_RESET 64 #define VIRTIO_DEV_STATUS_FAILED 128 +#define VIRTIO_FEATURES_0_31 0 + /** Common configuration structure layout according to VIRTIO version 1.0 */ typedef struct virtio_pci_common_cfg { ioport32_t device_feature_select; @@ -178,6 +180,10 @@ extern errno_t virtio_virtq_setup(virtio_dev_t *, uint16_t, uint16_t, size_t, uint16_t); extern void virtio_virtq_teardown(virtio_dev_t *, uint16_t); +extern errno_t virtio_device_setup_start(virtio_dev_t *, uint32_t); +extern void virtio_device_setup_fail(virtio_dev_t *); +extern void virtio_device_setup_finalize(virtio_dev_t *); + extern errno_t virtio_pci_dev_initialize(ddf_dev_t *, virtio_dev_t *); extern errno_t virtio_pci_dev_cleanup(virtio_dev_t *); -- 2.11.4.GIT