mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-08 13:07:01 +00:00
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: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
7e0380b9bb
commit
0d3545e76c
4
hw/esp.c
4
hw/esp.c
@ -217,7 +217,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
|
|||||||
s->async_len = 0;
|
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) {
|
if (!s->current_dev) {
|
||||||
// No such drive
|
// No such drive
|
||||||
s->rregs[ESP_RSTAT] = 0;
|
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);
|
trace_esp_do_busid_cmd(busid);
|
||||||
lun = busid & 7;
|
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);
|
s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL);
|
||||||
datalen = scsi_req_enqueue(s->current_req);
|
datalen = scsi_req_enqueue(s->current_req);
|
||||||
s->ti_size = datalen;
|
s->ti_size = datalen;
|
||||||
|
@ -767,7 +767,7 @@ static void lsi_do_command(LSIState *s)
|
|||||||
s->command_complete = 0;
|
s->command_complete = 0;
|
||||||
|
|
||||||
id = (s->select_tag >> 8) & 0xf;
|
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) {
|
if (!dev) {
|
||||||
lsi_bad_selection(s, id);
|
lsi_bad_selection(s, id);
|
||||||
return;
|
return;
|
||||||
@ -1198,7 +1198,7 @@ again:
|
|||||||
}
|
}
|
||||||
s->sstat0 |= LSI_SSTAT0_WOA;
|
s->sstat0 |= LSI_SSTAT0_WOA;
|
||||||
s->scntl1 &= ~LSI_SCNTL1_IARB;
|
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);
|
lsi_bad_selection(s, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = {
|
|||||||
.size = sizeof(SCSIBus),
|
.size = sizeof(SCSIBus),
|
||||||
.get_fw_dev_path = scsibus_get_fw_dev_path,
|
.get_fw_dev_path = scsibus_get_fw_dev_path,
|
||||||
.props = (Property[]) {
|
.props = (Property[]) {
|
||||||
|
DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
|
||||||
DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
|
DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
|
||||||
DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
|
DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
@ -40,6 +41,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
SCSIDevice *d;
|
SCSIDevice *d;
|
||||||
int rc = -1;
|
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) {
|
if (dev->id != -1 && dev->id > bus->info->max_target) {
|
||||||
error_report("bad scsi device id: %d", dev->id);
|
error_report("bad scsi device id: %d", dev->id);
|
||||||
goto err;
|
goto err;
|
||||||
@ -51,7 +56,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
dev->lun = 0;
|
dev->lun = 0;
|
||||||
}
|
}
|
||||||
do {
|
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);
|
} while (d && d->lun == dev->lun && id <= bus->info->max_target);
|
||||||
if (id > bus->info->max_target) {
|
if (id > bus->info->max_target) {
|
||||||
error_report("no free target");
|
error_report("no free target");
|
||||||
@ -61,7 +66,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
} else if (dev->lun == -1) {
|
} else if (dev->lun == -1) {
|
||||||
int lun = -1;
|
int lun = -1;
|
||||||
do {
|
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);
|
} while (d && d->lun == lun && lun < bus->info->max_lun);
|
||||||
if (lun > bus->info->max_lun) {
|
if (lun > bus->info->max_lun) {
|
||||||
error_report("no free lun");
|
error_report("no free lun");
|
||||||
@ -69,7 +74,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
}
|
}
|
||||||
dev->lun = lun;
|
dev->lun = lun;
|
||||||
} else {
|
} 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) {
|
if (dev->lun == d->lun && dev != d) {
|
||||||
qdev_free(&d->qdev);
|
qdev_free(&d->qdev);
|
||||||
}
|
}
|
||||||
@ -203,7 +208,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
|
|||||||
{
|
{
|
||||||
DeviceState *qdev;
|
DeviceState *qdev;
|
||||||
int i, len, n;
|
int i, len, n;
|
||||||
int id;
|
int channel, id;
|
||||||
bool found_lun0;
|
bool found_lun0;
|
||||||
|
|
||||||
if (r->req.cmd.xfer < 16) {
|
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) {
|
if (r->req.cmd.buf[2] > 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
channel = r->req.dev->channel;
|
||||||
id = r->req.dev->id;
|
id = r->req.dev->id;
|
||||||
found_lun0 = false;
|
found_lun0 = false;
|
||||||
n = 0;
|
n = 0;
|
||||||
QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
|
QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
|
||||||
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
|
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
|
||||||
|
|
||||||
if (dev->id == id) {
|
if (dev->channel == channel && dev->id == id) {
|
||||||
if (dev->lun == 0) {
|
if (dev->lun == 0) {
|
||||||
found_lun0 = true;
|
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) {
|
QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
|
||||||
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
|
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);
|
store_lun(&r->buf[i], dev->lun);
|
||||||
i += 8;
|
i += 8;
|
||||||
}
|
}
|
||||||
@ -1203,12 +1209,12 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
|
|||||||
char path[100];
|
char path[100];
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s@%d:%d:%d", qdev_fw_name(dev),
|
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);
|
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;
|
DeviceState *qdev;
|
||||||
SCSIDevice *target_dev = NULL;
|
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) {
|
QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
|
||||||
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
|
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
|
||||||
|
|
||||||
if (dev->id == id) {
|
if (dev->channel == channel && dev->id == id) {
|
||||||
if (dev->lun == lun) {
|
if (dev->lun == lun) {
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ struct SCSIDevice
|
|||||||
uint8_t sense[SCSI_SENSE_BUF_SIZE];
|
uint8_t sense[SCSI_SENSE_BUF_SIZE];
|
||||||
uint32_t sense_len;
|
uint32_t sense_len;
|
||||||
QTAILQ_HEAD(, SCSIRequest) requests;
|
QTAILQ_HEAD(, SCSIRequest) requests;
|
||||||
|
uint32_t channel;
|
||||||
uint32_t lun;
|
uint32_t lun;
|
||||||
int blocksize;
|
int blocksize;
|
||||||
int type;
|
int type;
|
||||||
@ -99,7 +100,7 @@ struct SCSIDeviceInfo {
|
|||||||
|
|
||||||
struct SCSIBusInfo {
|
struct SCSIBusInfo {
|
||||||
int tcq;
|
int tcq;
|
||||||
int max_target, max_lun;
|
int max_channel, max_target, max_lun;
|
||||||
void (*transfer_data)(SCSIRequest *req, uint32_t arg);
|
void (*transfer_data)(SCSIRequest *req, uint32_t arg);
|
||||||
void (*complete)(SCSIRequest *req, uint32_t arg);
|
void (*complete)(SCSIRequest *req, uint32_t arg);
|
||||||
void (*cancel)(SCSIRequest *req);
|
void (*cancel)(SCSIRequest *req);
|
||||||
@ -194,6 +195,6 @@ void scsi_req_abort(SCSIRequest *req, int status);
|
|||||||
void scsi_req_cancel(SCSIRequest *req);
|
void scsi_req_cancel(SCSIRequest *req);
|
||||||
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
|
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
|
||||||
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
|
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
|
#endif
|
||||||
|
@ -160,11 +160,7 @@ retry:
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel) {
|
return scsi_device_find(bus, channel, id, *lun);
|
||||||
*lun = -1;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return scsi_device_find(bus, id, *lun);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
|
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 = {
|
static const struct SCSIBusInfo vscsi_scsi_info = {
|
||||||
.tcq = true,
|
.tcq = true,
|
||||||
.max_target = 63, /* logical unit addressing format */
|
.max_channel = 7, /* logical unit addressing format */
|
||||||
|
.max_target = 63,
|
||||||
.max_lun = 31,
|
.max_lun = 31,
|
||||||
|
|
||||||
.transfer_data = vscsi_transfer_data,
|
.transfer_data = vscsi_transfer_data,
|
||||||
|
Loading…
Reference in New Issue
Block a user