From patchwork Mon Jun 6 16:04:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 98954 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E47A7B6F90 for ; Tue, 7 Jun 2011 02:47:43 +1000 (EST) Received: from localhost ([::1]:51740 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTcxo-0008Ec-BZ for incoming@patchwork.ozlabs.org; Mon, 06 Jun 2011 12:47:40 -0400 Received: from eggs.gnu.org ([140.186.70.92]:54659) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTcIa-0005u2-J0 for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:05:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QTcIW-0000Gk-Vl for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:05:03 -0400 Received: from mail-pw0-f45.google.com ([209.85.160.45]:42002) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTcIW-0000GS-KA for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:05:00 -0400 Received: by pwi6 with SMTP id 6so2335408pwi.4 for ; Mon, 06 Jun 2011 09:04:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:subject:date:message-id:x-mailer :in-reply-to:references; bh=Z77PtGKpnZHCt2iZslCeh3WPkPqxToSqafnHc5b8yJY=; b=ANj+jEZyCNOvDMR8ZzK9ywPkKeFdsRkmsfE+hCTEhOvOBZ56Yd9rtKkxQlMzCNuTm4 gXDTOjLKhVn49JT9DSKTnWMt5zzkDEBY/It8GGlWTRAo9YJ5QY8YSBglbAKdLJhYo6ko Z1y47PeOYiWQlnNtgpMqyooRY+vq8u8fH+CLw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; b=QVqe1SzgT5cnd2IKi1xNn50jTPHLY8BdJUkWtTeB6FUe3mNWUSLFiERysHpR0dmJd4 ClkRq+5HMq54/p5aolX0FOufISef69/zMbeQaw8NhD07oQqkNq/qPwjFyihTignG3jjQ x3v8zBBMeaVU/uCUqHpcgYHGK0Ja5VG91G8pA= Received: by 10.142.156.12 with SMTP id d12mr764666wfe.184.1307376298168; Mon, 06 Jun 2011 09:04:58 -0700 (PDT) Received: from localhost.localdomain (93-34-184-88.ip51.fastwebnet.it [93.34.184.88]) by mx.google.com with ESMTPS id c3sm3770633pbk.77.2011.06.06.09.04.55 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 06 Jun 2011 09:04:57 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 6 Jun 2011 18:04:13 +0200 Message-Id: <1307376262-1255-5-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1307376262-1255-1-git-send-email-pbonzini@redhat.com> References: <1307376262-1255-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.160.45 Subject: [Qemu-devel] [RFC PATCH v2 04/13] scsi: let a SCSIDevice have children devices 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This provides the infrastructure for simple devices to pick LUNs. Of course, this will not do anything until there is a device that can report the existence of those LUNs. Signed-off-by: Paolo Bonzini --- hw/esp.c | 4 +++- hw/lsi53c895a.c | 2 +- hw/scsi-bus.c | 15 +++++++++++++++ hw/scsi.h | 3 +++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index e47dfec..a821a0a 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -239,12 +239,14 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) { + SCSIDevice *dev; int32_t datalen; int lun; DPRINTF("do_busid_cmd: busid 0x%x\n", busid); lun = busid & 7; - s->current_req = scsi_req_new(s->current_dev, &s->busdev.qdev, 0, lun); + dev = scsi_find_lun(s->current_dev, lun, buf); + s->current_req = scsi_req_new(dev, &s->busdev.qdev, 0, lun); datalen = scsi_req_enqueue(s->current_req, buf); s->ti_size = datalen; if (datalen != 0) { diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 96b19f9..a908324 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -780,7 +780,7 @@ static void lsi_do_command(LSIState *s) s->command_complete = 0; id = (s->select_tag >> 8) & 0xf; - dev = s->bus.devs[id]; + dev = scsi_find_lun(s->bus.devs[id], s->current_lun, buf); if (!dev) { lsi_bad_selection(s, id); return; diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 24e91bf..b44f308 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -745,6 +745,21 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) return strdup(path); } +/* Simplified walk of the SCSI bus hierarchy, for devices that only support + one bus and only flat-space LUNs (typically 3-bit ones!). */ +SCSIDevice *scsi_find_lun(SCSIDevice *sdev, int lun, uint8_t *cdb) +{ + SCSIBus *sbus = sdev->children; + if (!sbus || + lun < 0 || + (lun == 0 && cdb[0] == REPORT_LUNS) || + lun >= sbus->ndev || sbus->devs[lun] == NULL) { + return sdev; + } else { + return sbus->devs[lun]; + } +} + /* Decode the bus and level parts of a LUN, as defined in the SCSI architecture model. If false is returned, the LUN could not be parsed. If true is return, "*bus" and "*target" identify the next two steps in the diff --git a/hw/scsi.h b/hw/scsi.h index fa3ca9b..8d5737b 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -59,6 +59,7 @@ struct SCSIDevice uint32_t id; BlockConf conf; SCSIDeviceInfo *info; + SCSIBus *children; QTAILQ_HEAD(, SCSIRequest) requests; int blocksize; int type; @@ -152,7 +153,9 @@ extern const struct SCSISense sense_code_LUN_FAILURE; int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed); int scsi_sense_valid(SCSISense sense); + SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun, int *lun); +SCSIDevice *scsi_find_lun(SCSIDevice *sdev, int lun, uint8_t *cdb); SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, DeviceState *initiator, uint32_t tag, uint32_t lun);