Commit 33f002714be2ed58ed05ae3870d5ea6915df4b47
1 parent
3e98dc8e
Add "cache" parameter to "-drive" (Laurent Vivier).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3848 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
12 changed files
with
102 additions
and
32 deletions
block-raw-posix.c
@@ -106,6 +106,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) | @@ -106,6 +106,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) | ||
106 | } | 106 | } |
107 | if (flags & BDRV_O_CREAT) | 107 | if (flags & BDRV_O_CREAT) |
108 | open_flags |= O_CREAT | O_TRUNC; | 108 | open_flags |= O_CREAT | O_TRUNC; |
109 | +#ifdef O_DIRECT | ||
110 | + if (flags & BDRV_O_DIRECT) | ||
111 | + open_flags |= O_DIRECT; | ||
112 | +#endif | ||
109 | 113 | ||
110 | s->type = FTYPE_FILE; | 114 | s->type = FTYPE_FILE; |
111 | 115 | ||
@@ -659,6 +663,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) | @@ -659,6 +663,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) | ||
659 | open_flags |= O_RDONLY; | 663 | open_flags |= O_RDONLY; |
660 | bs->read_only = 1; | 664 | bs->read_only = 1; |
661 | } | 665 | } |
666 | +#ifdef O_DIRECT | ||
667 | + if (flags & BDRV_O_DIRECT) | ||
668 | + open_flags |= O_DIRECT; | ||
669 | +#endif | ||
662 | 670 | ||
663 | s->type = FTYPE_FILE; | 671 | s->type = FTYPE_FILE; |
664 | #if defined(__linux__) | 672 | #if defined(__linux__) |
block-raw-win32.c
@@ -105,6 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) | @@ -105,6 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) | ||
105 | #else | 105 | #else |
106 | overlapped = FILE_FLAG_OVERLAPPED; | 106 | overlapped = FILE_FLAG_OVERLAPPED; |
107 | #endif | 107 | #endif |
108 | + if (flags & BDRV_O_DIRECT) | ||
109 | + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; | ||
108 | s->hfile = CreateFile(filename, access_flags, | 110 | s->hfile = CreateFile(filename, access_flags, |
109 | FILE_SHARE_READ, NULL, | 111 | FILE_SHARE_READ, NULL, |
110 | create_flags, overlapped, NULL); | 112 | create_flags, overlapped, NULL); |
@@ -473,6 +475,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) | @@ -473,6 +475,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) | ||
473 | #else | 475 | #else |
474 | overlapped = FILE_FLAG_OVERLAPPED; | 476 | overlapped = FILE_FLAG_OVERLAPPED; |
475 | #endif | 477 | #endif |
478 | + if (flags & BDRV_O_DIRECT) | ||
479 | + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; | ||
476 | s->hfile = CreateFile(filename, access_flags, | 480 | s->hfile = CreateFile(filename, access_flags, |
477 | FILE_SHARE_READ, NULL, | 481 | FILE_SHARE_READ, NULL, |
478 | create_flags, overlapped, NULL); | 482 | create_flags, overlapped, NULL); |
block.c
@@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | @@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
380 | /* Note: for compatibility, we open disk image files as RDWR, and | 380 | /* Note: for compatibility, we open disk image files as RDWR, and |
381 | RDONLY as fallback */ | 381 | RDONLY as fallback */ |
382 | if (!(flags & BDRV_O_FILE)) | 382 | if (!(flags & BDRV_O_FILE)) |
383 | - open_flags = BDRV_O_RDWR; | 383 | + open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT); |
384 | else | 384 | else |
385 | open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); | 385 | open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); |
386 | ret = drv->bdrv_open(bs, filename, open_flags); | 386 | ret = drv->bdrv_open(bs, filename, open_flags); |
block.h
@@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo { | @@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo { | ||
44 | use a disk image format on top of | 44 | use a disk image format on top of |
45 | it (default for | 45 | it (default for |
46 | bdrv_file_open()) */ | 46 | bdrv_file_open()) */ |
47 | +#define BDRV_O_DIRECT 0x0020 | ||
47 | 48 | ||
48 | #ifndef QEMU_IMG | 49 | #ifndef QEMU_IMG |
49 | void bdrv_info(void); | 50 | void bdrv_info(void); |
hw/fdc.c
@@ -382,7 +382,7 @@ struct fdctrl_t { | @@ -382,7 +382,7 @@ struct fdctrl_t { | ||
382 | uint8_t cur_drv; | 382 | uint8_t cur_drv; |
383 | uint8_t bootsel; | 383 | uint8_t bootsel; |
384 | /* Command FIFO */ | 384 | /* Command FIFO */ |
385 | - uint8_t fifo[FD_SECTOR_LEN]; | 385 | + uint8_t *fifo; |
386 | uint32_t data_pos; | 386 | uint32_t data_pos; |
387 | uint32_t data_len; | 387 | uint32_t data_len; |
388 | uint8_t data_state; | 388 | uint8_t data_state; |
@@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, | @@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, | ||
598 | fdctrl = qemu_mallocz(sizeof(fdctrl_t)); | 598 | fdctrl = qemu_mallocz(sizeof(fdctrl_t)); |
599 | if (!fdctrl) | 599 | if (!fdctrl) |
600 | return NULL; | 600 | return NULL; |
601 | + fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); | ||
602 | + if (fdctrl->fifo == NULL) { | ||
603 | + qemu_free(fdctrl); | ||
604 | + return NULL; | ||
605 | + } | ||
601 | fdctrl->result_timer = qemu_new_timer(vm_clock, | 606 | fdctrl->result_timer = qemu_new_timer(vm_clock, |
602 | fdctrl_result_timer, fdctrl); | 607 | fdctrl_result_timer, fdctrl); |
603 | 608 |
hw/ide.c
@@ -365,7 +365,7 @@ typedef struct IDEState { | @@ -365,7 +365,7 @@ typedef struct IDEState { | ||
365 | EndTransferFunc *end_transfer_func; | 365 | EndTransferFunc *end_transfer_func; |
366 | uint8_t *data_ptr; | 366 | uint8_t *data_ptr; |
367 | uint8_t *data_end; | 367 | uint8_t *data_end; |
368 | - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; | 368 | + uint8_t *io_buffer; |
369 | QEMUTimer *sector_write_timer; /* only used for win2k install hack */ | 369 | QEMUTimer *sector_write_timer; /* only used for win2k install hack */ |
370 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ | 370 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ |
371 | /* CF-ATA extended error */ | 371 | /* CF-ATA extended error */ |
@@ -2377,17 +2377,24 @@ struct partition { | @@ -2377,17 +2377,24 @@ struct partition { | ||
2377 | static int guess_disk_lchs(IDEState *s, | 2377 | static int guess_disk_lchs(IDEState *s, |
2378 | int *pcylinders, int *pheads, int *psectors) | 2378 | int *pcylinders, int *pheads, int *psectors) |
2379 | { | 2379 | { |
2380 | - uint8_t buf[512]; | 2380 | + uint8_t *buf; |
2381 | int ret, i, heads, sectors, cylinders; | 2381 | int ret, i, heads, sectors, cylinders; |
2382 | struct partition *p; | 2382 | struct partition *p; |
2383 | uint32_t nr_sects; | 2383 | uint32_t nr_sects; |
2384 | 2384 | ||
2385 | + buf = qemu_memalign(512, 512); | ||
2386 | + if (buf == NULL) | ||
2387 | + return -1; | ||
2385 | ret = bdrv_read(s->bs, 0, buf, 1); | 2388 | ret = bdrv_read(s->bs, 0, buf, 1); |
2386 | - if (ret < 0) | 2389 | + if (ret < 0) { |
2390 | + qemu_free(buf); | ||
2387 | return -1; | 2391 | return -1; |
2392 | + } | ||
2388 | /* test msdos magic */ | 2393 | /* test msdos magic */ |
2389 | - if (buf[510] != 0x55 || buf[511] != 0xaa) | 2394 | + if (buf[510] != 0x55 || buf[511] != 0xaa) { |
2395 | + qemu_free(buf); | ||
2390 | return -1; | 2396 | return -1; |
2397 | + } | ||
2391 | for(i = 0; i < 4; i++) { | 2398 | for(i = 0; i < 4; i++) { |
2392 | p = ((struct partition *)(buf + 0x1be)) + i; | 2399 | p = ((struct partition *)(buf + 0x1be)) + i; |
2393 | nr_sects = le32_to_cpu(p->nr_sects); | 2400 | nr_sects = le32_to_cpu(p->nr_sects); |
@@ -2408,9 +2415,11 @@ static int guess_disk_lchs(IDEState *s, | @@ -2408,9 +2415,11 @@ static int guess_disk_lchs(IDEState *s, | ||
2408 | printf("guessed geometry: LCHS=%d %d %d\n", | 2415 | printf("guessed geometry: LCHS=%d %d %d\n", |
2409 | cylinders, heads, sectors); | 2416 | cylinders, heads, sectors); |
2410 | #endif | 2417 | #endif |
2418 | + qemu_free(buf); | ||
2411 | return 0; | 2419 | return 0; |
2412 | } | 2420 | } |
2413 | } | 2421 | } |
2422 | + qemu_free(buf); | ||
2414 | return -1; | 2423 | return -1; |
2415 | } | 2424 | } |
2416 | 2425 | ||
@@ -2425,6 +2434,7 @@ static void ide_init2(IDEState *ide_state, | @@ -2425,6 +2434,7 @@ static void ide_init2(IDEState *ide_state, | ||
2425 | 2434 | ||
2426 | for(i = 0; i < 2; i++) { | 2435 | for(i = 0; i < 2; i++) { |
2427 | s = ide_state + i; | 2436 | s = ide_state + i; |
2437 | + s->io_buffer = qemu_memalign(512, MAX_MULT_SECTORS*512 + 4); | ||
2428 | if (i == 0) | 2438 | if (i == 0) |
2429 | s->bs = hd0; | 2439 | s->bs = hd0; |
2430 | else | 2440 | else |
hw/scsi-disk.c
@@ -46,7 +46,7 @@ typedef struct SCSIRequest { | @@ -46,7 +46,7 @@ typedef struct SCSIRequest { | ||
46 | int sector_count; | 46 | int sector_count; |
47 | /* The amounnt of data in the buffer. */ | 47 | /* The amounnt of data in the buffer. */ |
48 | int buf_len; | 48 | int buf_len; |
49 | - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; | 49 | + uint8_t *dma_buf; |
50 | BlockDriverAIOCB *aiocb; | 50 | BlockDriverAIOCB *aiocb; |
51 | struct SCSIRequest *next; | 51 | struct SCSIRequest *next; |
52 | } SCSIRequest; | 52 | } SCSIRequest; |
@@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag) | @@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag) | ||
78 | free_requests = r->next; | 78 | free_requests = r->next; |
79 | } else { | 79 | } else { |
80 | r = qemu_malloc(sizeof(SCSIRequest)); | 80 | r = qemu_malloc(sizeof(SCSIRequest)); |
81 | + r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE); | ||
81 | } | 82 | } |
82 | r->dev = s; | 83 | r->dev = s; |
83 | r->tag = tag; | 84 | r->tag = tag; |
hw/sd.c
@@ -96,6 +96,7 @@ struct SDState { | @@ -96,6 +96,7 @@ struct SDState { | ||
96 | qemu_irq readonly_cb; | 96 | qemu_irq readonly_cb; |
97 | qemu_irq inserted_cb; | 97 | qemu_irq inserted_cb; |
98 | BlockDriverState *bdrv; | 98 | BlockDriverState *bdrv; |
99 | + uint8_t *buf; | ||
99 | }; | 100 | }; |
100 | 101 | ||
101 | static void sd_set_status(SDState *sd) | 102 | static void sd_set_status(SDState *sd) |
@@ -405,6 +406,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) | @@ -405,6 +406,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) | ||
405 | SDState *sd; | 406 | SDState *sd; |
406 | 407 | ||
407 | sd = (SDState *) qemu_mallocz(sizeof(SDState)); | 408 | sd = (SDState *) qemu_mallocz(sizeof(SDState)); |
409 | + sd->buf = qemu_memalign(512, 512); | ||
408 | sd->spi = is_spi; | 410 | sd->spi = is_spi; |
409 | sd_reset(sd, bs); | 411 | sd_reset(sd, bs); |
410 | bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); | 412 | bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); |
@@ -1281,64 +1283,60 @@ int sd_do_command(SDState *sd, struct sd_request_s *req, | @@ -1281,64 +1283,60 @@ int sd_do_command(SDState *sd, struct sd_request_s *req, | ||
1281 | } | 1283 | } |
1282 | 1284 | ||
1283 | /* No real need for 64 bit addresses here */ | 1285 | /* No real need for 64 bit addresses here */ |
1284 | -static void sd_blk_read(BlockDriverState *bdrv, | ||
1285 | - void *data, uint32_t addr, uint32_t len) | 1286 | +static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len) |
1286 | { | 1287 | { |
1287 | - uint8_t buf[512]; | ||
1288 | uint32_t end = addr + len; | 1288 | uint32_t end = addr + len; |
1289 | 1289 | ||
1290 | - if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) { | 1290 | + if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { |
1291 | printf("sd_blk_read: read error on host side\n"); | 1291 | printf("sd_blk_read: read error on host side\n"); |
1292 | return; | 1292 | return; |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | if (end > (addr & ~511) + 512) { | 1295 | if (end > (addr & ~511) + 512) { |
1296 | - memcpy(data, buf + (addr & 511), 512 - (addr & 511)); | 1296 | + memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511)); |
1297 | 1297 | ||
1298 | - if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) { | 1298 | + if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { |
1299 | printf("sd_blk_read: read error on host side\n"); | 1299 | printf("sd_blk_read: read error on host side\n"); |
1300 | return; | 1300 | return; |
1301 | } | 1301 | } |
1302 | - memcpy(data + 512 - (addr & 511), buf, end & 511); | 1302 | + memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511); |
1303 | } else | 1303 | } else |
1304 | - memcpy(data, buf + (addr & 511), len); | 1304 | + memcpy(sd->data, sd->buf + (addr & 511), len); |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | -static void sd_blk_write(BlockDriverState *bdrv, | ||
1308 | - void *data, uint32_t addr, uint32_t len) | 1307 | +static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len) |
1309 | { | 1308 | { |
1310 | - uint8_t buf[512]; | ||
1311 | uint32_t end = addr + len; | 1309 | uint32_t end = addr + len; |
1312 | 1310 | ||
1313 | if ((addr & 511) || len < 512) | 1311 | if ((addr & 511) || len < 512) |
1314 | - if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) { | 1312 | + if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { |
1315 | printf("sd_blk_write: read error on host side\n"); | 1313 | printf("sd_blk_write: read error on host side\n"); |
1316 | return; | 1314 | return; |
1317 | } | 1315 | } |
1318 | 1316 | ||
1319 | if (end > (addr & ~511) + 512) { | 1317 | if (end > (addr & ~511) + 512) { |
1320 | - memcpy(buf + (addr & 511), data, 512 - (addr & 511)); | ||
1321 | - if (bdrv_write(bdrv, addr >> 9, buf, 1) == -1) { | 1318 | + memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511)); |
1319 | + if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { | ||
1322 | printf("sd_blk_write: write error on host side\n"); | 1320 | printf("sd_blk_write: write error on host side\n"); |
1323 | return; | 1321 | return; |
1324 | } | 1322 | } |
1325 | 1323 | ||
1326 | - if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) { | 1324 | + if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { |
1327 | printf("sd_blk_write: read error on host side\n"); | 1325 | printf("sd_blk_write: read error on host side\n"); |
1328 | return; | 1326 | return; |
1329 | } | 1327 | } |
1330 | - memcpy(buf, data + 512 - (addr & 511), end & 511); | ||
1331 | - if (bdrv_write(bdrv, end >> 9, buf, 1) == -1) | 1328 | + memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511); |
1329 | + if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1) | ||
1332 | printf("sd_blk_write: write error on host side\n"); | 1330 | printf("sd_blk_write: write error on host side\n"); |
1333 | } else { | 1331 | } else { |
1334 | - memcpy(buf + (addr & 511), data, len); | ||
1335 | - if (!bdrv || bdrv_write(bdrv, addr >> 9, buf, 1) == -1) | 1332 | + memcpy(sd->buf + (addr & 511), sd->data, len); |
1333 | + if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) | ||
1336 | printf("sd_blk_write: write error on host side\n"); | 1334 | printf("sd_blk_write: write error on host side\n"); |
1337 | } | 1335 | } |
1338 | } | 1336 | } |
1339 | 1337 | ||
1340 | -#define BLK_READ_BLOCK(a, len) sd_blk_read(sd->bdrv, sd->data, a, len) | ||
1341 | -#define BLK_WRITE_BLOCK(a, len) sd_blk_write(sd->bdrv, sd->data, a, len) | 1338 | +#define BLK_READ_BLOCK(a, len) sd_blk_read(sd, a, len) |
1339 | +#define BLK_WRITE_BLOCK(a, len) sd_blk_write(sd, a, len) | ||
1342 | #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len) | 1340 | #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len) |
1343 | #define APP_WRITE_BLOCK(a, len) | 1341 | #define APP_WRITE_BLOCK(a, len) |
1344 | 1342 |
osdep.c
@@ -61,6 +61,10 @@ void *qemu_malloc(size_t size) | @@ -61,6 +61,10 @@ void *qemu_malloc(size_t size) | ||
61 | } | 61 | } |
62 | 62 | ||
63 | #if defined(_WIN32) | 63 | #if defined(_WIN32) |
64 | +void *qemu_memalign(size_t alignment, size_t size) | ||
65 | +{ | ||
66 | + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); | ||
67 | +} | ||
64 | 68 | ||
65 | void *qemu_vmalloc(size_t size) | 69 | void *qemu_vmalloc(size_t size) |
66 | { | 70 | { |
@@ -172,6 +176,22 @@ static void kqemu_vfree(void *ptr) | @@ -172,6 +176,22 @@ static void kqemu_vfree(void *ptr) | ||
172 | 176 | ||
173 | #endif | 177 | #endif |
174 | 178 | ||
179 | +void *qemu_memalign(size_t alignment, size_t size) | ||
180 | +{ | ||
181 | +#if defined(_POSIX_C_SOURCE) | ||
182 | + int ret; | ||
183 | + void *ptr; | ||
184 | + ret = posix_memalign(&ptr, alignment, size); | ||
185 | + if (ret != 0) | ||
186 | + return NULL; | ||
187 | + return ptr; | ||
188 | +#elif defined(_BSD) | ||
189 | + return valloc(size); | ||
190 | +#else | ||
191 | + return memalign(alignment, size); | ||
192 | +#endif | ||
193 | +} | ||
194 | + | ||
175 | /* alloc shared memory pages */ | 195 | /* alloc shared memory pages */ |
176 | void *qemu_vmalloc(size_t size) | 196 | void *qemu_vmalloc(size_t size) |
177 | { | 197 | { |
osdep.h
@@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size); | @@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size); | ||
48 | void qemu_free(void *ptr); | 48 | void qemu_free(void *ptr); |
49 | char *qemu_strdup(const char *str); | 49 | char *qemu_strdup(const char *str); |
50 | 50 | ||
51 | +void *qemu_memalign(size_t alignment, size_t size); | ||
51 | void *qemu_vmalloc(size_t size); | 52 | void *qemu_vmalloc(size_t size); |
52 | void qemu_vfree(void *ptr); | 53 | void qemu_vfree(void *ptr); |
53 | 54 |
qemu-doc.texi
@@ -250,6 +250,8 @@ This option defines the type of the media: disk or cdrom. | @@ -250,6 +250,8 @@ This option defines the type of the media: disk or cdrom. | ||
250 | These options have the same definition as they have in @option{-hdachs}. | 250 | These options have the same definition as they have in @option{-hdachs}. |
251 | @item snapshot=@var{snapshot} | 251 | @item snapshot=@var{snapshot} |
252 | @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). | 252 | @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). |
253 | +@item cache=@var{cache} | ||
254 | +@var{cache} is "on" or "off" and allows to disable host cache to access data. | ||
253 | @end table | 255 | @end table |
254 | 256 | ||
255 | Instead of @option{-cdrom} you can use: | 257 | Instead of @option{-cdrom} you can use: |
vl.c
@@ -4880,8 +4880,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | @@ -4880,8 +4880,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | ||
4880 | BlockDriverState *bdrv; | 4880 | BlockDriverState *bdrv; |
4881 | int max_devs; | 4881 | int max_devs; |
4882 | int index; | 4882 | int index; |
4883 | + int cache; | ||
4884 | + int bdrv_flags; | ||
4883 | char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", | 4885 | char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", |
4884 | - "secs", "trans", "media", "snapshot", "file", NULL }; | 4886 | + "secs", "trans", "media", "snapshot", "file", |
4887 | + "cache", NULL }; | ||
4885 | 4888 | ||
4886 | if (check_params(buf, sizeof(buf), params, str) < 0) { | 4889 | if (check_params(buf, sizeof(buf), params, str) < 0) { |
4887 | fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", | 4890 | fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", |
@@ -4895,6 +4898,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | @@ -4895,6 +4898,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | ||
4895 | unit_id = -1; | 4898 | unit_id = -1; |
4896 | translation = BIOS_ATA_TRANSLATION_AUTO; | 4899 | translation = BIOS_ATA_TRANSLATION_AUTO; |
4897 | index = -1; | 4900 | index = -1; |
4901 | + cache = 1; | ||
4898 | 4902 | ||
4899 | if (!strcmp(machine->name, "realview") || | 4903 | if (!strcmp(machine->name, "realview") || |
4900 | !strcmp(machine->name, "SS-5") || | 4904 | !strcmp(machine->name, "SS-5") || |
@@ -5037,6 +5041,17 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | @@ -5037,6 +5041,17 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | ||
5037 | } | 5041 | } |
5038 | } | 5042 | } |
5039 | 5043 | ||
5044 | + if (get_param_value(buf, sizeof(buf), "cache", str)) { | ||
5045 | + if (!strcmp(buf, "off")) | ||
5046 | + cache = 0; | ||
5047 | + else if (!strcmp(buf, "on")) | ||
5048 | + cache = 1; | ||
5049 | + else { | ||
5050 | + fprintf(stderr, "qemu: invalid cache option\n"); | ||
5051 | + return -1; | ||
5052 | + } | ||
5053 | + } | ||
5054 | + | ||
5040 | get_param_value(file, sizeof(file), "file", str); | 5055 | get_param_value(file, sizeof(file), "file", str); |
5041 | 5056 | ||
5042 | /* compute bus and unit according index */ | 5057 | /* compute bus and unit according index */ |
@@ -5131,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | @@ -5131,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) | ||
5131 | } | 5146 | } |
5132 | if (!file[0]) | 5147 | if (!file[0]) |
5133 | return 0; | 5148 | return 0; |
5134 | - if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || | ||
5135 | - qemu_key_check(bdrv, file)) { | 5149 | + bdrv_flags = 0; |
5150 | + if (snapshot) | ||
5151 | + bdrv_flags |= BDRV_O_SNAPSHOT; | ||
5152 | + if (!cache) | ||
5153 | + bdrv_flags |= BDRV_O_DIRECT; | ||
5154 | + if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) { | ||
5136 | fprintf(stderr, "qemu: could not open disk image %s\n", | 5155 | fprintf(stderr, "qemu: could not open disk image %s\n", |
5137 | file); | 5156 | file); |
5138 | return -1; | 5157 | return -1; |
@@ -7480,7 +7499,8 @@ static void help(int exitcode) | @@ -7480,7 +7499,8 @@ static void help(int exitcode) | ||
7480 | "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" | 7499 | "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" |
7481 | "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" | 7500 | "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" |
7482 | "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" | 7501 | "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" |
7483 | - " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n" | 7502 | + " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]" |
7503 | + " [,cache=on|off]\n" | ||
7484 | " use 'file' as a drive image\n" | 7504 | " use 'file' as a drive image\n" |
7485 | "-mtdblock file use 'file' as on-board Flash memory image\n" | 7505 | "-mtdblock file use 'file' as on-board Flash memory image\n" |
7486 | "-sd file use 'file' as SecureDigital card image\n" | 7506 | "-sd file use 'file' as SecureDigital card image\n" |