diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2020-03-09 07:43:50 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2020-05-15 13:36:08 +0200 |
commit | f82e82a5ab2366e1f4299e53ec95584f39d57dc8 (patch) | |
tree | 1515fa68510673410814c2b637bd3ad90844c18a | |
parent | 040b92c6159773c36876f17f3fb02816ca9f6701 (diff) | |
download | seabios-hppa-f82e82a5ab2366e1f4299e53ec95584f39d57dc8.zip seabios-hppa-f82e82a5ab2366e1f4299e53ec95584f39d57dc8.tar.gz seabios-hppa-f82e82a5ab2366e1f4299e53ec95584f39d57dc8.tar.bz2 |
virtio-mmio: add support for scsi devices.
Add new fields to struct virtio_lun_s for mmio support,
add mmio parameter to virtio_scsi_init_lun(), so both
pci and mmio devices can be handled.
Add and use bootprio_find_scsi_mmio_device() to figure
boot priority of devices connected to a virtio-mmio
scsi controller.
Finally add init_virtio_scsi_mmio() to initialize one
virtio-mmio scsi controller.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r-- | src/boot.c | 10 | ||||
-rw-r--r-- | src/hw/virtio-mmio.c | 3 | ||||
-rw-r--r-- | src/hw/virtio-scsi.c | 73 | ||||
-rw-r--r-- | src/hw/virtio-scsi.h | 1 | ||||
-rw-r--r-- | src/util.h | 1 |
5 files changed, 76 insertions, 12 deletions
@@ -328,6 +328,16 @@ int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun) return find_prio(desc); } +int bootprio_find_scsi_mmio_device(void *mmio, int target, int lun) +{ + if (!CONFIG_BOOTORDER) + return -1; + char desc[256]; + snprintf(desc, sizeof(desc), "/virtio-mmio@%016x/*@0/*@%x,%x", + (u32)mmio, target, lun); + return find_prio(desc); +} + int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave) { if (CONFIG_CSM) diff --git a/src/hw/virtio-mmio.c b/src/hw/virtio-mmio.c index 0d6ef6e..daca8a0 100644 --- a/src/hw/virtio-mmio.c +++ b/src/hw/virtio-mmio.c @@ -4,6 +4,7 @@ #include "stacks.h" // run_thread #include "string.h" // memset #include "virtio-pci.h" +#include "virtio-scsi.h" #include "virtio-ring.h" #include "virtio-mmio.h" @@ -37,7 +38,7 @@ void virtio_mmio_setup_one(u64 addr) /* TODO */ break; case 8: /* scsi */ - /* TODO */ + run_thread(init_virtio_scsi_mmio, mmio); break; default: break; diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index a533284..59f1c65 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -22,10 +22,13 @@ #include "virtio-pci.h" #include "virtio-ring.h" #include "virtio-scsi.h" +#include "virtio-mmio.h" struct virtio_lun_s { struct drive_s drive; struct pci_device *pci; + void *mmio; + char name[16]; struct vring_virtqueue *vq; struct vp_device *vp; u16 target; @@ -94,7 +97,8 @@ virtio_scsi_process_op(struct disk_op_s *op) } static void -virtio_scsi_init_lun(struct virtio_lun_s *vlun, struct pci_device *pci, +virtio_scsi_init_lun(struct virtio_lun_s *vlun, + struct pci_device *pci, void *mmio, struct vp_device *vp, struct vring_virtqueue *vq, u16 target, u16 lun) { @@ -102,10 +106,15 @@ virtio_scsi_init_lun(struct virtio_lun_s *vlun, struct pci_device *pci, vlun->drive.type = DTYPE_VIRTIO_SCSI; vlun->drive.cntl_id = pci->bdf; vlun->pci = pci; + vlun->mmio = mmio; vlun->vp = vp; vlun->vq = vq; vlun->target = target; vlun->lun = lun; + if (vlun->pci) + snprintf(vlun->name, sizeof(vlun->name), "pci:%pP", vlun->pci); + if (vlun->mmio) + snprintf(vlun->name, sizeof(vlun->name), "mmio:%08x", (u32)vlun->mmio); } static int @@ -114,12 +123,17 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv) u8 skip_nonbootable = is_bootprio_strict(); struct virtio_lun_s *tmpl_vlun = container_of(tmpl_drv, struct virtio_lun_s, drive); - int prio = bootprio_find_scsi_device(tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun); + int prio = -1; + + if (tmpl_vlun->pci) + prio = bootprio_find_scsi_device(tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun); + if (tmpl_vlun->mmio) + prio = bootprio_find_scsi_mmio_device(tmpl_vlun->mmio, tmpl_vlun->target, tmpl_vlun->lun); if (skip_nonbootable && prio < 0) { - dprintf(1, "skipping init of a non-bootable virtio-scsi dev at %pP," + dprintf(1, "skipping init of a non-bootable virtio-scsi dev at %s," " target %d, lun %d\n", - tmpl_vlun->pci, tmpl_vlun->target, tmpl_vlun->lun); + tmpl_vlun->name, tmpl_vlun->target, tmpl_vlun->lun); return -1; } @@ -128,11 +142,12 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv) warn_noalloc(); return -1; } - virtio_scsi_init_lun(vlun, tmpl_vlun->pci, tmpl_vlun->vp, tmpl_vlun->vq, - tmpl_vlun->target, lun); + virtio_scsi_init_lun(vlun, tmpl_vlun->pci, tmpl_vlun->mmio,tmpl_vlun->vp, + tmpl_vlun->vq, tmpl_vlun->target, lun); - boot_lchs_find_scsi_device(vlun->pci, vlun->target, vlun->lun, - &(vlun->drive.lchs)); + if (vlun->pci) + boot_lchs_find_scsi_device(vlun->pci, vlun->target, vlun->lun, + &(vlun->drive.lchs)); int ret = scsi_drive_setup(&vlun->drive, "virtio-scsi", prio); if (ret) goto fail; @@ -144,13 +159,13 @@ fail: } static int -virtio_scsi_scan_target(struct pci_device *pci, struct vp_device *vp, +virtio_scsi_scan_target(struct pci_device *pci, void *mmio, struct vp_device *vp, struct vring_virtqueue *vq, u16 target) { struct virtio_lun_s vlun0; - virtio_scsi_init_lun(&vlun0, pci, vp, vq, target, 0); + virtio_scsi_init_lun(&vlun0, pci, mmio, vp, vq, target, 0); int ret = scsi_rep_luns_scan(&vlun0.drive, virtio_scsi_add_lun); return ret < 0 ? 0 : ret; @@ -198,7 +213,43 @@ init_virtio_scsi(void *data) int i, tot; for (tot = 0, i = 0; i < 256; i++) - tot += virtio_scsi_scan_target(pci, vp, vq, i); + tot += virtio_scsi_scan_target(pci, NULL, vp, vq, i); + + if (!tot) + goto fail; + + return; + +fail: + vp_reset(vp); + free(vp); + free(vq); +} + +void +init_virtio_scsi_mmio(void *mmio) +{ + dprintf(1, "found virtio-scsi-mmio at %p\n", mmio); + struct vring_virtqueue *vq = NULL; + struct vp_device *vp = malloc_high(sizeof(*vp)); + if (!vp) { + warn_noalloc(); + return; + } + vp_init_mmio(vp, mmio); + u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER; + + if (vp_find_vq(vp, 2, &vq) < 0 ) { + dprintf(1, "fail to find vq for virtio-scsi-mmio %p\n", mmio); + goto fail; + } + + status |= VIRTIO_CONFIG_S_DRIVER_OK; + vp_set_status(vp, status); + + int i, tot; + for (tot = 0, i = 0; i < 256; i++) + tot += virtio_scsi_scan_target(NULL, mmio, vp, vq, i); if (!tot) goto fail; diff --git a/src/hw/virtio-scsi.h b/src/hw/virtio-scsi.h index 7532cc9..8f01de4 100644 --- a/src/hw/virtio-scsi.h +++ b/src/hw/virtio-scsi.h @@ -43,5 +43,6 @@ struct virtio_scsi_resp_cmd { struct disk_op_s; int virtio_scsi_process_op(struct disk_op_s *op); void virtio_scsi_setup(void); +void init_virtio_scsi_mmio(void *data); #endif /* _VIRTIO_SCSI_H */ @@ -31,6 +31,7 @@ u8 is_bootprio_strict(void); struct pci_device; int bootprio_find_pci_device(struct pci_device *pci); int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun); +int bootprio_find_scsi_mmio_device(void *mmio, int target, int lun); int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave); int bootprio_find_fdc_device(struct pci_device *pci, int port, int fdid); int bootprio_find_pci_rom(struct pci_device *pci, int instance); |