From patchwork Thu Oct 13 11:03:48 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 119511 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 370A5B6F85 for ; Fri, 14 Oct 2011 00:28:17 +1100 (EST) Received: from localhost ([::1]:49647 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1REJ6b-0007vI-A3 for incoming@patchwork.ozlabs.org; Thu, 13 Oct 2011 07:05:41 -0400 Received: from eggs.gnu.org ([140.186.70.92]:55365) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1REJ5o-0006W9-Qi for qemu-devel@nongnu.org; Thu, 13 Oct 2011 07:04:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1REJ5l-0004FZ-M0 for qemu-devel@nongnu.org; Thu, 13 Oct 2011 07:04:52 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:61406) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1REJ5l-00048s-C0 for qemu-devel@nongnu.org; Thu, 13 Oct 2011 07:04:49 -0400 Received: by mail-wy0-f173.google.com with SMTP id 22so1888325wyh.4 for ; Thu, 13 Oct 2011 04:04:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=okkZBXwgscTraalu/GlySefOAGURX3bWxSVMeHHQJDA=; b=FsSMskD9pQqeN4kFPRu8fCR68IKhI8BYNvHp4/5Qz6NBiGZrVuszzrHRNHISycDpHy ARYRE8jWJPFw1dvsjl2KGFhs5JxwuBvaP+2jv577j8q8vhLjaIjrbcS+Td58yxP+nAUy KLmqOzD+QC1vzX48lYgLEo2X9rdfo777fXTvQ= Received: by 10.216.134.166 with SMTP id s38mr1053245wei.71.1318503888511; Thu, 13 Oct 2011 04:04:48 -0700 (PDT) Received: from localhost.localdomain (nat-pool-mxp-t.redhat.com. [209.132.186.18]) by mx.google.com with ESMTPS id g20sm5290288wbp.13.2011.10.13.04.04.47 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 13 Oct 2011 04:04:48 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 13 Oct 2011 13:03:48 +0200 Message-Id: <1318503845-11473-19-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1318503845-11473-1-git-send-email-pbonzini@redhat.com> References: <1318503845-11473-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.173 Subject: [Qemu-devel] [PATCH 18/35] scsi: add channel to addressing 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 also requires little more than adding the new argument to scsi_device_find, and the qdev property. All devices by default end up on channel 0. Signed-off-by: Paolo Bonzini --- hw/esp.c | 4 ++-- hw/lsi53c895a.c | 4 ++-- hw/scsi-bus.c | 24 +++++++++++++++--------- hw/scsi.h | 5 +++-- hw/spapr_vscsi.c | 9 +++------ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 0ebc181..9b97a84 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -217,7 +217,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) s->async_len = 0; } - s->current_dev = scsi_device_find(&s->bus, target, 0); + s->current_dev = scsi_device_find(&s->bus, 0, target, 0); if (!s->current_dev) { // No such drive s->rregs[ESP_RSTAT] = 0; @@ -236,7 +236,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) trace_esp_do_busid_cmd(busid); lun = busid & 7; - s->current_dev = scsi_device_find(&s->bus, s->current_dev->id, lun); + s->current_dev = scsi_device_find(&s->bus, 0, s->current_dev->id, lun); s->current_req = scsi_req_new(s->current_dev, 0, lun, buf, NULL); datalen = scsi_req_enqueue(s->current_req); s->ti_size = datalen; diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index d26e442..2984cea 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -767,7 +767,7 @@ static void lsi_do_command(LSIState *s) s->command_complete = 0; id = (s->select_tag >> 8) & 0xf; - dev = scsi_device_find(&s->bus, id, s->current_lun); + dev = scsi_device_find(&s->bus, 0, id, s->current_lun); if (!dev) { lsi_bad_selection(s, id); return; @@ -1198,7 +1198,7 @@ again: } s->sstat0 |= LSI_SSTAT0_WOA; s->scntl1 &= ~LSI_SCNTL1_IARB; - if (!scsi_device_find(&s->bus, id, 0)) { + if (!scsi_device_find(&s->bus, 0, id, 0)) { lsi_bad_selection(s, id); break; } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index cec06db..bdd6e94 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = { .size = sizeof(SCSIBus), .get_fw_dev_path = scsibus_get_fw_dev_path, .props = (Property[]) { + DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), DEFINE_PROP_END_OF_LIST(), @@ -40,6 +41,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) SCSIDevice *d; int rc = -1; + if (dev->channel > bus->info->max_channel) { + error_report("bad scsi channel id: %d", dev->channel); + goto err; + } if (dev->id != -1 && dev->id > bus->info->max_target) { error_report("bad scsi device id: %d", dev->id); goto err; @@ -51,7 +56,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) dev->lun = 0; } do { - d = scsi_device_find(bus, ++id, dev->lun); + d = scsi_device_find(bus, dev->channel, ++id, dev->lun); } while (d && d->lun == dev->lun && id <= bus->info->max_target); if (id > bus->info->max_target) { error_report("no free target"); @@ -61,7 +66,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) } else if (dev->lun == -1) { int lun = -1; do { - d = scsi_device_find(bus, dev->id, ++lun); + d = scsi_device_find(bus, dev->channel, dev->id, ++lun); } while (d && d->lun == lun && lun < bus->info->max_lun); if (lun > bus->info->max_lun) { error_report("no free lun"); @@ -69,7 +74,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) } dev->lun = lun; } else { - d = scsi_device_find(bus, dev->id, dev->lun); + d = scsi_device_find(bus, dev->channel, dev->id, dev->lun); if (dev->lun == d->lun && dev != d) { qdev_free(&d->qdev); } @@ -203,7 +208,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { DeviceState *qdev; int i, len, n; - int id; + int channel, id; bool found_lun0; if (r->req.cmd.xfer < 16) { @@ -212,13 +217,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) if (r->req.cmd.buf[2] > 2) { return false; } + channel = r->req.dev->channel; id = r->req.dev->id; found_lun0 = false; n = 0; QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); - if (dev->id == id) { + if (dev->channel == channel && dev->id == id) { if (dev->lun == 0) { found_lun0 = true; } @@ -240,7 +246,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); - if (dev->id == id) { + if (dev->channel == channel && dev->id == id) { store_lun(&r->buf[i], dev->lun); i += 8; } @@ -1203,12 +1209,12 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) char path[100]; snprintf(path, sizeof(path), "%s@%d:%d:%d", qdev_fw_name(dev), - 0, d->id, d->lun); + d->channel, d->id, d->lun); return strdup(path); } -SCSIDevice *scsi_device_find(SCSIBus *bus, int id, int lun) +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) { DeviceState *qdev; SCSIDevice *target_dev = NULL; @@ -1216,7 +1222,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int id, int lun) QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); - if (dev->id == id) { + if (dev->channel == channel && dev->id == id) { if (dev->lun == lun) { return dev; } diff --git a/hw/scsi.h b/hw/scsi.h index 401d8d3..c8649cf 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -66,6 +66,7 @@ struct SCSIDevice uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; QTAILQ_HEAD(, SCSIRequest) requests; + uint32_t channel; uint32_t lun; int blocksize; int type; @@ -99,7 +100,7 @@ struct SCSIDeviceInfo { struct SCSIBusInfo { int tcq; - int max_target, max_lun; + int max_channel, max_target, max_lun; void (*transfer_data)(SCSIRequest *req, uint32_t arg); void (*complete)(SCSIRequest *req, uint32_t arg); void (*cancel)(SCSIRequest *req); @@ -194,6 +195,6 @@ void scsi_req_abort(SCSIRequest *req, int status); void scsi_req_cancel(SCSIRequest *req); void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); -SCSIDevice *scsi_device_find(SCSIBus *bus, int target, int lun); +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); #endif diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 334b2e6..2f9cbc8 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -160,11 +160,7 @@ retry: abort(); } - if (channel) { - *lun = -1; - return NULL; - } - return scsi_device_find (bus, id, *lun); + return scsi_device_find (bus, channel, id, *lun); } static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, @@ -892,7 +888,8 @@ static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data) static const struct SCSIBusInfo vscsi_scsi_info = { .tcq = true, - .max_target = 63, /* logical unit addressing format */ + .max_channel = 7, /* logical unit addressing format */ + .max_target = 63, .max_lun = 31, .transfer_data = vscsi_transfer_data,