Commit 0d3545e7 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Kevin Wolf
Browse files

scsi: add channel to addressing



This also requires little more than adding the new argument to
scsi_device_find, and the qdev property.  All devices by default
end up on channel 0.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 7e0380b9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
        s->async_len = 0;
    }

    s->current_dev = scsi_device_find(&s->bus, target, 0);
    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
    if (!s->current_dev) {
        // No such drive
        s->rregs[ESP_RSTAT] = 0;
@@ -237,7 +237,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)

    trace_esp_do_busid_cmd(busid);
    lun = busid & 7;
    current_lun = scsi_device_find(&s->bus, s->current_dev->id, lun);
    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
    s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL);
    datalen = scsi_req_enqueue(s->current_req);
    s->ti_size = datalen;
+2 −2
Original line number Diff line number Diff line
@@ -767,7 +767,7 @@ static void lsi_do_command(LSIState *s)
    s->command_complete = 0;

    id = (s->select_tag >> 8) & 0xf;
    dev = scsi_device_find(&s->bus, id, s->current_lun);
    dev = scsi_device_find(&s->bus, 0, id, s->current_lun);
    if (!dev) {
        lsi_bad_selection(s, id);
        return;
@@ -1198,7 +1198,7 @@ again:
                }
                s->sstat0 |= LSI_SSTAT0_WOA;
                s->scntl1 &= ~LSI_SCNTL1_IARB;
                if (!scsi_device_find(&s->bus, id, 0)) {
                if (!scsi_device_find(&s->bus, 0, id, 0)) {
                    lsi_bad_selection(s, id);
                    break;
                }
+15 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = {
    .size  = sizeof(SCSIBus),
    .get_fw_dev_path = scsibus_get_fw_dev_path,
    .props = (Property[]) {
        DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
        DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
        DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
        DEFINE_PROP_END_OF_LIST(),
@@ -40,6 +41,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
    SCSIDevice *d;
    int rc = -1;

    if (dev->channel > bus->info->max_channel) {
        error_report("bad scsi channel id: %d", dev->channel);
        goto err;
    }
    if (dev->id != -1 && dev->id > bus->info->max_target) {
        error_report("bad scsi device id: %d", dev->id);
        goto err;
@@ -51,7 +56,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
            dev->lun = 0;
        }
        do {
            d = scsi_device_find(bus, ++id, dev->lun);
            d = scsi_device_find(bus, dev->channel, ++id, dev->lun);
        } while (d && d->lun == dev->lun && id <= bus->info->max_target);
        if (id > bus->info->max_target) {
            error_report("no free target");
@@ -61,7 +66,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
    } else if (dev->lun == -1) {
        int lun = -1;
        do {
            d = scsi_device_find(bus, dev->id, ++lun);
            d = scsi_device_find(bus, dev->channel, dev->id, ++lun);
        } while (d && d->lun == lun && lun < bus->info->max_lun);
        if (lun > bus->info->max_lun) {
            error_report("no free lun");
@@ -69,7 +74,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
        }
        dev->lun = lun;
    } else {
        d = scsi_device_find(bus, dev->id, dev->lun);
        d = scsi_device_find(bus, dev->channel, dev->id, dev->lun);
        if (dev->lun == d->lun && dev != d) {
            qdev_free(&d->qdev);
        }
@@ -203,7 +208,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
{
    DeviceState *qdev;
    int i, len, n;
    int id;
    int channel, id;
    bool found_lun0;

    if (r->req.cmd.xfer < 16) {
@@ -212,13 +217,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
    if (r->req.cmd.buf[2] > 2) {
        return false;
    }
    channel = r->req.dev->channel;
    id = r->req.dev->id;
    found_lun0 = false;
    n = 0;
    QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);

        if (dev->id == id) {
        if (dev->channel == channel && dev->id == id) {
            if (dev->lun == 0) {
                found_lun0 = true;
            }
@@ -240,7 +246,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
    QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);

        if (dev->id == id) {
        if (dev->channel == channel && dev->id == id) {
            store_lun(&r->buf[i], dev->lun);
            i += 8;
        }
@@ -1203,12 +1209,12 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
    char path[100];

    snprintf(path, sizeof(path), "%s@%d:%d:%d", qdev_fw_name(dev),
             0, d->id, d->lun);
             d->channel, d->id, d->lun);

    return strdup(path);
}

SCSIDevice *scsi_device_find(SCSIBus *bus, int id, int lun)
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
{
    DeviceState *qdev;
    SCSIDevice *target_dev = NULL;
@@ -1216,7 +1222,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int id, int lun)
    QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);

        if (dev->id == id) {
        if (dev->channel == channel && dev->id == id) {
            if (dev->lun == lun) {
                return dev;
            }
+3 −2
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct SCSIDevice
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
    uint32_t sense_len;
    QTAILQ_HEAD(, SCSIRequest) requests;
    uint32_t channel;
    uint32_t lun;
    int blocksize;
    int type;
@@ -99,7 +100,7 @@ struct SCSIDeviceInfo {

struct SCSIBusInfo {
    int tcq;
    int max_target, max_lun;
    int max_channel, max_target, max_lun;
    void (*transfer_data)(SCSIRequest *req, uint32_t arg);
    void (*complete)(SCSIRequest *req, uint32_t arg);
    void (*cancel)(SCSIRequest *req);
@@ -194,6 +195,6 @@ void scsi_req_abort(SCSIRequest *req, int status);
void scsi_req_cancel(SCSIRequest *req);
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
SCSIDevice *scsi_device_find(SCSIBus *bus, int target, int lun);
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);

#endif
+3 −6
Original line number Diff line number Diff line
@@ -160,11 +160,7 @@ retry:
        abort();
    }

    if (channel) {
        *lun = -1;
        return NULL;
    }
    return scsi_device_find(bus, id, *lun);
    return scsi_device_find(bus, channel, id, *lun);
}

static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
@@ -892,7 +888,8 @@ static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)

static const struct SCSIBusInfo vscsi_scsi_info = {
    .tcq = true,
    .max_target = 63, /* logical unit addressing format */
    .max_channel = 7, /* logical unit addressing format */
    .max_target = 63,
    .max_lun = 31,

    .transfer_data = vscsi_transfer_data,