From patchwork Tue May 3 16:50:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 93847 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 BC05DB6EF1 for ; Wed, 4 May 2011 02:53:20 +1000 (EST) Received: from localhost ([::1]:36548 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHIqc-0007oE-0W for incoming@patchwork.ozlabs.org; Tue, 03 May 2011 12:53:18 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42929) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHIo7-00046g-Fu for qemu-devel@nongnu.org; Tue, 03 May 2011 12:50:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QHIo6-0000DF-0H for qemu-devel@nongnu.org; Tue, 03 May 2011 12:50:43 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:35653) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QHIo5-0000Bg-Lc for qemu-devel@nongnu.org; Tue, 03 May 2011 12:50:41 -0400 Received: by mail-ww0-f53.google.com with SMTP id 40so289608wwj.10 for ; Tue, 03 May 2011 09:50:41 -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=pgjyFcahBQZ1N+sDj/Q6Av2V6HOMBGacfVQgrwbraCs=; b=aQ3dhT9Etq/yoNeKNmUsCgTTi9SFsMC7tQWSa6+Xj7URG0fQmPYfuuKU3lr9FmCsC3 xLWeqv5RVsQG+eiMANmuZgvrZ9waUxXNP7exOnSqc4F8InmNJ1fswbidNDhpleOwkH8v UJ8jpK9kA/BoxrRRffX3K8IJUlVTFBSsMhl8w= 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=T0L73t7ZIjxXfPbWaObBXXcm0ArDP7hP8aUDpDjwWi3xN/TBYaU4FCaAz7uCFrwTo5 DKPT0UDPgdPVKm5w9nHAElGQ8CUKopSA5Jv7wSpnN6w/8tJ4ETOBKtuurejdB+aQ2CQL PspWG/2lr1eOTa2Ed9zhIkoURZ0GdmFAp0aic= Received: by 10.227.100.212 with SMTP id z20mr65122wbn.27.1304441441203; Tue, 03 May 2011 09:50:41 -0700 (PDT) Received: from localhost.localdomain (93-34-184-88.ip51.fastwebnet.it [93.34.184.88]) by mx.google.com with ESMTPS id bs4sm167243wbb.52.2011.05.03.09.50.40 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 03 May 2011 09:50:40 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 3 May 2011 18:50:16 +0200 Message-Id: <1304441432-27434-5-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1304441432-27434-1-git-send-email-pbonzini@redhat.com> References: <1304441432-27434-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.53 Subject: [Qemu-devel] [PATCH 04/20] scsi: introduce SCSIBusOps 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 There are more operations than a SCSI bus can handle, besides completing commands. One example, which this series will introduce, is cleaning up after a request is cancelled. More long term, a "SCSI bus" can represent the LUNs attached to a target; in this case, while all commands will ultimately reach a logical unit, it is the target who is in charge of answering REPORT LUNs. Signed-off-by: Paolo Bonzini --- hw/esp.c | 6 +++++- hw/lsi53c895a.c | 6 +++++- hw/scsi-bus.c | 12 ++++++------ hw/scsi-generic.c | 2 +- hw/scsi.h | 13 +++++++------ hw/spapr_vscsi.c | 6 +++++- hw/usb-msd.c | 6 +++++- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index fa9d2a2..d8bba7a 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -714,6 +714,10 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, *dma_enable = qdev_get_gpio_in(dev, 1); } +static struct SCSIBusOps esp_scsi_ops = { + .complete = esp_command_complete +}; + static int esp_init1(SysBusDevice *dev) { ESPState *s = FROM_SYSBUS(ESPState, dev); @@ -728,7 +732,7 @@ static int esp_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2); - scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete); + scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops); return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index e4b51a8..56329c2 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -2214,6 +2214,10 @@ static int lsi_scsi_uninit(PCIDevice *d) return 0; } +static struct SCSIBusOps lsi_scsi_ops = { + .complete = lsi_command_complete +}; + static int lsi_scsi_init(PCIDevice *dev) { LSIState *s = DO_UPCAST(LSIState, dev, dev); @@ -2251,7 +2255,7 @@ static int lsi_scsi_init(PCIDevice *dev) PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); QTAILQ_INIT(&s->queue); - scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); + scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops); if (!dev->qdev.hotplugged) { return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 0afe3fb..63d9a68 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -21,13 +21,13 @@ static int next_scsi_bus; /* Create a scsi bus, and attach devices to it. */ void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, - scsi_completionfn complete) + SCSIBusOps *ops) { qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL); bus->busnr = next_scsi_bus++; bus->tcq = tcq; bus->ndev = ndev; - bus->complete = complete; + bus->ops = *ops; bus->qbus.allow_hotplug = 1; } @@ -498,7 +498,7 @@ static const char *scsi_command_name(uint8_t cmd) void scsi_req_data(SCSIRequest *req, int len) { trace_scsi_req_data(req->dev->id, req->lun, req->tag, len); - req->bus->complete(req->bus, SCSI_REASON_DATA, req->tag, len); + req->bus->ops.complete(req->bus, SCSI_REASON_DATA, req->tag, len); } void scsi_req_print(SCSIRequest *req) @@ -533,9 +533,9 @@ void scsi_req_complete(SCSIRequest *req) { assert(req->status != -1); scsi_req_dequeue(req); - req->bus->complete(req->bus, SCSI_REASON_DONE, - req->tag, - req->status); + req->bus->ops.complete(req->bus, SCSI_REASON_DONE, + req->tag, + req->status); } static char *scsibus_get_fw_dev_path(DeviceState *dev) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index e4f1f30..3db734a 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -335,7 +335,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, s->senselen = 7; s->driver_status = SG_ERR_DRIVER_SENSE; bus = scsi_bus_from_device(d); - bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION); + bus->ops.complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION); return 0; } diff --git a/hw/scsi.h b/hw/scsi.h index 7c09f32..d1753f9 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -16,10 +16,9 @@ enum scsi_reason { }; typedef struct SCSIBus SCSIBus; +typedef struct SCSIBusOps SCSIBusOps; typedef struct SCSIDevice SCSIDevice; typedef struct SCSIDeviceInfo SCSIDeviceInfo; -typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg); enum SCSIXferMode { SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */ @@ -74,20 +73,22 @@ struct SCSIDeviceInfo { uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag); }; -typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, - int unit); +struct SCSIBusOps { + void (*complete)(SCSIBus *bus, int reason, uint32_t tag, uint32_t arg); +}; + struct SCSIBus { BusState qbus; int busnr; int tcq, ndev; - scsi_completionfn complete; + SCSIBusOps ops; SCSIDevice *devs[MAX_SCSI_DEVS]; }; void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, - scsi_completionfn complete); + SCSIBusOps *ops); void scsi_qdev_register(SCSIDeviceInfo *info); static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 9928334..9f5c154 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -907,6 +907,10 @@ static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data) return 0; } +static struct SCSIBusOps vscsi_scsi_ops = { + .complete = vscsi_command_complete +}; + static int spapr_vscsi_init(VIOsPAPRDevice *dev) { VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev); @@ -923,7 +927,7 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev) dev->crq.SendFunc = vscsi_do_crq; scsi_bus_new(&s->bus, &dev->qdev, 1, VSCSI_REQ_LIMIT, - vscsi_command_complete); + &vscsi_scsi_ops); if (!dev->qdev.hotplugged) { scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 947fd3f..03317a2 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -486,6 +486,10 @@ static void usb_msd_password_cb(void *opaque, int err) qdev_unplug(&s->dev.qdev); } +static struct SCSIBusOps usb_msd_scsi_ops = { + .complete = usb_msd_command_complete +}; + static int usb_msd_initfn(USBDevice *dev) { MSDState *s = DO_UPCAST(MSDState, dev, dev); @@ -515,7 +519,7 @@ static int usb_msd_initfn(USBDevice *dev) } usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete); + scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, &usb_msd_scsi_ops); s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable); if (!s->scsi_dev) { return -1;