Revision 44740c38 hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
65 | 65 |
struct SCSIDiskState |
66 | 66 |
{ |
67 | 67 |
SCSIDevice qdev; |
68 |
BlockDriverState *bs; |
|
69 | 68 |
/* The qemu block layer uses a fixed 512 byte sector size. |
70 | 69 |
This is the number of 512 byte blocks in a single scsi sector. */ |
71 | 70 |
int cluster_size; |
... | ... | |
119 | 118 |
|
120 | 119 |
if (!r->iov.iov_base) { |
121 | 120 |
r->buflen = SCSI_DMA_BUF_SIZE; |
122 |
r->iov.iov_base = qemu_blockalign(s->bs, r->buflen); |
|
121 |
r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
|
|
123 | 122 |
} |
124 | 123 |
r->iov.iov_len = MIN(r->sector_count * 512, r->buflen); |
125 | 124 |
qemu_iovec_init_external(&r->qiov, &r->iov, 1); |
... | ... | |
134 | 133 |
|
135 | 134 |
if (r->req.aiocb != NULL) { |
136 | 135 |
r->req.aiocb = NULL; |
137 |
bdrv_acct_done(s->bs, &r->acct); |
|
136 |
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
|
|
138 | 137 |
} |
139 | 138 |
|
140 | 139 |
if (ret) { |
... | ... | |
158 | 157 |
|
159 | 158 |
if (r->req.aiocb != NULL) { |
160 | 159 |
r->req.aiocb = NULL; |
161 |
bdrv_acct_done(s->bs, &r->acct); |
|
160 |
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
|
|
162 | 161 |
} |
163 | 162 |
|
164 | 163 |
if (ret < 0) { |
... | ... | |
203 | 202 |
scsi_read_complete(r, -ENOMEDIUM); |
204 | 203 |
} |
205 | 204 |
n = scsi_init_iovec(r); |
206 |
bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); |
|
207 |
r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, |
|
205 |
bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
|
|
206 |
r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
|
|
208 | 207 |
scsi_read_complete, r); |
209 | 208 |
if (r->req.aiocb == NULL) { |
210 | 209 |
scsi_read_complete(r, -EIO); |
... | ... | |
215 | 214 |
{ |
216 | 215 |
int is_read = (type == SCSI_REQ_STATUS_RETRY_READ); |
217 | 216 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); |
218 |
BlockErrorAction action = bdrv_get_on_error(s->bs, is_read); |
|
217 |
BlockErrorAction action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
|
|
219 | 218 |
|
220 | 219 |
if (action == BLOCK_ERR_IGNORE) { |
221 |
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read); |
|
220 |
bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
|
|
222 | 221 |
return 0; |
223 | 222 |
} |
224 | 223 |
|
... | ... | |
228 | 227 |
type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK; |
229 | 228 |
r->status |= SCSI_REQ_STATUS_RETRY | type; |
230 | 229 |
|
231 |
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); |
|
230 |
bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
|
|
232 | 231 |
vm_stop(RUN_STATE_IO_ERROR); |
233 |
bdrv_iostatus_set_err(s->bs, error); |
|
232 |
bdrv_iostatus_set_err(s->qdev.conf.bs, error);
|
|
234 | 233 |
} else { |
235 | 234 |
switch (error) { |
236 | 235 |
case ENOMEDIUM: |
... | ... | |
246 | 245 |
scsi_check_condition(r, SENSE_CODE(IO_ERROR)); |
247 | 246 |
break; |
248 | 247 |
} |
249 |
bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); |
|
248 |
bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
|
|
250 | 249 |
} |
251 | 250 |
return 1; |
252 | 251 |
} |
... | ... | |
259 | 258 |
|
260 | 259 |
if (r->req.aiocb != NULL) { |
261 | 260 |
r->req.aiocb = NULL; |
262 |
bdrv_acct_done(s->bs, &r->acct); |
|
261 |
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
|
|
263 | 262 |
} |
264 | 263 |
|
265 | 264 |
if (ret) { |
... | ... | |
300 | 299 |
if (s->tray_open) { |
301 | 300 |
scsi_write_complete(r, -ENOMEDIUM); |
302 | 301 |
} |
303 |
bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); |
|
304 |
r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, |
|
302 |
bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
|
|
303 |
r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
|
|
305 | 304 |
scsi_write_complete, r); |
306 | 305 |
if (r->req.aiocb == NULL) { |
307 | 306 |
scsi_write_complete(r, -ENOMEM); |
... | ... | |
440 | 439 |
case 0x83: /* Device identification page, mandatory */ |
441 | 440 |
{ |
442 | 441 |
int max_len = 255 - 8; |
443 |
int id_len = strlen(bdrv_get_device_name(s->bs)); |
|
442 |
int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
|
|
444 | 443 |
|
445 | 444 |
if (id_len > max_len) { |
446 | 445 |
id_len = max_len; |
... | ... | |
454 | 453 |
outbuf[buflen++] = 0; // reserved |
455 | 454 |
outbuf[buflen++] = id_len; // length of data following |
456 | 455 |
|
457 |
memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len); |
|
456 |
memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
|
|
458 | 457 |
buflen += id_len; |
459 | 458 |
break; |
460 | 459 |
} |
... | ... | |
571 | 570 |
if (s->qdev.type != TYPE_ROM) { |
572 | 571 |
return false; |
573 | 572 |
} |
574 |
if (!bdrv_is_inserted(s->bs)) { |
|
573 |
if (!bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
575 | 574 |
return false; |
576 | 575 |
} |
577 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
576 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
578 | 577 |
return nb_sectors > CD_MAX_SECTORS; |
579 | 578 |
} |
580 | 579 |
|
... | ... | |
584 | 583 |
if (s->qdev.type != TYPE_ROM) { |
585 | 584 |
return false; |
586 | 585 |
} |
587 |
if (!bdrv_is_inserted(s->bs)) { |
|
586 |
if (!bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
588 | 587 |
return false; |
589 | 588 |
} |
590 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
589 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
591 | 590 |
return nb_sectors <= CD_MAX_SECTORS; |
592 | 591 |
} |
593 | 592 |
|
... | ... | |
615 | 614 |
} |
616 | 615 |
|
617 | 616 |
if (format != 0xff) { |
618 |
if (s->tray_open || !bdrv_is_inserted(s->bs)) { |
|
617 |
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
619 | 618 |
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); |
620 | 619 |
return -1; |
621 | 620 |
} |
... | ... | |
637 | 636 |
if (layer != 0) { |
638 | 637 |
goto fail; |
639 | 638 |
} |
640 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
639 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
641 | 640 |
|
642 | 641 |
outbuf[4] = 1; /* DVD-ROM, part version 1 */ |
643 | 642 |
outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ |
... | ... | |
692 | 691 |
media_status = 0; |
693 | 692 |
if (s->tray_open) { |
694 | 693 |
media_status = MS_TRAY_OPEN; |
695 |
} else if (bdrv_is_inserted(s->bs)) { |
|
694 |
} else if (bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
696 | 695 |
media_status = MS_MEDIA_PRESENT; |
697 | 696 |
} |
698 | 697 |
|
... | ... | |
795 | 794 |
[MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM), |
796 | 795 |
}; |
797 | 796 |
|
798 |
BlockDriverState *bdrv = s->bs; |
|
797 |
BlockDriverState *bdrv = s->qdev.conf.bs;
|
|
799 | 798 |
int cylinders, heads, secs; |
800 | 799 |
uint8_t *p = *p_outbuf; |
801 | 800 |
|
... | ... | |
887 | 886 |
if (page_control == 1) { /* Changeable Values */ |
888 | 887 |
break; |
889 | 888 |
} |
890 |
if (bdrv_enable_write_cache(s->bs)) { |
|
889 |
if (bdrv_enable_write_cache(s->qdev.conf.bs)) {
|
|
891 | 890 |
p[2] = 4; /* WCE */ |
892 | 891 |
} |
893 | 892 |
break; |
... | ... | |
959 | 958 |
memset(outbuf, 0, r->req.cmd.xfer); |
960 | 959 |
p = outbuf; |
961 | 960 |
|
962 |
if (bdrv_is_read_only(s->bs)) { |
|
961 |
if (bdrv_is_read_only(s->qdev.conf.bs)) {
|
|
963 | 962 |
dev_specific_param = 0x80; /* Readonly. */ |
964 | 963 |
} else { |
965 | 964 |
dev_specific_param = 0x00; |
... | ... | |
977 | 976 |
p += 8; |
978 | 977 |
} |
979 | 978 |
|
980 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
979 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
981 | 980 |
if (!dbd && nb_sectors) { |
982 | 981 |
if (r->req.cmd.buf[0] == MODE_SENSE) { |
983 | 982 |
outbuf[3] = 8; /* Block descriptor length */ |
... | ... | |
1043 | 1042 |
msf = req->cmd.buf[1] & 2; |
1044 | 1043 |
format = req->cmd.buf[2] & 0xf; |
1045 | 1044 |
start_track = req->cmd.buf[6]; |
1046 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
1045 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
1047 | 1046 |
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); |
1048 | 1047 |
nb_sectors /= s->cluster_size; |
1049 | 1048 |
switch (format) { |
... | ... | |
1080 | 1079 |
if (s->qdev.type == TYPE_ROM && loej) { |
1081 | 1080 |
if (!start && !s->tray_open && s->tray_locked) { |
1082 | 1081 |
scsi_check_condition(r, |
1083 |
bdrv_is_inserted(s->bs) |
|
1082 |
bdrv_is_inserted(s->qdev.conf.bs)
|
|
1084 | 1083 |
? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED) |
1085 | 1084 |
: SENSE_CODE(NOT_READY_REMOVAL_PREVENTED)); |
1086 | 1085 |
return -1; |
1087 | 1086 |
} |
1088 |
bdrv_eject(s->bs, !start); |
|
1087 |
bdrv_eject(s->qdev.conf.bs, !start);
|
|
1089 | 1088 |
s->tray_open = !start; |
1090 | 1089 |
} |
1091 | 1090 |
return 0; |
... | ... | |
1112 | 1111 |
goto illegal_request; |
1113 | 1112 |
} |
1114 | 1113 |
r->buflen = MAX(4096, req->cmd.xfer); |
1115 |
r->iov.iov_base = qemu_blockalign(s->bs, r->buflen); |
|
1114 |
r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
|
|
1116 | 1115 |
} |
1117 | 1116 |
|
1118 | 1117 |
outbuf = r->iov.iov_base; |
1119 | 1118 |
switch (req->cmd.buf[0]) { |
1120 | 1119 |
case TEST_UNIT_READY: |
1121 |
if (s->tray_open || !bdrv_is_inserted(s->bs)) { |
|
1120 |
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
1122 | 1121 |
goto not_ready; |
1123 | 1122 |
} |
1124 | 1123 |
break; |
... | ... | |
1168 | 1167 |
break; |
1169 | 1168 |
case ALLOW_MEDIUM_REMOVAL: |
1170 | 1169 |
s->tray_locked = req->cmd.buf[4] & 1; |
1171 |
bdrv_lock_medium(s->bs, req->cmd.buf[4] & 1); |
|
1170 |
bdrv_lock_medium(s->qdev.conf.bs, req->cmd.buf[4] & 1);
|
|
1172 | 1171 |
break; |
1173 | 1172 |
case READ_CAPACITY_10: |
1174 | 1173 |
/* The normal LEN field for this command is zero. */ |
1175 | 1174 |
memset(outbuf, 0, 8); |
1176 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
1175 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
1177 | 1176 |
if (!nb_sectors) { |
1178 | 1177 |
goto not_ready; |
1179 | 1178 |
} |
... | ... | |
1228 | 1227 |
if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { |
1229 | 1228 |
DPRINTF("SAI READ CAPACITY(16)\n"); |
1230 | 1229 |
memset(outbuf, 0, req->cmd.xfer); |
1231 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
1230 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
1232 | 1231 |
if (!nb_sectors) { |
1233 | 1232 |
goto not_ready; |
1234 | 1233 |
} |
... | ... | |
1275 | 1274 |
return buflen; |
1276 | 1275 |
|
1277 | 1276 |
not_ready: |
1278 |
if (s->tray_open || !bdrv_is_inserted(s->bs)) { |
|
1277 |
if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
1279 | 1278 |
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); |
1280 | 1279 |
} else { |
1281 | 1280 |
scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); |
... | ... | |
1342 | 1341 |
r->iov.iov_len = rc; |
1343 | 1342 |
break; |
1344 | 1343 |
case SYNCHRONIZE_CACHE: |
1345 |
bdrv_acct_start(s->bs, &r->acct, 0, BDRV_ACCT_FLUSH); |
|
1346 |
r->req.aiocb = bdrv_aio_flush(s->bs, scsi_flush_complete, r); |
|
1344 |
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
|
|
1345 |
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r);
|
|
1347 | 1346 |
if (r->req.aiocb == NULL) { |
1348 | 1347 |
scsi_flush_complete(r, -EIO); |
1349 | 1348 |
} |
... | ... | |
1418 | 1417 |
goto fail; |
1419 | 1418 |
} |
1420 | 1419 |
|
1421 |
rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size, |
|
1420 |
rc = bdrv_discard(s->qdev.conf.bs, r->req.cmd.lba * s->cluster_size,
|
|
1422 | 1421 |
len * s->cluster_size); |
1423 | 1422 |
if (rc < 0) { |
1424 | 1423 |
/* XXX: better error code ?*/ |
... | ... | |
1460 | 1459 |
|
1461 | 1460 |
scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET)); |
1462 | 1461 |
|
1463 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
1462 |
bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
|
|
1464 | 1463 |
nb_sectors /= s->cluster_size; |
1465 | 1464 |
if (nb_sectors) { |
1466 | 1465 |
nb_sectors--; |
... | ... | |
1530 | 1529 |
error_report("scsi-disk: drive property not set"); |
1531 | 1530 |
return -1; |
1532 | 1531 |
} |
1533 |
s->bs = s->qdev.conf.bs; |
|
1534 | 1532 |
|
1535 |
if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) { |
|
1533 |
if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->qdev.conf.bs)) {
|
|
1536 | 1534 |
error_report("Device needs media, but drive is empty"); |
1537 | 1535 |
return -1; |
1538 | 1536 |
} |
1539 | 1537 |
|
1540 | 1538 |
if (!s->serial) { |
1541 | 1539 |
/* try to fall back to value set with legacy -drive serial=... */ |
1542 |
dinfo = drive_get_by_blockdev(s->bs); |
|
1540 |
dinfo = drive_get_by_blockdev(s->qdev.conf.bs);
|
|
1543 | 1541 |
if (*dinfo->serial) { |
1544 | 1542 |
s->serial = g_strdup(dinfo->serial); |
1545 | 1543 |
} |
... | ... | |
1549 | 1547 |
s->version = g_strdup(QEMU_VERSION); |
1550 | 1548 |
} |
1551 | 1549 |
|
1552 |
if (bdrv_is_sg(s->bs)) { |
|
1550 |
if (bdrv_is_sg(s->qdev.conf.bs)) {
|
|
1553 | 1551 |
error_report("scsi-disk: unwanted /dev/sg*"); |
1554 | 1552 |
return -1; |
1555 | 1553 |
} |
1556 | 1554 |
|
1557 | 1555 |
if (scsi_type == TYPE_ROM) { |
1558 |
bdrv_set_dev_ops(s->bs, &scsi_cd_block_ops, s); |
|
1556 |
bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s);
|
|
1559 | 1557 |
s->qdev.blocksize = 2048; |
1560 | 1558 |
} else if (scsi_type == TYPE_DISK) { |
1561 | 1559 |
s->qdev.blocksize = s->qdev.conf.logical_block_size; |
... | ... | |
1564 | 1562 |
return -1; |
1565 | 1563 |
} |
1566 | 1564 |
s->cluster_size = s->qdev.blocksize / 512; |
1567 |
bdrv_set_buffer_alignment(s->bs, s->qdev.blocksize); |
|
1565 |
bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize);
|
|
1568 | 1566 |
|
1569 | 1567 |
s->qdev.type = scsi_type; |
1570 | 1568 |
qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s); |
1571 |
bdrv_iostatus_enable(s->bs); |
|
1569 |
bdrv_iostatus_enable(s->qdev.conf.bs);
|
|
1572 | 1570 |
add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0"); |
1573 | 1571 |
return 0; |
1574 | 1572 |
} |
Also available in: Unified diff