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