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