summaryrefslogtreecommitdiffstats
path: root/src/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/disk.c')
-rw-r--r--src/disk.c124
1 files changed, 96 insertions, 28 deletions
diff --git a/src/disk.c b/src/disk.c
index 38fbb09..41d1823 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -118,7 +118,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
blkdev[len] = 0;
- fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
+ fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
if ( fd < 0 ) {
ERROR_INFO("Cannot open block device %s", blkdev);
return -1;
@@ -144,13 +144,13 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
ERROR("Block device name is too long");
return -1;
}
- fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
+ fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 && errno == ENOENT ) {
if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
ERROR("Block device name is too long");
return -1;
}
- fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
+ fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
}
if ( fd < 0 && errno == ENOENT ) {
blkdev[len] = 0;
@@ -201,7 +201,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
int disk_dump_dev(int fd, const char * file) {
- int fd2;
+ int fd2 = -1;
int ret;
char * path;
uint64_t blksize;
@@ -253,11 +253,15 @@ int disk_dump_dev(int fd, const char * file) {
return -1;
}
- fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if ( ! simulate ) {
+
+ fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ if ( fd2 < 0 ) {
+ ERROR_INFO("Cannot create file %s", file);
+ return -1;
+ }
- if ( fd2 < 0 ) {
- ERROR_INFO("Cannot create file %s", file);
- return -1;
}
sent = 0;
@@ -272,29 +276,89 @@ int disk_dump_dev(int fd, const char * file) {
break;
if ( size < 0 ) {
PRINTF_ERROR("Reading from block device failed");
- close(fd2);
+ if ( ! simulate )
+ close(fd2);
return -1;
}
- if ( write(fd2, global_buf, size) != size ) {
- PRINTF_ERROR("Dumping image failed");
- close(fd2);
- return -1;
+ if ( ! simulate ) {
+ if ( write(fd2, global_buf, size) != size ) {
+ PRINTF_ERROR("Dumping image failed");
+ close(fd2);
+ return -1;
+ }
}
sent += size;
printf_progressbar(sent, blksize);
}
- close(fd2);
+ if ( ! simulate )
+ close(fd2);
return 0;
}
-int disk_flash_dev(int fd, const char * file) {
+int disk_flash_dev(int fd, struct image * image) {
- ERROR("Not implemented yet");
- (void)fd;
- (void)file;
- return -1;
+ uint64_t blksize;
+ size_t need, sent;
+ ssize_t size;
+
+ if ( image->type != IMAGE_MMC )
+ ERROR_RETURN("Only mmc images are supported", -1);
+
+ printf("Writing image to block device...\n");
+
+#ifdef __linux__
+
+ if ( ioctl(fd, BLKGETSIZE64, &blksize) != 0 ) {
+ ERROR_INFO("Cannot get size of block device");
+ return -1;
+ }
+
+#else
+
+ blksize = lseek(fd, 0, SEEK_END);
+ if ( (off_t)blksize == (off_t)-1 ) {
+ ERROR_INFO("Cannot get size of block device");
+ return -1;
+ }
+
+ if ( lseek(fd, 0, SEEK_SET) == (off_t)-1 ) {
+ ERROR_INFO("Cannot seek to begin of block device");
+ return -1;
+ }
+
+#endif
+
+ if ( blksize == 0 )
+ ERROR_RETURN("Block device has zero size", -1);
+
+ if ( image->size > blksize )
+ ERROR_RETURN("Image is too big", -1);
+
+ sent = 0;
+ printf_progressbar(0, image->size);
+
+ while ( sent < image->size ) {
+ need = image->size - sent;
+ if ( need > sizeof(global_buf) )
+ need = sizeof(global_buf);
+ size = image_read(image, global_buf, need);
+ if ( size == 0 ) {
+ PRINTF_ERROR("Failed to read image");
+ return -1;
+ }
+ if ( ! simulate ) {
+ if ( write(fd, global_buf, size) != size ) {
+ PRINTF_ERROR("Writing image failed");
+ return -1;
+ }
+ }
+ sent += size;
+ printf_progressbar(sent, image->size);
+ }
+
+ return 0;
}
@@ -412,16 +476,14 @@ int disk_init(struct usb_device_info * dev) {
maj2 = tmp;
}
- /* TODO: change 1 to 0 when disk_flash_dev will be implemented */
-
/* RX-51, RM-680 and RM-696 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */
if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 || dev->device == DEVICE_RM_696 )
- fd = disk_open_dev(maj1, min1, -1, 1);
+ fd = disk_open_dev(maj1, min1, -1, simulate ? 1 : 0);
/* Other devices can export SD card as first partition and export whole mmc device, so host system will see MBR table */
else if ( maj2 != -1 && min2 != -1 )
- fd = disk_open_dev(maj2, min2, 1, 1);
+ fd = disk_open_dev(maj2, min2, 1, simulate ? 1 : 0);
else
- fd = disk_open_dev(maj1, min1, 1, 1);
+ fd = disk_open_dev(maj1, min1, 1, simulate ? 1 : 0);
if ( fd < 0 )
return -1;
@@ -454,10 +516,16 @@ enum device disk_get_device(struct usb_device_info * dev) {
int disk_flash_image(struct usb_device_info * dev, struct image * image) {
- ERROR("Not implemented yet");
- (void)dev;
- (void)image;
- return -1;
+ int ret;
+
+ printf("Flash image:\n");
+ image_print_info(image);
+
+ ret = disk_flash_dev(dev->data, image);
+ if ( ret == 0 )
+ printf("Done\n");
+
+ return ret;
}