mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'bonzini/scsi-next' into staging
* bonzini/scsi-next: scsi: add get_dev_path virtio-scsi: call unregister_savevm properly scsi: copy serial number into VPD page 0x83 scsi-cd: check ready condition before processing several commands get rid of CONFIG_VIRTIO_SCSI
This commit is contained in:
commit
49f54371f2
|
@ -209,7 +209,7 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
|
||||||
# need to fix this properly
|
# need to fix this properly
|
||||||
obj-$(CONFIG_NO_PCI) += pci-stub.o
|
obj-$(CONFIG_NO_PCI) += pci-stub.o
|
||||||
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
|
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
|
||||||
obj-$(CONFIG_VIRTIO_SCSI) += virtio-scsi.o
|
obj-$(CONFIG_VIRTIO) += virtio-scsi.o
|
||||||
obj-y += vhost_net.o
|
obj-y += vhost_net.o
|
||||||
obj-$(CONFIG_VHOST_NET) += vhost.o
|
obj-$(CONFIG_VHOST_NET) += vhost.o
|
||||||
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
|
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
CONFIG_PCI=y
|
CONFIG_PCI=y
|
||||||
CONFIG_VIRTIO_PCI=y
|
CONFIG_VIRTIO_PCI=y
|
||||||
CONFIG_VIRTIO_SCSI=y
|
|
||||||
CONFIG_VIRTIO=y
|
CONFIG_VIRTIO=y
|
||||||
CONFIG_USB_UHCI=y
|
CONFIG_USB_UHCI=y
|
||||||
CONFIG_USB_OHCI=y
|
CONFIG_USB_OHCI=y
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
CONFIG_VIRTIO=y
|
CONFIG_VIRTIO=y
|
||||||
CONFIG_VIRTIO_SCSI=y
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
|
||||||
|
static char *scsibus_get_dev_path(DeviceState *dev);
|
||||||
static char *scsibus_get_fw_dev_path(DeviceState *dev);
|
static char *scsibus_get_fw_dev_path(DeviceState *dev);
|
||||||
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
|
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
|
||||||
static void scsi_req_dequeue(SCSIRequest *req);
|
static void scsi_req_dequeue(SCSIRequest *req);
|
||||||
|
@ -14,6 +15,7 @@ static void scsi_req_dequeue(SCSIRequest *req);
|
||||||
static struct BusInfo scsi_bus_info = {
|
static struct BusInfo scsi_bus_info = {
|
||||||
.name = "SCSI",
|
.name = "SCSI",
|
||||||
.size = sizeof(SCSIBus),
|
.size = sizeof(SCSIBus),
|
||||||
|
.get_dev_path = scsibus_get_dev_path,
|
||||||
.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("channel", SCSIDevice, channel, 0),
|
||||||
|
@ -1423,6 +1425,22 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
|
||||||
sdev->unit_attention = sense;
|
sdev->unit_attention = sense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *scsibus_get_dev_path(DeviceState *dev)
|
||||||
|
{
|
||||||
|
SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
|
||||||
|
DeviceState *hba = dev->parent_bus->parent;
|
||||||
|
char *id = NULL;
|
||||||
|
|
||||||
|
if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) {
|
||||||
|
id = hba->parent_bus->info->get_dev_path(hba);
|
||||||
|
}
|
||||||
|
if (id) {
|
||||||
|
return g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun);
|
||||||
|
} else {
|
||||||
|
return g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static char *scsibus_get_fw_dev_path(DeviceState *dev)
|
static char *scsibus_get_fw_dev_path(DeviceState *dev)
|
||||||
{
|
{
|
||||||
SCSIDevice *d = SCSI_DEVICE(dev);
|
SCSIDevice *d = SCSI_DEVICE(dev);
|
||||||
|
|
|
@ -471,8 +471,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
|
||||||
|
|
||||||
case 0x83: /* Device identification page, mandatory */
|
case 0x83: /* Device identification page, mandatory */
|
||||||
{
|
{
|
||||||
int max_len = 255 - 8;
|
const char *str = s->serial ?: bdrv_get_device_name(s->qdev.conf.bs);
|
||||||
int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
|
int max_len = s->serial ? 20 : 255 - 8;
|
||||||
|
int id_len = strlen(str);
|
||||||
|
|
||||||
if (id_len > max_len) {
|
if (id_len > max_len) {
|
||||||
id_len = max_len;
|
id_len = max_len;
|
||||||
|
@ -486,7 +487,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
|
||||||
outbuf[buflen++] = 0; // reserved
|
outbuf[buflen++] = 0; // reserved
|
||||||
outbuf[buflen++] = id_len; // length of data following
|
outbuf[buflen++] = id_len; // length of data following
|
||||||
|
|
||||||
memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
|
memcpy(outbuf+buflen, str, id_len);
|
||||||
buflen += id_len;
|
buflen += id_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1152,9 +1153,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
|
||||||
outbuf = r->iov.iov_base;
|
outbuf = r->iov.iov_base;
|
||||||
switch (req->cmd.buf[0]) {
|
switch (req->cmd.buf[0]) {
|
||||||
case TEST_UNIT_READY:
|
case TEST_UNIT_READY:
|
||||||
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
assert(!s->tray_open && bdrv_is_inserted(s->qdev.conf.bs));
|
||||||
goto not_ready;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
buflen = scsi_disk_emulate_inquiry(req, outbuf);
|
buflen = scsi_disk_emulate_inquiry(req, outbuf);
|
||||||
|
@ -1209,7 +1208,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
|
||||||
memset(outbuf, 0, 8);
|
memset(outbuf, 0, 8);
|
||||||
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
||||||
if (!nb_sectors) {
|
if (!nb_sectors) {
|
||||||
goto not_ready;
|
scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
|
if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
|
||||||
goto illegal_request;
|
goto illegal_request;
|
||||||
|
@ -1269,7 +1269,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
|
||||||
memset(outbuf, 0, req->cmd.xfer);
|
memset(outbuf, 0, req->cmd.xfer);
|
||||||
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
||||||
if (!nb_sectors) {
|
if (!nb_sectors) {
|
||||||
goto not_ready;
|
scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
|
if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
|
||||||
goto illegal_request;
|
goto illegal_request;
|
||||||
|
@ -1314,14 +1315,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
|
||||||
buflen = MIN(buflen, req->cmd.xfer);
|
buflen = MIN(buflen, req->cmd.xfer);
|
||||||
return buflen;
|
return buflen;
|
||||||
|
|
||||||
not_ready:
|
|
||||||
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
||||||
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
|
||||||
} else {
|
|
||||||
scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
illegal_request:
|
illegal_request:
|
||||||
if (r->req.status == -1) {
|
if (r->req.status == -1) {
|
||||||
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
|
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
|
||||||
|
@ -1355,6 +1348,30 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case INQUIRY:
|
||||||
|
case MODE_SENSE:
|
||||||
|
case MODE_SENSE_10:
|
||||||
|
case RESERVE:
|
||||||
|
case RESERVE_10:
|
||||||
|
case RELEASE:
|
||||||
|
case RELEASE_10:
|
||||||
|
case START_STOP:
|
||||||
|
case ALLOW_MEDIUM_REMOVAL:
|
||||||
|
case GET_CONFIGURATION:
|
||||||
|
case GET_EVENT_STATUS_NOTIFICATION:
|
||||||
|
case MECHANISM_STATUS:
|
||||||
|
case REQUEST_SENSE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
||||||
|
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case TEST_UNIT_READY:
|
case TEST_UNIT_READY:
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
|
|
|
@ -613,5 +613,7 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
|
||||||
|
|
||||||
void virtio_scsi_exit(VirtIODevice *vdev)
|
void virtio_scsi_exit(VirtIODevice *vdev)
|
||||||
{
|
{
|
||||||
|
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||||
|
unregister_savevm(s->qdev, "virtio-scsi", s);
|
||||||
virtio_cleanup(vdev);
|
virtio_cleanup(vdev);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue