Statistics
| Branch: | Revision:

root / block / raw-posix.c @ 71e72a19

History | View | Annotate | Download (38.5 kB)

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"
30
#ifdef CONFIG_AIO
31
#include "posix-aio-compat.h"
32
#endif
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 <signal.h>
58
#include <sys/disk.h>
59
#include <sys/cdio.h>
60
#endif
61

    
62
#ifdef __OpenBSD__
63
#include <sys/ioctl.h>
64
#include <sys/disklabel.h>
65
#include <sys/dkio.h>
66
#endif
67

    
68
#ifdef __DragonFly__
69
#include <sys/ioctl.h>
70
#include <sys/diskslice.h>
71
#endif
72

    
73
//#define DEBUG_FLOPPY
74

    
75
//#define DEBUG_BLOCK
76
#if defined(DEBUG_BLOCK)
77
#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
78
    { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
79
#else
80
#define DEBUG_BLOCK_PRINT(formatCstr, ...)
81
#endif
82

    
83
/* OS X does not have O_DSYNC */
84
#ifndef O_DSYNC
85
#ifdef O_SYNC
86
#define O_DSYNC O_SYNC
87
#elif defined(O_FSYNC)
88
#define O_DSYNC O_FSYNC
89
#endif
90
#endif
91

    
92
/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
93
#ifndef O_DIRECT
94
#define O_DIRECT O_DSYNC
95
#endif
96

    
97
#define FTYPE_FILE   0
98
#define FTYPE_CD     1
99
#define FTYPE_FD     2
100

    
101
#define ALIGNED_BUFFER_SIZE (32 * 512)
102

    
103
/* if the FD is not accessed during that time (in ms), we try to
104
   reopen it to see if the disk has been changed */
105
#define FD_OPEN_TIMEOUT 1000
106

    
107
typedef struct BDRVRawState {
108
    int fd;
109
    int type;
110
    unsigned int lseek_err_cnt;
111
    int open_flags;
112
#if defined(__linux__)
113
    /* linux floppy specific */
114
    int64_t fd_open_time;
115
    int64_t fd_error_time;
116
    int fd_got_error;
117
    int fd_media_changed;
118
#endif
119
    uint8_t* aligned_buf;
120
} BDRVRawState;
121

    
122
static int posix_aio_init(void);
123

    
124
static int fd_open(BlockDriverState *bs);
125
static int64_t raw_getlength(BlockDriverState *bs);
126

    
127
#if defined(__FreeBSD__)
128
static int cdrom_reopen(BlockDriverState *bs);
129
#endif
130

    
131
static int raw_open_common(BlockDriverState *bs, const char *filename,
132
                           int bdrv_flags, int open_flags)
133
{
134
    BDRVRawState *s = bs->opaque;
135
    int fd, ret;
136

    
137
    posix_aio_init();
138

    
139
    s->lseek_err_cnt = 0;
140

    
141
    s->open_flags = open_flags | O_BINARY;
142
    s->open_flags &= ~O_ACCMODE;
143
    if ((bdrv_flags & BDRV_O_ACCESS) == BDRV_O_RDWR) {
144
        s->open_flags |= O_RDWR;
145
    } else {
146
        s->open_flags |= O_RDONLY;
147
        bs->read_only = 1;
148
    }
149

    
150
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
151
     * and O_DIRECT for no caching. */
152
    if ((bdrv_flags & BDRV_O_NOCACHE))
153
        s->open_flags |= O_DIRECT;
154
    else if (!(bdrv_flags & BDRV_O_CACHE_WB))
155
        s->open_flags |= O_DSYNC;
156

    
157
    s->fd = -1;
158
    fd = open(filename, s->open_flags, 0644);
159
    if (fd < 0) {
160
        ret = -errno;
161
        if (ret == -EROFS)
162
            ret = -EACCES;
163
        return ret;
164
    }
165
    s->fd = fd;
166
    s->aligned_buf = NULL;
167
    if ((bdrv_flags & BDRV_O_NOCACHE)) {
168
        s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
169
        if (s->aligned_buf == NULL) {
170
            ret = -errno;
171
            close(fd);
172
            return ret;
173
        }
174
    }
175
    return 0;
176
}
177

    
178
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
179
{
180
    BDRVRawState *s = bs->opaque;
181
    int open_flags = 0;
182

    
183
    s->type = FTYPE_FILE;
184
    if (flags & BDRV_O_CREAT)
185
        open_flags = O_CREAT | O_TRUNC;
186

    
187
    return raw_open_common(bs, filename, flags, open_flags);
188
}
189

    
190
/* XXX: use host sector size if necessary with:
191
#ifdef DIOCGSECTORSIZE
192
        {
193
            unsigned int sectorsize = 512;
194
            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
195
                sectorsize > bufsize)
196
                bufsize = sectorsize;
197
        }
198
#endif
199
#ifdef CONFIG_COCOA
200
        u_int32_t   blockSize = 512;
201
        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
202
            bufsize = blockSize;
203
        }
204
#endif
205
*/
206

    
207
/*
208
 * offset and count are in bytes, but must be multiples of 512 for files
209
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
210
 *
211
 * This function may be called without alignment if the caller ensures
212
 * that O_DIRECT is not in effect.
213
 */
214
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
215
                     uint8_t *buf, int count)
216
{
217
    BDRVRawState *s = bs->opaque;
218
    int ret;
219

    
220
    ret = fd_open(bs);
221
    if (ret < 0)
222
        return ret;
223

    
224
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
225
        ++(s->lseek_err_cnt);
226
        if(s->lseek_err_cnt <= 10) {
227
            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
228
                              "] lseek failed : %d = %s\n",
229
                              s->fd, bs->filename, offset, buf, count,
230
                              bs->total_sectors, errno, strerror(errno));
231
        }
