From patchwork Thu Mar 24 08:30:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 8659021 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2C82F9F3D1 for ; Thu, 24 Mar 2016 08:38:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1FBD5201FE for ; Thu, 24 Mar 2016 08:38:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D3265203AE for ; Thu, 24 Mar 2016 08:38:25 +0000 (UTC) Received: from localhost ([::1]:48551 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aj0mf-0006YU-7Y for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Mar 2016 04:38:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52014) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aj0en-00018o-IY for qemu-devel@nongnu.org; Thu, 24 Mar 2016 04:30:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aj0el-0001hc-5N for qemu-devel@nongnu.org; Thu, 24 Mar 2016 04:30:17 -0400 Received: from e06smtp13.uk.ibm.com ([195.75.94.109]:51577) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aj0ek-0001hI-Rg for qemu-devel@nongnu.org; Thu, 24 Mar 2016 04:30:15 -0400 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 24 Mar 2016 08:30:14 -0000 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 24 Mar 2016 08:30:12 -0000 X-IBM-Helo: d06dlp03.portsmouth.uk.ibm.com X-IBM-MailFrom: cornelia.huck@de.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 50B9C1B08067 for ; Thu, 24 Mar 2016 08:30:44 +0000 (GMT) Received: from d06av06.portsmouth.uk.ibm.com (d06av06.portsmouth.uk.ibm.com [9.149.37.217]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u2O8UBbP67043582 for ; Thu, 24 Mar 2016 08:30:11 GMT Received: from d06av06.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u2O8UBE9005820 for ; Thu, 24 Mar 2016 04:30:11 -0400 Received: from gondolin.boeblingen.de.ibm.com (dyn-9-152-224-197.boeblingen.de.ibm.com [9.152.224.197]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u2O8U5Sh005417 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 24 Mar 2016 04:30:11 -0400 From: Cornelia Huck To: peter.maydell@linaro.org Date: Thu, 24 Mar 2016 09:30:00 +0100 Message-Id: <1458808203-21339-12-git-send-email-cornelia.huck@de.ibm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1458808203-21339-1-git-send-email-cornelia.huck@de.ibm.com> References: <1458808203-21339-1-git-send-email-cornelia.huck@de.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16032408-0013-0000-0000-00000BD21995 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.109 Cc: qemu-devel@nongnu.org, agraf@suse.de, borntraeger@de.ibm.com, jfrei@linux.vnet.ibm.com, Cornelia Huck , "Eugene \(jno\) Dvurechenski" Subject: [Qemu-devel] [PULL for-2.6 11/14] pc-bios/s390-ccw: enable virtio-scsi X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "Eugene (jno) Dvurechenski" Make the code added before to work. Signed-off-by: Eugene (jno) Dvurechenski Signed-off-by: Cornelia Huck --- pc-bios/s390-ccw/Makefile | 2 +- pc-bios/s390-ccw/main.c | 8 +--- pc-bios/s390-ccw/virtio.c | 113 +++++++++++++++++++++++++++++++++------------- pc-bios/s390-ccw/virtio.h | 32 +++++++++++++ 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 11c5dd4..4208cb4 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) .PHONY : all clean build-all -OBJECTS = start.o main.o bootmap.o sclp-ascii.o virtio.o +OBJECTS = start.o main.o bootmap.o sclp-ascii.o virtio.o virtio-scsi.o CFLAGS += -fPIE -fno-stack-protector -ffreestanding -march=z900 CFLAGS += -fno-delete-null-pointer-checks -msoft-float LDFLAGS += -Wl,-pie -nostdlib diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 69a02fe..1c9e079 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -91,15 +91,11 @@ static void virtio_setup(uint64_t dev_info) } } - if (!found) { - panic("No virtio-blk device found!\n"); - } + IPL_assert(found, "No virtio device found"); virtio_setup_device(blk_schid); - if (!virtio_ipl_disk_is_valid()) { - panic("No valid hard disk detected.\n"); - } + IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected"); } int main(void) diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c index 4ab4d47..1d34e8c 100644 --- a/pc-bios/s390-ccw/virtio.c +++ b/pc-bios/s390-ccw/virtio.c @@ -10,6 +10,7 @@ #include "s390-ccw.h" #include "virtio.h" +#include "virtio-scsi.h" #define VRING_WAIT_REPLY_TIMEOUT 3 @@ -26,6 +27,8 @@ static VDev vdev = { .ring_area = ring_area, .wait_reply_timeout = VRING_WAIT_REPLY_TIMEOUT, .schid = { .one = 1 }, + .scsi_block_size = VIRTIO_SCSI_BLOCK_SIZE, + .blk_factor = 1, }; VDev *virtio_get_device(void) @@ -284,6 +287,8 @@ 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; @@ -317,6 +322,25 @@ 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; @@ -324,22 +348,30 @@ VirtioGDN virtio_guessed_disk_nature(void) void virtio_assume_scsi(void) { - vdev.guessed_disk_nature = VIRTIO_GDN_SCSI; switch (vdev.senseid.cu_model) { case VIRTIO_ID_BLOCK: - vdev.config.blk.blk_size = 512; + 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) { - vdev.guessed_disk_nature = VIRTIO_GDN_CDROM; switch (vdev.senseid.cu_model) { case VIRTIO_ID_BLOCK: - vdev.config.blk.blk_size = 2048; + 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; } } @@ -347,16 +379,19 @@ void virtio_assume_iso9660(void) 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; - vdev.config.blk.physical_block_exp = 0; - - /* this must be here to calculate code segment position */ - vdev.config.blk.geometry.heads = 15; - vdev.config.blk.geometry.sectors = 12; + 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) @@ -368,30 +403,13 @@ bool virtio_disk_is_scsi(void) case VIRTIO_ID_BLOCK: return (vdev.config.blk.geometry.heads == 255) && (vdev.config.blk.geometry.sectors == 63) - && (virtio_get_block_size() == 512); + && (virtio_get_block_size() == VIRTIO_SCSI_BLOCK_SIZE); + case VIRTIO_ID_SCSI: + return true; } return false; } -/* - * 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; -} - bool virtio_disk_is_eckd(void) { const int block_size = virtio_get_block_size(); @@ -404,6 +422,8 @@ bool virtio_disk_is_eckd(void) 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; } @@ -418,6 +438,8 @@ 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; } @@ -427,6 +449,9 @@ 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; } @@ -436,25 +461,33 @@ 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 / - (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); + 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) { - int i, cfg_size; + int i, cfg_size = 0; unsigned char status = VIRTIO_CONFIG_S_DRIVER_OK; + IPL_assert(virtio_is_supported(vdev->schid), "PE"); + /* device ID has been established now */ + vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ vdev->guessed_disk_nature = VIRTIO_GDN_NONE; @@ -466,6 +499,11 @@ static void virtio_setup_ccw(VDev *vdev) vdev->cmd_vr_idx = 0; cfg_size = sizeof(vdev->config.blk); break; + case VIRTIO_ID_SCSI: + vdev->nr_vqs = 3; + vdev->cmd_vr_idx = VR_REQUEST; + cfg_size = sizeof(vdev->config.scsi); + break; default: panic("Unsupported virtio device\n"); } @@ -511,6 +549,7 @@ void virtio_setup_device(SubChannelId schid) 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 @@ -519,6 +558,15 @@ void virtio_setup_device(SubChannelId schid) 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"); } @@ -535,6 +583,7 @@ bool virtio_is_supported(SubChannelId schid) if (vdev.senseid.cu_type == 0x3832) { switch (vdev.senseid.cu_model) { case VIRTIO_ID_BLOCK: + case VIRTIO_ID_SCSI: return true; } } diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h index 57c71a2..3c6e915 100644 --- a/pc-bios/s390-ccw/virtio.h +++ b/pc-bios/s390-ccw/virtio.h @@ -28,6 +28,7 @@ enum VirtioDevType { VIRTIO_ID_BLOCK = 2, VIRTIO_ID_CONSOLE = 3, VIRTIO_ID_BALLOON = 5, + VIRTIO_ID_SCSI = 8, }; typedef enum VirtioDevType VirtioDevType; @@ -224,12 +225,35 @@ extern uint64_t virtio_get_blocks(void); extern int virtio_read_many(ulong sector, void *load_addr, int sec_num); #define VIRTIO_SECTOR_SIZE 512 +#define VIRTIO_ISO_BLOCK_SIZE 2048 +#define VIRTIO_SCSI_BLOCK_SIZE 512 static inline ulong virtio_sector_adjust(ulong sector) { return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE); } +struct VirtioScsiConfig { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} __attribute__((packed)); +typedef struct VirtioScsiConfig VirtioScsiConfig; + +struct ScsiDevice { + uint16_t channel; /* Always 0 in QEMU */ + uint16_t target; /* will be scanned over */ + uint32_t lun; /* will be reported */ +}; +typedef struct ScsiDevice ScsiDevice; + struct VDev { int nr_vqs; VRing *vrings; @@ -241,7 +265,15 @@ struct VDev { SenseId senseid; union { VirtioBlkConfig blk; + VirtioScsiConfig scsi; } config; + ScsiDevice *scsi_device; + bool is_cdrom; + int scsi_block_size; + int blk_factor; + uint64_t scsi_last_block; + uint32_t scsi_dev_cyls; + uint8_t scsi_dev_heads; }; typedef struct VDev VDev;