]> git.proxmox.com Git - qemu.git/blame - block/raw-posix.c
raw-posix: refactor AIO support
[qemu.git] / block / raw-posix.c
CommitLineData
83f64091 1/*
223d4670 2 * Block driver for RAW files (posix)
5fafdf24 3 *
83f64091 4 * Copyright (c) 2006 Fabrice Bellard
5fafdf24 5 *
83f64091
FB
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
faf07963 24#include "qemu-common.h"
87ecb68b 25#include "qemu-timer.h"
baf35cb9 26#include "qemu-char.h"
0bf9e31a 27#include "qemu-log.h"
83f64091 28#include "block_int.h"
5efa9d5a 29#include "module.h"
9ef91a67 30#include "block/raw-posix-aio.h"
83f64091 31
83f64091
FB
32#ifdef CONFIG_COCOA
33#include <paths.h>
34#include <sys/param.h>
35#include <IOKit/IOKitLib.h>
36#include <IOKit/IOBSD.h>
37#include <IOKit/storage/IOMediaBSDClient.h>
38#include <IOKit/storage/IOMedia.h>
39#include <IOKit/storage/IOCDMedia.h>
40//#include <IOKit/storage/IOCDTypes.h>
41#include <CoreFoundation/CoreFoundation.h>
42#endif
43
44#ifdef __sun__
2e9671da
TS
45#define _POSIX_PTHREAD_SEMANTICS 1
46#include <signal.h>
83f64091
FB
47#include <sys/dkio.h>
48#endif
19cb3738
FB
49#ifdef __linux__
50#include <sys/ioctl.h>
51#include <linux/cdrom.h>
52#include <linux/fd.h>
53#endif
1cb6c3fd 54#ifdef __FreeBSD__
543952ca 55#include <signal.h>
1cb6c3fd 56#include <sys/disk.h>
9f23011a 57#include <sys/cdio.h>
1cb6c3fd 58#endif
83f64091 59
128ab2ff
BS
60#ifdef __OpenBSD__
61#include <sys/ioctl.h>
62#include <sys/disklabel.h>
63#include <sys/dkio.h>
64#endif
65
c5e97233
BS
66#ifdef __DragonFly__
67#include <sys/ioctl.h>
68#include <sys/diskslice.h>
69#endif
70
19cb3738 71//#define DEBUG_FLOPPY
83f64091 72
faf07963 73//#define DEBUG_BLOCK
03ff3ca3 74#if defined(DEBUG_BLOCK)
001faf32
BS
75#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
76 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
8c05dbf9 77#else
001faf32 78#define DEBUG_BLOCK_PRINT(formatCstr, ...)
8c05dbf9
TS
79#endif
80
f6465578
AL
81/* OS X does not have O_DSYNC */
82#ifndef O_DSYNC
1c27a8b3 83#ifdef O_SYNC
7ab064d2 84#define O_DSYNC O_SYNC
1c27a8b3 85#elif defined(O_FSYNC)
86#define O_DSYNC O_FSYNC
87#endif
f6465578
AL
88#endif
89
9f7965c7
AL
90/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
91#ifndef O_DIRECT
92#define O_DIRECT O_DSYNC
93#endif
94
19cb3738
FB
95#define FTYPE_FILE 0
96#define FTYPE_CD 1
97#define FTYPE_FD 2
83f64091 98
bed5cc52
FB
99#define ALIGNED_BUFFER_SIZE (32 * 512)
100
19cb3738
FB
101/* if the FD is not accessed during that time (in ms), we try to
102 reopen it to see if the disk has been changed */
103#define FD_OPEN_TIMEOUT 1000
83f64091 104
19cb3738
FB
105typedef struct BDRVRawState {
106 int fd;
107 int type;
8c05dbf9 108 unsigned int lseek_err_cnt;
0e1d8f4c 109 int open_flags;
9ef91a67 110 void *aio_ctx;
19cb3738
FB
111#if defined(__linux__)
112 /* linux floppy specific */
19cb3738
FB
113 int64_t fd_open_time;
114 int64_t fd_error_time;
115 int fd_got_error;
116 int fd_media_changed;
83f64091 117#endif
bed5cc52 118 uint8_t* aligned_buf;
19cb3738
FB
119} BDRVRawState;
120
121static int fd_open(BlockDriverState *bs);
22afa7b5 122static int64_t raw_getlength(BlockDriverState *bs);
83f64091 123
9f23011a 124#if defined(__FreeBSD__)
f3a5d3f8 125static int cdrom_reopen(BlockDriverState *bs);
9f23011a
BS
126#endif
127
90babde0 128static int raw_open_common(BlockDriverState *bs, const char *filename,
19a3da7f 129 int bdrv_flags, int open_flags)
83f64091
FB
130{
131 BDRVRawState *s = bs->opaque;
0e1d8f4c 132 int fd, ret;
83f64091 133
8c05dbf9
TS
134 s->lseek_err_cnt = 0;
135
19a3da7f 136 s->open_flags = open_flags | O_BINARY;
11a1feb6 137 s->open_flags &= ~O_ACCMODE;
19a3da7f 138 if ((bdrv_flags & BDRV_O_ACCESS) == BDRV_O_RDWR) {
0e1d8f4c 139 s->open_flags |= O_RDWR;
83f64091 140 } else {
0e1d8f4c 141 s->open_flags |= O_RDONLY;
83f64091
FB
142 bs->read_only = 1;
143 }
9f7965c7
AL
144
145 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
146 * and O_DIRECT for no caching. */
19a3da7f 147 if ((bdrv_flags & BDRV_O_NOCACHE))
0e1d8f4c 148 s->open_flags |= O_DIRECT;
19a3da7f 149 else if (!(bdrv_flags & BDRV_O_CACHE_WB))
0e1d8f4c 150 s->open_flags |= O_DSYNC;
83f64091 151
90babde0 152 s->fd = -1;
0e1d8f4c 153 fd = open(filename, s->open_flags, 0644);
19cb3738
FB
154 if (fd < 0) {
155 ret = -errno;
156 if (ret == -EROFS)
157 ret = -EACCES;
158 return ret;
159 }
83f64091 160 s->fd = fd;
bed5cc52 161 s->aligned_buf = NULL;
19a3da7f 162 if ((bdrv_flags & BDRV_O_NOCACHE)) {
e268ca52 163 s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
bed5cc52 164 if (s->aligned_buf == NULL) {
9ef91a67 165 goto out_close;
bed5cc52
FB
166 }
167 }
9ef91a67
CH
168
169 s->aio_ctx = paio_init();
170 if (!s->aio_ctx) {
171 goto out_free_buf;
172 }
173
83f64091 174 return 0;
9ef91a67
CH
175
176out_free_buf:
177 qemu_vfree(s->aligned_buf);
178out_close:
179 close(fd);
180 return -errno;
83f64091
FB
181}
182
90babde0
CH
183static int raw_open(BlockDriverState *bs, const char *filename, int flags)
184{
185 BDRVRawState *s = bs->opaque;
19a3da7f 186 int open_flags = 0;
90babde0
CH
187
188 s->type = FTYPE_FILE;
189 if (flags & BDRV_O_CREAT)
19a3da7f 190 open_flags = O_CREAT | O_TRUNC;
90babde0 191
19a3da7f 192 return raw_open_common(bs, filename, flags, open_flags);
90babde0
CH
193}
194
83f64091
FB
195/* XXX: use host sector size if necessary with:
196#ifdef DIOCGSECTORSIZE
197 {
198 unsigned int sectorsize = 512;
199 if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
200 sectorsize > bufsize)
201 bufsize = sectorsize;
202 }
203#endif
204#ifdef CONFIG_COCOA
205 u_int32_t blockSize = 512;
206 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
207 bufsize = blockSize;
208 }
209#endif
210*/
211
bed5cc52
FB
212/*
213 * offset and count are in bytes, but must be multiples of 512 for files
214 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
215 *
216 * This function may be called without alignment if the caller ensures
217 * that O_DIRECT is not in effect.
218 */
219static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
83f64091
FB
220 uint8_t *buf, int count)
221{
222 BDRVRawState *s = bs->opaque;
223 int ret;
3b46e624 224
19cb3738
FB
225 ret = fd_open(bs);
226 if (ret < 0)
227 return ret;
228
985a03b0 229 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
8c05dbf9
TS
230 ++(s->lseek_err_cnt);
231 if(s->lseek_err_cnt <= 10) {
92868412
JM
232 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
233 "] lseek failed : %d = %s\n",
8c05dbf9
TS
234 s->fd, bs->filename, offset, buf, count,
235 bs->total_sectors, errno, strerror(errno));
236 }
237 return -1;
238 }
239 s->lseek_err_cnt=0;
240
83f64091 241 ret = read(s->fd, buf, count);
8c05dbf9
TS
242 if (ret == count)
243 goto label__raw_read__success;
244
22afa7b5
KW
245 /* Allow reads beyond the end (needed for pwrite) */
246 if ((ret == 0) && bs->growable) {
247 int64_t size = raw_getlength(bs);
248 if (offset >= size) {
249 memset(buf, 0, count);
250 ret = count;
251 goto label__raw_read__success;
252 }
253 }
254
92868412
JM
255 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
256 "] read failed %d : %d = %s\n",
8c05dbf9
TS
257 s->fd, bs->filename, offset, buf, count,
258 bs->total_sectors, ret, errno, strerror(errno));
259
260 /* Try harder for CDrom. */
261 if (bs->type == BDRV_TYPE_CDROM) {
262 lseek(s->fd, offset, SEEK_SET);
263 ret = read(s->fd, buf, count);
264 if (ret == count)
265 goto label__raw_read__success;
266 lseek(s->fd, offset, SEEK_SET);
267 ret = read(s->fd, buf, count);
268 if (ret == count)
269 goto label__raw_read__success;
270
92868412
JM
271 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
272 "] retry read failed %d : %d = %s\n",
8c05dbf9
TS
273 s->fd, bs->filename, offset, buf, count,
274 bs->total_sectors, ret, errno, strerror(errno));
275 }
276
8c05dbf9
TS
277label__raw_read__success:
278
94c6d6d8 279 return (ret < 0) ? -errno : ret;
83f64091
FB
280}
281
bed5cc52
FB
282/*
283 * offset and count are in bytes, but must be multiples of 512 for files
284 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
285 *
286 * This function may be called without alignment if the caller ensures
287 * that O_DIRECT is not in effect.
288 */
289static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
83f64091
FB
290 const uint8_t *buf, int count)
291{
292 BDRVRawState *s = bs->opaque;
293 int ret;
3b46e624 294
19cb3738
FB
295 ret = fd_open(bs);
296 if (ret < 0)
4141d4c2 297 return -errno;
19cb3738 298
985a03b0 299 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
8c05dbf9
TS
300 ++(s->lseek_err_cnt);
301 if(s->lseek_err_cnt) {
92868412
JM
302 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
303 PRId64 "] lseek failed : %d = %s\n",
8c05dbf9
TS
304 s->fd, bs->filename, offset, buf, count,
305 bs->total_sectors, errno, strerror(errno));
306 }
4141d4c2 307 return -EIO;
8c05dbf9
TS
308 }
309 s->lseek_err_cnt = 0;
310
83f64091 311 ret = write(s->fd, buf, count);
8c05dbf9
TS
312 if (ret == count)
313 goto label__raw_write__success;
314
92868412
JM
315 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
316 "] write failed %d : %d = %s\n",
8c05dbf9
TS
317 s->fd, bs->filename, offset, buf, count,
318 bs->total_sectors, ret, errno, strerror(errno));
319
8c05dbf9
TS
320label__raw_write__success:
321
4141d4c2 322 return (ret < 0) ? -errno : ret;
83f64091
FB
323}
324
bed5cc52 325
bed5cc52
FB
326/*
327 * offset and count are in bytes and possibly not aligned. For files opened
328 * with O_DIRECT, necessary alignments are ensured before calling
329 * raw_pread_aligned to do the actual read.
330 */
331static int raw_pread(BlockDriverState *bs, int64_t offset,
332 uint8_t *buf, int count)
333{
334 BDRVRawState *s = bs->opaque;
335 int size, ret, shift, sum;
336
337 sum = 0;
338
339 if (s->aligned_buf != NULL) {
340
341 if (offset & 0x1ff) {
342 /* align offset on a 512 bytes boundary */
343
344 shift = offset & 0x1ff;
345 size = (shift + count + 0x1ff) & ~0x1ff;
346 if (size > ALIGNED_BUFFER_SIZE)
347 size = ALIGNED_BUFFER_SIZE;
348 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
349 if (ret < 0)
350 return ret;
351
352 size = 512 - shift;
353 if (size > count)
354 size = count;
355 memcpy(buf, s->aligned_buf + shift, size);
356
357 buf += size;
358 offset += size;
359 count -= size;
360 sum += size;
361
362 if (count == 0)
363 return sum;
364 }
365 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
366
367 /* read on aligned buffer */
368
369 while (count) {
370
371 size = (count + 0x1ff) & ~0x1ff;
372 if (size > ALIGNED_BUFFER_SIZE)
373 size = ALIGNED_BUFFER_SIZE;
374
375 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
376 if (ret < 0)
377 return ret;
378
379 size = ret;
380 if (size > count)
381 size = count;
382
383 memcpy(buf, s->aligned_buf, size);
384
385 buf += size;
386 offset += size;
387 count -= size;
388 sum += size;
389 }
390
391 return sum;
392 }
393 }
394
395 return raw_pread_aligned(bs, offset, buf, count) + sum;
396}
397
eda578e5
AL
398static int raw_read(BlockDriverState *bs, int64_t sector_num,
399 uint8_t *buf, int nb_sectors)
400{
537a1d4b
AL
401 int ret;
402
403 ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
404 if (ret == (nb_sectors * 512))
405 ret = 0;
406 return ret;
eda578e5
AL
407}
408
bed5cc52
FB
409/*
410 * offset and count are in bytes and possibly not aligned. For files opened
411 * with O_DIRECT, necessary alignments are ensured before calling
412 * raw_pwrite_aligned to do the actual write.
413 */
414static int raw_pwrite(BlockDriverState *bs, int64_t offset,
415 const uint8_t *buf, int count)
416{
417 BDRVRawState *s = bs->opaque;
418 int size, ret, shift, sum;
419
420 sum = 0;
421
422 if (s->aligned_buf != NULL) {
423
424 if (offset & 0x1ff) {
425 /* align offset on a 512 bytes boundary */
426 shift = offset & 0x1ff;
427 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
428 if (ret < 0)
429 return ret;
430
431 size = 512 - shift;
432 if (size > count)
433 size = count;
434 memcpy(s->aligned_buf + shift, buf, size);
435
436 ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
437 if (ret < 0)
438 return ret;
439
440 buf += size;
441 offset += size;
442 count -= size;
443 sum += size;
444
445 if (count == 0)
446 return sum;
447 }
448 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
449
450 while ((size = (count & ~0x1ff)) != 0) {
451
452 if (size > ALIGNED_BUFFER_SIZE)
453 size = ALIGNED_BUFFER_SIZE;
454
455 memcpy(s->aligned_buf, buf, size);
456
457 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
458 if (ret < 0)
459 return ret;
460
461 buf += ret;
462 offset += ret;
463 count -= ret;
464 sum += ret;
465 }
466 /* here, count < 512 because (count & ~0x1ff) == 0 */
467 if (count) {
468 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
469 if (ret < 0)
470 return ret;
471 memcpy(s->aligned_buf, buf, count);
472
473 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
474 if (ret < 0)
475 return ret;
476 if (count < ret)
477 ret = count;
478
479 sum += ret;
480 }
481 return sum;
482 }
483 }
484 return raw_pwrite_aligned(bs, offset, buf, count) + sum;
485}
486
eda578e5
AL
487static int raw_write(BlockDriverState *bs, int64_t sector_num,
488 const uint8_t *buf, int nb_sectors)
489{
537a1d4b
AL
490 int ret;
491 ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
492 if (ret == (nb_sectors * 512))
493 ret = 0;
494 return ret;
eda578e5
AL
495}
496
9ef91a67
CH
497/*
498 * Check if all memory in this vector is sector aligned.
499 */
500static int qiov_is_aligned(QEMUIOVector *qiov)
a76bab49 501{
9ef91a67 502 int i;
83f64091 503
9ef91a67
CH
504 for (i = 0; i < qiov->niov; i++) {
505 if ((uintptr_t) qiov->iov[i].iov_base % 512) {
506 return 0;
c16b5a2c 507 }
c16b5a2c 508 }
c16b5a2c 509
9ef91a67 510 return 1;
c16b5a2c
CH
511}
512
9ef91a67
CH
513static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
514 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
515 BlockDriverCompletionFunc *cb, void *opaque, int type)
83f64091 516{
ce1a14dc 517 BDRVRawState *s = bs->opaque;
ce1a14dc 518
19cb3738
FB
519 if (fd_open(bs) < 0)
520 return NULL;
521
f141eafe
AL
522 /*
523 * If O_DIRECT is used the buffer needs to be aligned on a sector
9ef91a67
CH
524 * boundary. Check if this is the case or telll the low-level
525 * driver that it needs to copy the buffer.
f141eafe 526 */
9ef91a67
CH
527 if (s->aligned_buf && !qiov_is_aligned(qiov)) {
528 type |= QEMU_AIO_MISALIGNED;
529 }
f141eafe 530
9ef91a67
CH
531 return paio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, nb_sectors,
532 cb, opaque, type);
83f64091
FB
533}
534
f141eafe
AL
535static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
536 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
ce1a14dc 537 BlockDriverCompletionFunc *cb, void *opaque)
83f64091 538{
9ef91a67
CH
539 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
540 cb, opaque, QEMU_AIO_READ);
83f64091
FB
541}
542
f141eafe
AL
543static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
544 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
ce1a14dc 545 BlockDriverCompletionFunc *cb, void *opaque)
83f64091 546{
9ef91a67
CH
547 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
548 cb, opaque, QEMU_AIO_WRITE);
83f64091 549}
53538725 550
83f64091
FB
551static void raw_close(BlockDriverState *bs)
552{
553 BDRVRawState *s = bs->opaque;
19cb3738
FB
554 if (s->fd >= 0) {
555 close(s->fd);
556 s->fd = -1;
bed5cc52
FB
557 if (s->aligned_buf != NULL)
558 qemu_free(s->aligned_buf);
19cb3738 559 }
83f64091
FB
560}
561
562static int raw_truncate(BlockDriverState *bs, int64_t offset)
563{
564 BDRVRawState *s = bs->opaque;
19cb3738
FB
565 if (s->type != FTYPE_FILE)
566 return -ENOTSUP;
83f64091
FB
567 if (ftruncate(s->fd, offset) < 0)
568 return -errno;
569 return 0;
570}
571
128ab2ff
BS
572#ifdef __OpenBSD__
573static int64_t raw_getlength(BlockDriverState *bs)
574{
575 BDRVRawState *s = bs->opaque;
576 int fd = s->fd;
577 struct stat st;
578
579 if (fstat(fd, &st))
580 return -1;
581 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
582 struct disklabel dl;
583
584 if (ioctl(fd, DIOCGDINFO, &dl))
585 return -1;
586 return (uint64_t)dl.d_secsize *
587 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
588 } else
589 return st.st_size;
590}
591#else /* !__OpenBSD__ */
83f64091
FB
592static int64_t raw_getlength(BlockDriverState *bs)
593{
594 BDRVRawState *s = bs->opaque;
595 int fd = s->fd;
596 int64_t size;
71e72a19 597#ifdef CONFIG_BSD
83f64091 598 struct stat sb;
9f23011a
BS
599#ifdef __FreeBSD__
600 int reopened = 0;
601#endif
83f64091
FB
602#endif
603#ifdef __sun__
604 struct dk_minfo minfo;
605 int rv;
606#endif
19cb3738
FB
607 int ret;
608
609 ret = fd_open(bs);
610 if (ret < 0)
611 return ret;
83f64091 612
71e72a19 613#ifdef CONFIG_BSD
9f23011a
BS
614#ifdef __FreeBSD__
615again:
616#endif
83f64091
FB
617 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
618#ifdef DIOCGMEDIASIZE
619 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
c5e97233
BS
620#elif defined(DIOCGPART)
621 {
622 struct partinfo pi;
623 if (ioctl(fd, DIOCGPART, &pi) == 0)
624 size = pi.media_size;
625 else
626 size = 0;
627 }
628 if (size == 0)
83f64091
FB
629#endif
630#ifdef CONFIG_COCOA
631 size = LONG_LONG_MAX;
632#else
633 size = lseek(fd, 0LL, SEEK_END);
9f23011a
BS
634#endif
635#ifdef __FreeBSD__
636 switch(s->type) {
637 case FTYPE_CD:
638 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
639 if (size == 2048LL * (unsigned)-1)
640 size = 0;
641 /* XXX no disc? maybe we need to reopen... */
f3a5d3f8 642 if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
9f23011a
BS
643 reopened = 1;
644 goto again;
645 }
646 }
83f64091
FB
647#endif
648 } else
649#endif
650#ifdef __sun__
651 /*
652 * use the DKIOCGMEDIAINFO ioctl to read the size.
653 */
654 rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
655 if ( rv != -1 ) {
656 size = minfo.dki_lbsize * minfo.dki_capacity;
657 } else /* there are reports that lseek on some devices
658 fails, but irc discussion said that contingency
659 on contingency was overkill */
660#endif
661 {
662 size = lseek(fd, 0, SEEK_END);
663 }
83f64091
FB
664 return size;
665}
128ab2ff 666#endif
83f64091 667
0e7e1989 668static int raw_create(const char *filename, QEMUOptionParameter *options)
83f64091
FB
669{
670 int fd;
1e37d059 671 int result = 0;
0e7e1989 672 int64_t total_size = 0;
83f64091 673
0e7e1989
KW
674 /* Read out options */
675 while (options && options->name) {
676 if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
677 total_size = options->value.n / 512;
678 }
679 options++;
680 }
83f64091 681
5fafdf24 682 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
83f64091 683 0644);
1e37d059
SW
684 if (fd < 0) {
685 result = -errno;
686 } else {
687 if (ftruncate(fd, total_size * 512) != 0) {
688 result = -errno;
689 }
690 if (close(fd) != 0) {
691 result = -errno;
692 }
693 }
694 return result;
83f64091
FB
695}
696
697static void raw_flush(BlockDriverState *bs)
698{
699 BDRVRawState *s = bs->opaque;
700 fsync(s->fd);
701}
702
0e7e1989
KW
703
704static QEMUOptionParameter raw_create_options[] = {
db08adf5
KW
705 {
706 .name = BLOCK_OPT_SIZE,
707 .type = OPT_SIZE,
708 .help = "Virtual disk size"
709 },
0e7e1989
KW
710 { NULL }
711};
712
5efa9d5a 713static BlockDriver bdrv_raw = {
856ae5c3
BS
714 .format_name = "raw",
715 .instance_size = sizeof(BDRVRawState),
716 .bdrv_probe = NULL, /* no probe for protocols */
717 .bdrv_open = raw_open,
718 .bdrv_read = raw_read,
719 .bdrv_write = raw_write,
720 .bdrv_close = raw_close,
721 .bdrv_create = raw_create,
722 .bdrv_flush = raw_flush,
3b46e624 723
f141eafe
AL
724 .bdrv_aio_readv = raw_aio_readv,
725 .bdrv_aio_writev = raw_aio_writev,
3c529d93 726
83f64091
FB
727 .bdrv_truncate = raw_truncate,
728 .bdrv_getlength = raw_getlength,
0e7e1989
KW
729
730 .create_options = raw_create_options,
83f64091
FB
731};
732
19cb3738
FB
733/***********************************************/
734/* host device */
735
736#ifdef CONFIG_COCOA
737static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
738static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
739
740kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
741{
5fafdf24 742 kern_return_t kernResult;
19cb3738
FB
743 mach_port_t masterPort;
744 CFMutableDictionaryRef classesToMatch;
745
746 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
747 if ( KERN_SUCCESS != kernResult ) {
748 printf( "IOMasterPort returned %d\n", kernResult );
749 }
3b46e624 750
5fafdf24 751 classesToMatch = IOServiceMatching( kIOCDMediaClass );
19cb3738
FB
752 if ( classesToMatch == NULL ) {
753 printf( "IOServiceMatching returned a NULL dictionary.\n" );
754 } else {
755 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
756 }
757 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
758 if ( KERN_SUCCESS != kernResult )
759 {
760 printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
761 }
3b46e624 762
19cb3738
FB
763 return kernResult;
764}
765
766kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
767{
768 io_object_t nextMedia;
769 kern_return_t kernResult = KERN_FAILURE;
770 *bsdPath = '\0';
771 nextMedia = IOIteratorNext( mediaIterator );
772 if ( nextMedia )
773 {
774 CFTypeRef bsdPathAsCFString;
775 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
776 if ( bsdPathAsCFString ) {
777 size_t devPathLength;
778 strcpy( bsdPath, _PATH_DEV );
779 strcat( bsdPath, "r" );
780 devPathLength = strlen( bsdPath );
781 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
782 kernResult = KERN_SUCCESS;
783 }
784 CFRelease( bsdPathAsCFString );
785 }
786 IOObjectRelease( nextMedia );
787 }
3b46e624 788
19cb3738
FB
789 return kernResult;
790}
791
792#endif
793
508c7cb3
CH
794static int hdev_probe_device(const char *filename)
795{
796 struct stat st;
797
798 /* allow a dedicated CD-ROM driver to match with a higher priority */
799 if (strstart(filename, "/dev/cdrom", NULL))
800 return 50;
801
802 if (stat(filename, &st) >= 0 &&
803 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
804 return 100;
805 }
806
807 return 0;
808}
809
19cb3738
FB
810static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
811{
812 BDRVRawState *s = bs->opaque;
a76bab49 813
19cb3738
FB
814#ifdef CONFIG_COCOA
815 if (strstart(filename, "/dev/cdrom", NULL)) {
816 kern_return_t kernResult;
817 io_iterator_t mediaIterator;
818 char bsdPath[ MAXPATHLEN ];
819 int fd;
5fafdf24 820
19cb3738
FB
821 kernResult = FindEjectableCDMedia( &mediaIterator );
822 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
3b46e624 823
19cb3738
FB
824 if ( bsdPath[ 0 ] != '\0' ) {
825 strcat(bsdPath,"s0");
826 /* some CDs don't have a partition 0 */
827 fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
828 if (fd < 0) {
829 bsdPath[strlen(bsdPath)-1] = '1';
830 } else {
831 close(fd);
832 }
833 filename = bsdPath;
834 }
3b46e624 835
19cb3738
FB
836 if ( mediaIterator )
837 IOObjectRelease( mediaIterator );
838 }
839#endif
19cb3738
FB
840
841 s->type = FTYPE_FILE;
4dd75c70 842#if defined(__linux__)
f3a5d3f8 843 if (strstart(filename, "/dev/sg", NULL)) {
985a03b0 844 bs->sg = 1;
19cb3738
FB
845 }
846#endif
90babde0 847
19a3da7f 848 return raw_open_common(bs, filename, flags, 0);
19cb3738
FB
849}
850
03ff3ca3 851#if defined(__linux__)
19cb3738
FB
852/* Note: we do not have a reliable method to detect if the floppy is
853 present. The current method is to try to open the floppy at every
854 I/O and to keep it opened during a few hundreds of ms. */
855static int fd_open(BlockDriverState *bs)
856{
857 BDRVRawState *s = bs->opaque;
858 int last_media_present;
859
860 if (s->type != FTYPE_FD)
861 return 0;
862 last_media_present = (s->fd >= 0);
5fafdf24 863 if (s->fd >= 0 &&
19cb3738
FB
864 (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
865 close(s->fd);
866 s->fd = -1;
867#ifdef DEBUG_FLOPPY
868 printf("Floppy closed\n");
869#endif
870 }
871 if (s->fd < 0) {
5fafdf24 872 if (s->fd_got_error &&
19cb3738
FB
873 (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
874#ifdef DEBUG_FLOPPY
875 printf("No floppy (open delayed)\n");
876#endif
877 return -EIO;
878 }
0e1d8f4c 879 s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
19cb3738
FB
880 if (s->fd < 0) {
881 s->fd_error_time = qemu_get_clock(rt_clock);
882 s->fd_got_error = 1;
883 if (last_media_present)
884 s->fd_media_changed = 1;
885#ifdef DEBUG_FLOPPY
886 printf("No floppy\n");
887#endif
888 return -EIO;
889 }
890#ifdef DEBUG_FLOPPY
891 printf("Floppy opened\n");
892#endif
893 }
894 if (!last_media_present)
895 s->fd_media_changed = 1;
896 s->fd_open_time = qemu_get_clock(rt_clock);
897 s->fd_got_error = 0;
898 return 0;
899}
19cb3738 900
63ec93db 901static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
985a03b0
TS
902{
903 BDRVRawState *s = bs->opaque;
904
905 return ioctl(s->fd, req, buf);
906}
221f715d 907
63ec93db 908static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
221f715d
AL
909 unsigned long int req, void *buf,
910 BlockDriverCompletionFunc *cb, void *opaque)
911{
f141eafe 912 BDRVRawState *s = bs->opaque;
221f715d 913
f141eafe
AL
914 if (fd_open(bs) < 0)
915 return NULL;
9ef91a67 916 return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
221f715d
AL
917}
918
9f23011a 919#elif defined(__FreeBSD__)
9f23011a
BS
920static int fd_open(BlockDriverState *bs)
921{
922 BDRVRawState *s = bs->opaque;
923
924 /* this is just to ensure s->fd is sane (its called by io ops) */
925 if (s->fd >= 0)
926 return 0;
927 return -EIO;
928}
9f23011a 929#else /* !linux && !FreeBSD */
19cb3738 930
08af02e2
AL
931static int fd_open(BlockDriverState *bs)
932{
933 return 0;
934}
935
221f715d 936#endif /* !linux && !FreeBSD */
04eeb8b6 937
0e7e1989 938static int hdev_create(const char *filename, QEMUOptionParameter *options)
93c65b47
AL
939{
940 int fd;
941 int ret = 0;
942 struct stat stat_buf;
0e7e1989 943 int64_t total_size = 0;
93c65b47 944
0e7e1989
KW
945 /* Read out options */
946 while (options && options->name) {
947 if (!strcmp(options->name, "size")) {
948 total_size = options->value.n / 512;
949 }
950 options++;
951 }
93c65b47
AL
952
953 fd = open(filename, O_WRONLY | O_BINARY);
954 if (fd < 0)
955 return -EIO;
956
957 if (fstat(fd, &stat_buf) < 0)
958 ret = -EIO;
4099df58 959 else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
93c65b47
AL
960 ret = -EIO;
961 else if (lseek(fd, 0, SEEK_END) < total_size * 512)
962 ret = -ENOSPC;
963
964 close(fd);
965 return ret;
966}
967
5efa9d5a 968static BlockDriver bdrv_host_device = {
e60f469c
AJ
969 .format_name = "host_device",
970 .instance_size = sizeof(BDRVRawState),
508c7cb3 971 .bdrv_probe_device = hdev_probe_device,
e60f469c
AJ
972 .bdrv_open = hdev_open,
973 .bdrv_close = raw_close,
93c65b47 974 .bdrv_create = hdev_create,
e60f469c 975 .bdrv_flush = raw_flush,
3b46e624 976
f141eafe
AL
977 .bdrv_aio_readv = raw_aio_readv,
978 .bdrv_aio_writev = raw_aio_writev,
3c529d93 979
eda578e5
AL
980 .bdrv_read = raw_read,
981 .bdrv_write = raw_write,
e60f469c 982 .bdrv_getlength = raw_getlength,
19cb3738 983
f3a5d3f8 984 /* generic scsi device */
63ec93db
CH
985#ifdef __linux__
986 .bdrv_ioctl = hdev_ioctl,
63ec93db
CH
987 .bdrv_aio_ioctl = hdev_aio_ioctl,
988#endif
f3a5d3f8
CH
989};
990
991#ifdef __linux__
992static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
993{
994 BDRVRawState *s = bs->opaque;
995 int ret;
996
f3a5d3f8 997 s->type = FTYPE_FD;
f3a5d3f8 998
19a3da7f
BS
999 /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1000 ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
f3a5d3f8
CH
1001 if (ret)
1002 return ret;
1003
1004 /* close fd so that we can reopen it as needed */
1005 close(s->fd);
1006 s->fd = -1;
1007 s->fd_media_changed = 1;
1008
1009 return 0;
1010}
1011
508c7cb3
CH
1012static int floppy_probe_device(const char *filename)
1013{
1014 if (strstart(filename, "/dev/fd", NULL))
1015 return 100;
1016 return 0;
1017}
1018
1019
f3a5d3f8
CH
1020static int floppy_is_inserted(BlockDriverState *bs)
1021{
1022 return fd_open(bs) >= 0;
1023}
1024
1025static int floppy_media_changed(BlockDriverState *bs)
1026{
1027 BDRVRawState *s = bs->opaque;
1028 int ret;
1029
1030 /*
1031 * XXX: we do not have a true media changed indication.
1032 * It does not work if the floppy is changed without trying to read it.
1033 */
1034 fd_open(bs);
1035 ret = s->fd_media_changed;
1036 s->fd_media_changed = 0;
1037#ifdef DEBUG_FLOPPY
1038 printf("Floppy changed=%d\n", ret);
1039#endif
1040 return ret;
1041}
1042
1043static int floppy_eject(BlockDriverState *bs, int eject_flag)
1044{
1045 BDRVRawState *s = bs->opaque;
1046 int fd;
1047
1048 if (s->fd >= 0) {
1049 close(s->fd);
1050 s->fd = -1;
1051 }
1052 fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1053 if (fd >= 0) {
1054 if (ioctl(fd, FDEJECT, 0) < 0)
1055 perror("FDEJECT");
1056 close(fd);
1057 }
1058
1059 return 0;
1060}
1061
1062static BlockDriver bdrv_host_floppy = {
1063 .format_name = "host_floppy",
1064 .instance_size = sizeof(BDRVRawState),
508c7cb3 1065 .bdrv_probe_device = floppy_probe_device,
f3a5d3f8
CH
1066 .bdrv_open = floppy_open,
1067 .bdrv_close = raw_close,
1068 .bdrv_create = hdev_create,
1069 .bdrv_flush = raw_flush,
1070
f3a5d3f8
CH
1071 .bdrv_aio_readv = raw_aio_readv,
1072 .bdrv_aio_writev = raw_aio_writev,
f3a5d3f8
CH
1073
1074 .bdrv_read = raw_read,
1075 .bdrv_write = raw_write,
1076 .bdrv_getlength = raw_getlength,
1077
1078 /* removable device support */
1079 .bdrv_is_inserted = floppy_is_inserted,
1080 .bdrv_media_changed = floppy_media_changed,
1081 .bdrv_eject = floppy_eject,
f3a5d3f8
CH
1082};
1083
1084static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1085{
1086 BDRVRawState *s = bs->opaque;
1087
f3a5d3f8
CH
1088 s->type = FTYPE_CD;
1089
19a3da7f
BS
1090 /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1091 return raw_open_common(bs, filename, flags, O_NONBLOCK);
f3a5d3f8
CH
1092}
1093
508c7cb3
CH
1094static int cdrom_probe_device(const char *filename)
1095{
1096 if (strstart(filename, "/dev/cd", NULL))
1097 return 100;
1098 return 0;
1099}
1100
f3a5d3f8
CH
1101static int cdrom_is_inserted(BlockDriverState *bs)
1102{
1103 BDRVRawState *s = bs->opaque;
1104 int ret;
1105
1106 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1107 if (ret == CDS_DISC_OK)
1108 return 1;
1109 return 0;
1110}
1111
1112static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1113{
1114 BDRVRawState *s = bs->opaque;
1115
1116 if (eject_flag) {
1117 if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1118 perror("CDROMEJECT");
1119 } else {
1120 if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1121 perror("CDROMEJECT");
1122 }
1123
1124 return 0;
1125}
1126
1127static int cdrom_set_locked(BlockDriverState *bs, int locked)
1128{
1129 BDRVRawState *s = bs->opaque;
1130
1131 if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1132 /*
1133 * Note: an error can happen if the distribution automatically
1134 * mounts the CD-ROM
1135 */
1136 /* perror("CDROM_LOCKDOOR"); */
1137 }
1138
1139 return 0;
1140}
1141
1142static BlockDriver bdrv_host_cdrom = {
1143 .format_name = "host_cdrom",
1144 .instance_size = sizeof(BDRVRawState),
508c7cb3 1145 .bdrv_probe_device = cdrom_probe_device,
f3a5d3f8
CH
1146 .bdrv_open = cdrom_open,
1147 .bdrv_close = raw_close,
1148 .bdrv_create = hdev_create,
1149 .bdrv_flush = raw_flush,
1150
f3a5d3f8
CH
1151 .bdrv_aio_readv = raw_aio_readv,
1152 .bdrv_aio_writev = raw_aio_writev,
f3a5d3f8
CH
1153
1154 .bdrv_read = raw_read,
1155 .bdrv_write = raw_write,
1156 .bdrv_getlength = raw_getlength,
1157
1158 /* removable device support */
1159 .bdrv_is_inserted = cdrom_is_inserted,
1160 .bdrv_eject = cdrom_eject,
1161 .bdrv_set_locked = cdrom_set_locked,
1162
1163 /* generic scsi device */
63ec93db 1164 .bdrv_ioctl = hdev_ioctl,
63ec93db 1165 .bdrv_aio_ioctl = hdev_aio_ioctl,
f3a5d3f8
CH
1166};
1167#endif /* __linux__ */
1168
1169#ifdef __FreeBSD__
1170static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1171{
1172 BDRVRawState *s = bs->opaque;
1173 int ret;
1174
1175 s->type = FTYPE_CD;
1176
19a3da7f 1177 ret = raw_open_common(bs, filename, flags, 0);
f3a5d3f8
CH
1178 if (ret)
1179 return ret;
1180
1181 /* make sure the door isnt locked at this time */
1182 ioctl(s->fd, CDIOCALLOW);
1183 return 0;
1184}
1185
508c7cb3
CH
1186static int cdrom_probe_device(const char *filename)
1187{
1188 if (strstart(filename, "/dev/cd", NULL) ||
1189 strstart(filename, "/dev/acd", NULL))
1190 return 100;
1191 return 0;
1192}
1193
f3a5d3f8
CH
1194static int cdrom_reopen(BlockDriverState *bs)
1195{
1196 BDRVRawState *s = bs->opaque;
1197 int fd;
1198
1199 /*
1200 * Force reread of possibly changed/newly loaded disc,
1201 * FreeBSD seems to not notice sometimes...
1202 */
1203 if (s->fd >= 0)
1204 close(s->fd);
1205 fd = open(bs->filename, s->open_flags, 0644);
1206 if (fd < 0) {
1207 s->fd = -1;
1208 return -EIO;
1209 }
1210 s->fd = fd;
1211
1212 /* make sure the door isnt locked at this time */
1213 ioctl(s->fd, CDIOCALLOW);
1214 return 0;
1215}
1216
1217static int cdrom_is_inserted(BlockDriverState *bs)
1218{
1219 return raw_getlength(bs) > 0;
1220}
1221
1222static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1223{
1224 BDRVRawState *s = bs->opaque;
1225
1226 if (s->fd < 0)
1227 return -ENOTSUP;
1228
1229 (void) ioctl(s->fd, CDIOCALLOW);
1230
1231 if (eject_flag) {
1232 if (ioctl(s->fd, CDIOCEJECT) < 0)
1233 perror("CDIOCEJECT");
1234 } else {
1235 if (ioctl(s->fd, CDIOCCLOSE) < 0)
1236 perror("CDIOCCLOSE");
1237 }
1238
1239 if (cdrom_reopen(bs) < 0)
1240 return -ENOTSUP;
1241 return 0;
1242}
1243
1244static int cdrom_set_locked(BlockDriverState *bs, int locked)
1245{
1246 BDRVRawState *s = bs->opaque;
1247
1248 if (s->fd < 0)
1249 return -ENOTSUP;
1250 if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1251 /*
1252 * Note: an error can happen if the distribution automatically
1253 * mounts the CD-ROM
1254 */
1255 /* perror("CDROM_LOCKDOOR"); */
1256 }
1257
1258 return 0;
1259}
1260
1261static BlockDriver bdrv_host_cdrom = {
1262 .format_name = "host_cdrom",
1263 .instance_size = sizeof(BDRVRawState),
508c7cb3 1264 .bdrv_probe_device = cdrom_probe_device,
f3a5d3f8
CH
1265 .bdrv_open = cdrom_open,
1266 .bdrv_close = raw_close,
1267 .bdrv_create = hdev_create,
1268 .bdrv_flush = raw_flush,
1269
f3a5d3f8
CH
1270 .bdrv_aio_readv = raw_aio_readv,
1271 .bdrv_aio_writev = raw_aio_writev,
f3a5d3f8
CH
1272
1273 .bdrv_read = raw_read,
1274 .bdrv_write = raw_write,
1275 .bdrv_getlength = raw_getlength,
1276
19cb3738 1277 /* removable device support */
f3a5d3f8
CH
1278 .bdrv_is_inserted = cdrom_is_inserted,
1279 .bdrv_eject = cdrom_eject,
1280 .bdrv_set_locked = cdrom_set_locked,
19cb3738 1281};
f3a5d3f8 1282#endif /* __FreeBSD__ */
5efa9d5a
AL
1283
1284static void bdrv_raw_init(void)
1285{
508c7cb3
CH
1286 /*
1287 * Register all the drivers. Note that order is important, the driver
1288 * registered last will get probed first.
1289 */
5efa9d5a
AL
1290 bdrv_register(&bdrv_raw);
1291 bdrv_register(&bdrv_host_device);
f3a5d3f8
CH
1292#ifdef __linux__
1293 bdrv_register(&bdrv_host_floppy);
1294 bdrv_register(&bdrv_host_cdrom);
1295#endif
1296#ifdef __FreeBSD__
1297 bdrv_register(&bdrv_host_cdrom);
1298#endif
5efa9d5a
AL
1299}
1300
1301block_init(bdrv_raw_init);