232
        return -1;
233
    }
234
    s->lseek_err_cnt=0;
235

    
236
    ret = read(s->fd, buf, count);
237
    if (ret == count)
238
        goto label__raw_read__success;
239

    
240
    /* Allow reads beyond the end (needed for pwrite) */
241
    if ((ret == 0) && bs->growable) {
242
        int64_t size = raw_getlength(bs);
243
        if (offset >= size) {
244
            memset(buf, 0, count);
245
            ret = count;
246
            goto label__raw_read__success;
247
        }
248
    }
249

    
250
    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
251
                      "] read failed %d : %d = %s\n",
252
                      s->fd, bs->filename, offset, buf, count,
253
                      bs->total_sectors, ret, errno, strerror(errno));
254

    
255
    /* Try harder for CDrom. */
256
    if (bs->type == BDRV_TYPE_CDROM) {
257
        lseek(s->fd, offset, SEEK_SET);
258
        ret = read(s->fd, buf, count);
259
        if (ret == count)
260
            goto label__raw_read__success;
261
        lseek(s->fd, offset, SEEK_SET);
262
        ret = read(s->fd, buf, count);
263
        if (ret == count)
264
            goto label__raw_read__success;
265

    
266
        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
267
                          "] retry read failed %d : %d = %s\n",
268
                          s->fd, bs->filename, offset, buf, count,
269
                          bs->total_sectors, ret, errno, strerror(errno));
270
    }
271

    
272
label__raw_read__success:
273

    
274
    return  (ret < 0) ? -errno : ret;
275
}
276

    
277
/*
278
 * offset and count are in bytes, but must be multiples of 512 for files
279
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
280
 *
281
 * This function may be called without alignment if the caller ensures
282
 * that O_DIRECT is not in effect.
283
 */
284
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
285
                      const uint8_t *buf, int count)
286
{
287
    BDRVRawState *s = bs->opaque;
288
    int ret;
289

    
290
    ret = fd_open(bs);
291
    if (ret < 0)
292
        return -errno;
293

    
294
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
295
        ++(s->lseek_err_cnt);
296
        if(s->lseek_err_cnt) {
297
            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
298
                              PRId64 "] lseek failed : %d = %s\n",
299
                              s->fd, bs->filename, offset, buf, count,
300
                              bs->total_sectors, errno, strerror(errno));
301
        }
302
        return -EIO;
303
    }
304
    s->lseek_err_cnt = 0;
305

    
306
    ret = write(s->fd, buf, count);
307
    if (ret == count)
308
        goto label__raw_write__success;
309

    
310
    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
311
                      "] write failed %d : %d = %s\n",
312
                      s->fd, bs->filename, offset, buf, count,
313
                      bs->total_sectors, ret, errno, strerror(errno));
314

    
315
label__raw_write__success:
316

    
317
    return  (ret < 0) ? -errno : ret;
318
}
319

    
320

    
321
/*
322
 * offset and count are in bytes and possibly not aligned. For files opened
323
 * with O_DIRECT, necessary alignments are ensured before calling
324
 * raw_pread_aligned to do the actual read.
325
 */
326
static int raw_pread(BlockDriverState *bs, int64_t offset,
327
                     uint8_t *buf, int count)
328
{
329
    BDRVRawState *s = bs->opaque;
330
    int size, ret, shift, sum;
331

    
332
    sum = 0;
333

    
334
    if (s->aligned_buf != NULL)  {
335

    
336
        if (offset & 0x1ff) {
337
            /* align offset on a 512 bytes boundary */
338

    
339
            shift = offset & 0x1ff;
340
            size = (shift + count + 0x1ff) & ~0x1ff;
341
            if (size > ALIGNED_BUFFER_SIZE)
342
                size = ALIGNED_BUFFER_SIZE;
343
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
344
            if (ret < 0)
345
                return ret;
346

    
347
            size = 512 - shift;
348
            if (size > count)
349
                size = count;
350
            memcpy(buf, s->aligned_buf + shift, size);
351

    
352
            buf += size;
353
            offset += size;
354
            count -= size;
355
            sum += size;
356

    
357
            if (count == 0)
358
                return sum;
359
        }
360
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
361

    
362
            /* read on aligned buffer */
363

    
364
            while (count) {
365

    
366
                size = (count + 0x1ff) & ~0x1ff;
367
                if (size > ALIGNED_BUFFER_SIZE)
368
                    size = ALIGNED_BUFFER_SIZE;
369

    
370
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
371
                if (ret < 0)
372
                    return ret;
373

    
374
                size = ret;
375
                if (size > count)
376
                    size = count;
377

    
378
                memcpy(buf, s->aligned_buf, size);
379

    
380
                buf += size;
381
                offset += size;
382
                count -= size;
383
                sum += size;
384
            }
385

    
386
            return sum;
387
        }
388
    }
389

    
390
    return raw_pread_aligned(bs, offset, buf, count) + sum;
391
}
392

    
393
static int raw_read(BlockDriverState *bs, int64_t sector_num,
394
                    uint8_t *buf, int nb_sectors)
395
{
396
    int ret;
397

    
398
    ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
399
    if (ret == (nb_sectors * 512))
400
        ret = 0;
401
    return ret;
402
}
403

    
404
/*
405
 * offset and count are in bytes and possibly not aligned. For files opened
406
 * with O_DIRECT, necessary alignments are ensured before calling
407
 * raw_pwrite_aligned to do the actual write.
408
 */
409
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
410
                      const uint8_t *buf, int count)
