aboutsummaryrefslogtreecommitdiff
path: root/pc-bios/s390-ccw/virtio.c
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2017-07-12 14:49:45 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2017-07-14 12:29:48 +0200
commit867e039a06a02d3f2f8fa9e0246bda7917150fd9 (patch)
treed63971b9d918cc3cffe2471be2c4d355cbe3c2c3 /pc-bios/s390-ccw/virtio.c
parentaf3bb73ab1352287848eec7f0ae395f26e004929 (diff)
pc-bios/s390-ccw: Move virtio-block related functions into a separate file
The netboot code is going to link against the code from virtio.c, too, so we've got to move the virtio-block and -scsi related code out of the way. Reviewed-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1499863793-18627-4-git-send-email-thuth@redhat.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'pc-bios/s390-ccw/virtio.c')
-rw-r--r--pc-bios/s390-ccw/virtio.c277
1 files changed, 6 insertions, 271 deletions
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 87683314cf..9d9e61faa3 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -70,7 +70,7 @@ static long virtio_notify(SubChannelId schid, int vq_idx, long cookie)
* Virtio functions *
***********************************************/
-static int drain_irqs(SubChannelId schid)
+int drain_irqs(SubChannelId schid)
{
Irb irb = {};
int r = 0;
@@ -149,13 +149,13 @@ static void vring_init(VRing *vr, VqInfo *info)
debug_print_addr("init vr", vr);
}
-static bool vring_notify(VRing *vr)
+bool vring_notify(VRing *vr)
{
vr->cookie = virtio_notify(vr->schid, vr->id, vr->cookie);
return vr->cookie >= 0;
}
-static void vring_send_buf(VRing *vr, void *p, int len, int flags)
+void vring_send_buf(VRing *vr, void *p, int len, int flags)
{
/* For follow-up chains we need to keep the first entry point */
if (!(flags & VRING_HIDDEN_IS_CHAIN)) {
@@ -188,7 +188,7 @@ ulong get_second(void)
return (get_clock() >> 12) / 1000000;
}
-static int vr_poll(VRing *vr)
+int vr_poll(VRing *vr)
{
if (vr->used->idx == vr->used_idx) {
vring_notify(vr);
@@ -210,7 +210,7 @@ static int vr_poll(VRing *vr)
*
* Returns 0 on success, 1 on timeout.
*/
-static int vring_wait_reply(void)
+int vring_wait_reply(void)
{
ulong target_second = get_second() + vdev.wait_reply_timeout;
@@ -247,242 +247,7 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd)
return 0;
}
-/***********************************************
- * Virtio block *
- ***********************************************/
-
-static int virtio_blk_read_many(VDev *vdev,
- ulong sector, void *load_addr, int sec_num)
-{
- VirtioBlkOuthdr out_hdr;
- u8 status;
- VRing *vr = &vdev->vrings[vdev->cmd_vr_idx];
-
- /* Tell the host we want to read */
- out_hdr.type = VIRTIO_BLK_T_IN;
- out_hdr.ioprio = 99;
- out_hdr.sector = virtio_sector_adjust(sector);
-
- vring_send_buf(vr, &out_hdr, sizeof(out_hdr), VRING_DESC_F_NEXT);
-
- /* This is where we want to receive data */
- vring_send_buf(vr, load_addr, virtio_get_block_size() * sec_num,
- VRING_DESC_F_WRITE | VRING_HIDDEN_IS_CHAIN |
- VRING_DESC_F_NEXT);
-
- /* status field */
- vring_send_buf(vr, &status, sizeof(u8),
- VRING_DESC_F_WRITE | VRING_HIDDEN_IS_CHAIN);
-
- /* Now we can tell the host to read */
- vring_wait_reply();
-
- if (drain_irqs(vr->schid)) {
- /* Well, whatever status is supposed to contain... */
- status = 1;
- }
- return status;
-}
-
-int virtio_read_many(ulong sector, void *load_addr, int sec_num)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return virtio_blk_read_many(&vdev, sector, load_addr, sec_num);
- case VIRTIO_ID_SCSI:
- return virtio_scsi_read_many(&vdev, sector, load_addr, sec_num);
- }
- panic("\n! No readable IPL device !\n");
- return -1;
-}
-
-unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2,
- ulong subchan_id, void *load_addr)
-{
- u8 status;
- int sec = rec_list1;
- int sec_num = ((rec_list2 >> 32) & 0xffff) + 1;
- int sec_len = rec_list2 >> 48;
- ulong addr = (ulong)load_addr;
-
- if (sec_len != virtio_get_block_size()) {
- return -1;
- }
-
- sclp_print(".");
- status = virtio_read_many(sec, (void *)addr, sec_num);
- if (status) {
- panic("I/O Error");
- }
- addr += sec_num * virtio_get_block_size();
-
- return addr;
-}
-
-int virtio_read(ulong sector, void *load_addr)
-{
- return virtio_read_many(sector, load_addr, 1);
-}
-
-/*
- * Other supported value pairs, if any, would need to be added here.
- * Note: head count is always 15.
- */
-static inline u8 virtio_eckd_sectors_for_block_size(int size)
-{
- switch (size) {
- case 512:
- return 49;
- case 1024:
- return 33;
- case 2048:
- return 21;
- case 4096:
- return 12;
- }
- return 0;
-}
-
-VirtioGDN virtio_guessed_disk_nature(void)
-{
- return vdev.guessed_disk_nature;
-}
-
-void virtio_assume_scsi(void)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- vdev.guessed_disk_nature = VIRTIO_GDN_SCSI;
- vdev.config.blk.blk_size = VIRTIO_SCSI_BLOCK_SIZE;
- vdev.config.blk.physical_block_exp = 0;
- vdev.blk_factor = 1;
- break;
- case VIRTIO_ID_SCSI:
- vdev.scsi_block_size = VIRTIO_SCSI_BLOCK_SIZE;
- break;
- }
-}
-
-void virtio_assume_iso9660(void)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- vdev.guessed_disk_nature = VIRTIO_GDN_SCSI;
- vdev.config.blk.blk_size = VIRTIO_ISO_BLOCK_SIZE;
- vdev.config.blk.physical_block_exp = 0;
- vdev.blk_factor = VIRTIO_ISO_BLOCK_SIZE / VIRTIO_SECTOR_SIZE;
- break;
- case VIRTIO_ID_SCSI:
- vdev.scsi_block_size = VIRTIO_ISO_BLOCK_SIZE;
- break;
- }
-}
-
-void virtio_assume_eckd(void)
-{
- vdev.guessed_disk_nature = VIRTIO_GDN_DASD;
- vdev.blk_factor = 1;
- vdev.config.blk.physical_block_exp = 0;
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- vdev.config.blk.blk_size = 4096;
- break;
- case VIRTIO_ID_SCSI:
- vdev.config.blk.blk_size = vdev.scsi_block_size;
- break;
- }
- vdev.config.blk.geometry.heads = 15;
- vdev.config.blk.geometry.sectors =
- virtio_eckd_sectors_for_block_size(vdev.config.blk.blk_size);
-}
-
-bool virtio_disk_is_scsi(void)
-{
- if (vdev.guessed_disk_nature == VIRTIO_GDN_SCSI) {
- return true;
- }
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return (vdev.config.blk.geometry.heads == 255)
- && (vdev.config.blk.geometry.sectors == 63)
- && (virtio_get_block_size() == VIRTIO_SCSI_BLOCK_SIZE);
- case VIRTIO_ID_SCSI:
- return true;
- }
- return false;
-}
-
-bool virtio_disk_is_eckd(void)
-{
- const int block_size = virtio_get_block_size();
-
- if (vdev.guessed_disk_nature == VIRTIO_GDN_DASD) {
- return true;
- }
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return (vdev.config.blk.geometry.heads == 15)
- && (vdev.config.blk.geometry.sectors ==
- virtio_eckd_sectors_for_block_size(block_size));
- case VIRTIO_ID_SCSI:
- return false;
- }
- return false;
-}
-
-bool virtio_ipl_disk_is_valid(void)
-{
- return virtio_disk_is_scsi() || virtio_disk_is_eckd();
-}
-
-int virtio_get_block_size(void)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return vdev.config.blk.blk_size << vdev.config.blk.physical_block_exp;
- case VIRTIO_ID_SCSI:
- return vdev.scsi_block_size;
- }
- return 0;
-}
-
-uint8_t virtio_get_heads(void)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return vdev.config.blk.geometry.heads;
- case VIRTIO_ID_SCSI:
- return vdev.guessed_disk_nature == VIRTIO_GDN_DASD
- ? vdev.config.blk.geometry.heads : 255;
- }
- return 0;
-}
-
-uint8_t virtio_get_sectors(void)
-{
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return vdev.config.blk.geometry.sectors;
- case VIRTIO_ID_SCSI:
- return vdev.guessed_disk_nature == VIRTIO_GDN_DASD
- ? vdev.config.blk.geometry.sectors : 63;
- }
- return 0;
-}
-
-uint64_t virtio_get_blocks(void)
-{
- const uint64_t factor = virtio_get_block_size() / VIRTIO_SECTOR_SIZE;
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- return vdev.config.blk.capacity / factor;
- case VIRTIO_ID_SCSI:
- return vdev.scsi_last_block / factor;
- }
- return 0;
-}
-
-static void virtio_setup_ccw(VDev *vdev)
+void virtio_setup_ccw(VDev *vdev)
{
int i, cfg_size = 0;
unsigned char status = VIRTIO_CONFIG_S_DRIVER_OK;
@@ -544,36 +309,6 @@ static void virtio_setup_ccw(VDev *vdev)
"Could not write status to host");
}
-void virtio_setup_device(SubChannelId schid)
-{
- vdev.schid = schid;
- virtio_setup_ccw(&vdev);
-
- switch (vdev.senseid.cu_model) {
- case VIRTIO_ID_BLOCK:
- sclp_print("Using virtio-blk.\n");
- if (!virtio_ipl_disk_is_valid()) {
- /* make sure all getters but blocksize return 0 for
- * invalid IPL disk
- */
- memset(&vdev.config.blk, 0, sizeof(vdev.config.blk));
- virtio_assume_scsi();
- }
- break;
- case VIRTIO_ID_SCSI:
- IPL_assert(vdev.config.scsi.sense_size == VIRTIO_SCSI_SENSE_SIZE,
- "Config: sense size mismatch");
- IPL_assert(vdev.config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE,
- "Config: CDB size mismatch");
-
- sclp_print("Using virtio-scsi.\n");
- virtio_scsi_setup(&vdev);
- break;
- default:
- panic("\n! No IPL device available !\n");
- }
-}
-
bool virtio_is_supported(SubChannelId schid)
{
vdev.schid = schid;