diff options
| -rw-r--r-- | drivers/virtio/virtio_mmio.c | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 9c877d2375a5..6010d7ec0a0f 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
| @@ -156,22 +156,85 @@ static void vm_get(struct virtio_device *vdev, unsigned offset, | |||
| 156 | void *buf, unsigned len) | 156 | void *buf, unsigned len) |
| 157 | { | 157 | { |
| 158 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); | 158 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 159 | u8 *ptr = buf; | 159 | void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG; |
| 160 | int i; | 160 | u8 b; |
| 161 | __le16 w; | ||
| 162 | __le32 l; | ||
| 161 | 163 | ||
| 162 | for (i = 0; i < len; i++) | 164 | if (vm_dev->version == 1) { |
| 163 | ptr[i] = readb(vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); | 165 | u8 *ptr = buf; |
| 166 | int i; | ||
| 167 | |||
| 168 | for (i = 0; i < len; i++) | ||
| 169 | ptr[i] = readb(base + offset + i); | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | |||
| 173 | switch (len) { | ||
| 174 | case 1: | ||
| 175 | b = readb(base + offset); | ||
| 176 | memcpy(buf, &b, sizeof b); | ||
| 177 | break; | ||
| 178 | case 2: | ||
| 179 | w = cpu_to_le16(readw(base + offset)); | ||
| 180 | memcpy(buf, &w, sizeof w); | ||
| 181 | break; | ||
| 182 | case 4: | ||
| 183 | l = cpu_to_le32(readl(base + offset)); | ||
| 184 | memcpy(buf, &l, sizeof l); | ||
| 185 | break; | ||
| 186 | case 8: | ||
| 187 | l = cpu_to_le32(readl(base + offset)); | ||
| 188 | memcpy(buf, &l, sizeof l); | ||
| 189 | l = cpu_to_le32(ioread32(base + offset + sizeof l)); | ||
| 190 | memcpy(buf + sizeof l, &l, sizeof l); | ||
| 191 | break; | ||
| 192 | default: | ||
| 193 | BUG(); | ||
| 194 | } | ||
| 164 | } | 195 | } |
| 165 | 196 | ||
| 166 | static void vm_set(struct virtio_device *vdev, unsigned offset, | 197 | static void vm_set(struct virtio_device *vdev, unsigned offset, |
| 167 | const void *buf, unsigned len) | 198 | const void *buf, unsigned len) |
| 168 | { | 199 | { |
| 169 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); | 200 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 170 | const u8 *ptr = buf; | 201 | void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG; |
| 171 | int i; | 202 | u8 b; |
| 203 | __le16 w; | ||
| 204 | __le32 l; | ||
| 172 | 205 | ||
| 173 | for (i = 0; i < len; i++) | 206 | if (vm_dev->version == 1) { |
| 174 | writeb(ptr[i], vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); | 207 | const u8 *ptr = buf; |
| 208 | int i; | ||
| 209 | |||
| 210 | for (i = 0; i < len; i++) | ||
| 211 | writeb(ptr[i], base + offset + i); | ||
| 212 | |||
| 213 | return; | ||
| 214 | } | ||
| 215 | |||
| 216 | switch (len) { | ||
| 217 | case 1: | ||
| 218 | memcpy(&b, buf, sizeof b); | ||
| 219 | writeb(b, base + offset); | ||
| 220 | break; | ||
| 221 | case 2: | ||
| 222 | memcpy(&w, buf, sizeof w); | ||
| 223 | writew(le16_to_cpu(w), base + offset); | ||
| 224 | break; | ||
| 225 | case 4: | ||
| 226 | memcpy(&l, buf, sizeof l); | ||
| 227 | writel(le32_to_cpu(l), base + offset); | ||
| 228 | break; | ||
| 229 | case 8: | ||
| 230 | memcpy(&l, buf, sizeof l); | ||
| 231 | writel(le32_to_cpu(l), base + offset); | ||
| 232 | memcpy(&l, buf + sizeof l, sizeof l); | ||
| 233 | writel(le32_to_cpu(l), base + offset + sizeof l); | ||
| 234 | break; | ||
| 235 | default: | ||
| 236 | BUG(); | ||
| 237 | } | ||
| 175 | } | 238 | } |
| 176 | 239 | ||
| 177 | static u32 vm_generation(struct virtio_device *vdev) | 240 | static u32 vm_generation(struct virtio_device *vdev) |