411
{
412
    BDRVRawState *s = bs->opaque;
413
    int size, ret, shift, sum;
414

    
415
    sum = 0;
416

    
417
    if (s->aligned_buf != NULL) {
418

    
419
        if (offset & 0x1ff) {
420
            /* align offset on a 512 bytes boundary */
421
            shift = offset & 0x1ff;
422
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
423
            if (ret < 0)
424
                return ret;
425

    
426
            size = 512 - shift;
427
            if (size > count)
428
                size = count;
429
            memcpy(s->aligned_buf + shift, buf, size);
430

    
431
            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
432
            if (ret < 0)
433
                return ret;
434

    
435
            buf += size;
436
            offset += size;
437
            count -= size;
438
            sum += size;
439

    
440
            if (count == 0)
441
                return sum;
442
        }
443
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
444

    
445
            while ((size = (count & ~0x1ff)) != 0) {
446

    
447
                if (size > ALIGNED_BUFFER_SIZE)
448
                    size = ALIGNED_BUFFER_SIZE;
449

    
450
                memcpy(s->aligned_buf, buf, size);
451

    
452
                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
453
                if (ret < 0)
454
                    return ret;
455

    
456
                buf += ret;
457
                offset += ret;
458
                count -= ret;
459
                sum += ret;
460
            }
461
            /* here, count < 512 because (count & ~0x1ff) == 0 */
462
            if (count) {
463
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
464
                if (ret < 0)
465
                    return ret;
466
                 memcpy(s->aligned_buf, buf, count);
467

    
468
                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
469
                 if (ret < 0)
470
                     return ret;
471
                 if (count < ret)
472
                     ret = count;
473

    
474
                 sum += ret;
475
            }
476
            return sum;
477
        }
478
    }
479
    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
480
}
481

    
482
static int raw_write(BlockDriverState *bs, int64_t sector_num,
483
                     const uint8_t *buf, int nb_sectors)
484
{
485
    int ret;
486
    ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
487
    if (ret == (nb_sectors * 512))
488
        ret = 0;
489
    return ret;
490
}
491

    
492
#ifdef CONFIG_AIO
493
/***********************************************************/
494
/* Unix AIO using POSIX AIO */
495

    
496
typedef struct RawAIOCB {
497
    BlockDriverAIOCB common;
498
    struct qemu_paiocb aiocb;
499
    struct RawAIOCB *next;
500
    int ret;
501
} RawAIOCB;
502

    
503
typedef struct PosixAioState
504
{
505
    int rfd, wfd;
506
    RawAIOCB *first_aio;
507
} PosixAioState;
508

    
509
static void posix_aio_read(void *opaque)
510
{
511
    PosixAioState *s = opaque;
512
    RawAIOCB *acb, **pacb;
513
    int ret;
514
    ssize_t len;
515

    
516
    /* read all bytes from signal pipe */
517
    for (;;) {
518
        char bytes[16];
519

    
520
        len = read(s->rfd, bytes, sizeof(bytes));
521
        if (len == -1 && errno == EINTR)
522
            continue; /* try again */
523
        if (len == sizeof(bytes))
524
            continue; /* more to read */
525
        break;
526
    }
527

    
528
    for(;;) {
529
        pacb = &s->first_aio;
530
        for(;;) {
531
            acb = *pacb;
532
            if (!acb)
533
                goto the_end;
534
            ret = qemu_paio_error(&acb->aiocb);
535
            if (ret == ECANCELED) {
536
                /* remove the request */
537
                *pacb = acb->next;
538
                qemu_aio_release(acb);
539
            } else if (ret != EINPROGRESS) {
540
                /* end of aio */
541
                if (ret == 0) {
542
                    ret = qemu_paio_return(&acb->aiocb);
543
                    if (ret == acb->aiocb.aio_nbytes)
544
                        ret = 0;
545
                    else
546
                        ret = -EINVAL;
547
                } else {
548
                    ret = -ret;
549
                }
550
                /* remove the request */
551
                *pacb = acb->next;
552
                /* call the callback */
553
                acb->common.cb(acb->common.opaque, ret);
554
                qemu_aio_release(acb);
555
                break;
556
            } else {
557
                pacb = &acb->next;
558
            }
559
        }
560
    }
561
 the_end: ;
562
}
563

    
564
static int posix_aio_flush(void *opaque)
565
{
566
    PosixAioState *s = opaque;
567
    return !!s->first_aio;
568
}
569

    
570
static PosixAioState *posix_aio_state;
571

    
572
static void aio_signal_handler(int signum)
573
{
574
    if (posix_aio_state) {
575
        char byte = 0;
576

    
577
        write(posix_aio_state->wfd, &byte, sizeof(byte));
578
    }
579

    
580
    qemu_service_io();
581
}
582

    
583
static int posix_aio_init(void)
584
{
585
    struct sigaction act;
586
    PosixAioState *s;
587
    int fds[2];
588
    struct qemu_paioinit ai;
589
  
590
    if (posix_aio_state)
591
        return 0;
592

    
593
    s = qemu_malloc(sizeof(PosixAioState));
594

    
595
    sigfillset(&act.sa_mask);
596
    act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
597
    act.sa_handler = aio_signal_handler;
598
    sigaction(SIGUSR2, &act, NULL);
599

    
600
    s->first_aio = NULL;
601
    if (pipe(fds) == -1) {
602
        fprintf(stderr, "failed to create pipe\n");
603
        return -errno;
604
    }
605

    
606
    s->rfd = fds[0];
607
    s->wfd = fds[1];
608

    
609
    fcntl(s->rfd, F_SETFL, O_NONBLOCK);
610
    fcntl(s->wfd, F_SETFL, O_NONBLOCK);
611

    
612
    qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, s);
613

    
614
    memset(&ai, 0, sizeof(ai));
615
    ai.aio_threads = 64;
616
    ai.aio_num = 64;
617
    qemu_paio_init(&ai);
618

    
619
    posix_aio_state = s;
620

    
621
    return 0;
622
}
623

    
624
static void raw_aio_remove(RawAIOCB *acb)
625
{
626
    RawAIOCB **pacb;
627

    
628
    /* remove the callback from the queue */
629
    pacb = &posix_aio_state->first_aio;
630
    for(;;) {
631
        if (*pacb == NULL) {
632
            fprintf(stderr, "raw_aio_remove: aio request not found!\n");
633
            break;
634
        } else if (*pacb == acb) {
635
            *pacb = acb->next;
636
            qemu_aio_release(acb);
637
            break;
638
        }
639
        pacb = &(*pacb)->next;
640
    }
641
}
642

    
643
static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
644
{
645
    int ret;
646
    RawAIOCB *acb = (RawAIOCB *)blockacb;
647

    
648
    ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
649
    if (ret == QEMU_PAIO_NOTCANCELED) {
650
        /* fail safe: if the aio could not be canceled, we wait for
651
           it */
652
        while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
653
    }
654

    
655
    raw_aio_remove(acb);
656
}
657

    
658
static AIOPool raw_aio_pool = {
659
    .aiocb_size         = sizeof(RawAIOCB),
660
    .cancel             = raw_aio_cancel,
661
};
662

    
663
static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num,
664
        QEMUIOVector *qiov, int nb_sectors,
665
        BlockDriverCompletionFunc *cb, void *opaque)
666
{
667
    BDRVRawState *s = bs->opaque;
668
    RawAIOCB *acb;
669

    
670
    if (fd_open(bs) < 0)
671
        return NULL;
672

    
673
    acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
674
    if (!acb)
675
        return NULL;
676
    acb->aiocb.aio_fildes = s->fd;
677
    acb->aiocb.ev_signo = SIGUSR2;
678
    acb->aiocb.aio_iov = qiov->iov;
679
    acb->aiocb.aio_niov = qiov->niov;
680
    acb->aiocb.aio_nbytes = nb_sectors * 512;
681
    acb->aiocb.aio_offset = sector_num * 512;
682
    acb->aiocb.aio_flags = 0;
683

    
684
    /*
685
     * If O_DIRECT is used the buffer needs to be aligned on a sector
686
     * boundary. Tell the low level code to ensure that in case it's
687
     * not done yet.
688
     */
689
    if (s->aligned_buf)
690
        acb->aiocb.aio_flags |= QEMU_AIO_SECTOR_ALIGNED;
691

    
692
    acb->next = posix_aio_state->first_aio;
693
    posix_aio_state->first_aio = acb;
694
    return acb;
695
}
696

    
697
static BlockDriverAIOCB *raw_aio_readv(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_read(&acb->aiocb) < 0) {
707
        raw_aio_remove(acb);
708
        return NULL;
709
    }
710
    return &acb->common;
711
}
712

    
713
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
714
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
715
        BlockDriverCompletionFunc *cb, void *opaque)
716
{
717
    RawAIOCB *acb;
718

    
719
    acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
720
    if (!acb)
721
        return NULL;
722
    if (qemu_paio_write(&acb->aiocb) < 0) {
723
        raw_aio_remove(acb);
724
        return NULL;
725
    }
726
    return &acb->common;
727
}
728
#else /* CONFIG_AIO */
729
static int posix_aio_init(void)
730
{
731
    return 0;
732
}
733
#endif /* CONFIG_AIO */
734

    
735

    
736
static void raw_close(BlockDriverState *bs)
737
{
738
    BDRVRawState *s = bs->opaque;
739
    if (s->fd >= 0) {
740
        close(s->fd);
741
        s->fd = -1;
742
        if (s->aligned_buf != NULL)
743
            qemu_free(s->aligned_buf);
744
    }
745
}
746

    
747
static int raw_truncate(BlockDriverState *bs, int64_t offset)
748
{
749
    BDRVRawState *s = bs->opaque;
750
    if (s->type != FTYPE_FILE)
751
        return -ENOTSUP;
752
    if (ftruncate(s->fd, offset) < 0)
753
        return -errno;
754
    return 0;
755
}
756

    
757
#ifdef __OpenBSD__
758
static int64_t raw_getlength(BlockDriverState *bs)
759
{
760
    BDRVRawState *s = bs->opaque;
761
    int fd = s->fd;
762
    struct stat st;
763

    
764
    if (fstat(fd, &st))
765
        return -1;
766
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
767
        struct disklabel dl;
768

    
769
        if (ioctl(fd, DIOCGDINFO, &dl))
770
            return -1;
771
        return (uint64_t)dl.d_secsize *
772
            dl.d_partitions[DISKPART(st.st_rdev)].p_size;
773
    } else
774
        return st.st_size;
775
}
776
#else /* !__OpenBSD__ */
777
static int64_t  raw_getlength(BlockDriverState *bs)
778
{
779
    BDRVRawState *s = bs->opaque;
780
    int fd = s->fd;
781
    int64_t size;
782
#ifdef CONFIG_BSD
783
    struct stat sb;
784
#ifdef __FreeBSD__
785
    int reopened = 0;
786
#endif
787
#endif
788
#ifdef __sun__
789
    struct dk_minfo minfo;
790
    int rv;
791
#endif
792
    int ret;
793

    
794
    ret = fd_open(bs);
795
    if (ret < 0)
796
        return ret;
797

    
798
#ifdef CONFIG_BSD
799
#ifdef __FreeBSD__
800
again:
801
#endif
802
    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
803
#ifdef DIOCGMEDIASIZE
804
        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
805
#elif defined(DIOCGPART)
806
        {
807
                struct partinfo pi;
808
                if (ioctl(fd, DIOCGPART, &pi) == 0)
809
                        size = pi.media_size;
810
                else
811
                        size = 0;
812
        }
813
        if (size == 0)
814
#endif
815
#ifdef CONFIG_COCOA
816
        size = LONG_LONG_MAX;
817
#else
818
        size = lseek(fd, 0LL, SEEK_END);
819
#endif
820
#ifdef __FreeBSD__
821
        switch(s->type) {
822
        case FTYPE_CD:
823
            /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
824
            if (size == 2048LL * (unsigned)-1)
825
                size = 0;
826
            /* XXX no disc?  maybe we need to reopen... */
827
            if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
828
                reopened = 1;
829
                goto again;
830
            }
831
        }
832
#endif
833
    } else
834
#endif
835
#ifdef __sun__
836
    /*
837
     * use the DKIOCGMEDIAINFO ioctl to read the size.
838
     */
839
    rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
840
    if ( rv != -1 ) {
841
        size = minfo.dki_lbsize * minfo.dki_capacity;
842
    } else /* there are reports that lseek on some devices
843
              fails, but irc discussion said that contingency
844
              on contingency was overkill */
845
#endif
846
    {
847
        size = lseek(fd, 0, SEEK_END);
848
    }
849
    return size;
850
}
851
#endif
852

    
853
static int raw_create(const char *filename, QEMUOptionParameter *options)
854
{
855
    int fd;
856
    int result = 0;
857
    int64_t total_size = 0;
858

    
859
    /* Read out options */
860
    while (options && options->name) {
861
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
862
            total_size = options->value.n / 512;
863
        }
864
        options++;
865
    }
866

    
867
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
868
              0644);
869
    if (fd < 0) {
870
        result = -errno;
871
    } else {
872
        if (ftruncate(fd, total_size * 512) != 0) {
873
            result = -errno;
874
        }
875
        if (close(fd) != 0) {
876
            result = -errno;
877
        }
878
    }
879
    return result;
880
}
881

    
882
static void raw_flush(BlockDriverState *bs)
883
{
884
    BDRVRawState *s = bs->opaque;
885
    fsync(s->fd);
886
}
887

    
888

    
889
static QEMUOptionParameter raw_create_options[] = {
890
    {
891
        .name = BLOCK_OPT_SIZE,
892
        .type = OPT_SIZE,
893
        .help = "Virtual disk size"
894
    },
895
    { NULL }
896
};
897

    
898
static BlockDriver bdrv_raw = {
899
    .format_name = "raw",
900
    .instance_size = sizeof(BDRVRawState),
901
    .bdrv_probe = NULL, /* no probe for protocols */
902
    .bdrv_open = raw_open,
903
    .bdrv_read = raw_read,
904
    .bdrv_write = raw_write,
905
    .bdrv_close = raw_close,
906
    .bdrv_create = raw_create,
907
    .bdrv_flush = raw_flush,
908

    
909
#ifdef CONFIG_AIO
910
    .bdrv_aio_readv = raw_aio_readv,
911
    .bdrv_aio_writev = raw_aio_writev,
912
#endif
913

    
914
    .bdrv_truncate = raw_truncate,
915
    .bdrv_getlength = raw_getlength,
916

    
917
    .create_options = raw_create_options,
918
};
919

    
920
/***********************************************/
921
/* host device */
922

    
923
#ifdef CONFIG_COCOA
924
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
925
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
926

    
927
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
928
{
929
    kern_return_t       kernResult;
930
    mach_port_t     masterPort;
931
    CFMutableDictionaryRef  classesToMatch;
932

    
933
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
934
    if ( KERN_SUCCESS != kernResult ) {
935
        printf( "IOMasterPort returned %d\n", kernResult );
936
    }
937

    
938
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
939
    if ( classesToMatch == NULL ) {
940
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
941
    } else {
942
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
943
    }
944
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
945
    if ( KERN_SUCCESS != kernResult )
946
    {
947
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
948
    }
949

    
950
    return kernResult;
951
}
952

    
953
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
954
{
955
    io_object_t     nextMedia;
956
    kern_return_t   kernResult = KERN_FAILURE;
957
    *bsdPath = '\0';
958
    nextMedia = IOIteratorNext( mediaIterator );
959
    if ( nextMedia )
960
    {
961
        CFTypeRef   bsdPathAsCFString;
962
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
963
        if ( bsdPathAsCFString ) {
964
            size_t devPathLength;
965
            strcpy( bsdPath, _PATH_DEV );
966
            strcat( bsdPath, "r" );
967
            devPathLength = strlen( bsdPath );
968
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
969
                kernResult = KERN_SUCCESS;
970
            }
971
            CFRelease( bsdPathAsCFString );
972
        }
973
        IOObjectRelease( nextMedia );
974
    }
975

    
976
    return kernResult;
977
}
978

    
979
#endif
980

    
981
static int hdev_probe_device(const char *filename)
982
{
983
    struct stat st;
984

    
985
    /* allow a dedicated CD-ROM driver to match with a higher priority */
986
    if (strstart(filename, "/dev/cdrom", NULL))
987
        return 50;
988

    
989
    if (stat(filename, &st) >= 0 &&
990
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
991
        return 100;
992
    }
993

    
994
    return 0;
995
}
996

    
997
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
998
{
999
    BDRVRawState *s = bs->opaque;
1000

    
1001
#ifdef CONFIG_COCOA
1002
    if (strstart(filename, "/dev/cdrom", NULL)) {
1003
        kern_return_t kernResult;
1004
        io_iterator_t mediaIterator;
1005
        char bsdPath[ MAXPATHLEN ];
1006
        int fd;
1007

    
1008
        kernResult = FindEjectableCDMedia( &mediaIterator );
1009
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
1010

    
1011
        if ( bsdPath[ 0 ] != '\0' ) {
1012
            strcat(bsdPath,"s0");
1013
            /* some CDs don't have a partition 0 */
1014
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
1015
            if (fd < 0) {
1016
                bsdPath[strlen(bsdPath)-1] = '1';
1017
            } else {
1018
                close(fd);
1019
            }
1020
            filename = bsdPath;
1021
        }
1022

    
1023
        if ( mediaIterator )
1024
            IOObjectRelease( mediaIterator );
1025
    }
1026
#endif
1027

    
1028
    s->type = FTYPE_FILE;
1029
#if defined(__linux__) && defined(CONFIG_AIO)
1030
    if (strstart(filename, "/dev/sg", NULL)) {
1031
        bs->sg = 1;
1032
    }
1033
#endif
1034

    
1035
    return raw_open_common(bs, filename, flags, 0);
1036
}
1037

    
1038
#if defined(__linux__)
1039
/* Note: we do not have a reliable method to detect if the floppy is
1040
   present. The current method is to try to open the floppy at every
1041
   I/O and to keep it opened during a few hundreds of ms. */
1042
static int fd_open(BlockDriverState *bs)
1043
{
1044
    BDRVRawState *s = bs->opaque;
1045
    int last_media_present;
1046

    
1047
    if (s->type != FTYPE_FD)
1048
        return 0;
1049
    last_media_present = (s->fd >= 0);
1050
    if (s->fd >= 0 &&
1051
        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1052
        close(s->fd);
1053
        s->fd = -1;
1054
#ifdef DEBUG_FLOPPY
1055
        printf("Floppy closed\n");
1056
#endif
1057
    }
1058
    if (s->fd < 0) {
1059
        if (s->fd_got_error &&
1060
            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1061
#ifdef DEBUG_FLOPPY
1062
            printf("No floppy (open delayed)\n");
1063
#endif
1064
            return -EIO;
1065
        }
1066
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
1067
        if (s->fd < 0) {
1068
            s->fd_error_time = qemu_get_clock(rt_clock);
1069
            s->fd_got_error = 1;
1070
            if (last_media_present)
1071
                s->fd_media_changed = 1;
1072
#ifdef DEBUG_FLOPPY
1073
            printf("No floppy\n");
1074
#endif
1075
            return -EIO;
1076
        }
1077
#ifdef DEBUG_FLOPPY
1078
        printf("Floppy opened\n");
1079
#endif
1080
    }
1081
    if (!last_media_present)
1082
        s->fd_media_changed = 1;
1083
    s->fd_open_time = qemu_get_clock(rt_clock);
1084
    s->fd_got_error = 0;
1085
    return 0;
1086
}
1087

    
1088
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1089
{
1090
    BDRVRawState *s = bs->opaque;
1091

    
1092
    return ioctl(s->fd, req, buf);
1093
}
1094

    
1095
#ifdef CONFIG_AIO
1096
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1097
        unsigned long int req, void *buf,
1098
        BlockDriverCompletionFunc *cb, void *opaque)
