1*f4d8de48SHenrik Nordström /* 2*f4d8de48SHenrik Nordström * Copyright (C) 2013 Henrik Nordstrom <henrik@henriknordstrom.net> 3*f4d8de48SHenrik Nordström * 4*f4d8de48SHenrik Nordström * SPDX-License-Identifier: GPL-2.0+ 5*f4d8de48SHenrik Nordström */ 6*f4d8de48SHenrik Nordström 7*f4d8de48SHenrik Nordström #include <config.h> 8*f4d8de48SHenrik Nordström #include <common.h> 9*f4d8de48SHenrik Nordström #include <part.h> 10*f4d8de48SHenrik Nordström #include <os.h> 11*f4d8de48SHenrik Nordström #include <malloc.h> 12*f4d8de48SHenrik Nordström #include <sandboxblockdev.h> 13*f4d8de48SHenrik Nordström #include <asm/errno.h> 14*f4d8de48SHenrik Nordström 15*f4d8de48SHenrik Nordström static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES]; 16*f4d8de48SHenrik Nordström 17*f4d8de48SHenrik Nordström static struct host_block_dev *find_host_device(int dev) 18*f4d8de48SHenrik Nordström { 19*f4d8de48SHenrik Nordström if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES) 20*f4d8de48SHenrik Nordström return &host_devices[dev]; 21*f4d8de48SHenrik Nordström 22*f4d8de48SHenrik Nordström return NULL; 23*f4d8de48SHenrik Nordström } 24*f4d8de48SHenrik Nordström 25*f4d8de48SHenrik Nordström static unsigned long host_block_read(int dev, unsigned long start, 26*f4d8de48SHenrik Nordström lbaint_t blkcnt, void *buffer) 27*f4d8de48SHenrik Nordström { 28*f4d8de48SHenrik Nordström struct host_block_dev *host_dev = find_host_device(dev); 29*f4d8de48SHenrik Nordström 30*f4d8de48SHenrik Nordström if (!host_dev) 31*f4d8de48SHenrik Nordström return -1; 32*f4d8de48SHenrik Nordström if (os_lseek(host_dev->fd, 33*f4d8de48SHenrik Nordström start * host_dev->blk_dev.blksz, 34*f4d8de48SHenrik Nordström OS_SEEK_SET) == -1) { 35*f4d8de48SHenrik Nordström printf("ERROR: Invalid position\n"); 36*f4d8de48SHenrik Nordström return -1; 37*f4d8de48SHenrik Nordström } 38*f4d8de48SHenrik Nordström ssize_t len = os_read(host_dev->fd, buffer, 39*f4d8de48SHenrik Nordström blkcnt * host_dev->blk_dev.blksz); 40*f4d8de48SHenrik Nordström if (len >= 0) 41*f4d8de48SHenrik Nordström return len / host_dev->blk_dev.blksz; 42*f4d8de48SHenrik Nordström return -1; 43*f4d8de48SHenrik Nordström } 44*f4d8de48SHenrik Nordström 45*f4d8de48SHenrik Nordström static unsigned long host_block_write(int dev, unsigned long start, 46*f4d8de48SHenrik Nordström lbaint_t blkcnt, const void *buffer) 47*f4d8de48SHenrik Nordström { 48*f4d8de48SHenrik Nordström struct host_block_dev *host_dev = find_host_device(dev); 49*f4d8de48SHenrik Nordström if (os_lseek(host_dev->fd, 50*f4d8de48SHenrik Nordström start * host_dev->blk_dev.blksz, 51*f4d8de48SHenrik Nordström OS_SEEK_SET) == -1) { 52*f4d8de48SHenrik Nordström printf("ERROR: Invalid position\n"); 53*f4d8de48SHenrik Nordström return -1; 54*f4d8de48SHenrik Nordström } 55*f4d8de48SHenrik Nordström ssize_t len = os_write(host_dev->fd, buffer, blkcnt * 56*f4d8de48SHenrik Nordström host_dev->blk_dev.blksz); 57*f4d8de48SHenrik Nordström if (len >= 0) 58*f4d8de48SHenrik Nordström return len / host_dev->blk_dev.blksz; 59*f4d8de48SHenrik Nordström return -1; 60*f4d8de48SHenrik Nordström } 61*f4d8de48SHenrik Nordström 62*f4d8de48SHenrik Nordström int host_dev_bind(int dev, char *filename) 63*f4d8de48SHenrik Nordström { 64*f4d8de48SHenrik Nordström struct host_block_dev *host_dev = find_host_device(dev); 65*f4d8de48SHenrik Nordström 66*f4d8de48SHenrik Nordström if (!host_dev) 67*f4d8de48SHenrik Nordström return -1; 68*f4d8de48SHenrik Nordström if (host_dev->blk_dev.priv) { 69*f4d8de48SHenrik Nordström os_close(host_dev->fd); 70*f4d8de48SHenrik Nordström host_dev->blk_dev.priv = NULL; 71*f4d8de48SHenrik Nordström } 72*f4d8de48SHenrik Nordström if (host_dev->filename) 73*f4d8de48SHenrik Nordström free(host_dev->filename); 74*f4d8de48SHenrik Nordström if (filename && *filename) { 75*f4d8de48SHenrik Nordström host_dev->filename = strdup(filename); 76*f4d8de48SHenrik Nordström } else { 77*f4d8de48SHenrik Nordström host_dev->filename = NULL; 78*f4d8de48SHenrik Nordström return 0; 79*f4d8de48SHenrik Nordström } 80*f4d8de48SHenrik Nordström 81*f4d8de48SHenrik Nordström host_dev->fd = os_open(host_dev->filename, OS_O_RDWR); 82*f4d8de48SHenrik Nordström if (host_dev->fd == -1) { 83*f4d8de48SHenrik Nordström printf("Failed to access host backing file '%s'\n", 84*f4d8de48SHenrik Nordström host_dev->filename); 85*f4d8de48SHenrik Nordström return 1; 86*f4d8de48SHenrik Nordström } 87*f4d8de48SHenrik Nordström 88*f4d8de48SHenrik Nordström block_dev_desc_t *blk_dev = &host_dev->blk_dev; 89*f4d8de48SHenrik Nordström blk_dev->if_type = IF_TYPE_HOST; 90*f4d8de48SHenrik Nordström blk_dev->priv = host_dev; 91*f4d8de48SHenrik Nordström blk_dev->blksz = 512; 92*f4d8de48SHenrik Nordström blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; 93*f4d8de48SHenrik Nordström blk_dev->block_read = host_block_read; 94*f4d8de48SHenrik Nordström blk_dev->block_write = host_block_write; 95*f4d8de48SHenrik Nordström blk_dev->dev = dev; 96*f4d8de48SHenrik Nordström blk_dev->part_type = PART_TYPE_UNKNOWN; 97*f4d8de48SHenrik Nordström init_part(blk_dev); 98*f4d8de48SHenrik Nordström 99*f4d8de48SHenrik Nordström return 0; 100*f4d8de48SHenrik Nordström } 101*f4d8de48SHenrik Nordström 102*f4d8de48SHenrik Nordström int host_get_dev_err(int dev, block_dev_desc_t **blk_devp) 103*f4d8de48SHenrik Nordström { 104*f4d8de48SHenrik Nordström struct host_block_dev *host_dev = find_host_device(dev); 105*f4d8de48SHenrik Nordström 106*f4d8de48SHenrik Nordström if (!host_dev) 107*f4d8de48SHenrik Nordström return -ENODEV; 108*f4d8de48SHenrik Nordström 109*f4d8de48SHenrik Nordström if (!host_dev->blk_dev.priv) 110*f4d8de48SHenrik Nordström return -ENOENT; 111*f4d8de48SHenrik Nordström 112*f4d8de48SHenrik Nordström *blk_devp = &host_dev->blk_dev; 113*f4d8de48SHenrik Nordström return 0; 114*f4d8de48SHenrik Nordström } 115*f4d8de48SHenrik Nordström 116*f4d8de48SHenrik Nordström block_dev_desc_t *host_get_dev(int dev) 117*f4d8de48SHenrik Nordström { 118*f4d8de48SHenrik Nordström block_dev_desc_t *blk_dev; 119*f4d8de48SHenrik Nordström 120*f4d8de48SHenrik Nordström if (host_get_dev_err(dev, &blk_dev)) 121*f4d8de48SHenrik Nordström return NULL; 122*f4d8de48SHenrik Nordström 123*f4d8de48SHenrik Nordström return blk_dev; 124*f4d8de48SHenrik Nordström } 125