Break up vl.h.
[qemu] / block-raw.c
1 /*
2  * Block driver for RAW files
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 #ifndef QEMU_IMG
26 #include "qemu-timer.h"
27 #include "exec-all.h"
28 #endif
29 #include "block_int.h"
30 #include <assert.h>
31 #ifndef _WIN32
32 #include <aio.h>
33
34 #ifdef CONFIG_COCOA
35 #include <paths.h>
36 #include <sys/param.h>
37 #include <IOKit/IOKitLib.h>
38 #include <IOKit/IOBSD.h>
39 #include <IOKit/storage/IOMediaBSDClient.h>
40 #include <IOKit/storage/IOMedia.h>
41 #include <IOKit/storage/IOCDMedia.h>
42 //#include <IOKit/storage/IOCDTypes.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #endif
45
46 #ifdef __sun__
47 #define _POSIX_PTHREAD_SEMANTICS 1
48 #include <signal.h>
49 #include <sys/dkio.h>
50 #endif
51 #ifdef __linux__
52 #include <sys/ioctl.h>
53 #include <linux/cdrom.h>
54 #include <linux/fd.h>
55 #endif
56 #ifdef __FreeBSD__
57 #include <sys/disk.h>
58 #endif
59
60 //#define DEBUG_FLOPPY
61
62 //#define DEBUG_BLOCK
63 #if defined(DEBUG_BLOCK) && !defined(QEMU_IMG)
64 #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0)  \
65     { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
66 #else
67 #define DEBUG_BLOCK_PRINT(formatCstr, args...)
68 #endif
69
70 #define FTYPE_FILE   0
71 #define FTYPE_CD     1
72 #define FTYPE_FD     2
73
74 /* if the FD is not accessed during that time (in ms), we try to
75    reopen it to see if the disk has been changed */
76 #define FD_OPEN_TIMEOUT 1000
77
78 typedef struct BDRVRawState {
79     int fd;
80     int type;
81     unsigned int lseek_err_cnt;
82 #if defined(__linux__)
83     /* linux floppy specific */
84     int fd_open_flags;
85     int64_t fd_open_time;
86     int64_t fd_error_time;
87     int fd_got_error;
88     int fd_media_changed;
89 #endif
90 } BDRVRawState;
91
92 static int fd_open(BlockDriverState *bs);
93
94 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
95 {
96     BDRVRawState *s = bs->opaque;
97     int fd, open_flags, ret;
98
99     s->lseek_err_cnt = 0;
100
101     open_flags = O_BINARY;
102     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
103         open_flags |= O_RDWR;
104     } else {
105         open_flags |= O_RDONLY;
106         bs->read_only = 1;
107     }
108     if (flags & BDRV_O_CREAT)
109         open_flags |= O_CREAT | O_TRUNC;
110
111     s->type = FTYPE_FILE;
112
113     fd = open(filename, open_flags, 0644);
114     if (fd < 0) {
115         ret = -errno;
116         if (ret == -EROFS)
117             ret = -EACCES;
118         return ret;
119     }
120     s->fd = fd;
121     return 0;
122 }
123
124 /* XXX: use host sector size if necessary with:
125 #ifdef DIOCGSECTORSIZE
126         {
127             unsigned int sectorsize = 512;
128             if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
129                 sectorsize > bufsize)
130                 bufsize = sectorsize;
131         }
132 #endif
133 #ifdef CONFIG_COCOA
134         u_int32_t   blockSize = 512;
135         if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
136             bufsize = blockSize;
137         }
138 #endif
139 */
140
141 static int raw_pread(BlockDriverState *bs, int64_t offset,
142                      uint8_t *buf, int count)
143 {
144     BDRVRawState *s = bs->opaque;
145     int ret;
146
147     ret = fd_open(bs);
148     if (ret < 0)
149         return ret;
150
151     if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
152         ++(s->lseek_err_cnt);
153         if(s->lseek_err_cnt <= 10) {
154             DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
155                               "] lseek failed : %d = %s\n",
156                               s->fd, bs->filename, offset, buf, count,
157                               bs->total_sectors, errno, strerror(errno));
158         }
159         return -1;
160     }
161     s->lseek_err_cnt=0;
162
163     ret = read(s->fd, buf, count);
164     if (ret == count)
165         goto label__raw_read__success;
166
167     DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
168                       "] read failed %d : %d = %s\n",
169                       s->fd, bs->filename, offset, buf, count,
170                       bs->total_sectors, ret, errno, strerror(errno));
171
172     /* Try harder for CDrom. */
173     if (bs->type == BDRV_TYPE_CDROM) {
174         lseek(s->fd, offset, SEEK_SET);
175         ret = read(s->fd, buf, count);
176         if (ret == count)
177             goto label__raw_read__success;
178         lseek(s->fd, offset, SEEK_SET);
179         ret = read(s->fd, buf, count);
180         if (ret == count)
181             goto label__raw_read__success;
182
183         DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
184                           "] retry read failed %d : %d = %s\n",
185                           s->fd, bs->filename, offset, buf, count,
186                           bs->total_sectors, ret, errno, strerror(errno));
187     }
188
189 label__raw_read__success:
190
191     return ret;
192 }
193
194 static int raw_pwrite(BlockDriverState *bs, int64_t offset,
195                       const uint8_t *buf, int count)
196 {
197     BDRVRawState *s = bs->opaque;
198     int ret;
199
200     ret = fd_open(bs);
201     if (ret < 0)
202         return ret;
203
204     if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
205         ++(s->lseek_err_cnt);
206         if(s->lseek_err_cnt) {
207             DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
208                               PRId64 "] lseek failed : %d = %s\n",
209                               s->fd, bs->filename, offset, buf, count,
210                               bs->total_sectors, errno, strerror(errno));
211         }
212         return -1;
213     }
214     s->lseek_err_cnt = 0;
215
216     ret = write(s->fd, buf, count);
217     if (ret == count)
218         goto label__raw_write__success;
219
220     DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
221                       "] write failed %d : %d = %s\n",
222                       s->fd, bs->filename, offset, buf, count,
223                       bs->total_sectors, ret, errno, strerror(errno));
224
225 label__raw_write__success:
226
227     return ret;
228 }
229
230 /***********************************************************/
231 /* Unix AIO using POSIX AIO */
232
233 typedef struct RawAIOCB {
234     BlockDriverAIOCB common;
235     struct aiocb aiocb;
236     struct RawAIOCB *next;
237 } RawAIOCB;
238
239 static int aio_sig_num = SIGUSR2;
240 static RawAIOCB *first_aio; /* AIO issued */
241 static int aio_initialized = 0;
242
243 static void aio_signal_handler(int signum)
244 {
245 #ifndef QEMU_IMG
246     CPUState *env = cpu_single_env;
247     if (env) {
248         /* stop the currently executing cpu because a timer occured */
249         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
250 #ifdef USE_KQEMU
251         if (env->kqemu_enabled) {
252             kqemu_cpu_interrupt(env);
253         }
254 #endif
255     }
256 #endif
257 }
258
259 void qemu_aio_init(void)
260 {
261     struct sigaction act;
262
263     aio_initialized = 1;
264
265     sigfillset(&act.sa_mask);
266     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
267     act.sa_handler = aio_signal_handler;
268     sigaction(aio_sig_num, &act, NULL);
269
270 #if defined(__GLIBC__) && defined(__linux__)
271     {
272         /* XXX: aio thread exit seems to hang on RedHat 9 and this init
273            seems to fix the problem. */
274         struct aioinit ai;
275         memset(&ai, 0, sizeof(ai));
276         ai.aio_threads = 1;
277         ai.aio_num = 1;
278         ai.aio_idle_time = 365 * 100000;
279         aio_init(&ai);
280     }
281 #endif
282 }
283
284 void qemu_aio_poll(void)
285 {
286     RawAIOCB *acb, **pacb;
287     int ret;
288
289     for(;;) {
290         pacb = &first_aio;
291         for(;;) {
292             acb = *pacb;
293             if (!acb)
294                 goto the_end;
295             ret = aio_error(&acb->aiocb);
296             if (ret == ECANCELED) {
297                 /* remove the request */
298                 *pacb = acb->next;
299                 qemu_aio_release(acb);
300             } else if (ret != EINPROGRESS) {
301                 /* end of aio */
302                 if (ret == 0) {
303                     ret = aio_return(&acb->aiocb);
304                     if (ret == acb->aiocb.aio_nbytes)
305                         ret = 0;
306                     else
307                         ret = -EINVAL;
308                 } else {
309                     ret = -ret;
310                 }
311                 /* remove the request */
312                 *pacb = acb->next;
313                 /* call the callback */
314                 acb->common.cb(acb->common.opaque, ret);
315                 qemu_aio_release(acb);
316                 break;
317             } else {
318                 pacb = &acb->next;
319             }
320         }
321     }
322  the_end: ;
323 }
324
325 /* Wait for all IO requests to complete.  */
326 void qemu_aio_flush(void)
327 {
328     qemu_aio_wait_start();
329     qemu_aio_poll();
330     while (first_aio) {
331         qemu_aio_wait();
332     }
333     qemu_aio_wait_end();
334 }
335
336 /* wait until at least one AIO was handled */
337 static sigset_t wait_oset;
338
339 void qemu_aio_wait_start(void)
340 {
341     sigset_t set;
342
343     if (!aio_initialized)
344         qemu_aio_init();
345     sigemptyset(&set);
346     sigaddset(&set, aio_sig_num);
347     sigprocmask(SIG_BLOCK, &set, &wait_oset);
348 }
349
350 void qemu_aio_wait(void)
351 {
352     sigset_t set;
353     int nb_sigs;
354
355 #ifndef QEMU_IMG
356     if (qemu_bh_poll())
357         return;
358 #endif
359     sigemptyset(&set);
360     sigaddset(&set, aio_sig_num);
361     sigwait(&set, &nb_sigs);
362     qemu_aio_poll();
363 }
364
365 void qemu_aio_wait_end(void)
366 {
367     sigprocmask(SIG_SETMASK, &wait_oset, NULL);
368 }
369
370 static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
371         int64_t sector_num, uint8_t *buf, int nb_sectors,
372         BlockDriverCompletionFunc *cb, void *opaque)
373 {
374     BDRVRawState *s = bs->opaque;
375     RawAIOCB *acb;
376
377     if (fd_open(bs) < 0)
378         return NULL;
379
380     acb = qemu_aio_get(bs, cb, opaque);
381     if (!acb)
382         return NULL;
383     acb->aiocb.aio_fildes = s->fd;
384     acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
385     acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
386     acb->aiocb.aio_buf = buf;
387     acb->aiocb.aio_nbytes = nb_sectors * 512;
388     acb->aiocb.aio_offset = sector_num * 512;
389     acb->next = first_aio;
390     first_aio = acb;
391     return acb;
392 }
393
394 static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
395         int64_t sector_num, uint8_t *buf, int nb_sectors,
396         BlockDriverCompletionFunc *cb, void *opaque)
397 {
398     RawAIOCB *acb;
399
400     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
401     if (!acb)
402         return NULL;
403     if (aio_read(&acb->aiocb) < 0) {
404         qemu_aio_release(acb);
405         return NULL;
406     }
407     return &acb->common;
408 }
409
410 static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
411         int64_t sector_num, const uint8_t *buf, int nb_sectors,
412         BlockDriverCompletionFunc *cb, void *opaque)
413 {
414     RawAIOCB *acb;
415
416     acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
417     if (!acb)
418         return NULL;
419     if (aio_write(&acb->aiocb) < 0) {
420         qemu_aio_release(acb);
421         return NULL;
422     }
423     return &acb->common;
424 }
425
426 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
427 {
428     int ret;
429     RawAIOCB *acb = (RawAIOCB *)blockacb;
430     RawAIOCB **pacb;
431
432     ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
433     if (ret == AIO_NOTCANCELED) {
434         /* fail safe: if the aio could not be canceled, we wait for
435            it */
436         while (aio_error(&acb->aiocb) == EINPROGRESS);
437     }
438
439     /* remove the callback from the queue */
440     pacb = &first_aio;
441     for(;;) {
442         if (*pacb == NULL) {
443             break;
444         } else if (*pacb == acb) {
445             *pacb = acb->next;
446             qemu_aio_release(acb);
447             break;
448         }
449         pacb = &acb->next;
450     }
451 }
452
453 static void raw_close(BlockDriverState *bs)
454 {
455     BDRVRawState *s = bs->opaque;
456     if (s->fd >= 0) {
457         close(s->fd);
458         s->fd = -1;
459     }
460 }
461
462 static int raw_truncate(BlockDriverState *bs, int64_t offset)
463 {
464     BDRVRawState *s = bs->opaque;
465     if (s->type != FTYPE_FILE)
466         return -ENOTSUP;
467     if (ftruncate(s->fd, offset) < 0)
468         return -errno;
469     return 0;
470 }
471
472 static int64_t  raw_getlength(BlockDriverState *bs)
473 {
474     BDRVRawState *s = bs->opaque;
475     int fd = s->fd;
476     int64_t size;
477 #ifdef _BSD
478     struct stat sb;
479 #endif
480 #ifdef __sun__
481     struct dk_minfo minfo;
482     int rv;
483 #endif
484     int ret;
485
486     ret = fd_open(bs);
487     if (ret < 0)
488         return ret;
489
490 #ifdef _BSD
491     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
492 #ifdef DIOCGMEDIASIZE
493         if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
494 #endif
495 #ifdef CONFIG_COCOA
496         size = LONG_LONG_MAX;
497 #else
498         size = lseek(fd, 0LL, SEEK_END);
499 #endif
500     } else
501 #endif
502 #ifdef __sun__
503     /*
504      * use the DKIOCGMEDIAINFO ioctl to read the size.
505      */
506     rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
507     if ( rv != -1 ) {
508         size = minfo.dki_lbsize * minfo.dki_capacity;
509     } else /* there are reports that lseek on some devices
510               fails, but irc discussion said that contingency
511               on contingency was overkill */
512 #endif
513     {
514         size = lseek(fd, 0, SEEK_END);
515     }
516     return size;
517 }
518
519 static int raw_create(const char *filename, int64_t total_size,
520                       const char *backing_file, int flags)
521 {
522     int fd;
523
524     if (flags || backing_file)
525         return -ENOTSUP;
526
527     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
528               0644);
529     if (fd < 0)
530         return -EIO;
531     ftruncate(fd, total_size * 512);
532     close(fd);
533     return 0;
534 }
535
536 static void raw_flush(BlockDriverState *bs)
537 {
538     BDRVRawState *s = bs->opaque;
539     fsync(s->fd);
540 }
541
542 BlockDriver bdrv_raw = {
543     "raw",
544     sizeof(BDRVRawState),
545     NULL, /* no probe for protocols */
546     raw_open,
547     NULL,
548     NULL,
549     raw_close,
550     raw_create,
551     raw_flush,
552
553     .bdrv_aio_read = raw_aio_read,
554     .bdrv_aio_write = raw_aio_write,
555     .bdrv_aio_cancel = raw_aio_cancel,
556     .aiocb_size = sizeof(RawAIOCB),
557     .protocol_name = "file",
558     .bdrv_pread = raw_pread,
559     .bdrv_pwrite = raw_pwrite,
560     .bdrv_truncate = raw_truncate,
561     .bdrv_getlength = raw_getlength,
562 };
563
564 /***********************************************/
565 /* host device */
566
567 #ifdef CONFIG_COCOA
568 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
569 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
570
571 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
572 {
573     kern_return_t       kernResult;
574     mach_port_t     masterPort;
575     CFMutableDictionaryRef  classesToMatch;
576
577     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
578     if ( KERN_SUCCESS != kernResult ) {
579         printf( "IOMasterPort returned %d\n", kernResult );
580     }
581
582     classesToMatch = IOServiceMatching( kIOCDMediaClass );
583     if ( classesToMatch == NULL ) {
584         printf( "IOServiceMatching returned a NULL dictionary.\n" );
585     } else {
586     CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
587     }
588     kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
589     if ( KERN_SUCCESS != kernResult )
590     {
591         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
592     }
593
594     return kernResult;
595 }
596
597 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
598 {
599     io_object_t     nextMedia;
600     kern_return_t   kernResult = KERN_FAILURE;
601     *bsdPath = '\0';
602     nextMedia = IOIteratorNext( mediaIterator );
603     if ( nextMedia )
604     {
605         CFTypeRef   bsdPathAsCFString;
606     bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
607         if ( bsdPathAsCFString ) {
608             size_t devPathLength;
609             strcpy( bsdPath, _PATH_DEV );
610             strcat( bsdPath, "r" );
611             devPathLength = strlen( bsdPath );
612             if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
613                 kernResult = KERN_SUCCESS;
614             }
615             CFRelease( bsdPathAsCFString );
616         }
617         IOObjectRelease( nextMedia );
618     }
619
620     return kernResult;
621 }
622
623 #endif
624
625 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
626 {
627     BDRVRawState *s = bs->opaque;
628     int fd, open_flags, ret;
629
630 #ifdef CONFIG_COCOA
631     if (strstart(filename, "/dev/cdrom", NULL)) {
632         kern_return_t kernResult;
633         io_iterator_t mediaIterator;
634         char bsdPath[ MAXPATHLEN ];
635         int fd;
636
637         kernResult = FindEjectableCDMedia( &mediaIterator );
638         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
639
640         if ( bsdPath[ 0 ] != '\0' ) {
641             strcat(bsdPath,"s0");
642             /* some CDs don't have a partition 0 */
643             fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
644             if (fd < 0) {
645                 bsdPath[strlen(bsdPath)-1] = '1';
646             } else {
647                 close(fd);
648             }
649             filename = bsdPath;
650         }
651
652         if ( mediaIterator )
653             IOObjectRelease( mediaIterator );
654     }
655 #endif
656     open_flags = O_BINARY;
657     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
658         open_flags |= O_RDWR;
659     } else {
660         open_flags |= O_RDONLY;
661         bs->read_only = 1;
662     }
663
664     s->type = FTYPE_FILE;
665 #if defined(__linux__)
666     if (strstart(filename, "/dev/cd", NULL)) {
667         /* open will not fail even if no CD is inserted */
668         open_flags |= O_NONBLOCK;
669         s->type = FTYPE_CD;
670     } else if (strstart(filename, "/dev/fd", NULL)) {
671         s->type = FTYPE_FD;
672         s->fd_open_flags = open_flags;
673         /* open will not fail even if no floppy is inserted */
674         open_flags |= O_NONBLOCK;
675     }
676 #endif
677     fd = open(filename, open_flags, 0644);
678     if (fd < 0) {
679         ret = -errno;
680         if (ret == -EROFS)
681             ret = -EACCES;
682         return ret;
683     }
684     s->fd = fd;
685 #if defined(__linux__)
686     /* close fd so that we can reopen it as needed */
687     if (s->type == FTYPE_FD) {
688         close(s->fd);
689         s->fd = -1;
690         s->fd_media_changed = 1;
691     }
692 #endif
693     return 0;
694 }
695
696 #if defined(__linux__) && !defined(QEMU_IMG)
697
698 /* Note: we do not have a reliable method to detect if the floppy is
699    present. The current method is to try to open the floppy at every
700    I/O and to keep it opened during a few hundreds of ms. */
701 static int fd_open(BlockDriverState *bs)
702 {
703     BDRVRawState *s = bs->opaque;
704     int last_media_present;
705
706     if (s->type != FTYPE_FD)
707         return 0;
708     last_media_present = (s->fd >= 0);
709     if (s->fd >= 0 &&
710         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
711         close(s->fd);
712         s->fd = -1;
713 #ifdef DEBUG_FLOPPY
714         printf("Floppy closed\n");
715 #endif
716     }
717     if (s->fd < 0) {
718         if (s->fd_got_error &&
719             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
720 #ifdef DEBUG_FLOPPY
721             printf("No floppy (open delayed)\n");
722 #endif
723             return -EIO;
724         }
725         s->fd = open(bs->filename, s->fd_open_flags);
726         if (s->fd < 0) {
727             s->fd_error_time = qemu_get_clock(rt_clock);
728             s->fd_got_error = 1;
729             if (last_media_present)
730                 s->fd_media_changed = 1;
731 #ifdef DEBUG_FLOPPY
732             printf("No floppy\n");
733 #endif
734             return -EIO;
735         }
736 #ifdef DEBUG_FLOPPY
737         printf("Floppy opened\n");
738 #endif
739     }
740     if (!last_media_present)
741         s->fd_media_changed = 1;
742     s->fd_open_time = qemu_get_clock(rt_clock);
743     s->fd_got_error = 0;
744     return 0;
745 }
746 #else
747 static int fd_open(BlockDriverState *bs)
748 {
749     return 0;
750 }
751 #endif
752
753 #if defined(__linux__)
754
755 static int raw_is_inserted(BlockDriverState *bs)
756 {
757     BDRVRawState *s = bs->opaque;
758     int ret;
759
760     switch(s->type) {
761     case FTYPE_CD:
762         ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
763         if (ret == CDS_DISC_OK)
764             return 1;
765         else
766             return 0;
767         break;
768     case FTYPE_FD:
769         ret = fd_open(bs);
770         return (ret >= 0);
771     default:
772         return 1;
773     }
774 }
775
776 /* currently only used by fdc.c, but a CD version would be good too */
777 static int raw_media_changed(BlockDriverState *bs)
778 {
779     BDRVRawState *s = bs->opaque;
780
781     switch(s->type) {
782     case FTYPE_FD:
783         {
784             int ret;
785             /* XXX: we do not have a true media changed indication. It
786                does not work if the floppy is changed without trying
787                to read it */
788             fd_open(bs);
789             ret = s->fd_media_changed;
790             s->fd_media_changed = 0;
791 #ifdef DEBUG_FLOPPY
792             printf("Floppy changed=%d\n", ret);
793 #endif
794             return ret;
795         }
796     default:
797         return -ENOTSUP;
798     }
799 }
800
801 static int raw_eject(BlockDriverState *bs, int eject_flag)
802 {
803     BDRVRawState *s = bs->opaque;
804
805     switch(s->type) {
806     case FTYPE_CD:
807         if (eject_flag) {
808             if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
809                 perror("CDROMEJECT");
810         } else {
811             if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
812                 perror("CDROMEJECT");
813         }
814         break;
815     case FTYPE_FD:
816         {
817             int fd;
818             if (s->fd >= 0) {
819                 close(s->fd);
820                 s->fd = -1;
821             }
822             fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
823             if (fd >= 0) {
824                 if (ioctl(fd, FDEJECT, 0) < 0)
825                     perror("FDEJECT");
826                 close(fd);
827             }
828         }
829         break;
830     default:
831         return -ENOTSUP;
832     }
833     return 0;
834 }
835
836 static int raw_set_locked(BlockDriverState *bs, int locked)
837 {
838     BDRVRawState *s = bs->opaque;
839
840     switch(s->type) {
841     case FTYPE_CD:
842         if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
843             /* Note: an error can happen if the distribution automatically
844                mounts the CD-ROM */
845             //        perror("CDROM_LOCKDOOR");
846         }
847         break;
848     default:
849         return -ENOTSUP;
850     }
851     return 0;
852 }
853
854 #else
855
856 static int raw_is_inserted(BlockDriverState *bs)
857 {
858     return 1;
859 }
860
861 static int raw_media_changed(BlockDriverState *bs)
862 {
863     return -ENOTSUP;
864 }
865
866 static int raw_eject(BlockDriverState *bs, int eject_flag)
867 {
868     return -ENOTSUP;
869 }
870
871 static int raw_set_locked(BlockDriverState *bs, int locked)
872 {
873     return -ENOTSUP;
874 }
875
876 #endif /* !linux */
877
878 BlockDriver bdrv_host_device = {
879     "host_device",
880     sizeof(BDRVRawState),
881     NULL, /* no probe for protocols */
882     hdev_open,
883     NULL,
884     NULL,
885     raw_close,
886     NULL,
887     raw_flush,
888
889     .bdrv_aio_read = raw_aio_read,
890     .bdrv_aio_write = raw_aio_write,
891     .bdrv_aio_cancel = raw_aio_cancel,
892     .aiocb_size = sizeof(RawAIOCB),
893     .bdrv_pread = raw_pread,
894     .bdrv_pwrite = raw_pwrite,
895     .bdrv_getlength = raw_getlength,
896
897     /* removable device support */
898     .bdrv_is_inserted = raw_is_inserted,
899     .bdrv_media_changed = raw_media_changed,
900     .bdrv_eject = raw_eject,
901     .bdrv_set_locked = raw_set_locked,
902 };
903
904 #else /* _WIN32 */
905
906 /* XXX: use another file ? */
907 #include <winioctl.h>
908
909 #define FTYPE_FILE 0
910 #define FTYPE_CD     1
911 #define FTYPE_HARDDISK 2
912
913 typedef struct BDRVRawState {
914     HANDLE hfile;
915     int type;
916     char drive_path[16]; /* format: "d:\" */
917 } BDRVRawState;
918
919 typedef struct RawAIOCB {
920     BlockDriverAIOCB common;
921     HANDLE hEvent;
922     OVERLAPPED ov;
923     int count;
924 } RawAIOCB;
925
926 int qemu_ftruncate64(int fd, int64_t length)
927 {
928     LARGE_INTEGER li;
929     LONG high;
930     HANDLE h;
931     BOOL res;
932
933     if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
934         return -1;
935
936     h = (HANDLE)_get_osfhandle(fd);
937
938     /* get current position, ftruncate do not change position */
939     li.HighPart = 0;
940     li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
941     if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
942         return -1;
943
944     high = length >> 32;
945     if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
946         return -1;
947     res = SetEndOfFile(h);
948
949     /* back to old position */
950     SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
951     return res ? 0 : -1;
952 }
953
954 static int set_sparse(int fd)
955 {
956     DWORD returned;
957     return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
958                                  NULL, 0, NULL, 0, &returned, NULL);
959 }
960
961 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
962 {
963     BDRVRawState *s = bs->opaque;
964     int access_flags, create_flags;
965     DWORD overlapped;
966
967     s->type = FTYPE_FILE;
968
969     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
970         access_flags = GENERIC_READ | GENERIC_WRITE;
971     } else {
972         access_flags = GENERIC_READ;
973     }
974     if (flags & BDRV_O_CREAT) {
975         create_flags = CREATE_ALWAYS;
976     } else {
977         create_flags = OPEN_EXISTING;
978     }
979 #ifdef QEMU_IMG
980     overlapped = FILE_ATTRIBUTE_NORMAL;
981 #else
982     overlapped = FILE_FLAG_OVERLAPPED;
983 #endif
984     s->hfile = CreateFile(filename, access_flags,
985                           FILE_SHARE_READ, NULL,
986                           create_flags, overlapped, NULL);
987     if (s->hfile == INVALID_HANDLE_VALUE) {
988         int err = GetLastError();
989
990         if (err == ERROR_ACCESS_DENIED)
991             return -EACCES;
992         return -1;
993     }
994     return 0;
995 }
996
997 static int raw_pread(BlockDriverState *bs, int64_t offset,
998                      uint8_t *buf, int count)
999 {
1000     BDRVRawState *s = bs->opaque;
1001     OVERLAPPED ov;
1002     DWORD ret_count;
1003     int ret;
1004
1005     memset(&ov, 0, sizeof(ov));
1006     ov.Offset = offset;
1007     ov.OffsetHigh = offset >> 32;
1008     ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
1009     if (!ret) {
1010         ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
1011         if (!ret)
1012             return -EIO;
1013         else
1014             return ret_count;
1015     }
1016     return ret_count;
1017 }
1018
1019 static int raw_pwrite(BlockDriverState *bs, int64_t offset,
1020                       const uint8_t *buf, int count)
1021 {
1022     BDRVRawState *s = bs->opaque;
1023     OVERLAPPED ov;
1024     DWORD ret_count;
1025     int ret;
1026
1027     memset(&ov, 0, sizeof(ov));
1028     ov.Offset = offset;
1029     ov.OffsetHigh = offset >> 32;
1030     ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
1031     if (!ret) {
1032         ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
1033         if (!ret)
1034             return -EIO;
1035         else
1036             return ret_count;
1037     }
1038     return ret_count;
1039 }
1040
1041 #if 0
1042 #ifndef QEMU_IMG
1043 static void raw_aio_cb(void *opaque)
1044 {
1045     RawAIOCB *acb = opaque;
1046     BlockDriverState *bs = acb->common.bs;
1047     BDRVRawState *s = bs->opaque;
1048     DWORD ret_count;
1049     int ret;
1050
1051     ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
1052     if (!ret || ret_count != acb->count) {
1053         acb->common.cb(acb->common.opaque, -EIO);
1054     } else {
1055         acb->common.cb(acb->common.opaque, 0);
1056     }
1057 }
1058 #endif
1059
1060 static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
1061         int64_t sector_num, uint8_t *buf, int nb_sectors,
1062         BlockDriverCompletionFunc *cb, void *opaque)
1063 {
1064     RawAIOCB *acb;
1065     int64_t offset;
1066
1067     acb = qemu_aio_get(bs, cb, opaque);
1068     if (acb->hEvent) {
1069         acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1070         if (!acb->hEvent) {
1071             qemu_aio_release(acb);
1072             return NULL;
1073         }
1074     }
1075     memset(&acb->ov, 0, sizeof(acb->ov));
1076     offset = sector_num * 512;
1077     acb->ov.Offset = offset;
1078     acb->ov.OffsetHigh = offset >> 32;
1079     acb->ov.hEvent = acb->hEvent;
1080     acb->count = nb_sectors * 512;
1081 #ifndef QEMU_IMG
1082     qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1083 #endif
1084     return acb;
1085 }
1086
1087 static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
1088         int64_t sector_num, uint8_t *buf, int nb_sectors,
1089         BlockDriverCompletionFunc *cb, void *opaque)
1090 {
1091     BDRVRawState *s = bs->opaque;
1092     RawAIOCB *acb;
1093     int ret;
1094
1095     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1096     if (!acb)
1097         return NULL;
1098     ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1099     if (!ret) {
1100         qemu_aio_release(acb);
1101         return NULL;
1102     }
1103 #ifdef QEMU_IMG
1104     qemu_aio_release(acb);
1105 #endif
1106     return (BlockDriverAIOCB *)acb;
1107 }
1108
1109 static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
1110         int64_t sector_num, uint8_t *buf, int nb_sectors,
1111         BlockDriverCompletionFunc *cb, void *opaque)
1112 {
1113     BDRVRawState *s = bs->opaque;
1114     RawAIOCB *acb;
1115     int ret;
1116
1117     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1118     if (!acb)
1119         return NULL;
1120     ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1121     if (!ret) {
1122         qemu_aio_release(acb);
1123         return NULL;
1124     }
1125 #ifdef QEMU_IMG
1126     qemu_aio_release(acb);
1127 #endif
1128     return (BlockDriverAIOCB *)acb;
1129 }
1130
1131 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
1132 {
1133 #ifndef QEMU_IMG
1134     RawAIOCB *acb = (RawAIOCB *)blockacb;
1135     BlockDriverState *bs = acb->common.bs;
1136     BDRVRawState *s = bs->opaque;
1137
1138     qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1139     /* XXX: if more than one async I/O it is not correct */
1140     CancelIo(s->hfile);
1141     qemu_aio_release(acb);
1142 #endif
1143 }
1144 #endif /* #if 0 */
1145
1146 static void raw_flush(BlockDriverState *bs)
1147 {
1148     BDRVRawState *s = bs->opaque;
1149     FlushFileBuffers(s->hfile);
1150 }
1151
1152 static void raw_close(BlockDriverState *bs)
1153 {
1154     BDRVRawState *s = bs->opaque;
1155     CloseHandle(s->hfile);
1156 }
1157
1158 static int raw_truncate(BlockDriverState *bs, int64_t offset)
1159 {
1160     BDRVRawState *s = bs->opaque;
1161     DWORD low, high;
1162
1163     low = offset;
1164     high = offset >> 32;
1165     if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
1166         return -EIO;
1167     if (!SetEndOfFile(s->hfile))
1168         return -EIO;
1169     return 0;
1170 }
1171
1172 static int64_t raw_getlength(BlockDriverState *bs)
1173 {
1174     BDRVRawState *s = bs->opaque;
1175     LARGE_INTEGER l;
1176     ULARGE_INTEGER available, total, total_free;
1177     DISK_GEOMETRY_EX dg;
1178     DWORD count;
1179     BOOL status;
1180
1181     switch(s->type) {
1182     case FTYPE_FILE:
1183         l.LowPart = GetFileSize(s->hfile, &l.HighPart);
1184         if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
1185             return -EIO;
1186         break;
1187     case FTYPE_CD:
1188         if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
1189             return -EIO;
1190         l.QuadPart = total.QuadPart;
1191         break;
1192     case FTYPE_HARDDISK:
1193         status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
1194                                  NULL, 0, &dg, sizeof(dg), &count, NULL);
1195         if (status != 0) {
1196             l = dg.DiskSize;
1197         }
1198         break;
1199     default:
1200         return -EIO;
1201     }
1202     return l.QuadPart;
1203 }
1204
1205 static int raw_create(const char *filename, int64_t total_size,
1206                       const char *backing_file, int flags)
1207 {
1208     int fd;
1209
1210     if (flags || backing_file)
1211         return -ENOTSUP;
1212
1213     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
1214               0644);
1215     if (fd < 0)
1216         return -EIO;
1217     set_sparse(fd);
1218     ftruncate(fd, total_size * 512);
1219     close(fd);
1220     return 0;
1221 }
1222
1223 void qemu_aio_init(void)
1224 {
1225 }
1226
1227 void qemu_aio_poll(void)
1228 {
1229 }
1230
1231 void qemu_aio_flush(void)
1232 {
1233 }
1234
1235 void qemu_aio_wait_start(void)
1236 {
1237 }
1238
1239 void qemu_aio_wait(void)
1240 {
1241 #ifndef QEMU_IMG
1242     qemu_bh_poll();
1243 #endif
1244 }
1245
1246 void qemu_aio_wait_end(void)
1247 {
1248 }
1249
1250 BlockDriver bdrv_raw = {
1251     "raw",
1252     sizeof(BDRVRawState),
1253     NULL, /* no probe for protocols */
1254     raw_open,
1255     NULL,
1256     NULL,
1257     raw_close,
1258     raw_create,
1259     raw_flush,
1260
1261 #if 0
1262     .bdrv_aio_read = raw_aio_read,
1263     .bdrv_aio_write = raw_aio_write,
1264     .bdrv_aio_cancel = raw_aio_cancel,
1265     .aiocb_size = sizeof(RawAIOCB);
1266 #endif
1267     .protocol_name = "file",
1268     .bdrv_pread = raw_pread,
1269     .bdrv_pwrite = raw_pwrite,
1270     .bdrv_truncate = raw_truncate,
1271     .bdrv_getlength = raw_getlength,
1272 };
1273
1274 /***********************************************/
1275 /* host device */
1276
1277 static int find_cdrom(char *cdrom_name, int cdrom_name_size)
1278 {
1279     char drives[256], *pdrv = drives;
1280     UINT type;
1281
1282     memset(drives, 0, sizeof(drives));
1283     GetLogicalDriveStrings(sizeof(drives), drives);
1284     while(pdrv[0] != '\0') {
1285         type = GetDriveType(pdrv);
1286         switch(type) {
1287         case DRIVE_CDROM:
1288             snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
1289             return 0;
1290             break;
1291         }
1292         pdrv += lstrlen(pdrv) + 1;
1293     }
1294     return -1;
1295 }
1296
1297 static int find_device_type(BlockDriverState *bs, const char *filename)
1298 {
1299     BDRVRawState *s = bs->opaque;
1300     UINT type;
1301     const char *p;
1302
1303     if (strstart(filename, "\\\\.\\", &p) ||
1304         strstart(filename, "//./", &p)) {
1305         if (stristart(p, "PhysicalDrive", NULL))
1306             return FTYPE_HARDDISK;
1307         snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
1308         type = GetDriveType(s->drive_path);
1309         if (type == DRIVE_CDROM)
1310             return FTYPE_CD;
1311         else
1312             return FTYPE_FILE;
1313     } else {
1314         return FTYPE_FILE;
1315     }
1316 }
1317
1318 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
1319 {
1320     BDRVRawState *s = bs->opaque;
1321     int access_flags, create_flags;
1322     DWORD overlapped;
1323     char device_name[64];
1324
1325     if (strstart(filename, "/dev/cdrom", NULL)) {
1326         if (find_cdrom(device_name, sizeof(device_name)) < 0)
1327             return -ENOENT;
1328         filename = device_name;
1329     } else {
1330         /* transform drive letters into device name */
1331         if (((filename[0] >= 'a' && filename[0] <= 'z') ||
1332              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
1333             filename[1] == ':' && filename[2] == '\0') {
1334             snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
1335             filename = device_name;
1336         }
1337     }
1338     s->type = find_device_type(bs, filename);
1339
1340     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
1341         access_flags = GENERIC_READ | GENERIC_WRITE;
1342     } else {
1343         access_flags = GENERIC_READ;
1344     }
1345     create_flags = OPEN_EXISTING;
1346
1347 #ifdef QEMU_IMG
1348     overlapped = FILE_ATTRIBUTE_NORMAL;
1349 #else
1350     overlapped = FILE_FLAG_OVERLAPPED;
1351 #endif
1352     s->hfile = CreateFile(filename, access_flags,
1353                           FILE_SHARE_READ, NULL,
1354                           create_flags, overlapped, NULL);
1355     if (s->hfile == INVALID_HANDLE_VALUE) {
1356         int err = GetLastError();
1357
1358         if (err == ERROR_ACCESS_DENIED)
1359             return -EACCES;
1360         return -1;
1361     }
1362     return 0;
1363 }
1364
1365 #if 0
1366 /***********************************************/
1367 /* removable device additional commands */
1368
1369 static int raw_is_inserted(BlockDriverState *bs)
1370 {
1371     return 1;
1372 }
1373
1374 static int raw_media_changed(BlockDriverState *bs)
1375 {
1376     return -ENOTSUP;
1377 }
1378
1379 static int raw_eject(BlockDriverState *bs, int eject_flag)
1380 {
1381     DWORD ret_count;
1382
1383     if (s->type == FTYPE_FILE)
1384         return -ENOTSUP;
1385     if (eject_flag) {
1386         DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
1387                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1388     } else {
1389         DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
1390                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1391     }
1392 }
1393
1394 static int raw_set_locked(BlockDriverState *bs, int locked)
1395 {
1396     return -ENOTSUP;
1397 }
1398 #endif
1399
1400 BlockDriver bdrv_host_device = {
1401     "host_device",
1402     sizeof(BDRVRawState),
1403     NULL, /* no probe for protocols */
1404     hdev_open,
1405     NULL,
1406     NULL,
1407     raw_close,
1408     NULL,
1409     raw_flush,
1410
1411 #if 0
1412     .bdrv_aio_read = raw_aio_read,
1413     .bdrv_aio_write = raw_aio_write,
1414     .bdrv_aio_cancel = raw_aio_cancel,
1415     .aiocb_size = sizeof(RawAIOCB);
1416 #endif
1417     .bdrv_pread = raw_pread,
1418     .bdrv_pwrite = raw_pwrite,
1419     .bdrv_getlength = raw_getlength,
1420 };
1421 #endif /* _WIN32 */