1099
{
1100
    BDRVRawState *s = bs->opaque;
1101
    RawAIOCB *acb;
1102

    
1103
    if (fd_open(bs) < 0)
1104
        return NULL;
1105

    
1106
    acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
1107
    if (!acb)
1108
        return NULL;
1109
    acb->aiocb.aio_fildes = s->fd;
1110
    acb->aiocb.ev_signo = SIGUSR2;
1111
    acb->aiocb.aio_offset = 0;
1112
    acb->aiocb.aio_flags = 0;
1113

    
1114
    acb->next = posix_aio_state->first_aio;
1115
    posix_aio_state->first_aio = acb;
1116

    
1117
    acb->aiocb.aio_ioctl_buf = buf;
1118
    acb->aiocb.aio_ioctl_cmd = req;
1119
    if (qemu_paio_ioctl(&acb->aiocb) < 0) {
1120
        raw_aio_remove(acb);
1121
        return NULL;
1122
    }
1123

    
1124
    return &acb->common;
1125
}
1126
#endif
1127

    
1128
#elif defined(__FreeBSD__)
1129
static int fd_open(BlockDriverState *bs)
1130
{
1131
    BDRVRawState *s = bs->opaque;
1132

    
1133
    /* this is just to ensure s->fd is sane (its called by io ops) */
1134
    if (s->fd >= 0)
1135
        return 0;
1136
    return -EIO;
1137
}
1138
#else /* !linux && !FreeBSD */
1139

    
1140
static int fd_open(BlockDriverState *bs)
1141
{
1142
    return 0;
1143
}
1144

    
1145
#endif /* !linux && !FreeBSD */
1146

    
1147
static int hdev_create(const char *filename, QEMUOptionParameter *options)
1148
{
1149
    int fd;
1150
    int ret = 0;
1151
    struct stat stat_buf;
1152
    int64_t total_size = 0;
1153

    
1154
    /* Read out options */
1155
    while (options && options->name) {
1156
        if (!strcmp(options->name, "size")) {
1157
            total_size = options->value.n / 512;
1158
        }
1159
        options++;
1160
    }
1161

    
1162
    fd = open(filename, O_WRONLY | O_BINARY);
1163
    if (fd < 0)
1164
        return -EIO;
1165

    
1166
    if (fstat(fd, &stat_buf) < 0)
1167
        ret = -EIO;
1168
    else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1169
        ret = -EIO;
1170
    else if (lseek(fd, 0, SEEK_END) < total_size * 512)
1171
        ret = -ENOSPC;
1172

    
1173
    close(fd);
1174
    return ret;
1175
}
1176

    
1177
static BlockDriver bdrv_host_device = {
1178
    .format_name        = "host_device",
1179
    .instance_size        = sizeof(BDRVRawState),
1180
    .bdrv_probe_device        = hdev_probe_device,
1181
    .bdrv_open                = hdev_open,
1182
    .bdrv_close                = raw_close,
1183
    .bdrv_create        = hdev_create,
1184
    .bdrv_flush                = raw_flush,
1185

    
1186
#ifdef CONFIG_AIO
1187
    .bdrv_aio_readv        = raw_aio_readv,
1188
    .bdrv_aio_writev        = raw_aio_writev,
1189
#endif
1190

    
1191
    .bdrv_read          = raw_read,
1192
    .bdrv_write         = raw_write,
1193
    .bdrv_getlength        = raw_getlength,
1194

    
1195
    /* generic scsi device */
1196
#ifdef __linux__
1197
    .bdrv_ioctl         = hdev_ioctl,
1198
#ifdef CONFIG_AIO
1199
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1200
#endif
1201
#endif
1202
};
1203

    
1204
#ifdef __linux__
1205
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1206
{
1207
    BDRVRawState *s = bs->opaque;
1208
    int ret;
1209

    
1210
    posix_aio_init();
1211

    
1212
    s->type = FTYPE_FD;
1213

    
1214
    /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1215
    ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1216
    if (ret)
1217
        return ret;
1218

    
1219
    /* close fd so that we can reopen it as needed */
1220
    close(s->fd);
1221
    s->fd = -1;
1222
    s->fd_media_changed = 1;
1223

    
1224
    return 0;
1225
}
1226

    
1227
static int floppy_probe_device(const char *filename)
1228
{
1229
    if (strstart(filename, "/dev/fd", NULL))
1230
        return 100;
1231
    return 0;
1232
}
1233

    
1234

    
1235
static int floppy_is_inserted(BlockDriverState *bs)
1236
{
1237
    return fd_open(bs) >= 0;
1238
}
1239

    
1240
static int floppy_media_changed(BlockDriverState *bs)
1241
{
1242
    BDRVRawState *s = bs->opaque;
1243
    int ret;
1244

    
1245
    /*
1246
     * XXX: we do not have a true media changed indication.
1247
     * It does not work if the floppy is changed without trying to read it.
1248
     */
1249
    fd_open(bs);
1250
    ret = s->fd_media_changed;
1251
    s->fd_media_changed = 0;
1252
#ifdef DEBUG_FLOPPY
1253
    printf("Floppy changed=%d\n", ret);
1254
#endif
1255
    return ret;
1256
}
1257

    
1258
static int floppy_eject(BlockDriverState *bs, int eject_flag)
1259
{
1260
    BDRVRawState *s = bs->opaque;
1261
    int fd;
1262

    
1263
    if (s->fd >= 0) {
1264
        close(s->fd);
1265
        s->fd = -1;
1266
    }
1267
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1268
    if (fd >= 0) {
1269
        if (ioctl(fd, FDEJECT, 0) < 0)
1270
            perror("FDEJECT");
1271
        close(fd);
1272
    }
1273

    
1274
    return 0;
1275
}
1276

    
1277
static BlockDriver bdrv_host_floppy = {
1278
    .format_name        = "host_floppy",
1279
    .instance_size      = sizeof(BDRVRawState),
1280
    .bdrv_probe_device        = floppy_probe_device,
1281
    .bdrv_open          = floppy_open,
1282
    .bdrv_close         = raw_close,
1283
    .bdrv_create        = hdev_create,
1284
    .bdrv_flush         = raw_flush,
1285

    
1286
#ifdef CONFIG_AIO
1287
    .bdrv_aio_readv     = raw_aio_readv,
1288
    .bdrv_aio_writev    = raw_aio_writev,
1289
#endif
1290

    
1291
    .bdrv_read          = raw_read,
1292
    .bdrv_write         = raw_write,
1293
    .bdrv_getlength        = raw_getlength,
1294

    
1295
    /* removable device support */
1296
    .bdrv_is_inserted   = floppy_is_inserted,
1297
    .bdrv_media_changed = floppy_media_changed,
1298
    .bdrv_eject         = floppy_eject,
1299
};
1300

    
1301
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1302
{
1303
    BDRVRawState *s = bs->opaque;
1304

    
1305
    s->type = FTYPE_CD;
1306

    
1307
    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1308
    return raw_open_common(bs, filename, flags, O_NONBLOCK);
1309
}
1310

    
1311
static int cdrom_probe_device(const char *filename)
1312
{
1313
    if (strstart(filename, "/dev/cd", NULL))
1314
        return 100;
1315
    return 0;
1316
}
1317

    
1318
static int cdrom_is_inserted(BlockDriverState *bs)
1319
{
1320
    BDRVRawState *s = bs->opaque;
1321
    int ret;
1322

    
1323
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1324
    if (ret == CDS_DISC_OK)
1325
        return 1;
1326
    return 0;
1327
}
1328

    
1329
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1330
{
1331
    BDRVRawState *s = bs->opaque;
1332

    
1333
    if (eject_flag) {
1334
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1335
            perror("CDROMEJECT");
1336
    } else {
1337
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1338
            perror("CDROMEJECT");
1339
    }
1340

    
1341
    return 0;
1342
}
1343

    
1344
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1345
{
1346
    BDRVRawState *s = bs->opaque;
1347

    
1348
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1349
        /*
1350
         * Note: an error can happen if the distribution automatically
1351
         * mounts the CD-ROM
1352
         */
1353
        /* perror("CDROM_LOCKDOOR"); */
1354
    }
1355

    
1356
    return 0;
