qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH][v9] megasas: LSI Megaraid SAS HBA emulation


From: Andreas Färber
Subject: Re: [Qemu-devel] [PATCH][v9] megasas: LSI Megaraid SAS HBA emulation
Date: Fri, 13 Jan 2012 17:54:38 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111220 Thunderbird/9.0

Am 13.01.2012 12:19, schrieb Hannes Reinecke:
> This patch adds an emulation for the LSI Megaraid SAS 8708EM2 HBA.
> I've tested it to work with Linux, Windows Vista, and Windows7.
> 
> Changes since v8:
> - Remove 'disable' keyword from trace definitions
> - Convert hand-crafted debugging statements with trace
>   definitions
> - Treat 'context' tag as little endian
> 
> Changes since v7:
> - Port to new memory API
> - Port to new PCI infrastructure
> - Use fixed buffers for sense processing
> - Update to updated SCSI infrastructure
> 
> Changes since v6:
> - Preliminary patches pushed to Kevins block tree
> - Implement 64bit contexts, required for Windows7
> - Use iovecs for DCMD processing
> - Add MSI-X support
>   Latest Linux driver now happily uses MSI-X.
> - Static iovec allocation
>   We have a fixed upper number of iovecs, so we can
>   save us the allocation. Suggested by Alex Graf.
> - Update MFI header
>   Latest Linux driver has some more definitions,
>   add them
> - Fixup AEN handling
> - Update tracing details
> - Remove sdev pointer from megasas_cmd_t
> 
> Changes since v5:
> - megasas: Use tracing infrastructure instead of DPRINTF
> - megasas: Use new PCI infrastructure
> - megasas: Check for iovec mapping failure
>   cpu_map_physical_memory() might fail, so we need to check for
>   it when mapping iovecs.
> - megasas: Trace scsi buffer overflow
>   The transfer length as specified in the SCSI command might
>   disagree with the length of the iovec. We should be tracing
>   these issues.
> - megasas: Reset frames after init firmware
>   When receiving an INIT FIRMWARE command we need reset all
>   frames, otherwise some frames might point to invalid memory.
> 
> Chances since v4:
> - megasas: checkpatch.pl fixes and update to work with the
>   changed interface in scsi_req_new(). Also included the
>   suggested fixes from Alex.
> 
> Signed-off-by: Hannes Reinecke <address@hidden>
> ---
>  Makefile.objs           |    1 +
>  default-configs/pci.mak |    1 +
>  hw/megasas.c            | 2119 
> +++++++++++++++++++++++++++++++++++++++++++++++
>  hw/mfi.h                | 1281 ++++++++++++++++++++++++++++
>  hw/pci_ids.h            |    3 +-
>  trace-events            |   73 ++
>  6 files changed, 3477 insertions(+), 1 deletions(-)
>  create mode 100644 hw/megasas.c
>  create mode 100644 hw/mfi.h

