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