1*24ffa71bSTiwei Bie // SPDX-License-Identifier: GPL-2.0 2*24ffa71bSTiwei Bie /* 3*24ffa71bSTiwei Bie * Copyright (C) 2020 Intel Corporation 4*24ffa71bSTiwei Bie * Author: Johannes Berg <johannes@sipsolutions.net> 5*24ffa71bSTiwei Bie */ 6*24ffa71bSTiwei Bie #include <linux/module.h> 7*24ffa71bSTiwei Bie #include <linux/pci.h> 8*24ffa71bSTiwei Bie #include <linux/virtio.h> 9*24ffa71bSTiwei Bie #include <linux/virtio_config.h> 10*24ffa71bSTiwei Bie #include <linux/logic_iomem.h> 11*24ffa71bSTiwei Bie #include <linux/of_platform.h> 12*24ffa71bSTiwei Bie #include <linux/irqdomain.h> 13*24ffa71bSTiwei Bie #include <linux/virtio_pcidev.h> 14*24ffa71bSTiwei Bie #include <linux/virtio-uml.h> 15*24ffa71bSTiwei Bie #include <linux/delay.h> 16*24ffa71bSTiwei Bie #include <linux/msi.h> 17*24ffa71bSTiwei Bie #include <linux/unaligned.h> 18*24ffa71bSTiwei Bie #include <irq_kern.h> 19*24ffa71bSTiwei Bie 20*24ffa71bSTiwei Bie #include "virt-pci.h" 21*24ffa71bSTiwei Bie 22*24ffa71bSTiwei Bie #define to_virtio_pcidev(_pdev) \ 23*24ffa71bSTiwei Bie container_of(_pdev, struct virtio_pcidev_device, pdev) 24*24ffa71bSTiwei Bie 25*24ffa71bSTiwei Bie /* for MSI-X we have a 32-bit payload */ 26*24ffa71bSTiwei Bie #define MAX_IRQ_MSG_SIZE (sizeof(struct virtio_pcidev_msg) + sizeof(u32)) 27*24ffa71bSTiwei Bie #define NUM_IRQ_MSGS 10 28*24ffa71bSTiwei Bie 29*24ffa71bSTiwei Bie struct virtio_pcidev_message_buffer { 30*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr; 31*24ffa71bSTiwei Bie u8 data[8]; 32*24ffa71bSTiwei Bie }; 33*24ffa71bSTiwei Bie 34*24ffa71bSTiwei Bie struct virtio_pcidev_device { 35*24ffa71bSTiwei Bie struct um_pci_device pdev; 36*24ffa71bSTiwei Bie struct virtio_device *vdev; 37*24ffa71bSTiwei Bie 38*24ffa71bSTiwei Bie struct virtqueue *cmd_vq, *irq_vq; 39*24ffa71bSTiwei Bie 40*24ffa71bSTiwei Bie #define VIRTIO_PCIDEV_WRITE_BUFS 20 41*24ffa71bSTiwei Bie struct virtio_pcidev_message_buffer bufs[VIRTIO_PCIDEV_WRITE_BUFS + 1]; 42*24ffa71bSTiwei Bie void *extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS + 1]; 43*24ffa71bSTiwei Bie DECLARE_BITMAP(used_bufs, VIRTIO_PCIDEV_WRITE_BUFS); 44*24ffa71bSTiwei Bie 45*24ffa71bSTiwei Bie #define UM_PCI_STAT_WAITING 0 46*24ffa71bSTiwei Bie unsigned long status; 47*24ffa71bSTiwei Bie 48*24ffa71bSTiwei Bie bool platform; 49*24ffa71bSTiwei Bie }; 50*24ffa71bSTiwei Bie 51*24ffa71bSTiwei Bie static unsigned int virtio_pcidev_max_delay_us = 40000; 52*24ffa71bSTiwei Bie module_param_named(max_delay_us, virtio_pcidev_max_delay_us, uint, 0644); 53*24ffa71bSTiwei Bie 54*24ffa71bSTiwei Bie static int virtio_pcidev_get_buf(struct virtio_pcidev_device *dev, bool *posted) 55*24ffa71bSTiwei Bie { 56*24ffa71bSTiwei Bie int i; 57*24ffa71bSTiwei Bie 58*24ffa71bSTiwei Bie for (i = 0; i < VIRTIO_PCIDEV_WRITE_BUFS; i++) { 59*24ffa71bSTiwei Bie if (!test_and_set_bit(i, dev->used_bufs)) 60*24ffa71bSTiwei Bie return i; 61*24ffa71bSTiwei Bie } 62*24ffa71bSTiwei Bie 63*24ffa71bSTiwei Bie *posted = false; 64*24ffa71bSTiwei Bie return VIRTIO_PCIDEV_WRITE_BUFS; 65*24ffa71bSTiwei Bie } 66*24ffa71bSTiwei Bie 67*24ffa71bSTiwei Bie static void virtio_pcidev_free_buf(struct virtio_pcidev_device *dev, void *buf) 68*24ffa71bSTiwei Bie { 69*24ffa71bSTiwei Bie int i; 70*24ffa71bSTiwei Bie 71*24ffa71bSTiwei Bie if (buf == &dev->bufs[VIRTIO_PCIDEV_WRITE_BUFS]) { 72*24ffa71bSTiwei Bie kfree(dev->extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS]); 73*24ffa71bSTiwei Bie dev->extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS] = NULL; 74*24ffa71bSTiwei Bie return; 75*24ffa71bSTiwei Bie } 76*24ffa71bSTiwei Bie 77*24ffa71bSTiwei Bie for (i = 0; i < VIRTIO_PCIDEV_WRITE_BUFS; i++) { 78*24ffa71bSTiwei Bie if (buf == &dev->bufs[i]) { 79*24ffa71bSTiwei Bie kfree(dev->extra_ptrs[i]); 80*24ffa71bSTiwei Bie dev->extra_ptrs[i] = NULL; 81*24ffa71bSTiwei Bie WARN_ON(!test_and_clear_bit(i, dev->used_bufs)); 82*24ffa71bSTiwei Bie return; 83*24ffa71bSTiwei Bie } 84*24ffa71bSTiwei Bie } 85*24ffa71bSTiwei Bie 86*24ffa71bSTiwei Bie WARN_ON(1); 87*24ffa71bSTiwei Bie } 88*24ffa71bSTiwei Bie 89*24ffa71bSTiwei Bie static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev, 90*24ffa71bSTiwei Bie struct virtio_pcidev_msg *cmd, 91*24ffa71bSTiwei Bie unsigned int cmd_size, 92*24ffa71bSTiwei Bie const void *extra, unsigned int extra_size, 93*24ffa71bSTiwei Bie void *out, unsigned int out_size) 94*24ffa71bSTiwei Bie { 95*24ffa71bSTiwei Bie struct scatterlist out_sg, extra_sg, in_sg; 96*24ffa71bSTiwei Bie struct scatterlist *sgs_list[] = { 97*24ffa71bSTiwei Bie [0] = &out_sg, 98*24ffa71bSTiwei Bie [1] = extra ? &extra_sg : &in_sg, 99*24ffa71bSTiwei Bie [2] = extra ? &in_sg : NULL, 100*24ffa71bSTiwei Bie }; 101*24ffa71bSTiwei Bie struct virtio_pcidev_message_buffer *buf; 102*24ffa71bSTiwei Bie int delay_count = 0; 103*24ffa71bSTiwei Bie bool bounce_out; 104*24ffa71bSTiwei Bie int ret, len; 105*24ffa71bSTiwei Bie int buf_idx; 106*24ffa71bSTiwei Bie bool posted; 107*24ffa71bSTiwei Bie 108*24ffa71bSTiwei Bie if (WARN_ON(cmd_size < sizeof(*cmd) || cmd_size > sizeof(*buf))) 109*24ffa71bSTiwei Bie return -EINVAL; 110*24ffa71bSTiwei Bie 111*24ffa71bSTiwei Bie switch (cmd->op) { 112*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_CFG_WRITE: 113*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_MMIO_WRITE: 114*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_MMIO_MEMSET: 115*24ffa71bSTiwei Bie /* in PCI, writes are posted, so don't wait */ 116*24ffa71bSTiwei Bie posted = !out; 117*24ffa71bSTiwei Bie WARN_ON(!posted); 118*24ffa71bSTiwei Bie break; 119*24ffa71bSTiwei Bie default: 120*24ffa71bSTiwei Bie posted = false; 121*24ffa71bSTiwei Bie break; 122*24ffa71bSTiwei Bie } 123*24ffa71bSTiwei Bie 124*24ffa71bSTiwei Bie bounce_out = !posted && cmd_size <= sizeof(*cmd) && 125*24ffa71bSTiwei Bie out && out_size <= sizeof(buf->data); 126*24ffa71bSTiwei Bie 127*24ffa71bSTiwei Bie buf_idx = virtio_pcidev_get_buf(dev, &posted); 128*24ffa71bSTiwei Bie buf = &dev->bufs[buf_idx]; 129*24ffa71bSTiwei Bie memcpy(buf, cmd, cmd_size); 130*24ffa71bSTiwei Bie 131*24ffa71bSTiwei Bie if (posted && extra && extra_size > sizeof(buf) - cmd_size) { 132*24ffa71bSTiwei Bie dev->extra_ptrs[buf_idx] = kmemdup(extra, extra_size, 133*24ffa71bSTiwei Bie GFP_ATOMIC); 134*24ffa71bSTiwei Bie 135*24ffa71bSTiwei Bie if (!dev->extra_ptrs[buf_idx]) { 136*24ffa71bSTiwei Bie virtio_pcidev_free_buf(dev, buf); 137*24ffa71bSTiwei Bie return -ENOMEM; 138*24ffa71bSTiwei Bie } 139*24ffa71bSTiwei Bie extra = dev->extra_ptrs[buf_idx]; 140*24ffa71bSTiwei Bie } else if (extra && extra_size <= sizeof(buf) - cmd_size) { 141*24ffa71bSTiwei Bie memcpy((u8 *)buf + cmd_size, extra, extra_size); 142*24ffa71bSTiwei Bie cmd_size += extra_size; 143*24ffa71bSTiwei Bie extra_size = 0; 144*24ffa71bSTiwei Bie extra = NULL; 145*24ffa71bSTiwei Bie cmd = (void *)buf; 146*24ffa71bSTiwei Bie } else { 147*24ffa71bSTiwei Bie cmd = (void *)buf; 148*24ffa71bSTiwei Bie } 149*24ffa71bSTiwei Bie 150*24ffa71bSTiwei Bie sg_init_one(&out_sg, cmd, cmd_size); 151*24ffa71bSTiwei Bie if (extra) 152*24ffa71bSTiwei Bie sg_init_one(&extra_sg, extra, extra_size); 153*24ffa71bSTiwei Bie /* allow stack for small buffers */ 154*24ffa71bSTiwei Bie if (bounce_out) 155*24ffa71bSTiwei Bie sg_init_one(&in_sg, buf->data, out_size); 156*24ffa71bSTiwei Bie else if (out) 157*24ffa71bSTiwei Bie sg_init_one(&in_sg, out, out_size); 158*24ffa71bSTiwei Bie 159*24ffa71bSTiwei Bie /* add to internal virtio queue */ 160*24ffa71bSTiwei Bie ret = virtqueue_add_sgs(dev->cmd_vq, sgs_list, 161*24ffa71bSTiwei Bie extra ? 2 : 1, 162*24ffa71bSTiwei Bie out ? 1 : 0, 163*24ffa71bSTiwei Bie cmd, GFP_ATOMIC); 164*24ffa71bSTiwei Bie if (ret) { 165*24ffa71bSTiwei Bie virtio_pcidev_free_buf(dev, buf); 166*24ffa71bSTiwei Bie return ret; 167*24ffa71bSTiwei Bie } 168*24ffa71bSTiwei Bie 169*24ffa71bSTiwei Bie if (posted) { 170*24ffa71bSTiwei Bie virtqueue_kick(dev->cmd_vq); 171*24ffa71bSTiwei Bie return 0; 172*24ffa71bSTiwei Bie } 173*24ffa71bSTiwei Bie 174*24ffa71bSTiwei Bie /* kick and poll for getting a response on the queue */ 175*24ffa71bSTiwei Bie set_bit(UM_PCI_STAT_WAITING, &dev->status); 176*24ffa71bSTiwei Bie virtqueue_kick(dev->cmd_vq); 177*24ffa71bSTiwei Bie ret = 0; 178*24ffa71bSTiwei Bie 179*24ffa71bSTiwei Bie while (1) { 180*24ffa71bSTiwei Bie void *completed = virtqueue_get_buf(dev->cmd_vq, &len); 181*24ffa71bSTiwei Bie 182*24ffa71bSTiwei Bie if (completed == buf) 183*24ffa71bSTiwei Bie break; 184*24ffa71bSTiwei Bie 185*24ffa71bSTiwei Bie if (completed) 186*24ffa71bSTiwei Bie virtio_pcidev_free_buf(dev, completed); 187*24ffa71bSTiwei Bie 188*24ffa71bSTiwei Bie if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || 189*24ffa71bSTiwei Bie ++delay_count > virtio_pcidev_max_delay_us, 190*24ffa71bSTiwei Bie "um virt-pci delay: %d", delay_count)) { 191*24ffa71bSTiwei Bie ret = -EIO; 192*24ffa71bSTiwei Bie break; 193*24ffa71bSTiwei Bie } 194*24ffa71bSTiwei Bie udelay(1); 195*24ffa71bSTiwei Bie } 196*24ffa71bSTiwei Bie clear_bit(UM_PCI_STAT_WAITING, &dev->status); 197*24ffa71bSTiwei Bie 198*24ffa71bSTiwei Bie if (bounce_out) 199*24ffa71bSTiwei Bie memcpy(out, buf->data, out_size); 200*24ffa71bSTiwei Bie 201*24ffa71bSTiwei Bie virtio_pcidev_free_buf(dev, buf); 202*24ffa71bSTiwei Bie 203*24ffa71bSTiwei Bie return ret; 204*24ffa71bSTiwei Bie } 205*24ffa71bSTiwei Bie 206*24ffa71bSTiwei Bie static unsigned long virtio_pcidev_cfgspace_read(struct um_pci_device *pdev, 207*24ffa71bSTiwei Bie unsigned int offset, int size) 208*24ffa71bSTiwei Bie { 209*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 210*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr = { 211*24ffa71bSTiwei Bie .op = VIRTIO_PCIDEV_OP_CFG_READ, 212*24ffa71bSTiwei Bie .size = size, 213*24ffa71bSTiwei Bie .addr = offset, 214*24ffa71bSTiwei Bie }; 215*24ffa71bSTiwei Bie /* max 8, we might not use it all */ 216*24ffa71bSTiwei Bie u8 data[8]; 217*24ffa71bSTiwei Bie 218*24ffa71bSTiwei Bie memset(data, 0xff, sizeof(data)); 219*24ffa71bSTiwei Bie 220*24ffa71bSTiwei Bie /* size has been checked in um_pci_cfgspace_read() */ 221*24ffa71bSTiwei Bie if (virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, data, size)) 222*24ffa71bSTiwei Bie return ULONG_MAX; 223*24ffa71bSTiwei Bie 224*24ffa71bSTiwei Bie switch (size) { 225*24ffa71bSTiwei Bie case 1: 226*24ffa71bSTiwei Bie return data[0]; 227*24ffa71bSTiwei Bie case 2: 228*24ffa71bSTiwei Bie return le16_to_cpup((void *)data); 229*24ffa71bSTiwei Bie case 4: 230*24ffa71bSTiwei Bie return le32_to_cpup((void *)data); 231*24ffa71bSTiwei Bie #ifdef CONFIG_64BIT 232*24ffa71bSTiwei Bie case 8: 233*24ffa71bSTiwei Bie return le64_to_cpup((void *)data); 234*24ffa71bSTiwei Bie #endif 235*24ffa71bSTiwei Bie default: 236*24ffa71bSTiwei Bie return ULONG_MAX; 237*24ffa71bSTiwei Bie } 238*24ffa71bSTiwei Bie } 239*24ffa71bSTiwei Bie 240*24ffa71bSTiwei Bie static void virtio_pcidev_cfgspace_write(struct um_pci_device *pdev, 241*24ffa71bSTiwei Bie unsigned int offset, int size, 242*24ffa71bSTiwei Bie unsigned long val) 243*24ffa71bSTiwei Bie { 244*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 245*24ffa71bSTiwei Bie struct { 246*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr; 247*24ffa71bSTiwei Bie /* maximum size - we may only use parts of it */ 248*24ffa71bSTiwei Bie u8 data[8]; 249*24ffa71bSTiwei Bie } msg = { 250*24ffa71bSTiwei Bie .hdr = { 251*24ffa71bSTiwei Bie .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 252*24ffa71bSTiwei Bie .size = size, 253*24ffa71bSTiwei Bie .addr = offset, 254*24ffa71bSTiwei Bie }, 255*24ffa71bSTiwei Bie }; 256*24ffa71bSTiwei Bie 257*24ffa71bSTiwei Bie /* size has been checked in um_pci_cfgspace_write() */ 258*24ffa71bSTiwei Bie switch (size) { 259*24ffa71bSTiwei Bie case 1: 260*24ffa71bSTiwei Bie msg.data[0] = (u8)val; 261*24ffa71bSTiwei Bie break; 262*24ffa71bSTiwei Bie case 2: 263*24ffa71bSTiwei Bie put_unaligned_le16(val, (void *)msg.data); 264*24ffa71bSTiwei Bie break; 265*24ffa71bSTiwei Bie case 4: 266*24ffa71bSTiwei Bie put_unaligned_le32(val, (void *)msg.data); 267*24ffa71bSTiwei Bie break; 268*24ffa71bSTiwei Bie #ifdef CONFIG_64BIT 269*24ffa71bSTiwei Bie case 8: 270*24ffa71bSTiwei Bie put_unaligned_le64(val, (void *)msg.data); 271*24ffa71bSTiwei Bie break; 272*24ffa71bSTiwei Bie #endif 273*24ffa71bSTiwei Bie } 274*24ffa71bSTiwei Bie 275*24ffa71bSTiwei Bie WARN_ON(virtio_pcidev_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0)); 276*24ffa71bSTiwei Bie } 277*24ffa71bSTiwei Bie 278*24ffa71bSTiwei Bie static void virtio_pcidev_bar_copy_from(struct um_pci_device *pdev, 279*24ffa71bSTiwei Bie int bar, void *buffer, 280*24ffa71bSTiwei Bie unsigned int offset, int size) 281*24ffa71bSTiwei Bie { 282*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 283*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr = { 284*24ffa71bSTiwei Bie .op = VIRTIO_PCIDEV_OP_MMIO_READ, 285*24ffa71bSTiwei Bie .bar = bar, 286*24ffa71bSTiwei Bie .size = size, 287*24ffa71bSTiwei Bie .addr = offset, 288*24ffa71bSTiwei Bie }; 289*24ffa71bSTiwei Bie 290*24ffa71bSTiwei Bie memset(buffer, 0xff, size); 291*24ffa71bSTiwei Bie 292*24ffa71bSTiwei Bie virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, buffer, size); 293*24ffa71bSTiwei Bie } 294*24ffa71bSTiwei Bie 295*24ffa71bSTiwei Bie static unsigned long virtio_pcidev_bar_read(struct um_pci_device *pdev, int bar, 296*24ffa71bSTiwei Bie unsigned int offset, int size) 297*24ffa71bSTiwei Bie { 298*24ffa71bSTiwei Bie /* 8 is maximum size - we may only use parts of it */ 299*24ffa71bSTiwei Bie u8 data[8]; 300*24ffa71bSTiwei Bie 301*24ffa71bSTiwei Bie /* size has been checked in um_pci_bar_read() */ 302*24ffa71bSTiwei Bie virtio_pcidev_bar_copy_from(pdev, bar, data, offset, size); 303*24ffa71bSTiwei Bie 304*24ffa71bSTiwei Bie switch (size) { 305*24ffa71bSTiwei Bie case 1: 306*24ffa71bSTiwei Bie return data[0]; 307*24ffa71bSTiwei Bie case 2: 308*24ffa71bSTiwei Bie return le16_to_cpup((void *)data); 309*24ffa71bSTiwei Bie case 4: 310*24ffa71bSTiwei Bie return le32_to_cpup((void *)data); 311*24ffa71bSTiwei Bie #ifdef CONFIG_64BIT 312*24ffa71bSTiwei Bie case 8: 313*24ffa71bSTiwei Bie return le64_to_cpup((void *)data); 314*24ffa71bSTiwei Bie #endif 315*24ffa71bSTiwei Bie default: 316*24ffa71bSTiwei Bie return ULONG_MAX; 317*24ffa71bSTiwei Bie } 318*24ffa71bSTiwei Bie } 319*24ffa71bSTiwei Bie 320*24ffa71bSTiwei Bie static void virtio_pcidev_bar_copy_to(struct um_pci_device *pdev, 321*24ffa71bSTiwei Bie int bar, unsigned int offset, 322*24ffa71bSTiwei Bie const void *buffer, int size) 323*24ffa71bSTiwei Bie { 324*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 325*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr = { 326*24ffa71bSTiwei Bie .op = VIRTIO_PCIDEV_OP_MMIO_WRITE, 327*24ffa71bSTiwei Bie .bar = bar, 328*24ffa71bSTiwei Bie .size = size, 329*24ffa71bSTiwei Bie .addr = offset, 330*24ffa71bSTiwei Bie }; 331*24ffa71bSTiwei Bie 332*24ffa71bSTiwei Bie virtio_pcidev_send_cmd(dev, &hdr, sizeof(hdr), buffer, size, NULL, 0); 333*24ffa71bSTiwei Bie } 334*24ffa71bSTiwei Bie 335*24ffa71bSTiwei Bie static void virtio_pcidev_bar_write(struct um_pci_device *pdev, int bar, 336*24ffa71bSTiwei Bie unsigned int offset, int size, 337*24ffa71bSTiwei Bie unsigned long val) 338*24ffa71bSTiwei Bie { 339*24ffa71bSTiwei Bie /* maximum size - we may only use parts of it */ 340*24ffa71bSTiwei Bie u8 data[8]; 341*24ffa71bSTiwei Bie 342*24ffa71bSTiwei Bie /* size has been checked in um_pci_bar_write() */ 343*24ffa71bSTiwei Bie switch (size) { 344*24ffa71bSTiwei Bie case 1: 345*24ffa71bSTiwei Bie data[0] = (u8)val; 346*24ffa71bSTiwei Bie break; 347*24ffa71bSTiwei Bie case 2: 348*24ffa71bSTiwei Bie put_unaligned_le16(val, (void *)data); 349*24ffa71bSTiwei Bie break; 350*24ffa71bSTiwei Bie case 4: 351*24ffa71bSTiwei Bie put_unaligned_le32(val, (void *)data); 352*24ffa71bSTiwei Bie break; 353*24ffa71bSTiwei Bie #ifdef CONFIG_64BIT 354*24ffa71bSTiwei Bie case 8: 355*24ffa71bSTiwei Bie put_unaligned_le64(val, (void *)data); 356*24ffa71bSTiwei Bie break; 357*24ffa71bSTiwei Bie #endif 358*24ffa71bSTiwei Bie } 359*24ffa71bSTiwei Bie 360*24ffa71bSTiwei Bie virtio_pcidev_bar_copy_to(pdev, bar, offset, data, size); 361*24ffa71bSTiwei Bie } 362*24ffa71bSTiwei Bie 363*24ffa71bSTiwei Bie static void virtio_pcidev_bar_set(struct um_pci_device *pdev, int bar, 364*24ffa71bSTiwei Bie unsigned int offset, u8 value, int size) 365*24ffa71bSTiwei Bie { 366*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = to_virtio_pcidev(pdev); 367*24ffa71bSTiwei Bie struct { 368*24ffa71bSTiwei Bie struct virtio_pcidev_msg hdr; 369*24ffa71bSTiwei Bie u8 data; 370*24ffa71bSTiwei Bie } msg = { 371*24ffa71bSTiwei Bie .hdr = { 372*24ffa71bSTiwei Bie .op = VIRTIO_PCIDEV_OP_CFG_WRITE, 373*24ffa71bSTiwei Bie .bar = bar, 374*24ffa71bSTiwei Bie .size = size, 375*24ffa71bSTiwei Bie .addr = offset, 376*24ffa71bSTiwei Bie }, 377*24ffa71bSTiwei Bie .data = value, 378*24ffa71bSTiwei Bie }; 379*24ffa71bSTiwei Bie 380*24ffa71bSTiwei Bie virtio_pcidev_send_cmd(dev, &msg.hdr, sizeof(msg), NULL, 0, NULL, 0); 381*24ffa71bSTiwei Bie } 382*24ffa71bSTiwei Bie 383*24ffa71bSTiwei Bie static const struct um_pci_ops virtio_pcidev_um_pci_ops = { 384*24ffa71bSTiwei Bie .cfgspace_read = virtio_pcidev_cfgspace_read, 385*24ffa71bSTiwei Bie .cfgspace_write = virtio_pcidev_cfgspace_write, 386*24ffa71bSTiwei Bie .bar_read = virtio_pcidev_bar_read, 387*24ffa71bSTiwei Bie .bar_write = virtio_pcidev_bar_write, 388*24ffa71bSTiwei Bie .bar_copy_from = virtio_pcidev_bar_copy_from, 389*24ffa71bSTiwei Bie .bar_copy_to = virtio_pcidev_bar_copy_to, 390*24ffa71bSTiwei Bie .bar_set = virtio_pcidev_bar_set, 391*24ffa71bSTiwei Bie }; 392*24ffa71bSTiwei Bie 393*24ffa71bSTiwei Bie static void virtio_pcidev_irq_vq_addbuf(struct virtqueue *vq, void *buf, bool kick) 394*24ffa71bSTiwei Bie { 395*24ffa71bSTiwei Bie struct scatterlist sg[1]; 396*24ffa71bSTiwei Bie 397*24ffa71bSTiwei Bie sg_init_one(sg, buf, MAX_IRQ_MSG_SIZE); 398*24ffa71bSTiwei Bie if (virtqueue_add_inbuf(vq, sg, 1, buf, GFP_ATOMIC)) 399*24ffa71bSTiwei Bie kfree(buf); 400*24ffa71bSTiwei Bie else if (kick) 401*24ffa71bSTiwei Bie virtqueue_kick(vq); 402*24ffa71bSTiwei Bie } 403*24ffa71bSTiwei Bie 404*24ffa71bSTiwei Bie static void virtio_pcidev_handle_irq_message(struct virtqueue *vq, 405*24ffa71bSTiwei Bie struct virtio_pcidev_msg *msg) 406*24ffa71bSTiwei Bie { 407*24ffa71bSTiwei Bie struct virtio_device *vdev = vq->vdev; 408*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = vdev->priv; 409*24ffa71bSTiwei Bie 410*24ffa71bSTiwei Bie if (!dev->pdev.irq) 411*24ffa71bSTiwei Bie return; 412*24ffa71bSTiwei Bie 413*24ffa71bSTiwei Bie /* we should properly chain interrupts, but on ARCH=um we don't care */ 414*24ffa71bSTiwei Bie 415*24ffa71bSTiwei Bie switch (msg->op) { 416*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_INT: 417*24ffa71bSTiwei Bie generic_handle_irq(dev->pdev.irq); 418*24ffa71bSTiwei Bie break; 419*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_MSI: 420*24ffa71bSTiwei Bie /* our MSI message is just the interrupt number */ 421*24ffa71bSTiwei Bie if (msg->size == sizeof(u32)) 422*24ffa71bSTiwei Bie generic_handle_irq(le32_to_cpup((void *)msg->data)); 423*24ffa71bSTiwei Bie else 424*24ffa71bSTiwei Bie generic_handle_irq(le16_to_cpup((void *)msg->data)); 425*24ffa71bSTiwei Bie break; 426*24ffa71bSTiwei Bie case VIRTIO_PCIDEV_OP_PME: 427*24ffa71bSTiwei Bie /* nothing to do - we already woke up due to the message */ 428*24ffa71bSTiwei Bie break; 429*24ffa71bSTiwei Bie default: 430*24ffa71bSTiwei Bie dev_err(&vdev->dev, "unexpected virt-pci message %d\n", msg->op); 431*24ffa71bSTiwei Bie break; 432*24ffa71bSTiwei Bie } 433*24ffa71bSTiwei Bie } 434*24ffa71bSTiwei Bie 435*24ffa71bSTiwei Bie static void virtio_pcidev_cmd_vq_cb(struct virtqueue *vq) 436*24ffa71bSTiwei Bie { 437*24ffa71bSTiwei Bie struct virtio_device *vdev = vq->vdev; 438*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = vdev->priv; 439*24ffa71bSTiwei Bie void *cmd; 440*24ffa71bSTiwei Bie int len; 441*24ffa71bSTiwei Bie 442*24ffa71bSTiwei Bie if (test_bit(UM_PCI_STAT_WAITING, &dev->status)) 443*24ffa71bSTiwei Bie return; 444*24ffa71bSTiwei Bie 445*24ffa71bSTiwei Bie while ((cmd = virtqueue_get_buf(vq, &len))) 446*24ffa71bSTiwei Bie virtio_pcidev_free_buf(dev, cmd); 447*24ffa71bSTiwei Bie } 448*24ffa71bSTiwei Bie 449*24ffa71bSTiwei Bie static void virtio_pcidev_irq_vq_cb(struct virtqueue *vq) 450*24ffa71bSTiwei Bie { 451*24ffa71bSTiwei Bie struct virtio_pcidev_msg *msg; 452*24ffa71bSTiwei Bie int len; 453*24ffa71bSTiwei Bie 454*24ffa71bSTiwei Bie while ((msg = virtqueue_get_buf(vq, &len))) { 455*24ffa71bSTiwei Bie if (len >= sizeof(*msg)) 456*24ffa71bSTiwei Bie virtio_pcidev_handle_irq_message(vq, msg); 457*24ffa71bSTiwei Bie 458*24ffa71bSTiwei Bie /* recycle the message buffer */ 459*24ffa71bSTiwei Bie virtio_pcidev_irq_vq_addbuf(vq, msg, true); 460*24ffa71bSTiwei Bie } 461*24ffa71bSTiwei Bie } 462*24ffa71bSTiwei Bie 463*24ffa71bSTiwei Bie static int virtio_pcidev_init_vqs(struct virtio_pcidev_device *dev) 464*24ffa71bSTiwei Bie { 465*24ffa71bSTiwei Bie struct virtqueue_info vqs_info[] = { 466*24ffa71bSTiwei Bie { "cmd", virtio_pcidev_cmd_vq_cb }, 467*24ffa71bSTiwei Bie { "irq", virtio_pcidev_irq_vq_cb }, 468*24ffa71bSTiwei Bie }; 469*24ffa71bSTiwei Bie struct virtqueue *vqs[2]; 470*24ffa71bSTiwei Bie int err, i; 471*24ffa71bSTiwei Bie 472*24ffa71bSTiwei Bie err = virtio_find_vqs(dev->vdev, 2, vqs, vqs_info, NULL); 473*24ffa71bSTiwei Bie if (err) 474*24ffa71bSTiwei Bie return err; 475*24ffa71bSTiwei Bie 476*24ffa71bSTiwei Bie dev->cmd_vq = vqs[0]; 477*24ffa71bSTiwei Bie dev->irq_vq = vqs[1]; 478*24ffa71bSTiwei Bie 479*24ffa71bSTiwei Bie virtio_device_ready(dev->vdev); 480*24ffa71bSTiwei Bie 481*24ffa71bSTiwei Bie for (i = 0; i < NUM_IRQ_MSGS; i++) { 482*24ffa71bSTiwei Bie void *msg = kzalloc(MAX_IRQ_MSG_SIZE, GFP_KERNEL); 483*24ffa71bSTiwei Bie 484*24ffa71bSTiwei Bie if (msg) 485*24ffa71bSTiwei Bie virtio_pcidev_irq_vq_addbuf(dev->irq_vq, msg, false); 486*24ffa71bSTiwei Bie } 487*24ffa71bSTiwei Bie 488*24ffa71bSTiwei Bie virtqueue_kick(dev->irq_vq); 489*24ffa71bSTiwei Bie 490*24ffa71bSTiwei Bie return 0; 491*24ffa71bSTiwei Bie } 492*24ffa71bSTiwei Bie 493*24ffa71bSTiwei Bie static void __virtio_pcidev_virtio_platform_remove(struct virtio_device *vdev, 494*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev) 495*24ffa71bSTiwei Bie { 496*24ffa71bSTiwei Bie um_pci_platform_device_unregister(&dev->pdev); 497*24ffa71bSTiwei Bie 498*24ffa71bSTiwei Bie virtio_reset_device(vdev); 499*24ffa71bSTiwei Bie vdev->config->del_vqs(vdev); 500*24ffa71bSTiwei Bie 501*24ffa71bSTiwei Bie kfree(dev); 502*24ffa71bSTiwei Bie } 503*24ffa71bSTiwei Bie 504*24ffa71bSTiwei Bie static int virtio_pcidev_virtio_platform_probe(struct virtio_device *vdev, 505*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev) 506*24ffa71bSTiwei Bie { 507*24ffa71bSTiwei Bie int err; 508*24ffa71bSTiwei Bie 509*24ffa71bSTiwei Bie dev->platform = true; 510*24ffa71bSTiwei Bie 511*24ffa71bSTiwei Bie err = virtio_pcidev_init_vqs(dev); 512*24ffa71bSTiwei Bie if (err) 513*24ffa71bSTiwei Bie goto err_free; 514*24ffa71bSTiwei Bie 515*24ffa71bSTiwei Bie err = um_pci_platform_device_register(&dev->pdev); 516*24ffa71bSTiwei Bie if (err) 517*24ffa71bSTiwei Bie goto err_reset; 518*24ffa71bSTiwei Bie 519*24ffa71bSTiwei Bie err = of_platform_default_populate(vdev->dev.of_node, NULL, &vdev->dev); 520*24ffa71bSTiwei Bie if (err) 521*24ffa71bSTiwei Bie goto err_unregister; 522*24ffa71bSTiwei Bie 523*24ffa71bSTiwei Bie return 0; 524*24ffa71bSTiwei Bie 525*24ffa71bSTiwei Bie err_unregister: 526*24ffa71bSTiwei Bie um_pci_platform_device_unregister(&dev->pdev); 527*24ffa71bSTiwei Bie err_reset: 528*24ffa71bSTiwei Bie virtio_reset_device(vdev); 529*24ffa71bSTiwei Bie vdev->config->del_vqs(vdev); 530*24ffa71bSTiwei Bie err_free: 531*24ffa71bSTiwei Bie kfree(dev); 532*24ffa71bSTiwei Bie return err; 533*24ffa71bSTiwei Bie } 534*24ffa71bSTiwei Bie 535*24ffa71bSTiwei Bie static int virtio_pcidev_virtio_probe(struct virtio_device *vdev) 536*24ffa71bSTiwei Bie { 537*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev; 538*24ffa71bSTiwei Bie int err; 539*24ffa71bSTiwei Bie 540*24ffa71bSTiwei Bie dev = kzalloc(sizeof(*dev), GFP_KERNEL); 541*24ffa71bSTiwei Bie if (!dev) 542*24ffa71bSTiwei Bie return -ENOMEM; 543*24ffa71bSTiwei Bie 544*24ffa71bSTiwei Bie dev->vdev = vdev; 545*24ffa71bSTiwei Bie vdev->priv = dev; 546*24ffa71bSTiwei Bie 547*24ffa71bSTiwei Bie dev->pdev.ops = &virtio_pcidev_um_pci_ops; 548*24ffa71bSTiwei Bie 549*24ffa71bSTiwei Bie if (of_device_is_compatible(vdev->dev.of_node, "simple-bus")) 550*24ffa71bSTiwei Bie return virtio_pcidev_virtio_platform_probe(vdev, dev); 551*24ffa71bSTiwei Bie 552*24ffa71bSTiwei Bie err = virtio_pcidev_init_vqs(dev); 553*24ffa71bSTiwei Bie if (err) 554*24ffa71bSTiwei Bie goto err_free; 555*24ffa71bSTiwei Bie 556*24ffa71bSTiwei Bie err = um_pci_device_register(&dev->pdev); 557*24ffa71bSTiwei Bie if (err) 558*24ffa71bSTiwei Bie goto err_reset; 559*24ffa71bSTiwei Bie 560*24ffa71bSTiwei Bie device_set_wakeup_enable(&vdev->dev, true); 561*24ffa71bSTiwei Bie 562*24ffa71bSTiwei Bie /* 563*24ffa71bSTiwei Bie * In order to do suspend-resume properly, don't allow VQs 564*24ffa71bSTiwei Bie * to be suspended. 565*24ffa71bSTiwei Bie */ 566*24ffa71bSTiwei Bie virtio_uml_set_no_vq_suspend(vdev, true); 567*24ffa71bSTiwei Bie 568*24ffa71bSTiwei Bie return 0; 569*24ffa71bSTiwei Bie 570*24ffa71bSTiwei Bie err_reset: 571*24ffa71bSTiwei Bie virtio_reset_device(vdev); 572*24ffa71bSTiwei Bie vdev->config->del_vqs(vdev); 573*24ffa71bSTiwei Bie err_free: 574*24ffa71bSTiwei Bie kfree(dev); 575*24ffa71bSTiwei Bie return err; 576*24ffa71bSTiwei Bie } 577*24ffa71bSTiwei Bie 578*24ffa71bSTiwei Bie static void virtio_pcidev_virtio_remove(struct virtio_device *vdev) 579*24ffa71bSTiwei Bie { 580*24ffa71bSTiwei Bie struct virtio_pcidev_device *dev = vdev->priv; 581*24ffa71bSTiwei Bie 582*24ffa71bSTiwei Bie if (dev->platform) { 583*24ffa71bSTiwei Bie of_platform_depopulate(&vdev->dev); 584*24ffa71bSTiwei Bie __virtio_pcidev_virtio_platform_remove(vdev, dev); 585*24ffa71bSTiwei Bie return; 586*24ffa71bSTiwei Bie } 587*24ffa71bSTiwei Bie 588*24ffa71bSTiwei Bie device_set_wakeup_enable(&vdev->dev, false); 589*24ffa71bSTiwei Bie 590*24ffa71bSTiwei Bie um_pci_device_unregister(&dev->pdev); 591*24ffa71bSTiwei Bie 592*24ffa71bSTiwei Bie /* Stop all virtqueues */ 593*24ffa71bSTiwei Bie virtio_reset_device(vdev); 594*24ffa71bSTiwei Bie dev->cmd_vq = NULL; 595*24ffa71bSTiwei Bie dev->irq_vq = NULL; 596*24ffa71bSTiwei Bie vdev->config->del_vqs(vdev); 597*24ffa71bSTiwei Bie 598*24ffa71bSTiwei Bie kfree(dev); 599*24ffa71bSTiwei Bie } 600*24ffa71bSTiwei Bie 601*24ffa71bSTiwei Bie static struct virtio_device_id id_table[] = { 602*24ffa71bSTiwei Bie { CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID, VIRTIO_DEV_ANY_ID }, 603*24ffa71bSTiwei Bie { 0 }, 604*24ffa71bSTiwei Bie }; 605*24ffa71bSTiwei Bie MODULE_DEVICE_TABLE(virtio, id_table); 606*24ffa71bSTiwei Bie 607*24ffa71bSTiwei Bie static struct virtio_driver virtio_pcidev_virtio_driver = { 608*24ffa71bSTiwei Bie .driver.name = "virtio-pci", 609*24ffa71bSTiwei Bie .id_table = id_table, 610*24ffa71bSTiwei Bie .probe = virtio_pcidev_virtio_probe, 611*24ffa71bSTiwei Bie .remove = virtio_pcidev_virtio_remove, 612*24ffa71bSTiwei Bie }; 613*24ffa71bSTiwei Bie 614*24ffa71bSTiwei Bie static int __init virtio_pcidev_init(void) 615*24ffa71bSTiwei Bie { 616*24ffa71bSTiwei Bie if (WARN(CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID < 0, 617*24ffa71bSTiwei Bie "No virtio device ID configured for PCI - no PCI support\n")) 618*24ffa71bSTiwei Bie return 0; 619*24ffa71bSTiwei Bie 620*24ffa71bSTiwei Bie return register_virtio_driver(&virtio_pcidev_virtio_driver); 621*24ffa71bSTiwei Bie } 622*24ffa71bSTiwei Bie late_initcall(virtio_pcidev_init); 623*24ffa71bSTiwei Bie 624*24ffa71bSTiwei Bie static void __exit virtio_pcidev_exit(void) 625*24ffa71bSTiwei Bie { 626*24ffa71bSTiwei Bie unregister_virtio_driver(&virtio_pcidev_virtio_driver); 627*24ffa71bSTiwei Bie } 628*24ffa71bSTiwei Bie module_exit(virtio_pcidev_exit); 629