diff options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/lguest/lguest.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 5cd705c3d75b..3be8ab2a886a 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -131,6 +131,9 @@ struct device | |||
131 | /* Any queues attached to this device */ | 131 | /* Any queues attached to this device */ |
132 | struct virtqueue *vq; | 132 | struct virtqueue *vq; |
133 | 133 | ||
134 | /* Handle status being finalized (ie. feature bits stable). */ | ||
135 | void (*ready)(struct device *me); | ||
136 | |||
134 | /* Device-specific data. */ | 137 | /* Device-specific data. */ |
135 | void *priv; | 138 | void *priv; |
136 | }; | 139 | }; |
@@ -925,24 +928,40 @@ static void enable_fd(int fd, struct virtqueue *vq) | |||
925 | write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); | 928 | write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); |
926 | } | 929 | } |
927 | 930 | ||
928 | /* When the Guest asks us to reset a device, it's is fairly easy. */ | 931 | /* When the Guest tells us they updated the status field, we handle it. */ |
929 | static void reset_device(struct device *dev) | 932 | static void update_device_status(struct device *dev) |
930 | { | 933 | { |
931 | struct virtqueue *vq; | 934 | struct virtqueue *vq; |
932 | 935 | ||
933 | verbose("Resetting device %s\n", dev->name); | 936 | /* This is a reset. */ |
934 | /* Clear the status. */ | 937 | if (dev->desc->status == 0) { |
935 | dev->desc->status = 0; | 938 | verbose("Resetting device %s\n", dev->name); |
936 | 939 | ||
937 | /* Clear any features they've acked. */ | 940 | /* Clear any features they've acked. */ |
938 | memset(get_feature_bits(dev) + dev->desc->feature_len, 0, | 941 | memset(get_feature_bits(dev) + dev->desc->feature_len, 0, |
939 | dev->desc->feature_len); | 942 | dev->desc->feature_len); |
940 | 943 | ||
941 | /* Zero out the virtqueues. */ | 944 | /* Zero out the virtqueues. */ |
942 | for (vq = dev->vq; vq; vq = vq->next) { | 945 | for (vq = dev->vq; vq; vq = vq->next) { |
943 | memset(vq->vring.desc, 0, | 946 | memset(vq->vring.desc, 0, |
944 | vring_size(vq->config.num, getpagesize())); | 947 | vring_size(vq->config.num, getpagesize())); |
945 | vq->last_avail_idx = 0; | 948 | vq->last_avail_idx = 0; |
949 | } | ||
950 | } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { | ||
951 | warnx("Device %s configuration FAILED", dev->name); | ||
952 | } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { | ||
953 | unsigned int i; | ||
954 | |||
955 | verbose("Device %s OK: offered", dev->name); | ||
956 | for (i = 0; i < dev->desc->feature_len; i++) | ||
957 | verbose(" %08x", get_feature_bits(dev)[i]); | ||
958 | verbose(", accepted"); | ||
959 | for (i = 0; i < dev->desc->feature_len; i++) | ||
960 | verbose(" %08x", get_feature_bits(dev) | ||
961 | [dev->desc->feature_len+i]); | ||
962 | |||
963 | if (dev->ready) | ||
964 | dev->ready(dev); | ||
946 | } | 965 | } |
947 | } | 966 | } |
948 | 967 | ||
@@ -954,9 +973,9 @@ static void handle_output(int fd, unsigned long addr) | |||
954 | 973 | ||
955 | /* Check each device and virtqueue. */ | 974 | /* Check each device and virtqueue. */ |
956 | for (i = devices.dev; i; i = i->next) { | 975 | for (i = devices.dev; i; i = i->next) { |
957 | /* Notifications to device descriptors reset the device. */ | 976 | /* Notifications to device descriptors update device status. */ |
958 | if (from_guest_phys(addr) == i->desc) { | 977 | if (from_guest_phys(addr) == i->desc) { |
959 | reset_device(i); | 978 | update_device_status(i); |
960 | return; | 979 | return; |
961 | } | 980 | } |
962 | 981 | ||
@@ -1170,6 +1189,7 @@ static struct device *new_device(const char *name, u16 type, int fd, | |||
1170 | dev->handle_input = handle_input; | 1189 | dev->handle_input = handle_input; |
1171 | dev->name = name; | 1190 | dev->name = name; |
1172 | dev->vq = NULL; | 1191 | dev->vq = NULL; |
1192 | dev->ready = NULL; | ||
1173 | 1193 | ||
1174 | /* Append to device list. Prepending to a single-linked list is | 1194 | /* Append to device list. Prepending to a single-linked list is |
1175 | * easier, but the user expects the devices to be arranged on the bus | 1195 | * easier, but the user expects the devices to be arranged on the bus |