> diff --git a/hw/megasas.c b/hw/megasas.c
> new file mode 100644
> index 0000000..c49edd0
> --- /dev/null
> +++ b/hw/megasas.c
> @@ -0,0 +1,2119 @@
> +/*
> + * QEMU MegaRAID SAS 8708EM2 Host Bus Adapter emulation
> + *
> + * Copyright (c) 2009-2011 Hannes Reinecke, SUSE Labs
> + *
> + * This code is licensed under the LGPL.

Please clarify the license versions(s). Or-later kindly requested.

> +    if (cmd->iov_size > iov_size) {
> +        trace_megasas_iovec_len(cmd->index, "overflow", iov_size,
> +                                cmd->iov_size);
> +    } else if (cmd->iov_size < iov_size) {
> +        trace_megasas_iovec_len(cmd->iov_size, "underflow", iov_size,
> +                                cmd->iov_size);
> +    }

For anything except stderr these are going to be problematic. For
simpletrace "overflow" and "underflow" will just show up as a pointer
value and cannot be looked up post-mortem.

> +static void megasas_unmap_sgl(struct megasas_cmd_t *cmd)
> +{
> +    int i, is_write = megasas_frame_is_write(cmd);
> +
> +    for (i = 0; i < cmd->iov_cnt; i++) {
> +        cpu_physical_memory_unmap(cmd->iov[i].iov_base, cmd->iov[i].iov_len,
> +                                  is_write, cmd->iov[i].iov_len);

Not sure, but cpu_physical_memory_* sounds old-fashioned. Might need an
update to MemoryRegion?

> +    if (cmd->iov_size < sizeof(struct mfi_defaults)) {
> +        trace_megasas_dcmd_invalid_xfer_len(cmd->index, "MFC Get defaults",
> +                                            cmd->iov_size);

String in tracepoint.

> +        trace_megasas_dcmd_invalid_xfer_len(cmd->index, "Get BIOS info",
> +                                            cmd->iov_size);

dito

> +    trace_megasas_dcmd_enter(cmd->index, "Get Event Info");

dito

> +        trace_megasas_dcmd_invalid_xfer_len(cmd->index, "Get Event Wait",
> +                                            cmd->iov_size);

Dito, rest as exercise for the reader.

> +static const struct dcmd_cmd_tbl_t {
> +    int opcode;
> +    int (*func)(MPTState *s, struct megasas_cmd_t *cmd);
> +} dcmd_cmd_tbl[] = {
> +    {MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC, megasas_dcmd_dummy},

Spaces after { and before } missing.

> +    if (!sdev || (megasas_is_jbod(s) && is_logical)) {
> +        trace_megasas_scsi_target_not_present(
> +            mfi_frame_desc[cmd->frame->header.frame_cmd],
> +            is_logical ? "logical" : "physical",
> +            cmd->frame->header.target_id, cmd->frame->header.lun_id);

Two-state string could be 0/1-encoded here.

> +        if (len > cmd->iov_size) {
> +            trace_megasas_scsi_overflow(cmd->index, "scsi read",
> +                                        len, cmd->iov_size);
> +        }
> +        if (len < cmd->iov_size) {
> +            trace_megasas_scsi_underflow(cmd->index, "scsi read",
> +                                         len, cmd->iov_size);
> +            cmd->iov_size = len;
> +        }
> +        trace_megasas_scsi_start(cmd->index, "read", len);
> +        scsi_req_continue(cmd->req);
> +    } else if (len < 0) {
> +        if (-len > cmd->iov_size) {
> +            trace_megasas_scsi_overflow(cmd->index, "scsi write",
> +                                        -len, cmd->iov_size);
> +        }
> +        if (-len < cmd->iov_size) {
> +            trace_megasas_scsi_underflow(cmd->index, "scsi write",
> +                                         -len, cmd->iov_size);
> +            cmd->iov_size = -len;
> +        }
> +        trace_megasas_scsi_start(cmd->index, "write", -len);
> +        scsi_req_continue(cmd->req);
> +    } else {

Here you have tracepoints for overflow and underflow and pass "scsi
read" vs. "scsi write" as arguments; above (iovec) you were passing
"overflow" and "underflow" as arguments. Unify the scheme?

You already introduce quite a few tracepoints (a shining example, one
might say) so maybe just do ..._scsi_read_overflow() and
_scsi_read_underflow()?

On the other hand, when someone is actually looking for a particular
nesting of events, DTrace for example allows to set some per-CPU flag so
not passing the specific argument might work as well.

> +    if (desc) {
> +        trace_megasas_readl_reg("mmio", desc, retval);
> +    } else {
> +        trace_megasas_readl("mmio", addr, retval);
> +    }

Drop _reg version?

Didn't review the SCSI bits. Patch is pretty large, too. ;)

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



reply via email to

[Prev in Thread] Current Thread [Next in Thread]