Revision 428c149b
b/block_int.h | ||
---|---|---|
202 | 202 |
int is_windows_drive(const char *filename); |
203 | 203 |
#endif |
204 | 204 |
|
205 |
struct DriveInfo; |
|
206 |
|
|
207 |
typedef struct BlockConf { |
|
208 |
struct DriveInfo *dinfo; |
|
209 |
uint16_t physical_block_size; |
|
210 |
uint16_t min_io_size; |
|
211 |
uint32_t opt_io_size; |
|
212 |
} BlockConf; |
|
213 |
|
|
214 |
static inline unsigned int get_physical_block_exp(BlockConf *conf) |
|
215 |
{ |
|
216 |
unsigned int exp = 0, size; |
|
217 |
|
|
218 |
for (size = conf->physical_block_size; size > 512; size >>= 1) { |
|
219 |
exp++; |
|
220 |
} |
|
221 |
|
|
222 |
return exp; |
|
223 |
} |
|
224 |
|
|
225 |
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \ |
|
226 |
DEFINE_PROP_DRIVE("drive", _state, _conf.dinfo), \ |
|
227 |
DEFINE_PROP_UINT16("physical_block_size", _state, \ |
|
228 |
_conf.physical_block_size, 512), \ |
|
229 |
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 512), \ |
|
230 |
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 512) |
|
231 |
|
|
205 | 232 |
#endif /* BLOCK_INT_H */ |
b/hw/ide/core.c | ||
---|---|---|
2594 | 2594 |
ide_clear_hob(bus); |
2595 | 2595 |
} |
2596 | 2596 |
|
2597 |
void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version) |
|
2597 |
void ide_init_drive(IDEState *s, DriveInfo *dinfo, BlockConf *conf, |
|
2598 |
const char *version) |
|
2598 | 2599 |
{ |
2599 | 2600 |
int cylinders, heads, secs; |
2600 | 2601 |
uint64_t nb_sectors; |
... | ... | |
2619 | 2620 |
} |
2620 | 2621 |
strncpy(s->drive_serial_str, drive_get_serial(s->bs), |
2621 | 2622 |
sizeof(s->drive_serial_str)); |
2623 |
if (conf) { |
|
2624 |
s->conf = conf; |
|
2625 |
} |
|
2622 | 2626 |
} |
2623 | 2627 |
if (strlen(s->drive_serial_str) == 0) |
2624 | 2628 |
snprintf(s->drive_serial_str, sizeof(s->drive_serial_str), |
... | ... | |
2648 | 2652 |
s->sector_write_timer = qemu_new_timer(vm_clock, |
2649 | 2653 |
ide_sector_write_timer_cb, s); |
2650 | 2654 |
if (i == 0) |
2651 |
ide_init_drive(s, hd0, NULL); |
|
2655 |
ide_init_drive(s, hd0, NULL, NULL);
|
|
2652 | 2656 |
if (i == 1) |
2653 |
ide_init_drive(s, hd1, NULL); |
|
2657 |
ide_init_drive(s, hd1, NULL, NULL);
|
|
2654 | 2658 |
} |
2655 | 2659 |
bus->irq = irq; |
2656 | 2660 |
} |
b/hw/ide/internal.h | ||
---|---|---|
7 | 7 |
* non-internal declarations are in hw/ide.h |
8 | 8 |
*/ |
9 | 9 |
#include <hw/ide.h> |
10 |
#include "block_int.h" |
|
10 | 11 |
|
11 | 12 |
/* debug IDE devices */ |
12 | 13 |
//#define DEBUG_IDE |
... | ... | |
397 | 398 |
/* set for lba48 access */ |
398 | 399 |
uint8_t lba48; |
399 | 400 |
BlockDriverState *bs; |
401 |
BlockConf *conf; |
|
400 | 402 |
char version[9]; |
401 | 403 |
/* ATAPI specific */ |
402 | 404 |
uint8_t sense_key; |
... | ... | |
449 | 451 |
struct IDEDevice { |
450 | 452 |
DeviceState qdev; |
451 | 453 |
uint32_t unit; |
452 |
DriveInfo *dinfo;
|
|
454 |
BlockConf conf;
|
|
453 | 455 |
char *version; |
454 | 456 |
}; |
455 | 457 |
|
... | ... | |
551 | 553 |
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val); |
552 | 554 |
uint32_t ide_data_readl(void *opaque, uint32_t addr); |
553 | 555 |
|
554 |
void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version); |
|
556 |
void ide_init_drive(IDEState *s, DriveInfo *dinfo, BlockConf *conf, |
|
557 |
const char *version); |
|
555 | 558 |
void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1, |
556 | 559 |
qemu_irq irq); |
557 | 560 |
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2); |
b/hw/ide/qdev.c | ||
---|---|---|
40 | 40 |
IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base); |
41 | 41 |
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus); |
42 | 42 |
|
43 |
if (!dev->dinfo) { |
|
43 |
if (!dev->conf.dinfo) {
|
|
44 | 44 |
fprintf(stderr, "%s: no drive specified\n", qdev->info->name); |
45 | 45 |
goto err; |
46 | 46 |
} |
... | ... | |
99 | 99 |
static int ide_drive_initfn(IDEDevice *dev) |
100 | 100 |
{ |
101 | 101 |
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); |
102 |
ide_init_drive(bus->ifs + dev->unit, dev->dinfo, dev->version); |
|
102 |
ide_init_drive(bus->ifs + dev->unit, dev->conf.dinfo, &dev->conf, |
|
103 |
dev->version); |
|
103 | 104 |
return 0; |
104 | 105 |
} |
105 | 106 |
|
... | ... | |
109 | 110 |
.init = ide_drive_initfn, |
110 | 111 |
.qdev.props = (Property[]) { |
111 | 112 |
DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), |
112 |
DEFINE_PROP_DRIVE("drive", IDEDrive, dev.dinfo),
|
|
113 |
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),
|
|
113 | 114 |
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), |
114 | 115 |
DEFINE_PROP_END_OF_LIST(), |
115 | 116 |
} |
b/hw/s390-virtio-bus.c | ||
---|---|---|
123 | 123 |
{ |
124 | 124 |
VirtIODevice *vdev; |
125 | 125 |
|
126 |
vdev = virtio_blk_init((DeviceState *)dev, dev->dinfo); |
|
126 |
vdev = virtio_blk_init((DeviceState *)dev, dev->block.dinfo);
|
|
127 | 127 |
if (!vdev) { |
128 | 128 |
return -1; |
129 | 129 |
} |
... | ... | |
337 | 337 |
.qdev.name = "virtio-blk-s390", |
338 | 338 |
.qdev.size = sizeof(VirtIOS390Device), |
339 | 339 |
.qdev.props = (Property[]) { |
340 |
DEFINE_PROP_DRIVE("drive", VirtIOS390Device, dinfo),
|
|
340 |
DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
|
|
341 | 341 |
DEFINE_PROP_END_OF_LIST(), |
342 | 342 |
}, |
343 | 343 |
}; |
b/hw/s390-virtio-bus.h | ||
---|---|---|
38 | 38 |
ram_addr_t feat_offs; |
39 | 39 |
uint8_t feat_len; |
40 | 40 |
VirtIODevice *vdev; |
41 |
DriveInfo *dinfo;
|
|
41 |
BlockConf block;
|
|
42 | 42 |
NICConf nic; |
43 | 43 |
uint32_t host_features; |
44 | 44 |
/* Max. number of ports we can have for a the virtio-serial device */ |
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 |
}, |
b/hw/scsi-generic.c | ||
---|---|---|
58 | 58 |
struct SCSIGenericState |
59 | 59 |
{ |
60 | 60 |
SCSIDevice qdev; |
61 |
BlockDriverState *bs; |
|
61 | 62 |
int lun; |
62 | 63 |
int driver_status; |
63 | 64 |
uint8_t sensebuf[SCSI_SENSE_BUF_SIZE]; |
... | ... | |
212 | 213 |
return; |
213 | 214 |
} |
214 | 215 |
|
215 |
ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
|
|
216 |
ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
|
|
216 | 217 |
if (ret == -1) { |
217 | 218 |
scsi_command_complete(r, -EINVAL); |
218 | 219 |
return; |
... | ... | |
263 | 264 |
return 0; |
264 | 265 |
} |
265 | 266 |
|
266 |
ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
|
|
267 |
ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
|
|
267 | 268 |
if (ret == -1) { |
268 | 269 |
scsi_command_complete(r, -EINVAL); |
269 | 270 |
return 1; |
... | ... | |
357 | 358 |
qemu_free(r->buf); |
358 | 359 |
r->buflen = 0; |
359 | 360 |
r->buf = NULL; |
360 |
ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
|
|
361 |
ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
|
|
361 | 362 |
if (ret == -1) { |
362 | 363 |
scsi_command_complete(r, -EINVAL); |
363 | 364 |
return 0; |
... | ... | |
452 | 453 |
r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests)); |
453 | 454 |
scsi_remove_request(r); |
454 | 455 |
} |
455 |
drive_uninit(s->qdev.dinfo); |
|
456 |
drive_uninit(s->qdev.conf.dinfo);
|
|
456 | 457 |
} |
457 | 458 |
|
458 | 459 |
static int scsi_generic_initfn(SCSIDevice *dev) |
... | ... | |
461 | 462 |
int sg_version; |
462 | 463 |
struct sg_scsi_id scsiid; |
463 | 464 |
|
464 |
if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
|
|
465 |
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
|
|
465 | 466 |
qemu_error("scsi-generic: drive property not set\n"); |
466 | 467 |
return -1; |
467 | 468 |
} |
469 |
s->bs = s->qdev.conf.dinfo->bdrv; |
|
468 | 470 |
|
469 | 471 |
/* check we are really using a /dev/sg* file */ |
470 |
if (!bdrv_is_sg(s->qdev.dinfo->bdrv)) {
|
|
472 |
if (!bdrv_is_sg(s->bs)) {
|
|
471 | 473 |
qemu_error("scsi-generic: not /dev/sg*\n"); |
472 | 474 |
return -1; |
473 | 475 |
} |
474 | 476 |
|
475 | 477 |
/* check we are using a driver managing SG_IO (version 3 and after */ |
476 |
if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
|
|
478 |
if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
|
|
477 | 479 |
sg_version < 30000) { |
478 | 480 |
qemu_error("scsi-generic: scsi generic interface too old\n"); |
479 | 481 |
return -1; |
480 | 482 |
} |
481 | 483 |
|
482 | 484 |
/* get LUN of the /dev/sg? */ |
483 |
if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
|
|
485 |
if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
|
|
484 | 486 |
qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n"); |
485 | 487 |
return -1; |
486 | 488 |
} |
... | ... | |
491 | 493 |
s->qdev.type = scsiid.scsi_type; |
492 | 494 |
DPRINTF("device type %d\n", s->qdev.type); |
493 | 495 |
if (s->qdev.type == TYPE_TAPE) { |
494 |
s->qdev.blocksize = get_stream_blocksize(s->qdev.dinfo->bdrv);
|
|
496 |
s->qdev.blocksize = get_stream_blocksize(s->bs);
|
|
495 | 497 |
if (s->qdev.blocksize == -1) |
496 | 498 |
s->qdev.blocksize = 0; |
497 | 499 |
} else { |
498 |
s->qdev.blocksize = get_blocksize(s->qdev.dinfo->bdrv);
|
|
500 |
s->qdev.blocksize = get_blocksize(s->bs);
|
|
499 | 501 |
/* removable media returns 0 if not present */ |
500 | 502 |
if (s->qdev.blocksize <= 0) { |
501 | 503 |
if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) |
... | ... | |
522 | 524 |
.cancel_io = scsi_cancel_io, |
523 | 525 |
.get_buf = scsi_get_buf, |
524 | 526 |
.qdev.props = (Property[]) { |
525 |
DEFINE_PROP_DRIVE("drive", SCSIGenericState, qdev.dinfo),
|
|
527 |
DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
|
|
526 | 528 |
DEFINE_PROP_END_OF_LIST(), |
527 | 529 |
}, |
528 | 530 |
}; |
b/hw/scsi.h | ||
---|---|---|
3 | 3 |
|
4 | 4 |
#include "qdev.h" |
5 | 5 |
#include "block.h" |
6 |
#include "block_int.h" |
|
6 | 7 |
|
7 | 8 |
#define SCSI_CMD_BUF_SIZE 16 |
8 | 9 |
|
... | ... | |
49 | 50 |
{ |
50 | 51 |
DeviceState qdev; |
51 | 52 |
uint32_t id; |
52 |
DriveInfo *dinfo;
|
|
53 |
BlockConf conf;
|
|
53 | 54 |
SCSIDeviceInfo *info; |
54 | 55 |
QTAILQ_HEAD(, SCSIRequest) requests; |
55 | 56 |
int blocksize; |
b/hw/usb-msd.c | ||
---|---|---|
47 | 47 |
uint32_t residue; |
48 | 48 |
uint32_t tag; |
49 | 49 |
SCSIBus bus; |
50 |
DriveInfo *dinfo;
|
|
50 |
BlockConf conf;
|
|
51 | 51 |
SCSIDevice *scsi_dev; |
52 | 52 |
int result; |
53 | 53 |
/* For async completion. */ |
... | ... | |
523 | 523 |
{ |
524 | 524 |
MSDState *s = DO_UPCAST(MSDState, dev, dev); |
525 | 525 |
|
526 |
if (!s->dinfo || !s->dinfo->bdrv) {
|
|
526 |
if (!s->conf.dinfo || !s->conf.dinfo->bdrv) {
|
|
527 | 527 |
qemu_error("usb-msd: drive property not set\n"); |
528 | 528 |
return -1; |
529 | 529 |
} |
530 | 530 |
|
531 | 531 |
s->dev.speed = USB_SPEED_FULL; |
532 | 532 |
scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete); |
533 |
s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0); |
|
533 |
s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->conf.dinfo, 0);
|
|
534 | 534 |
s->bus.qbus.allow_hotplug = 0; |
535 | 535 |
usb_msd_handle_reset(dev); |
536 | 536 |
|
537 |
if (bdrv_key_required(s->dinfo->bdrv)) { |
|
537 |
if (bdrv_key_required(s->conf.dinfo->bdrv)) {
|
|
538 | 538 |
if (s->dev.qdev.hotplugged) { |
539 |
monitor_read_bdrv_key_start(cur_mon, s->dinfo->bdrv, |
|
539 |
monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv,
|
|
540 | 540 |
usb_msd_password_cb, s); |
541 | 541 |
s->dev.auto_attach = 0; |
542 | 542 |
} else { |
... | ... | |
611 | 611 |
.usbdevice_name = "disk", |
612 | 612 |
.usbdevice_init = usb_msd_init, |
613 | 613 |
.qdev.props = (Property[]) { |
614 |
DEFINE_PROP_DRIVE("drive", MSDState, dinfo),
|
|
614 |
DEFINE_BLOCK_PROPERTIES(MSDState, conf),
|
|
615 | 615 |
DEFINE_PROP_END_OF_LIST(), |
616 | 616 |
}, |
617 | 617 |
}; |
b/hw/virtio-blk.c | ||
---|---|---|
457 | 457 |
return 0; |
458 | 458 |
} |
459 | 459 |
|
460 |
VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo)
|
|
460 |
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
|
|
461 | 461 |
{ |
462 | 462 |
VirtIOBlock *s; |
463 | 463 |
int cylinders, heads, secs; |
... | ... | |
470 | 470 |
s->vdev.get_config = virtio_blk_update_config; |
471 | 471 |
s->vdev.get_features = virtio_blk_get_features; |
472 | 472 |
s->vdev.reset = virtio_blk_reset; |
473 |
s->bs = dinfo->bdrv; |
|
473 |
s->bs = conf->dinfo->bdrv;
|
|
474 | 474 |
s->rq = NULL; |
475 | 475 |
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); |
476 | 476 |
bdrv_set_geometry_hint(s->bs, cylinders, heads, secs); |
b/hw/virtio-pci.c | ||
---|---|---|
22 | 22 |
#include "sysemu.h" |
23 | 23 |
#include "msix.h" |
24 | 24 |
#include "net.h" |
25 |
#include "block_int.h" |
|
25 | 26 |
#include "loader.h" |
26 | 27 |
|
27 | 28 |
/* from Linux's linux/virtio_pci.h */ |
... | ... | |
92 | 93 |
uint32_t addr; |
93 | 94 |
uint32_t class_code; |
94 | 95 |
uint32_t nvectors; |
95 |
DriveInfo *dinfo;
|
|
96 |
BlockConf block;
|
|
96 | 97 |
NICConf nic; |
97 | 98 |
uint32_t host_features; |
98 | 99 |
/* Max. number of ports we can have for a the virtio-serial device */ |
... | ... | |
457 | 458 |
proxy->class_code != PCI_CLASS_STORAGE_OTHER) |
458 | 459 |
proxy->class_code = PCI_CLASS_STORAGE_SCSI; |
459 | 460 |
|
460 |
if (!proxy->dinfo) { |
|
461 |
if (!proxy->block.dinfo) {
|
|
461 | 462 |
qemu_error("virtio-blk-pci: drive property not set\n"); |
462 | 463 |
return -1; |
463 | 464 |
} |
464 |
vdev = virtio_blk_init(&pci_dev->qdev, proxy->dinfo);
|
|
465 |
vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
|
|
465 | 466 |
vdev->nvectors = proxy->nvectors; |
466 | 467 |
virtio_init_pci(proxy, vdev, |
467 | 468 |
PCI_VENDOR_ID_REDHAT_QUMRANET, |
... | ... | |
481 | 482 |
{ |
482 | 483 |
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); |
483 | 484 |
|
484 |
drive_uninit(proxy->dinfo); |
|
485 |
drive_uninit(proxy->block.dinfo);
|
|
485 | 486 |
return virtio_exit_pci(pci_dev); |
486 | 487 |
} |
487 | 488 |
|
... | ... | |
558 | 559 |
.exit = virtio_blk_exit_pci, |
559 | 560 |
.qdev.props = (Property[]) { |
560 | 561 |
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), |
561 |
DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo),
|
|
562 |
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
|
|
562 | 563 |
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), |
563 | 564 |
DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), |
564 | 565 |
DEFINE_PROP_END_OF_LIST(), |
b/hw/virtio.h | ||
---|---|---|
18 | 18 |
#include "net.h" |
19 | 19 |
#include "qdev.h" |
20 | 20 |
#include "sysemu.h" |
21 |
#include "block_int.h" |
|
21 | 22 |
|
22 | 23 |
/* from Linux's linux/virtio_config.h */ |
23 | 24 |
|
... | ... | |
169 | 170 |
void *opaque); |
170 | 171 |
|
171 | 172 |
/* Base devices. */ |
172 |
VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
|
|
173 |
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
|
|
173 | 174 |
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf); |
174 | 175 |
VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports); |
175 | 176 |
VirtIODevice *virtio_balloon_init(DeviceState *dev); |
Also available in: Unified diff