xref: /openbmc/qemu/block.c (revision 0849bf0821fc174621d6b91a3c0a5709639ddab4)
1fc01f7e7Sbellard /*
2fc01f7e7Sbellard  * QEMU System Emulator block driver
3fc01f7e7Sbellard  *
4fc01f7e7Sbellard  * Copyright (c) 2003 Fabrice Bellard
5fc01f7e7Sbellard  *
6fc01f7e7Sbellard  * Permission is hereby granted, free of charge, to any person obtaining a copy
7fc01f7e7Sbellard  * of this software and associated documentation files (the "Software"), to deal
8fc01f7e7Sbellard  * in the Software without restriction, including without limitation the rights
9fc01f7e7Sbellard  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10fc01f7e7Sbellard  * copies of the Software, and to permit persons to whom the Software is
11fc01f7e7Sbellard  * furnished to do so, subject to the following conditions:
12fc01f7e7Sbellard  *
13fc01f7e7Sbellard  * The above copyright notice and this permission notice shall be included in
14fc01f7e7Sbellard  * all copies or substantial portions of the Software.
15fc01f7e7Sbellard  *
16fc01f7e7Sbellard  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fc01f7e7Sbellard  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fc01f7e7Sbellard  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19fc01f7e7Sbellard  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20fc01f7e7Sbellard  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21fc01f7e7Sbellard  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22fc01f7e7Sbellard  * THE SOFTWARE.
23fc01f7e7Sbellard  */
24fc01f7e7Sbellard #include <stdlib.h>
25fc01f7e7Sbellard #include <stdio.h>
26fc01f7e7Sbellard #include <stdarg.h>
27fc01f7e7Sbellard #include <string.h>
28fc01f7e7Sbellard #include <getopt.h>
29fc01f7e7Sbellard #include <inttypes.h>
30fc01f7e7Sbellard #include <unistd.h>
31fc01f7e7Sbellard #include <sys/mman.h>
32fc01f7e7Sbellard #include <fcntl.h>
33fc01f7e7Sbellard #include <signal.h>
34fc01f7e7Sbellard #include <time.h>
35fc01f7e7Sbellard #include <sys/time.h>
36fc01f7e7Sbellard #include <malloc.h>
37fc01f7e7Sbellard #include <termios.h>
38fc01f7e7Sbellard #include <sys/poll.h>
39fc01f7e7Sbellard #include <errno.h>
40fc01f7e7Sbellard #include <sys/wait.h>
41fc01f7e7Sbellard 
42fc01f7e7Sbellard #include "vl.h"
43fc01f7e7Sbellard 
44fc01f7e7Sbellard struct BlockDriverState {
45fc01f7e7Sbellard     int fd;
46fc01f7e7Sbellard     int64_t total_sectors;
47*0849bf08Sbellard     int read_only;
48fc01f7e7Sbellard };
49fc01f7e7Sbellard 
50fc01f7e7Sbellard BlockDriverState *bdrv_open(const char *filename)
51fc01f7e7Sbellard {
52fc01f7e7Sbellard     BlockDriverState *bs;
53fc01f7e7Sbellard     int fd;
54fc01f7e7Sbellard     int64_t size;
55fc01f7e7Sbellard 
56fc01f7e7Sbellard     bs = malloc(sizeof(BlockDriverState));
57fc01f7e7Sbellard     if(!bs)
58fc01f7e7Sbellard         return NULL;
59*0849bf08Sbellard     bs->read_only = 0;
60fc01f7e7Sbellard     fd = open(filename, O_RDWR);
61fc01f7e7Sbellard     if (fd < 0) {
62*0849bf08Sbellard         fd = open(filename, O_RDONLY);
63*0849bf08Sbellard         if (fd < 0) {
64fc01f7e7Sbellard             close(fd);
65fc01f7e7Sbellard             free(bs);
66fc01f7e7Sbellard             return NULL;
67fc01f7e7Sbellard         }
68*0849bf08Sbellard         bs->read_only = 1;
69*0849bf08Sbellard     }
70fc01f7e7Sbellard     size = lseek64(fd, 0, SEEK_END);
71fc01f7e7Sbellard     bs->total_sectors = size / 512;
72fc01f7e7Sbellard     bs->fd = fd;
73fc01f7e7Sbellard     return bs;
74fc01f7e7Sbellard }
75fc01f7e7Sbellard 
76fc01f7e7Sbellard void bdrv_close(BlockDriverState *bs)
77fc01f7e7Sbellard {
78fc01f7e7Sbellard     close(bs->fd);
79fc01f7e7Sbellard     free(bs);
80fc01f7e7Sbellard }
81fc01f7e7Sbellard 
82fc01f7e7Sbellard /* return -1 if error */
83fc01f7e7Sbellard int bdrv_read(BlockDriverState *bs, int64_t sector_num,
84fc01f7e7Sbellard               uint8_t *buf, int nb_sectors)
85fc01f7e7Sbellard {
86fc01f7e7Sbellard     int ret;
87fc01f7e7Sbellard 
88fc01f7e7Sbellard     lseek64(bs->fd, sector_num * 512, SEEK_SET);
89fc01f7e7Sbellard     ret = read(bs->fd, buf, nb_sectors * 512);
90fc01f7e7Sbellard     if (ret != nb_sectors * 512)
91fc01f7e7Sbellard         return -1;
92fc01f7e7Sbellard     else
93fc01f7e7Sbellard         return 0;
94fc01f7e7Sbellard }
95fc01f7e7Sbellard 
96fc01f7e7Sbellard /* return -1 if error */
97fc01f7e7Sbellard int bdrv_write(BlockDriverState *bs, int64_t sector_num,
98fc01f7e7Sbellard                const uint8_t *buf, int nb_sectors)
99fc01f7e7Sbellard {
100fc01f7e7Sbellard     int ret;
101fc01f7e7Sbellard 
102*0849bf08Sbellard     if (bs->read_only)
103*0849bf08Sbellard         return -1;
104*0849bf08Sbellard 
105fc01f7e7Sbellard     lseek64(bs->fd, sector_num * 512, SEEK_SET);
106fc01f7e7Sbellard     ret = write(bs->fd, buf, nb_sectors * 512);
107fc01f7e7Sbellard     if (ret != nb_sectors * 512)
108fc01f7e7Sbellard         return -1;
109fc01f7e7Sbellard     else
110fc01f7e7Sbellard         return 0;
111fc01f7e7Sbellard }
112fc01f7e7Sbellard 
113fc01f7e7Sbellard void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
114fc01f7e7Sbellard {
115fc01f7e7Sbellard     *nb_sectors_ptr = bs->total_sectors;
116fc01f7e7Sbellard }
117