mirror of https://github.com/xemu-project/xemu.git
scsi-disk: restruct emulation: READ_TOC
Move READ_TOC emulation from scsi_send_command() to scsi_disk_emulate_command(). Add scsi_disk_emulate_read_toc() function which holds the longisch READ_TOC emulation code. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
fc903943f8
commit
02880f4349
|
@ -615,6 +615,42 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
|
||||||
|
{
|
||||||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
|
||||||
|
BlockDriverState *bdrv = req->dev->dinfo->bdrv;
|
||||||
|
int start_track, format, msf, toclen;
|
||||||
|
uint64_t nb_sectors;
|
||||||
|
|
||||||
|
msf = req->cmd.buf[1] & 2;
|
||||||
|
format = req->cmd.buf[2] & 0xf;
|
||||||
|
start_track = req->cmd.buf[6];
|
||||||
|
bdrv_get_geometry(bdrv, &nb_sectors);
|
||||||
|
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
|
||||||
|
nb_sectors /= s->cluster_size;
|
||||||
|
switch (format) {
|
||||||
|
case 0:
|
||||||
|
toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* multi session : only a single session defined */
|
||||||
|
toclen = 12;
|
||||||
|
memset(outbuf, 0, 12);
|
||||||
|
outbuf[1] = 0x0a;
|
||||||
|
outbuf[2] = 0x01;
|
||||||
|
outbuf[3] = 0x01;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (toclen > req->cmd.xfer)
|
||||||
|
toclen = req->cmd.xfer;
|
||||||
|
return toclen;
|
||||||
|
}
|
||||||
|
|
||||||
static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
|
static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
|
||||||
{
|
{
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
|
||||||
|
@ -656,6 +692,11 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
|
||||||
if (buflen < 0)
|
if (buflen < 0)
|
||||||
goto illegal_request;
|
goto illegal_request;
|
||||||
break;
|
break;
|
||||||
|
case READ_TOC:
|
||||||
|
buflen = scsi_disk_emulate_read_toc(req, outbuf);
|
||||||
|
if (buflen < 0)
|
||||||
|
goto illegal_request;
|
||||||
|
break;
|
||||||
case RESERVE:
|
case RESERVE:
|
||||||
if (req->cmd.buf[1] & 1)
|
if (req->cmd.buf[1] & 1)
|
||||||
goto illegal_request;
|
goto illegal_request;
|
||||||
|
@ -823,6 +864,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
case ALLOW_MEDIUM_REMOVAL:
|
case ALLOW_MEDIUM_REMOVAL:
|
||||||
case READ_CAPACITY:
|
case READ_CAPACITY:
|
||||||
case SYNCHRONIZE_CACHE:
|
case SYNCHRONIZE_CACHE:
|
||||||
|
case READ_TOC:
|
||||||
rc = scsi_disk_emulate_command(&r->req, outbuf);
|
rc = scsi_disk_emulate_command(&r->req, outbuf);
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
r->iov.iov_len = rc;
|
r->iov.iov_len = rc;
|
||||||
|
@ -851,44 +893,6 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
r->sector_count = len * s->cluster_size;
|
r->sector_count = len * s->cluster_size;
|
||||||
is_write = 1;
|
is_write = 1;
|
||||||
break;
|
break;
|
||||||
case READ_TOC:
|
|
||||||
{
|
|
||||||
int start_track, format, msf, toclen;
|
|
||||||
|
|
||||||
msf = buf[1] & 2;
|
|
||||||
format = buf[2] & 0xf;
|
|
||||||
start_track = buf[6];
|
|
||||||
bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
|
|
||||||
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
|
|
||||||
nb_sectors /= s->cluster_size;
|
|
||||||
switch(format) {
|
|
||||||
case 0:
|
|
||||||
toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* multi session : only a single session defined */
|
|
||||||
toclen = 12;
|
|
||||||
memset(outbuf, 0, 12);
|
|
||||||
outbuf[1] = 0x0a;
|
|
||||||
outbuf[2] = 0x01;
|
|
||||||
outbuf[3] = 0x01;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error_cmd;
|
|
||||||
}
|
|
||||||
if (toclen > 0) {
|
|
||||||
if (len > toclen)
|
|
||||||
len = toclen;
|
|
||||||
r->iov.iov_len = len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error_cmd:
|
|
||||||
DPRINTF("Read TOC error\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
case 0x46:
|
case 0x46:
|
||||||
DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
|
DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
|
||||||
memset(outbuf, 0, 8);
|
memset(outbuf, 0, 8);
|
||||||
|
|
Loading…
Reference in New Issue