All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: Alexander Bezzubikov <zuban32s@gmail.com>, qemu-devel@nongnu.org
Cc: jsnow@redhat.com, abezzubikov@ispras.ru
Subject: Re: [Qemu-devel] [PATCH RFC v3 4/5] ATAPI-SCSI bridge functions created an can be used by bridge
Date: Wed, 19 Aug 2015 13:08:04 +0200	[thread overview]
Message-ID: <55D46394.2030106@suse.de> (raw)
In-Reply-To: <1439981843-2860-5-git-send-email-abezzubikov@ispras.ru>

On 08/19/2015 12:57 PM, Alexander Bezzubikov wrote:
> ide: bridge functions created
> ide: Makefile corrected due to bridge creation
> scsi: added function to enable bridge send SCSI requests
> ide: bridge can now forward requests to SCSI
> ide: bridge functions assigned to SCSIBusInfo
> Signed-off-by: Alexander Bezzubikov <abezzubikov@ispras.ru>
> ---
>  hw/ide/Makefile.objs   |   2 +-
>  hw/ide/atapi.c         |  16 +++++++
>  hw/ide/bridge.c        | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/ide/bridge.h        |   1 +
>  hw/ide/internal.h      |   2 +
>  hw/ide/qdev.c          |   4 +-
>  hw/scsi/scsi-disk.c    |  43 +++++++++++++++++++
>  include/hw/scsi/scsi.h |   3 ++
>  8 files changed, 182 insertions(+), 3 deletions(-)
>  create mode 100644 hw/ide/bridge.c
> 
> diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs
> index 729e9bd..f54f275 100644
> --- a/hw/ide/Makefile.objs
> +++ b/hw/ide/Makefile.objs
> @@ -1,4 +1,4 @@
> -common-obj-$(CONFIG_IDE_CORE) += core.o atapi.o
> +common-obj-$(CONFIG_IDE_CORE) += core.o atapi.o bridge.o
>  common-obj-$(CONFIG_IDE_QDEV) += qdev.o
>  common-obj-$(CONFIG_IDE_PCI) += pci.o
>  common-obj-$(CONFIG_IDE_ISA) += isa.o
> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
> index f6135e1..3eb56e2 100644
> --- a/hw/ide/atapi.c
> +++ b/hw/ide/atapi.c
> @@ -1253,6 +1253,22 @@ void ide_atapi_cmd(IDEState *s)
>          return;
>      }
>  
> +    if (s->drive_kind == IDE_BRIDGE) {
> +        IDEDevice *dev = s->bus->master;
> +        SCSIDevice *scsi_dev = scsi_device_find(&dev->scsi_bus, 0, 0, 0);
> +        s->cur_req = scsi_new_request_from_bridge(scsi_dev, 0, 0, buf, NULL);
> +
> +        /* Necessary to prevent ide from reading while data isn't ready */
> +        if (buf[0] == READ_10) {
> +            s->status |= BUSY_STAT;
> +        }
> +
> +        if (scsi_req_enqueue(s->cur_req)) {
> +            scsi_req_continue(s->cur_req);
> +        }
> +        return;
> +    }
> +
>      /* Execute the command */
>      if (atapi_cmd_table[s->io_buffer[0]].handler) {
>          atapi_cmd_table[s->io_buffer[0]].handler(s, buf);
> diff --git a/hw/ide/bridge.c b/hw/ide/bridge.c
> new file mode 100644
> index 0000000..2e93311
> --- /dev/null
> +++ b/hw/ide/bridge.c
> @@ -0,0 +1,114 @@
> +#include "hw/ide/bridge.h"
> +
> +void ide_bridge_do_transfer(IDEState *s)
> +{
> +    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, s->cur_req);
> +
> +    if (r->buflen > 0) {
> +        int size = r->buflen;
> +
> +        int byte_count_limit = s->lcyl | (s->hcyl << 8);
> +        if (byte_count_limit == 0xffff) {
> +            byte_count_limit--;
> +        }
> +        if (size > byte_count_limit) {
> +            /* byte count limit must be even if this case */
> +            if (byte_count_limit & 1) {
> +                byte_count_limit--;
> +            }
> +            size = byte_count_limit;
> +        }
> +        s->lcyl = size;
> +        s->hcyl = size >> 8;
> +        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
> +
> +        int offset = (r->buflen == r->qiov.size) ? 0 : r->qiov.size - r->buflen;
> +        r->buflen -= size;
> +
> +        ide_transfer_start(s, s->io_buffer + offset, size,
> +                           ide_bridge_do_transfer);
> +        ide_set_irq(s->bus);
> +    } else {
> +        scsi_req_complete(s->cur_req, GOOD);
> +    }
> +}
> +
> +static void ide_bridge_dma_complete(void *opaque, int ret)
> +{
> +    IDEState *s = opaque;
> +
> +    s->io_buffer_size = s->bus->dma->iov.iov_len;
> +    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
> +    s->bus->dma->ops->rw_buf(s->bus->dma, 1);
> +    scsi_req_complete(s->cur_req, GOOD);
> +
> +    s->status = READY_STAT | SEEK_STAT;
> +
> +    ide_set_irq(s->bus);
> +    ide_set_inactive(s, false);
> +}
> +
> +void ide_bridge_start_transfer(SCSIRequest *req, uint32_t len)
> +{
> +    IDEDevice *dev = IDE_DEVICE(req->bus->qbus.parent);
> +    IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
> +    IDEState *s = bus->ifs;
> +    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
> +
> +    int cmd = req->cmd.buf[0];
> +    if (cmd == READ_10) {
> +        if (s->feature & 1) {
> +            s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
> +            qemu_iovec_clone(&s->bus->dma->qiov, &r->qiov, NULL);
> +            qemu_iovec_to_buf(&r->qiov, 0, s->io_buffer, r->qiov.size);
> +        } else {
> +            qemu_iovec_to_buf(&r->qiov, 0, s->io_buffer, r->qiov.size);
> +        }
> +    } else {
> +        if (cmd == INQUIRY) {
> +            len = 36;
> +        }
> +        r->iov.iov_len = len;
> +        qemu_iovec_concat_iov(&r->qiov, &r->iov, len, 0, len);
> +        qemu_iovec_to_buf(&r->qiov, 0, s->io_buffer, r->qiov.size);
> +    }
> +
> +    s->io_buffer_index = 0;
> +    s->status = READY_STAT | SEEK_STAT;
> +
> +    if (cmd != TEST_UNIT_READY && cmd != ALLOW_MEDIUM_REMOVAL) {
> +        if (s->feature & 1) {
> +            s->io_buffer_index = 0;
> +            s->bus->retry_unit = s->unit;
> +            s->bus->retry_sector_num = ide_get_sector(s);
> +            s->bus->retry_nsector = s->nsector;
> +
> +            s->bus->dma->iov.iov_base = (void *)(s->io_buffer);
> +            s->bus->dma->iov.iov_len = r->qiov.size;
> +
> +            if (cmd != READ_10) {
> +                s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
> +            }
> +
> +            if (s->bus->dma->ops->start_dma) {
> +                s->bus->dma->ops->start_dma(s->bus->dma, s,
> +                                            ide_bridge_dma_complete);
> +            }
> +        } else {
> +            r->buflen = r->qiov.size;
> +            ide_bridge_do_transfer(s);
> +        }
> +    } else {
> +        scsi_req_complete(req, GOOD);
> +    }
> +}
> +
> +void ide_bridge_complete(SCSIRequest *req, uint32_t status, size_t resid)
> +{
> +    IDEDevice *dev = IDE_DEVICE(req->bus->qbus.parent);
> +    IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
> +    IDEState *s = bus->ifs;
> +
> +    ide_atapi_cmd_ok(s);
> +    ide_set_irq(s->bus);
> +}
> diff --git a/hw/ide/bridge.h b/hw/ide/bridge.h
> index dca5d73..59f2f25 100644
> --- a/hw/ide/bridge.h
> +++ b/hw/ide/bridge.h
> @@ -5,5 +5,6 @@
>  
>  void ide_bridge_start_transfer(SCSIRequest *req, uint32_t len);
>  void ide_bridge_complete(SCSIRequest *req, uint32_t status, size_t resid);
> +void ide_bridge_do_transfer(IDEState *s);
>  
>  #endif
> diff --git a/hw/ide/internal.h b/hw/ide/internal.h
> index 79c85be..fd385bc 100644
> --- a/hw/ide/internal.h
> +++ b/hw/ide/internal.h
> @@ -429,6 +429,8 @@ struct IDEState {
>      uint8_t *smart_selftest_data;
>      /* AHCI */
>      int ncq_queues;
> +    /* ATAPI-SCSI bridge */
> +    SCSIRequest *cur_req;
>  };
>  
>  struct IDEDMAOps {
As discussed on the list, can you rename 'cur_req' to 'scsi_req' ?

Thanks.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

  reply	other threads:[~2015-08-19 11:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-19 10:57 [Qemu-devel] [PATCH RFC v3 0/5] QEMU ATAPI-SCSI bridge GSoC project Alexander Bezzubikov
2015-08-19 10:57 ` [Qemu-devel] [PATCH RFC v3 1/5] ide: ATAPI-SCSI bridge TypeInfo and init function created Alexander Bezzubikov
2015-08-19 10:57 ` [Qemu-devel] [PATCH RFC v3 2/5] scsi: SCSIDiskReq declaration moved to header Alexander Bezzubikov
2015-08-19 10:57 ` [Qemu-devel] [PATCH RFC v3 3/5] ide: necessary checks corrected to treat ATAPI-SCSI bridge as CDROM Alexander Bezzubikov
2015-08-19 10:57 ` [Qemu-devel] [PATCH RFC v3 4/5] ATAPI-SCSI bridge functions created an can be used by bridge Alexander Bezzubikov
2015-08-19 11:08   ` Hannes Reinecke [this message]
2015-08-19 10:57 ` [Qemu-devel] [PATCH RFC v3 5/5] ide: ATAPI-SCSI bridge transfer is treated as PIO Alexander Bezzubikov
2015-08-19 11:08 ` [Qemu-devel] [PATCH RFC v3 0/5] QEMU ATAPI-SCSI bridge GSoC project Hannes Reinecke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55D46394.2030106@suse.de \
    --to=hare@suse.de \
    --cc=abezzubikov@ispras.ru \
    --cc=jsnow@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=zuban32s@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.