Revision 428c149b hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
60 | 60 |
struct SCSIDiskState |
61 | 61 |
{ |
62 | 62 |
SCSIDevice qdev; |
63 |
BlockDriverState *bs; |
|
63 | 64 |
/* The qemu block layer uses a fixed 512 byte sector size. |
64 | 65 |
This is the number of 512 byte blocks in a single scsi sector. */ |
65 | 66 |
int cluster_size; |
... | ... | |
168 | 169 |
|
169 | 170 |
r->iov.iov_len = n * 512; |
170 | 171 |
qemu_iovec_init_external(&r->qiov, &r->iov, 1); |
171 |
r->req.aiocb = bdrv_aio_readv(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
|
|
172 |
r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
|
|
172 | 173 |
scsi_read_complete, r); |
173 | 174 |
if (r->req.aiocb == NULL) |
174 | 175 |
scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); |
... | ... | |
179 | 180 |
static int scsi_handle_write_error(SCSIDiskReq *r, int error) |
180 | 181 |
{ |
181 | 182 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); |
182 |
BlockInterfaceErrorAction action = |
|
183 |
drive_get_on_error(s->qdev.dinfo->bdrv, 0); |
|
183 |
BlockInterfaceErrorAction action = drive_get_on_error(s->bs, 0); |
|
184 | 184 |
|
185 | 185 |
if (action == BLOCK_ERR_IGNORE) { |
186 |
bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_IGNORE, 0);
|
|
186 |
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, 0);
|
|
187 | 187 |
return 0; |
188 | 188 |
} |
189 | 189 |
|
... | ... | |
191 | 191 |
|| action == BLOCK_ERR_STOP_ANY) { |
192 | 192 |
r->status |= SCSI_REQ_STATUS_RETRY; |
193 | 193 |
vm_stop(0); |
194 |
bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_STOP, 0);
|
|
194 |
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, 0);
|
|
195 | 195 |
} else { |
196 | 196 |
scsi_command_complete(r, CHECK_CONDITION, |
197 | 197 |
HARDWARE_ERROR); |
198 |
bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_REPORT, 0);
|
|
198 |
bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, 0);
|
|
199 | 199 |
} |
200 | 200 |
|
201 | 201 |
return 1; |
... | ... | |
238 | 238 |
n = r->iov.iov_len / 512; |
239 | 239 |
if (n) { |
240 | 240 |
qemu_iovec_init_external(&r->qiov, &r->iov, 1); |
241 |
r->req.aiocb = bdrv_aio_writev(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
|
|
241 |
r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
|
|
242 | 242 |
scsi_write_complete, r); |
243 | 243 |
if (r->req.aiocb == NULL) |
244 | 244 |
scsi_command_complete(r, CHECK_CONDITION, |
... | ... | |
319 | 319 |
|
320 | 320 |
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) |
321 | 321 |
{ |
322 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv; |
|
323 | 322 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); |
324 | 323 |
int buflen = 0; |
325 | 324 |
|
... | ... | |
338 | 337 |
return -1; |
339 | 338 |
} |
340 | 339 |
|
341 |
if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
|
|
340 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
|
|
342 | 341 |
outbuf[buflen++] = 5; |
343 | 342 |
} else { |
344 | 343 |
outbuf[buflen++] = 0; |
... | ... | |
358 | 357 |
|
359 | 358 |
case 0x80: /* Device serial number, optional */ |
360 | 359 |
{ |
361 |
const char *serial = req->dev->dinfo->serial ? |
|
362 |
req->dev->dinfo->serial : "0"; |
|
360 |
const char *serial = req->dev->conf.dinfo->serial ?
|
|
361 |
req->dev->conf.dinfo->serial : "0";
|
|
363 | 362 |
int l = strlen(serial); |
364 | 363 |
|
365 | 364 |
if (l > req->cmd.xfer) |
... | ... | |
378 | 377 |
case 0x83: /* Device identification page, mandatory */ |
379 | 378 |
{ |
380 | 379 |
int max_len = 255 - 8; |
381 |
int id_len = strlen(bdrv_get_device_name(bdrv));
|
|
380 |
int id_len = strlen(bdrv_get_device_name(s->bs));
|
|
382 | 381 |
|
383 | 382 |
if (id_len > max_len) |
384 | 383 |
id_len = max_len; |
... | ... | |
391 | 390 |
outbuf[buflen++] = 0; // reserved |
392 | 391 |
outbuf[buflen++] = id_len; // length of data following |
393 | 392 |
|
394 |
memcpy(outbuf+buflen, bdrv_get_device_name(bdrv), id_len);
|
|
393 |
memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
|
|
395 | 394 |
buflen += id_len; |
396 | 395 |
break; |
397 | 396 |
} |
... | ... | |
429 | 428 |
return buflen; |
430 | 429 |
} |
431 | 430 |
|
432 |
if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
|
|
431 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
|
|
433 | 432 |
outbuf[0] = 5; |
434 | 433 |
outbuf[1] = 0x80; |
435 | 434 |
memcpy(&outbuf[16], "QEMU CD-ROM ", 16); |
... | ... | |
460 | 459 |
static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p) |
461 | 460 |
{ |
462 | 461 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); |
463 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv;
|
|
462 |
BlockDriverState *bdrv = s->bs;
|
|
464 | 463 |
int cylinders, heads, secs; |
465 | 464 |
|
466 | 465 |
switch (page) { |
... | ... | |
532 | 531 |
case 8: /* Caching page. */ |
533 | 532 |
p[0] = 8; |
534 | 533 |
p[1] = 0x12; |
535 |
if (bdrv_enable_write_cache(s->qdev.dinfo->bdrv)) {
|
|
534 |
if (bdrv_enable_write_cache(s->bs)) {
|
|
536 | 535 |
p[2] = 4; /* WCE */ |
537 | 536 |
} |
538 | 537 |
return 20; |
... | ... | |
549 | 548 |
p[5] = 0xff; /* CD DA, DA accurate, RW supported, |
550 | 549 |
RW corrected, C2 errors, ISRC, |
551 | 550 |
UPC, Bar code */ |
552 |
p[6] = 0x2d | (bdrv_is_locked(s->qdev.dinfo->bdrv)? 2 : 0);
|
|
551 |
p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
|
|
553 | 552 |
/* Locking supported, jumper present, eject, tray */ |
554 | 553 |
p[7] = 0; /* no volume & mute control, no |
555 | 554 |
changer */ |
... | ... | |
575 | 574 |
static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) |
576 | 575 |
{ |
577 | 576 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); |
578 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv; |
|
579 | 577 |
uint64_t nb_sectors; |
580 | 578 |
int page, dbd, buflen; |
581 | 579 |
uint8_t *p; |
... | ... | |
588 | 586 |
|
589 | 587 |
p[1] = 0; /* Default media type. */ |
590 | 588 |
p[3] = 0; /* Block descriptor length. */ |
591 |
if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM ||
|
|
592 |
bdrv_is_read_only(bdrv)) {
|
|
589 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM ||
|
|
590 |
bdrv_is_read_only(s->bs)) {
|
|
593 | 591 |
p[2] = 0x80; /* Readonly. */ |
594 | 592 |
} |
595 | 593 |
p += 4; |
596 | 594 |
|
597 |
bdrv_get_geometry(bdrv, &nb_sectors);
|
|
595 |
bdrv_get_geometry(s->bs, &nb_sectors);
|
|
598 | 596 |
if ((~dbd) & nb_sectors) { |
599 | 597 |
outbuf[3] = 8; /* Block descriptor length */ |
600 | 598 |
nb_sectors /= s->cluster_size; |
... | ... | |
635 | 633 |
static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) |
636 | 634 |
{ |
637 | 635 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); |
638 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv; |
|
639 | 636 |
int start_track, format, msf, toclen; |
640 | 637 |
uint64_t nb_sectors; |
641 | 638 |
|
642 | 639 |
msf = req->cmd.buf[1] & 2; |
643 | 640 |
format = req->cmd.buf[2] & 0xf; |
644 | 641 |
start_track = req->cmd.buf[6]; |
645 |
bdrv_get_geometry(bdrv, &nb_sectors);
|
|
642 |
bdrv_get_geometry(s->bs, &nb_sectors);
|
|
646 | 643 |
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); |
647 | 644 |
nb_sectors /= s->cluster_size; |
648 | 645 |
switch (format) { |
... | ... | |
671 | 668 |
static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) |
672 | 669 |
{ |
673 | 670 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); |
674 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv; |
|
675 | 671 |
uint64_t nb_sectors; |
676 | 672 |
int buflen = 0; |
677 | 673 |
|
678 | 674 |
switch (req->cmd.buf[0]) { |
679 | 675 |
case TEST_UNIT_READY: |
680 |
if (!bdrv_is_inserted(bdrv))
|
|
676 |
if (!bdrv_is_inserted(s->bs))
|
|
681 | 677 |
goto not_ready; |
682 | 678 |
break; |
683 | 679 |
case REQUEST_SENSE: |
... | ... | |
731 | 727 |
goto illegal_request; |
732 | 728 |
break; |
733 | 729 |
case START_STOP: |
734 |
if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
|
|
730 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
|
|
735 | 731 |
/* load/eject medium */ |
736 |
bdrv_eject(bdrv, !(req->cmd.buf[4] & 1));
|
|
732 |
bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
|
|
737 | 733 |
} |
738 | 734 |
break; |
739 | 735 |
case ALLOW_MEDIUM_REMOVAL: |
740 |
bdrv_set_locked(bdrv, req->cmd.buf[4] & 1);
|
|
736 |
bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
|
|
741 | 737 |
break; |
742 | 738 |
case READ_CAPACITY: |
743 | 739 |
/* The normal LEN field for this command is zero. */ |
744 | 740 |
memset(outbuf, 0, 8); |
745 |
bdrv_get_geometry(bdrv, &nb_sectors);
|
|
741 |
bdrv_get_geometry(s->bs, &nb_sectors);
|
|
746 | 742 |
if (!nb_sectors) |
747 | 743 |
goto not_ready; |
748 | 744 |
nb_sectors /= s->cluster_size; |
... | ... | |
764 | 760 |
buflen = 8; |
765 | 761 |
break; |
766 | 762 |
case SYNCHRONIZE_CACHE: |
767 |
bdrv_flush(bdrv);
|
|
763 |
bdrv_flush(s->bs);
|
|
768 | 764 |
break; |
769 | 765 |
case GET_CONFIGURATION: |
770 | 766 |
memset(outbuf, 0, 8); |
... | ... | |
778 | 774 |
if ((req->cmd.buf[1] & 31) == 0x10) { |
779 | 775 |
DPRINTF("SAI READ CAPACITY(16)\n"); |
780 | 776 |
memset(outbuf, 0, req->cmd.xfer); |
781 |
bdrv_get_geometry(bdrv, &nb_sectors);
|
|
777 |
bdrv_get_geometry(s->bs, &nb_sectors);
|
|
782 | 778 |
if (!nb_sectors) |
783 | 779 |
goto not_ready; |
784 | 780 |
nb_sectors /= s->cluster_size; |
... | ... | |
993 | 989 |
r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); |
994 | 990 |
scsi_remove_request(r); |
995 | 991 |
} |
996 |
drive_uninit(s->qdev.dinfo); |
|
992 |
drive_uninit(s->qdev.conf.dinfo);
|
|
997 | 993 |
} |
998 | 994 |
|
999 | 995 |
static int scsi_disk_initfn(SCSIDevice *dev) |
... | ... | |
1001 | 997 |
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); |
1002 | 998 |
uint64_t nb_sectors; |
1003 | 999 |
|
1004 |
if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
|
|
1000 |
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
|
|
1005 | 1001 |
qemu_error("scsi-disk: drive property not set\n"); |
1006 | 1002 |
return -1; |
1007 | 1003 |
} |
1004 |
s->bs = s->qdev.conf.dinfo->bdrv; |
|
1008 | 1005 |
|
1009 |
if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
|
|
1006 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
|
|
1010 | 1007 |
s->cluster_size = 4; |
1011 | 1008 |
} else { |
1012 | 1009 |
s->cluster_size = 1; |
1013 | 1010 |
} |
1014 | 1011 |
s->qdev.blocksize = 512 * s->cluster_size; |
1015 | 1012 |
s->qdev.type = TYPE_DISK; |
1016 |
bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
|
|
1013 |
bdrv_get_geometry(s->bs, &nb_sectors);
|
|
1017 | 1014 |
nb_sectors /= s->cluster_size; |
1018 | 1015 |
if (nb_sectors) |
1019 | 1016 |
nb_sectors--; |
... | ... | |
1034 | 1031 |
.cancel_io = scsi_cancel_io, |
1035 | 1032 |
.get_buf = scsi_get_buf, |
1036 | 1033 |
.qdev.props = (Property[]) { |
1037 |
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo),
|
|
1034 |
DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),
|
|
1038 | 1035 |
DEFINE_PROP_STRING("ver", SCSIDiskState, version), |
1039 | 1036 |
DEFINE_PROP_END_OF_LIST(), |
1040 | 1037 |
}, |
Also available in: Unified diff