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