From patchwork Mon Jun 6 16:04:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 98972 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 586ECB6F99 for ; Tue, 7 Jun 2011 03:57:40 +1000 (EST) Received: from localhost ([::1]:56534 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTe3U-0001ZY-TE for incoming@patchwork.ozlabs.org; Mon, 06 Jun 2011 13:57:37 -0400 Received: from eggs.gnu.org ([140.186.70.92]:54625) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTcIV-0005rb-PS for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:05:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QTcIS-0000G0-HA for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:04:59 -0400 Received: from mail-pz0-f45.google.com ([209.85.210.45]:51045) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTcIS-0000FC-0r for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:04:56 -0400 Received: by mail-pz0-f45.google.com with SMTP id 30so2107087pzk.4 for ; Mon, 06 Jun 2011 09:04:55 -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=cvQifEnIdatT+6EwpXau6jLXqQxLdDA0o6jRtxZVD0Y=; b=lzVVRUg7otBRRnVzeIGCtcH3dOKZ8DpSdeUIxiNR25DXzBzEA53w/hWuUFem7Bd0FT 0j693sFGfqjNGZiSrvvCjhYgJqDddB9OVeUUXR67M4ty2LGcqJA8uir0mzdMVFFp8hqf wHpFE0HfD7ifQ4zf1v15YKSeYuvVBz0eoR1bo= 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=NM42S0a7yJm2xYJtV3uEhJhr+GPbKedEb/PpqWnX69EMlzPVg886kTwW+iyVhaitWt IS9eDySP4+NhsNK2cqF4DV8JY8MVys51yaypYsHPtkPRNdovQpxHADx8+BC9OmFX7W/U /NnPgR26l1L1F8+DyxjyifNkmXZMrRZ9YXD2g= Received: by 10.68.66.137 with SMTP id f9mr1877791pbt.407.1307376295594; Mon, 06 Jun 2011 09:04:55 -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.53 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 06 Jun 2011 09:04:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 6 Jun 2011 18:04:12 +0200 Message-Id: <1307376262-1255-4-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.210.45 Subject: [Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIRequest 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 Rather than relaying requests across multiple levels, I'm just skipping the intermediate layers after the LUN has been parsed, and letting the device know the bus which ultimately knows how to process the request. Signed-off-by: Paolo Bonzini --- hw/esp.c | 6 +++--- hw/lsi53c895a.c | 8 ++++---- hw/scsi-bus.c | 15 +++++++++------ hw/scsi-disk.c | 6 +++--- hw/scsi-generic.c | 5 +++-- hw/scsi.h | 21 ++++++++++++++++----- hw/spapr_vscsi.c | 6 +++--- hw/usb-msd.c | 6 +++--- 8 files changed, 44 insertions(+), 29 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 6d3f5d2..e47dfec 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -190,7 +190,7 @@ static void esp_dma_enable(void *opaque, int irq, int level) static void esp_request_cancelled(SCSIRequest *req) { - ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->initiator); if (req == s->current_req) { scsi_req_unref(s->current_req); @@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) DPRINTF("do_busid_cmd: busid 0x%x\n", busid); lun = busid & 7; - s->current_req = scsi_req_new(s->current_dev, 0, lun); + s->current_req = scsi_req_new(s->current_dev, &s->busdev.qdev, 0, lun); datalen = scsi_req_enqueue(s->current_req, buf); s->ti_size = datalen; if (datalen != 0) { @@ -397,7 +397,7 @@ static void esp_do_dma(ESPState *s) static void esp_command_complete(SCSIRequest *req, uint32_t status) { - ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->initiator); DPRINTF("SCSI Command complete\n"); if (s->ti_size != 0) { diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 83084b6..96b19f9 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -660,7 +660,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag) static void lsi_request_cancelled(SCSIRequest *req) { - LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); + LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->initiator); lsi_request *p; if (s->current && req == s->current->req) { @@ -715,7 +715,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len) /* Callback to indicate that the SCSI layer has completed a command. */ static void lsi_command_complete(SCSIRequest *req, uint32_t status) { - LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); + LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->initiator); int out; out = (s->sstat1 & PHASE_MASK) == PHASE_DO; @@ -789,8 +789,8 @@ static void lsi_do_command(LSIState *s) assert(s->current == NULL); s->current = qemu_mallocz(sizeof(lsi_request)); s->current->tag = s->select_tag; - s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun); - + s->current->req = scsi_req_new(dev, &s->dev.qdev, s->current->tag, + s->current_lun); n = scsi_req_enqueue(s->current->req, buf); if (n) { if (n > 0) { diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 3b80541..24e91bf 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -143,14 +143,16 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus) return res; } -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun) +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, DeviceState *initiator, + uint32_t tag, uint32_t lun) { SCSIRequest *req; req = qemu_mallocz(size); req->refcount = 1; - req->bus = scsi_bus_from_device(d); + req->bus = scsi_bus_from_device(d, initiator); req->dev = d; + req->initiator = initiator; req->tag = tag; req->lun = lun; req->status = -1; @@ -158,9 +160,10 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l return req; } -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun) +SCSIRequest *scsi_req_new(SCSIDevice *d, DeviceState *initiator, + uint32_t tag, uint32_t lun) { - return d->info->alloc_req(d, tag, lun); + return d->info->alloc_req(d, initiator, tag, lun); } uint8_t *scsi_req_get_buf(SCSIRequest *req) @@ -724,8 +727,8 @@ void scsi_device_purge_requests(SCSIDevice *sdev) static char *scsibus_get_fw_dev_path(DeviceState *dev) { - SCSIDevice *d = (SCSIDevice*)dev; - SCSIBus *bus = scsi_bus_from_device(d); + SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev); + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); char path[100]; int i; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 76c1748..87e5ac8 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -80,14 +80,14 @@ struct SCSIDiskState static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type); static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf); -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, - uint32_t lun) +static SCSIRequest *scsi_new_request(SCSIDevice *d, DeviceState *initiator, + uint32_t tag, uint32_t lun) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); SCSIRequest *req; SCSIDiskReq *r; - req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun); + req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, initiator, tag, lun); r = DO_UPCAST(SCSIDiskReq, req, req); r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE); return req; diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index b67e154..94aca18 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -96,11 +96,12 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len) return size; } -static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) +static SCSIRequest *scsi_new_request(SCSIDevice *d, DeviceState *initiator, + uint32_t tag, uint32_t lun) { SCSIRequest *req; - req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun); + req = scsi_req_alloc(sizeof(SCSIGenericReq), d, initiator, tag, lun); return req; } diff --git a/hw/scsi.h b/hw/scsi.h index 4ba1801..fa3ca9b 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -35,6 +35,7 @@ typedef struct SCSISense { struct SCSIRequest { SCSIBus *bus; + DeviceState *initiator; SCSIDevice *dev; uint32_t refcount; uint32_t tag; @@ -73,7 +74,8 @@ struct SCSIDeviceInfo { int (*init)(SCSIDevice *dev); void (*destroy)(SCSIDevice *s); void (*reset)(SCSIDevice *s); - SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun); + SCSIRequest *(*alloc_req)(SCSIDevice *s, DeviceState *initiator, + uint32_t tag, uint32_t lun); void (*free_req)(SCSIRequest *req); int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); void (*read_data)(SCSIRequest *req); @@ -103,9 +105,16 @@ void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, const SCSIBusOps *ops); void scsi_qdev_register(SCSIDeviceInfo *info); -static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) +static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d, DeviceState *initiator) { - return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); + SCSIBus *bus; + DeviceState *dev; + dev = &d->qdev; + do { + bus = DO_UPCAST(SCSIBus, qbus, dev->parent_bus); + dev = bus->qbus.parent; + } while (dev != initiator); + return bus; } SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, @@ -145,8 +154,10 @@ 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); -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); -SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun); +SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, DeviceState *initiator, + uint32_t tag, uint32_t lun); +SCSIRequest *scsi_req_new(SCSIDevice *d, DeviceState *initiator, uint32_t tag, + uint32_t lun); int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf); void scsi_req_free(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 038b9e4..5b5fa87 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -475,7 +475,7 @@ static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req) /* Callback to indicate that the SCSI layer has completed a transfer. */ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len) { - VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); + VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->initiator); vscsi_req *req = vscsi_find_req(s, sreq); uint8_t *buf; int rc = 0; @@ -561,7 +561,7 @@ static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status) static void vscsi_request_cancelled(SCSIRequest *sreq) { - VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); + VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->initiator); vscsi_req *req = vscsi_find_req(s, sreq); vscsi_put_req(s, req); @@ -649,7 +649,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) } req->lun = lun; - req->sreq = scsi_req_new(sdev, req->qtag, lun); + req->sreq = scsi_req_new(sdev, &s->vdev.qdev, req->qtag, lun); n = scsi_req_enqueue(req->sreq, srp->cmd.cdb); dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n", diff --git a/hw/usb-msd.c b/hw/usb-msd.c index c59797b..195089c 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -212,7 +212,7 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p) static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) { - MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->initiator); USBPacket *p = s->packet; if (req->tag != s->tag) { @@ -275,7 +275,7 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status) static void usb_msd_request_cancelled(SCSIRequest *req) { - MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->initiator); if (req == s->req) { scsi_req_unref(s->req); @@ -386,7 +386,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; s->scsi_len = 0; - s->req = scsi_req_new(s->scsi_dev, s->tag, 0); + s->req = scsi_req_new(s->scsi_dev, &s->dev.qdev, s->tag, 0); scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */