Commit 6baa963f authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging



* remotes/bonzini/scsi-next:
  virtio-scsi: define dummy handle_output for vhost-scsi vqs
  block/iscsi: drop obsolete pointers from iscsi_co_writev
  block/iscsi: fix init value for iTask->retries
  block/iscsi: bump libiscsi requirement to 1.9.0
  virtio-scsi: add support for the any_layout feature
  virtio-scsi: introduce virtio_scsi_complete_cmd_req
  virtio-scsi: prepare sense data handling for any_layout
  virtio-scsi: add extra argument and return type to qemu_sgl_concat
  virtio-scsi: add target swap for VirtIOSCSICtrlTMFReq fields
  virtio-scsi: start preparing for any_layout
  util: add return value to qemu_iovec_concat_iov
  megasas: use PCI DMA API
  scsi: Print command name in debug
  scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c5
  scsi-disk.c: Fix compilation with -DDEBUG_SCSI
  block/iscsi: use 16 byte CDBs only when necessary
  block/iscsi: fix potential segfault on early callback
  block/iscsi: handle BUSY condition

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 9f6f7f1a 91d670fb
Loading
Loading
Loading
Loading
+86 −103
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "config-host.h"

#include <poll.h>
#include <math.h>
#include <arpa/inet.h>
#include "qemu-common.h"
#include "qemu/config-file.h"
@@ -64,6 +65,7 @@ typedef struct IscsiLun {
    unsigned char *zeroblock;
    unsigned long *allocationmap;
    int cluster_sectors;
    bool use_16_for_rw;
} IscsiLun;

typedef struct IscsiTask {
@@ -75,6 +77,7 @@ typedef struct IscsiTask {
    Coroutine *co;
    QEMUBH *bh;
    IscsiLun *iscsilun;
    QEMUTimer retry_timer;
} IscsiTask;

typedef struct IscsiAIOCB {
@@ -86,7 +89,6 @@ typedef struct IscsiAIOCB {
    uint8_t *buf;
    int status;
    int canceled;
    int retries;
    int64_t sector_num;
    int nb_sectors;
#ifdef __linux__
@@ -96,7 +98,8 @@ typedef struct IscsiAIOCB {

#define NOP_INTERVAL 5000
#define MAX_NOP_FAILURES 3
#define ISCSI_CMD_RETRIES 5
#define ISCSI_CMD_RETRIES ARRAY_SIZE(iscsi_retry_times)
static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048};

/* this threshhold is a trade-off knob to choose between
 * the potential additional overhead of an extra GET_LBA_STATUS request
@@ -142,10 +145,25 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
static void iscsi_co_generic_bh_cb(void *opaque)
{
    struct IscsiTask *iTask = opaque;
    iTask->complete = 1;
    qemu_bh_delete(iTask->bh);
    qemu_coroutine_enter(iTask->co, NULL);
}

static void iscsi_retry_timer_expired(void *opaque)
{
    struct IscsiTask *iTask = opaque;
    iTask->complete = 1;
    if (iTask->co) {
        qemu_coroutine_enter(iTask->co, NULL);
    }
}

static inline unsigned exp_random(double mean)
{
    return -mean * log((double)rand() / RAND_MAX);
}

static void
iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
                        void *command_data, void *opaque)
@@ -153,19 +171,34 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
    struct IscsiTask *iTask = opaque;
    struct scsi_task *task = command_data;

    iTask->complete = 1;
    iTask->status = status;
    iTask->do_retry = 0;
    iTask->task = task;

    if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION
    if (status != SCSI_STATUS_GOOD) {
        if (iTask->retries++ < ISCSI_CMD_RETRIES) {
            if (status == SCSI_STATUS_CHECK_CONDITION
                && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
        error_report("iSCSI CheckCondition: %s", iscsi_get_error(iscsi));
                error_report("iSCSI CheckCondition: %s",
                             iscsi_get_error(iscsi));
                iTask->do_retry = 1;
                goto out;
            }

    if (status != SCSI_STATUS_GOOD) {
            if (status == SCSI_STATUS_BUSY) {
                unsigned retry_time =
                    exp_random(iscsi_retry_times[iTask->retries - 1]);
                error_report("iSCSI Busy (retry #%u in %u ms): %s",
                             iTask->retries, retry_time,
                             iscsi_get_error(iscsi));
                aio_timer_init(iTask->iscsilun->aio_context,
                               &iTask->retry_timer, QEMU_CLOCK_REALTIME,
                               SCALE_MS, iscsi_retry_timer_expired, iTask);
                timer_mod(&iTask->retry_timer,
                          qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);
                iTask->do_retry = 1;
                return;
            }
        }
        error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
    }

@@ -174,6 +207,8 @@ out:
        iTask->bh = aio_bh_new(iTask->iscsilun->aio_context,
                               iscsi_co_generic_bh_cb, iTask);
        qemu_bh_schedule(iTask->bh);
    } else {
        iTask->complete = 1;
    }
}

@@ -181,7 +216,6 @@ static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
{
    *iTask = (struct IscsiTask) {
        .co         = qemu_coroutine_self(),
        .retries        = ISCSI_CMD_RETRIES,
        .iscsilun   = iscsilun,
    };
}
@@ -325,8 +359,6 @@ static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,
    struct IscsiTask iTask;
    uint64_t lba;
    uint32_t num_sectors;
    uint8_t *data = NULL;
    uint8_t *buf = NULL;

    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
        return -EINVAL;
@@ -334,31 +366,24 @@ static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,

    lba = sector_qemu2lun(sector_num, iscsilun);
    num_sectors = sector_qemu2lun(nb_sectors, iscsilun);
#if !defined(LIBISCSI_FEATURE_IOVECTOR)
    /* if the iovec only contains one buffer we can pass it directly */
    if (iov->niov == 1) {
        data = iov->iov[0].iov_base;
    } else {
        size_t size = MIN(nb_sectors * BDRV_SECTOR_SIZE, iov->size);
        buf = g_malloc(size);
        qemu_iovec_to_buf(iov, 0, buf, size);
        data = buf;
    }
#endif
    iscsi_co_init_iscsitask(iscsilun, &iTask);
retry:
    if (iscsilun->use_16_for_rw) {
        iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba,
                                    data, num_sectors * iscsilun->block_size,
                                        NULL, num_sectors * iscsilun->block_size,
                                        iscsilun->block_size, 0, 0, 0, 0, 0,
                                        iscsi_co_generic_cb, &iTask);
    } else {
        iTask.task = iscsi_write10_task(iscsilun->iscsi, iscsilun->lun, lba,
                                        NULL, num_sectors * iscsilun->block_size,
                                        iscsilun->block_size, 0, 0, 0, 0, 0,
                                        iscsi_co_generic_cb, &iTask);
    }
    if (iTask.task == NULL) {
        g_free(buf);
        return -ENOMEM;
    }
#if defined(LIBISCSI_FEATURE_IOVECTOR)
    scsi_task_set_iov_out(iTask.task, (struct scsi_iovec *) iov->iov,
                          iov->niov);
#endif
    while (!iTask.complete) {
        iscsi_set_events(iscsilun);
        qemu_coroutine_yield();
@@ -374,8 +399,6 @@ retry:
        goto retry;
    }

    g_free(buf);

    if (iTask.status != SCSI_STATUS_GOOD) {
        return -EIO;
    }
@@ -386,7 +409,6 @@ retry:
}


#if defined(LIBISCSI_FEATURE_IOVECTOR)
static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun,
                                             int64_t sector_num, int nb_sectors)
{
@@ -496,9 +518,6 @@ out:
    return ret;
}

#endif /* LIBISCSI_FEATURE_IOVECTOR */


static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
                                       int64_t sector_num, int nb_sectors,
                                       QEMUIOVector *iov)
@@ -507,15 +526,11 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
    struct IscsiTask iTask;
    uint64_t lba;
    uint32_t num_sectors;
#if !defined(LIBISCSI_FEATURE_IOVECTOR)
    int i;
#endif

    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
        return -EINVAL;
    }

#if defined(LIBISCSI_FEATURE_IOVECTOR)
    if (iscsilun->lbprz && nb_sectors >= ISCSI_CHECKALLOC_THRES &&
        !iscsi_allocationmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
        int64_t ret;
@@ -529,42 +544,28 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
            return 0;
        }
    }
#endif

    lba = sector_qemu2lun(sector_num, iscsilun);
    num_sectors = sector_qemu2lun(nb_sectors, iscsilun);

    iscsi_co_init_iscsitask(iscsilun, &iTask);
retry:
    switch (iscsilun->type) {
    case TYPE_DISK:
    if (iscsilun->use_16_for_rw) {
        iTask.task = iscsi_read16_task(iscsilun->iscsi, iscsilun->lun, lba,
                                       num_sectors * iscsilun->block_size,
                                       iscsilun->block_size, 0, 0, 0, 0, 0,
                                       iscsi_co_generic_cb, &iTask);
        break;
    default:
    } else {
        iTask.task = iscsi_read10_task(iscsilun->iscsi, iscsilun->lun, lba,
                                       num_sectors * iscsilun->block_size,
                                       iscsilun->block_size,
#if !defined(CONFIG_LIBISCSI_1_4) /* API change from 1.4.0 to 1.5.0 */
                                       0, 0, 0, 0, 0,
#endif
                                       iscsi_co_generic_cb, &iTask);
        break;
    }
    if (iTask.task == NULL) {
        return -ENOMEM;
    }
#if defined(LIBISCSI_FEATURE_IOVECTOR)
    scsi_task_set_iov_in(iTask.task, (struct scsi_iovec *) iov->iov, iov->niov);
#else
    for (i = 0; i < iov->niov; i++) {
        scsi_task_add_data_in_buffer(iTask.task,
                                     iov->iov[i].iov_len,
                                     iov->iov[i].iov_base);
    }
#endif

    while (!iTask.complete) {
        iscsi_set_events(iscsilun);
@@ -719,18 +720,9 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
            data.data = acb->ioh->dxferp;
            data.size = acb->ioh->dxfer_len;
        } else {
#if defined(LIBISCSI_FEATURE_IOVECTOR)
            scsi_task_set_iov_out(acb->task,
                                 (struct scsi_iovec *) acb->ioh->dxferp,
                                 acb->ioh->iovec_count);
#else
            struct iovec *iov = (struct iovec *)acb->ioh->dxferp;

            acb->buf = g_malloc(acb->ioh->dxfer_len);
            data.data = acb->buf;
            data.size = iov_to_buf(iov, acb->ioh->iovec_count, 0,
                                   acb->buf, acb->ioh->dxfer_len);
#endif
        }
    }

@@ -750,20 +742,9 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
                                         acb->ioh->dxfer_len,
                                         acb->ioh->dxferp);
        } else {
#if defined(LIBISCSI_FEATURE_IOVECTOR)
            scsi_task_set_iov_in(acb->task,
                                 (struct scsi_iovec *) acb->ioh->dxferp,
                                 acb->ioh->iovec_count);
#else
            int i;
            for (i = 0; i < acb->ioh->iovec_count; i++) {
                struct iovec *iov = (struct iovec *)acb->ioh->dxferp;

                scsi_task_add_data_in_buffer(acb->task,
                    iov[i].iov_len,
                    iov[i].iov_base);
            }
#endif
        }
    }

@@ -772,7 +753,6 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
    return &acb->common;
}


static void ioctl_cb(void *opaque, int status)
{
    int *p_status = opaque;
@@ -877,8 +857,6 @@ retry:
    return 0;
}

#if defined(SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED)

static int
coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
                                   int nb_sectors, BdrvRequestFlags flags)
@@ -887,15 +865,23 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
    struct IscsiTask iTask;
    uint64_t lba;
    uint32_t nb_blocks;
    bool use_16_for_ws = iscsilun->use_16_for_rw;

    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
        return -EINVAL;
    }

    if ((flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->lbp.lbpws) {
        /* WRITE SAME with UNMAP is not supported by the target,
         * fall back and try WRITE SAME without UNMAP */
    if (flags & BDRV_REQ_MAY_UNMAP) {
        if (!use_16_for_ws && !iscsilun->lbp.lbpws10) {
            /* WRITESAME10 with UNMAP is unsupported try WRITESAME16 */
            use_16_for_ws = true;
        }
        if (use_16_for_ws && !iscsilun->lbp.lbpws) {
            /* WRITESAME16 with UNMAP is not supported by the target,
             * fall back and try WRITESAME10/16 without UNMAP */
            flags &= ~BDRV_REQ_MAY_UNMAP;
            use_16_for_ws = iscsilun->use_16_for_rw;
        }
    }

    if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
@@ -912,10 +898,18 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,

    iscsi_co_init_iscsitask(iscsilun, &iTask);
retry:
    if (iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
    if (use_16_for_ws) {
        iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
                                            iscsilun->zeroblock, iscsilun->block_size,
                                            nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
                                            0, 0, iscsi_co_generic_cb, &iTask);
    } else {
        iTask.task = iscsi_writesame10_task(iscsilun->iscsi, iscsilun->lun, lba,
                                            iscsilun->zeroblock, iscsilun->block_size,
                                            nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
                               0, 0, iscsi_co_generic_cb, &iTask) == NULL) {
                                            0, 0, iscsi_co_generic_cb, &iTask);
    }
    if (iTask.task == NULL) {
        return -ENOMEM;
    }

@@ -957,8 +951,6 @@ retry:
    return 0;
}

#endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */

static void parse_chap(struct iscsi_context *iscsi, const char *target,
                       Error **errp)
{
@@ -1068,7 +1060,6 @@ static char *parse_initiator_name(const char *target)
    return iscsi_name;
}

#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
static void iscsi_nop_timed_event(void *opaque)
{
    IscsiLun *iscsilun = opaque;
@@ -1086,7 +1077,6 @@ static void iscsi_nop_timed_event(void *opaque)
    timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
    iscsi_set_events(iscsilun);
}
#endif

static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
{
@@ -1113,6 +1103,7 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
                    iscsilun->num_blocks = rc16->returned_lba + 1;
                    iscsilun->lbpme = rc16->lbpme;
                    iscsilun->lbprz = rc16->lbprz;
                    iscsilun->use_16_for_rw = (rc16->returned_lba > 0xffffffff);
                }
            }
            break;
@@ -1224,14 +1215,12 @@ static void iscsi_attach_aio_context(BlockDriverState *bs,
    iscsilun->aio_context = new_context;
    iscsi_set_events(iscsilun);

#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
    /* Set up a timer for sending out iSCSI NOPs */
    iscsilun->nop_timer = aio_timer_new(iscsilun->aio_context,
                                        QEMU_CLOCK_REALTIME, SCALE_MS,
                                        iscsi_nop_timed_event, iscsilun);
    timer_mod(iscsilun->nop_timer,
              qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
#endif
}

/*
@@ -1423,13 +1412,11 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
        iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
#if defined(LIBISCSI_FEATURE_IOVECTOR)
        if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
            iscsilun->allocationmap =
                bitmap_new(DIV_ROUND_UP(bs->total_sectors,
                                        iscsilun->cluster_sectors));
        }
#endif
    }

out:
@@ -1614,13 +1601,9 @@ static BlockDriver bdrv_iscsi = {
    .bdrv_truncate   = iscsi_truncate,
    .bdrv_refresh_limits = iscsi_refresh_limits,

#if defined(LIBISCSI_FEATURE_IOVECTOR)
    .bdrv_co_get_block_status = iscsi_co_get_block_status,
#endif
    .bdrv_co_discard      = iscsi_co_discard,
#if defined(SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED)
    .bdrv_co_write_zeroes = iscsi_co_write_zeroes,
#endif
    .bdrv_co_readv         = iscsi_co_readv,
    .bdrv_co_writev        = iscsi_co_writev,
    .bdrv_co_flush_to_disk = iscsi_co_flush,
+3 −36
Original line number Diff line number Diff line
@@ -3405,46 +3405,20 @@ if compile_prog "" "" ; then
fi

##########################################
# Do we have libiscsi
# We check for iscsi_write16_sync() to make sure we have a
# at least version 1.4.0 of libiscsi.
# Do we have libiscsi >= 1.9.0
if test "$libiscsi" != "no" ; then
  cat > $TMPC << EOF
#include <stdio.h>
#include <iscsi/iscsi.h>
int main(void) { iscsi_write16_sync(NULL,0,0,NULL,0,0,0,0,0,0,0); return 0; }
EOF
  if $pkg_config --atleast-version=1.7.0 libiscsi; then
  if $pkg_config --atleast-version=1.9.0 libiscsi; then
    libiscsi="yes"
    libiscsi_cflags=$($pkg_config --cflags libiscsi)
    libiscsi_libs=$($pkg_config --libs libiscsi)
  elif compile_prog "" "-liscsi" ; then
    libiscsi="yes"
    libiscsi_libs="-liscsi"
  else
    if test "$libiscsi" = "yes" ; then
      feature_not_found "libiscsi" "Install libiscsi devel"
      feature_not_found "libiscsi" "Install libiscsi >= 1.9.0"
    fi
    libiscsi="no"
  fi
fi

# We also need to know the API version because there was an
# API change from 1.4.0 to 1.5.0.
if test "$libiscsi" = "yes"; then
  cat >$TMPC <<EOF
#include <iscsi/iscsi.h>
int main(void)
{
  iscsi_read10_task(0, 0, 0, 0, 0, 0, 0);
  return 0;
}
EOF
  if compile_prog "" "-liscsi"; then
    libiscsi_version="1.4.0"
  fi
fi

##########################################
# Do we need libm
cat > $TMPC << EOF
@@ -4218,11 +4192,7 @@ echo "nss used $smartcard_nss"
echo "libusb            $libusb"
echo "usb net redir     $usb_redir"
echo "GLX support       $glx"
if test "$libiscsi_version" = "1.4.0"; then
echo "libiscsi support  $libiscsi (1.4.0)"
else
echo "libiscsi support  $libiscsi"
fi
echo "libnfs support    $libnfs"
echo "build guest agent $guest_agent"
echo "QGA VSS support   $guest_agent_with_vss"
@@ -4579,9 +4549,6 @@ fi

if test "$libiscsi" = "yes" ; then
  echo "CONFIG_LIBISCSI=m" >> $config_host_mak
  if test "$libiscsi_version" = "1.4.0"; then
    echo "CONFIG_LIBISCSI_1_4=y" >> $config_host_mak
  fi
  echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
  echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak
fi
+10 −6
Original line number Diff line number Diff line
@@ -294,6 +294,7 @@ static void megasas_unmap_sgl(MegasasCmd *cmd)
static int megasas_build_sense(MegasasCmd *cmd, uint8_t *sense_ptr,
    uint8_t sense_len)
{
    PCIDevice *pcid = PCI_DEVICE(cmd->state);
    uint32_t pa_hi = 0, pa_lo;
    hwaddr pa;

@@ -306,7 +307,7 @@ static int megasas_build_sense(MegasasCmd *cmd, uint8_t *sense_ptr,
            pa_hi = le32_to_cpu(cmd->frame->pass.sense_addr_hi);
        }
        pa = ((uint64_t) pa_hi << 32) | pa_lo;
        cpu_physical_memory_write(pa, sense_ptr, sense_len);
        pci_dma_write(pcid, pa, sense_ptr, sense_len);
        cmd->frame->header.sense_len = sense_len;
    }
    return sense_len;
@@ -472,6 +473,7 @@ static MegasasCmd *megasas_next_frame(MegasasState *s,
static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
    hwaddr frame, uint64_t context, int count)
{
    PCIDevice *pcid = PCI_DEVICE(s);
    MegasasCmd *cmd = NULL;
    int frame_size = MFI_FRAME_SIZE * 16;
    hwaddr frame_size_p = frame_size;
@@ -484,11 +486,11 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
    if (!cmd->pa) {
        cmd->pa = frame;
        /* Map all possible frames */
        cmd->frame = cpu_physical_memory_map(frame, &frame_size_p, 0);
        cmd->frame = pci_dma_map(pcid, frame, &frame_size_p, 0);
        if (frame_size_p != frame_size) {
            trace_megasas_qf_map_failed(cmd->index, (unsigned long)frame);
            if (cmd->frame) {
                cpu_physical_memory_unmap(cmd->frame, frame_size_p, 0, 0);
                pci_dma_unmap(pcid, cmd->frame, frame_size_p, 0, 0);
                cmd->frame = NULL;
                cmd->pa = 0;
            }
@@ -561,13 +563,14 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context)

static void megasas_reset_frames(MegasasState *s)
{
    PCIDevice *pcid = PCI_DEVICE(s);
    int i;
    MegasasCmd *cmd;

    for (i = 0; i < s->fw_cmds; i++) {
        cmd = &s->frames[i];
        if (cmd->pa) {
            cpu_physical_memory_unmap(cmd->frame, cmd->pa_size, 0, 0);
            pci_dma_unmap(pcid, cmd->frame, cmd->pa_size, 0, 0);
            cmd->frame = NULL;
            cmd->pa = 0;
        }
@@ -584,6 +587,7 @@ static void megasas_abort_command(MegasasCmd *cmd)

static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
{
    PCIDevice *pcid = PCI_DEVICE(s);
    uint32_t pa_hi, pa_lo;
    hwaddr iq_pa, initq_size;
    struct mfi_init_qinfo *initq;
@@ -595,7 +599,7 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
    iq_pa = (((uint64_t) pa_hi << 32) | pa_lo);
    trace_megasas_init_firmware((uint64_t)iq_pa);
    initq_size = sizeof(*initq);
    initq = cpu_physical_memory_map(iq_pa, &initq_size, 0);
    initq = pci_dma_map(pcid, iq_pa, &initq_size, 0);
    if (!initq || initq_size != sizeof(*initq)) {
        trace_megasas_initq_map_failed(cmd->index);
        s->event_count++;
@@ -631,7 +635,7 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
    s->fw_state = MFI_FWSTATE_OPERATIONAL;
out:
    if (initq) {
        cpu_physical_memory_unmap(initq, initq_size, 0, 0);
        pci_dma_unmap(pcid, initq, initq_size, 0, 0);
    }
    return ret;
}
+3 −1
Original line number Diff line number Diff line
@@ -1429,7 +1429,7 @@ int scsi_build_sense(uint8_t *in_buf, int in_len,
    }
}

static const char *scsi_command_name(uint8_t cmd)
const char *scsi_command_name(uint8_t cmd)
{
    static const char *names[] = {
        [ TEST_UNIT_READY          ] = "TEST_UNIT_READY",
@@ -1545,6 +1545,8 @@ static const char *scsi_command_name(uint8_t cmd)
        [ SET_READ_AHEAD           ] = "SET_READ_AHEAD",
        [ ALLOW_OVERWRITE          ] = "ALLOW_OVERWRITE",
        [ MECHANISM_STATUS         ] = "MECHANISM_STATUS",
        [ GET_EVENT_STATUS_NOTIFICATION ] = "GET_EVENT_STATUS_NOTIFICATION",
        [ READ_DISC_INFORMATION    ] = "READ_DISC_INFORMATION",
    };

    if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL)
+4 −3
Original line number Diff line number Diff line
@@ -2015,7 +2015,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
    case VERIFY_10:
    case VERIFY_12:
    case VERIFY_16:
        DPRINTF("Verify (bytchk %lu)\n", (r->req.buf[1] >> 1) & 3);
        DPRINTF("Verify (bytchk %d)\n", (req->cmd.buf[1] >> 1) & 3);
        if (req->cmd.buf[1] & 6) {
            goto illegal_request;
        }
@@ -2027,7 +2027,8 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
                (long)r->req.cmd.xfer);
        break;
    default:
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
        DPRINTF("Unknown SCSI command (%2.2x=%s)\n", buf[0],
                scsi_command_name(buf[0]));
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
        return 0;
    }
@@ -2526,7 +2527,7 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
	 * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
	 * O_DIRECT everything must go through SG_IO.
         */
        if (bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE) {
        if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) {
            break;
        }

Loading