1357
}
1358

    
1359
static BlockDriver bdrv_host_cdrom = {
1360
    .format_name        = "host_cdrom",
1361
    .instance_size      = sizeof(BDRVRawState),
1362
    .bdrv_probe_device        = cdrom_probe_device,
1363
    .bdrv_open          = cdrom_open,
1364
    .bdrv_close         = raw_close,
1365
    .bdrv_create        = hdev_create,
1366
    .bdrv_flush         = raw_flush,
1367

    
1368
#ifdef CONFIG_AIO
1369
    .bdrv_aio_readv     = raw_aio_readv,
1370
    .bdrv_aio_writev    = raw_aio_writev,
1371
#endif
1372

    
1373
    .bdrv_read          = raw_read,
1374
    .bdrv_write         = raw_write,
1375
    .bdrv_getlength     = raw_getlength,
1376

    
1377
    /* removable device support */
1378
    .bdrv_is_inserted   = cdrom_is_inserted,
1379
    .bdrv_eject         = cdrom_eject,
1380
    .bdrv_set_locked    = cdrom_set_locked,
1381

    
1382
    /* generic scsi device */
1383
    .bdrv_ioctl         = hdev_ioctl,
1384
#ifdef CONFIG_AIO
1385
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1386
#endif
1387
};
1388
#endif /* __linux__ */
1389

    
1390
#ifdef __FreeBSD__
1391
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1392
{
1393
    BDRVRawState *s = bs->opaque;
1394
    int ret;
1395

    
1396
    s->type = FTYPE_CD;
1397

    
1398
    ret = raw_open_common(bs, filename, flags, 0);
1399
    if (ret)
1400
        return ret;
1401

    
1402
    /* make sure the door isnt locked at this time */
1403
    ioctl(s->fd, CDIOCALLOW);
1404
    return 0;
1405
}
1406

    
1407
static int cdrom_probe_device(const char *filename)
1408
{
1409
    if (strstart(filename, "/dev/cd", NULL) ||
1410
            strstart(filename, "/dev/acd", NULL))
1411
        return 100;
1412
    return 0;
1413
}
1414

    
1415
static int cdrom_reopen(BlockDriverState *bs)
1416
{
1417
    BDRVRawState *s = bs->opaque;
1418
    int fd;
1419

    
1420
    /*
1421
     * Force reread of possibly changed/newly loaded disc,
1422
     * FreeBSD seems to not notice sometimes...
1423
     */
1424
    if (s->fd >= 0)
1425
        close(s->fd);
1426
    fd = open(bs->filename, s->open_flags, 0644);
1427
    if (fd < 0) {
1428
        s->fd = -1;
1429
        return -EIO;
1430
    }
1431
    s->fd = fd;
1432

    
1433
    /* make sure the door isnt locked at this time */
1434
    ioctl(s->fd, CDIOCALLOW);
1435
    return 0;
1436
}
1437

    
1438
static int cdrom_is_inserted(BlockDriverState *bs)
1439
{
1440
    return raw_getlength(bs) > 0;
1441
}
1442

    
1443
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1444
{
1445
    BDRVRawState *s = bs->opaque;
1446

    
1447
    if (s->fd < 0)
1448
        return -ENOTSUP;
1449

    
1450
    (void) ioctl(s->fd, CDIOCALLOW);
1451

    
1452
    if (eject_flag) {
1453
        if (ioctl(s->fd, CDIOCEJECT) < 0)
1454
            perror("CDIOCEJECT");
1455
    } else {
1456
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
1457
            perror("CDIOCCLOSE");
1458
    }
1459

    
1460
    if (cdrom_reopen(bs) < 0)
1461
        return -ENOTSUP;
1462
    return 0;
1463
}
1464

    
1465
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1466
{
1467
    BDRVRawState *s = bs->opaque;
1468

    
1469
    if (s->fd < 0)
1470
        return -ENOTSUP;
1471
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1472
        /*
1473
         * Note: an error can happen if the distribution automatically
1474
         * mounts the CD-ROM
1475
         */
1476
        /* perror("CDROM_LOCKDOOR"); */
1477
    }
1478

    
1479
    return 0;
1480
}
1481

    
1482
static BlockDriver bdrv_host_cdrom = {
1483
    .format_name        = "host_cdrom",
1484
    .instance_size      = sizeof(BDRVRawState),
1485
    .bdrv_probe_device        = cdrom_probe_device,
1486
    .bdrv_open          = cdrom_open,
1487
    .bdrv_close         = raw_close,
1488
    .bdrv_create        = hdev_create,
1489
    .bdrv_flush         = raw_flush,
1490

    
1491
#ifdef CONFIG_AIO
1492
    .bdrv_aio_readv     = raw_aio_readv,
1493
    .bdrv_aio_writev    = raw_aio_writev,
1494
#endif
1495

    
1496
    .bdrv_read          = raw_read,
1497
    .bdrv_write         = raw_write,
1498
    .bdrv_getlength     = raw_getlength,
1499

    
1500
    /* removable device support */
1501
    .bdrv_is_inserted   = cdrom_is_inserted,
1502
    .bdrv_eject         = cdrom_eject,
1503
    .bdrv_set_locked    = cdrom_set_locked,
1504
};
1505
#endif /* __FreeBSD__ */
1506

    
1507
static void bdrv_raw_init(void)
1508
{
1509
    /*
1510
     * Register all the drivers.  Note that order is important, the driver
1511
     * registered last will get probed first.
1512
     */
1513
    bdrv_register(&bdrv_raw);
1514
    bdrv_register(&bdrv_host_device);
1515
#ifdef __linux__
1516
    bdrv_register(&bdrv_host_floppy);
1517
    bdrv_register(&bdrv_host_cdrom);
1518
#endif
1519
#ifdef __FreeBSD__
1520
    bdrv_register(&bdrv_host_cdrom);
1521
#endif
1522
}
1523

    
1524
block_init(bdrv_raw_init);