summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-01-05 00:25:15 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-07 15:52:33 +0100
commit950f4bdc027cb8c83fd2145590549fdcf5522078 (patch)
treefb2d845b03c31c3aee674b5f227b74c8216e622e
parent07781847826d6901e047c3c55d227aae487a9f4c (diff)
downloadrockbox-950f4bdc027cb8c83fd2145590549fdcf5522078.tar.gz
rockbox-950f4bdc027cb8c83fd2145590549fdcf5522078.zip
imxtools: move firmware read/write to library
Split the ugly firmware read/write into a API function and a much simplified code. Also the code can now report progress. Change-Id: I3f998eaf0c067c6da42b1d2dd9c5a5bf43c6915d
-rw-r--r--utils/imxtools/scsitools/scsitool.c264
-rw-r--r--utils/imxtools/scsitools/stmp_scsi.c175
-rw-r--r--utils/imxtools/scsitools/stmp_scsi.h8
3 files changed, 259 insertions, 188 deletions
diff --git a/utils/imxtools/scsitools/scsitool.c b/utils/imxtools/scsitools/scsitool.c
index a84b5919d7..8367af6939 100644
--- a/utils/imxtools/scsitools/scsitool.c
+++ b/utils/imxtools/scsitools/scsitool.c
@@ -31,6 +31,8 @@
31#include <sys/stat.h> 31#include <sys/stat.h>
32#include <fcntl.h> 32#include <fcntl.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <inttypes.h>
35#include <errno.h>
34#include "rbscsi.h" 36#include "rbscsi.h"
35#include "misc.h" 37#include "misc.h"
36#include "stmp_scsi.h" 38#include "stmp_scsi.h"
@@ -147,7 +149,7 @@ static int do_info(void)
147 cprintf_field(" Number of drives:", " %u\n", info.nr_drives); 149 cprintf_field(" Number of drives:", " %u\n", info.nr_drives);
148 if(info.has.size) 150 if(info.has.size)
149 { 151 {
150 cprintf_field(" Media size:", " %llu ", (unsigned long long)info.size); 152 cprintf_field(" Media size:", " %" PRIu64 " ", info.size);
151 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.size), get_size_suffix(info.size)); 153 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.size), get_size_suffix(info.size));
152 } 154 }
153 if(info.has.alloc_size) 155 if(info.has.alloc_size)
@@ -226,17 +228,17 @@ static int do_info(void)
226 continue; 228 continue;
227 if(info.has.sector_size) 229 if(info.has.sector_size)
228 { 230 {
229 cprintf_field(" Sector size:", " %llu ", (unsigned long long)info.sector_size); 231 cprintf_field(" Sector size:", " %" PRIu32 " ", info.sector_size);
230 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.sector_size), get_size_suffix(info.sector_size)); 232 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.sector_size), get_size_suffix(info.sector_size));
231 } 233 }
232 if(info.has.erase_size) 234 if(info.has.erase_size)
233 { 235 {
234 cprintf_field(" Erase size:", " %llu ", (unsigned long long)info.erase_size); 236 cprintf_field(" Erase size:", " %" PRIu32 " ", info.erase_size);
235 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.erase_size), get_size_suffix(info.erase_size)); 237 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.erase_size), get_size_suffix(info.erase_size));
236 } 238 }
237 if(info.has.size) 239 if(info.has.size)
238 { 240 {
239 cprintf_field(" Drive size:", " %llu ", (unsigned long long)info.size); 241 cprintf_field(" Drive size:", " %" PRIu64 " ", info.size);
240 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.size), get_size_suffix(info.size)); 242 cprintf(RED, "(%.3f %s)\n", get_size_natural(info.size), get_size_suffix(info.size));
241 } 243 }
242 if(info.has.sector_count) 244 if(info.has.sector_count)
@@ -282,92 +284,70 @@ static int do_info(void)
282 return 0; 284 return 0;
283} 285}
284 286
285void do_extract(const char *file) 287struct rw_fw_context_t
286{ 288{
287 FILE *f = NULL; 289 int tot_size;
288 cprintf(BLUE, "Extracting firmware...\n"); 290 int cur_size;
289 291 int last_percent;
290 struct stmp_logical_media_table_t *table = NULL; 292 FILE *f;
291 int ret = stmp_get_logical_media_table(g_dev_fd, &table); 293 bool read;
292 if(ret) 294};
293 { 295
294 cprintf(GREY, "Cannot get logical table: %d\n", ret); 296int rw_fw(void *user, void *buf, size_t size)
295 goto Lend; 297{
296 } 298 struct rw_fw_context_t *ctx = user;
297 int entry = 0; 299 int this_percent = (ctx->cur_size * 100LLU) / ctx->tot_size;
298 while(entry < table->header.count) 300 if(this_percent != ctx->last_percent && (this_percent % 5) == 0)
299 if(table->entry[entry].type == SCSI_STMP_DRIVE_TYPE_SYSTEM &&
300 table->entry[entry].tag == SCSI_STMP_DRIVE_TAG_SYSTEM_BOOT)
301 break;
302 else
303 entry++;
304 if(entry == table->header.count)
305 {
306 cprintf(GREY, "Cannot find firmware partition\n");
307 goto Lend;
308 }
309 uint8_t drive_no = table->entry[entry].drive_no;
310 uint64_t drive_sz = table->entry[entry].size;
311 if(g_debug)
312 {
313 cprintf(RED, "* ");
314 cprintf_field("Drive: ", "%#x\n", drive_no);
315 cprintf(RED, "* ");
316 cprintf_field("Size: ", "%#llx\n", (unsigned long long)drive_sz);
317 }
318 struct stmp_logical_drive_info_t info;
319 ret = stmp_get_logical_drive_info(g_dev_fd, drive_no, &info);
320 if(ret || !info.has.sector_size)
321 {
322 cprintf(GREY, "Cannot get sector size\n");
323 goto Lend;
324 }
325 unsigned sector_size = info.sector_size;
326 if(g_debug)
327 {
328 cprintf(RED, "* ");
329 cprintf_field("Sector size: ", "%lu\n", (unsigned long)sector_size);
330 }
331 uint8_t *sector = malloc(sector_size);
332 ret = stmp_read_logical_drive_sectors(g_dev_fd, drive_no, 0, 1, sector, sector_size);
333 if(ret)
334 {
335 cprintf(GREY, "Cannot read first sector: %d\n", ret);
336 goto Lend;
337 }
338 uint32_t fw_size = *(uint32_t *)(sector + 0x1c) * 16;
339 if(g_debug)
340 { 301 {
341 cprintf(RED, "* "); 302 cprintf(RED, "%d%%", this_percent);
342 cprintf_field("Firmware size: ", "%#x\n", fw_size); 303 cprintf(YELLOW, "...");
304 fflush(stdout);
343 } 305 }
306 ctx->last_percent = this_percent;
307 int ret = -1;
308 if(ctx->read)
309 ret = fread(buf, size, 1, ctx->f);
310 else
311 ret = fwrite(buf, size, 1, ctx->f);
312 ctx->cur_size += size;
313 if(ret != 1)
314 return -1;
315 else
316 return size;
317}
344 318
345 f = fopen(file, "wb"); 319void rw_finish(struct rw_fw_context_t *ctx)
320{
321 if(ctx->last_percent == 100)
322 return;
323 cprintf(RED, "100%%\n");
324}
325
326void do_extract(const char *file)
327{
328 FILE *f = fopen(file, "wb");
346 if(f == NULL) 329 if(f == NULL)
347 { 330 {
348 cprintf(GREY, "Cannot open '%s' for writing: %m\n", file); 331 cprintf(GREY, "Cannot open output file: %s\n", strerror(errno));
349 goto Lend; 332 return;
350 } 333 }
351 334 int ret = stmp_read_firmware(g_dev_fd, NULL, NULL);
352 for(int sec = 0; sec * sector_size < fw_size; sec++) 335 if(ret < 0)
353 { 336 {
354 ret = stmp_read_logical_drive_sectors(g_dev_fd, drive_no, sec, 1, sector, sector_size); 337 cprintf(GREY, "Cannot get firmware size: %d\n", ret);
355 if(ret) 338 return;
356 {
357 cprintf(GREY, "Cannot read sector %d: %d\n", sec, ret);
358 goto Lend;
359 }
360 if(fwrite(sector, sector_size, 1, f) != 1)
361 {
362 cprintf(GREY, "Write failed: %m\n");
363 goto Lend;
364 }
365 } 339 }
366 cprintf(BLUE, "Done\n"); 340 struct rw_fw_context_t ctx;
367Lend: 341 ctx.tot_size = ret;
368 free(table); 342 ctx.cur_size = 0;
369 if(f) 343 ctx.f = f;
370 fclose(f); 344 ctx.last_percent = -1;
345 ctx.read = false;
346 ret = stmp_read_firmware(g_dev_fd, &ctx, &rw_fw);
347 if(ret < 0)
348 cprintf(GREY, "Cannot read firmware: %d\n", ret);
349 rw_finish(&ctx);
350 fclose(f);
371} 351}
372 352
373void do_write(const char *file, int want_a_brick) 353void do_write(const char *file, int want_a_brick)
@@ -379,115 +359,25 @@ void do_write(const char *file, int want_a_brick)
379 cprintf(GREY, "option on the command line and do not complain if you end up with a brick ;)\n"); 359 cprintf(GREY, "option on the command line and do not complain if you end up with a brick ;)\n");
380 return; 360 return;
381 } 361 }
382 FILE *f = NULL; 362 FILE *f = fopen(file, "rb");
383 cprintf(BLUE, "Writing firmware...\n");
384
385 struct stmp_logical_media_table_t *table = NULL;
386 int ret = stmp_get_logical_media_table(g_dev_fd, &table);
387 if(ret)
388 {
389 cprintf(GREY, "Cannot get logical table: %d\n", ret);
390 goto Lend;
391 }
392 int entry = 0;
393 while(entry < table->header.count)
394 if(table->entry[entry].type == SCSI_STMP_DRIVE_TYPE_SYSTEM &&
395 table->entry[entry].tag == SCSI_STMP_DRIVE_TAG_SYSTEM_BOOT)
396 break;
397 else
398 entry++;
399 if(entry == table->header.count)
400 {
401 cprintf(GREY, "Cannot find firmware partition\n");
402 goto Lend;
403 }
404 uint8_t drive_no = table->entry[entry].drive_no;
405 uint64_t drive_sz = table->entry[entry].size;
406 if(g_debug)
407 {
408 cprintf(RED, "* ");
409 cprintf_field("Drive: ", "%#x\n", drive_no);
410 cprintf(RED, "* ");
411 cprintf_field("Size: ", "%#llx\n", (unsigned long long)drive_sz);
412 }
413 struct stmp_logical_drive_info_t info;
414 ret = stmp_get_logical_drive_info(g_dev_fd, drive_no, &info);
415 if(ret || !info.has.sector_size)
416 {
417 cprintf(GREY, "Cannot get sector size\n");
418 goto Lend;
419 }
420 unsigned sector_size = info.sector_size;
421 uint8_t *sector = malloc(sector_size);
422
423 /* sanity check by reading first sector */
424 ret = stmp_read_logical_drive_sectors(g_dev_fd, drive_no, 0, 1, sector, sector_size);
425 if(ret)
426 {
427 cprintf(GREY, "Cannot read first sector: %d\n", ret);
428 return;
429 }
430 uint32_t sig = *(uint32_t *)(sector + 0x14);
431 if(sig != 0x504d5453)
432 {
433 cprintf(GREY, "There is something wrong: the first sector doesn't have the STMP signature. Bailing out...\n");
434 return;
435 }
436
437 f = fopen(file, "rb");
438 if(f == NULL) 363 if(f == NULL)
439 { 364 {
440 cprintf(GREY, "Cannot open '%s' for writing: %m\n", file); 365 cprintf(GREY, "Cannot open output file: %s\n", strerror(errno));
441 goto Lend; 366 return;
442 } 367 }
368 struct rw_fw_context_t ctx;
443 fseek(f, 0, SEEK_END); 369 fseek(f, 0, SEEK_END);
444 int fw_size = ftell(f); 370 ctx.tot_size = ftell(f);
445 fseek(f, 0, SEEK_SET); 371 fseek(f, 0, SEEK_SET);
446 if(g_debug) 372 ctx.cur_size = 0;
447 { 373 ctx.f = f;
448 cprintf(RED, "* "); 374 ctx.last_percent = -1;
449 cprintf_field("Firmware size: ", "%#x\n", fw_size); 375 ctx.read = true;
450 } 376 int ret = stmp_write_firmware(g_dev_fd, &ctx, &rw_fw);
451 /* sanity check size */ 377 if(ret < 0)
452 if((uint64_t)fw_size > drive_sz) 378 cprintf(GREY, "Cannot write firmware: %d\n", ret);
453 { 379 rw_finish(&ctx);
454 cprintf(GREY, "You cannot write a firmware greater than the partition size.\n"); 380 fclose(f);
455 goto Lend;
456 }
457
458 int percent = -1;
459 for(int off = 0; off < fw_size; off += sector_size)
460 {
461 int sec = off / sector_size;
462 int this_percent = (sec * 100) / (fw_size / sector_size);
463 if(this_percent != percent && (this_percent % 5) == 0)
464 {
465 cprintf(RED, "%d%%", this_percent);
466 cprintf(YELLOW, "...");
467 fflush(stdout);
468 }
469 percent = this_percent;
470 int xfer_len = MIN(fw_size - off, (int)sector_size);
471 if(fread(sector, xfer_len, 1, f) != 1)
472 {
473 cprintf(GREY, "Read failed: %m\n");
474 goto Lend;
475 }
476 /* NOTE transfer a whole sector even if incomplete, the device won't access
477 * partial sectors */
478 if(xfer_len < (int)sector_size)
479 memset(sector + xfer_len, 0, sector_size - xfer_len);
480 ret = stmp_write_logical_drive_sectors(g_dev_fd, drive_no, sec, 1, sector, sector_size);
481 if(ret)
482 {
483 cprintf(GREY, "Cannot write sector %d: %d\n", sec, ret);
484 goto Lend;
485 }
486 }
487 cprintf(BLUE, "Done\n");
488Lend:
489 if(f)
490 fclose(f);
491} 381}
492 382
493static void usage(void) 383static void usage(void)
@@ -586,14 +476,14 @@ int main(int argc, char **argv)
586 rb_scsi_device_t scsi_dev = rb_scsi_open(argv[optind], g_debug ? RB_SCSI_DEBUG : 0, NULL, scsi_printf); 476 rb_scsi_device_t scsi_dev = rb_scsi_open(argv[optind], g_debug ? RB_SCSI_DEBUG : 0, NULL, scsi_printf);
587 if(scsi_dev == 0) 477 if(scsi_dev == 0)
588 { 478 {
589 cprintf(GREY, "Cannot open device: %m\n"); 479 cprintf(GREY, "Cannot open device\n");
590 ret = 1; 480 ret = 1;
591 goto Lend; 481 goto Lend;
592 } 482 }
593 g_dev_fd = stmp_open(scsi_dev, g_debug ? STMP_DEBUG : 0, NULL, scsi_printf); 483 g_dev_fd = stmp_open(scsi_dev, g_debug ? STMP_DEBUG : 0, NULL, scsi_printf);
594 if(g_dev_fd == 0) 484 if(g_dev_fd == 0)
595 { 485 {
596 cprintf(GREY, "Cannot open stmp device: %m\n"); 486 cprintf(GREY, "Cannot open stmp device\n");
597 ret = 2; 487 ret = 2;
598 goto Lend; 488 goto Lend;
599 } 489 }
diff --git a/utils/imxtools/scsitools/stmp_scsi.c b/utils/imxtools/scsitools/stmp_scsi.c
index dcda91e295..e1d0dc4c77 100644
--- a/utils/imxtools/scsitools/stmp_scsi.c
+++ b/utils/imxtools/scsitools/stmp_scsi.c
@@ -23,7 +23,6 @@
23#include <stdarg.h> 23#include <stdarg.h>
24#include <stdio.h> 24#include <stdio.h>
25#define _BSD_SOURCE 25#define _BSD_SOURCE
26#include <endian.h>
27#include "stmp_scsi.h" 26#include "stmp_scsi.h"
28 27
29#define MIN(a, b) ((a) < (b) ? (a) : (b)) 28#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -131,6 +130,7 @@ int stmp_sense_analysis(stmp_device_t dev, int status, uint8_t *sense, int sense
131 for(int i = 0; i < sense_size; i++) 130 for(int i = 0; i < sense_size; i++)
132 stmp_printf(dev, " %02x", sense[i]); 131 stmp_printf(dev, " %02x", sense[i]);
133 stmp_printf(dev, "\n"); 132 stmp_printf(dev, "\n");
133 rb_scsi_decode_sense(dev->dev, sense, sense_size);
134 } 134 }
135 return status; 135 return status;
136} 136}
@@ -614,3 +614,176 @@ int stmp_get_logical_drive_info(stmp_device_t dev, uint8_t drive, struct stmp_lo
614 } 614 }
615 return 0; 615 return 0;
616} 616}
617
618int stmp_read_firmware(stmp_device_t dev, void *user, stmp_fw_rw_fn_t fn)
619{
620 /* read logicial table */
621 uint8_t *sector = NULL;
622 struct stmp_logical_media_table_t *table = NULL;
623 int ret = stmp_get_logical_media_table(dev, &table);
624 if(ret)
625 {
626 stmp_printf(dev, "Cannot get logical table: %d\n", ret);
627 return -1;
628 }
629 /* locate firmware partition */
630 int entry = 0;
631 while(entry < table->header.count)
632 if(table->entry[entry].type == SCSI_STMP_DRIVE_TYPE_SYSTEM &&
633 table->entry[entry].tag == SCSI_STMP_DRIVE_TAG_SYSTEM_BOOT)
634 break;
635 else
636 entry++;
637 if(entry == table->header.count)
638 {
639 stmp_printf(dev, "Cannot find firmware partition\n");
640 goto Lerr;
641 }
642 uint8_t drive_no = table->entry[entry].drive_no;
643 uint64_t drive_sz = table->entry[entry].size;
644 stmp_debugf(dev, "Firmware drive: %#x\n", drive_no);
645 stmp_debugf(dev, "Firmware max size: %#llx\n", (unsigned long long)drive_sz);
646 /* get drive info */
647 struct stmp_logical_drive_info_t info;
648 ret = stmp_get_logical_drive_info(dev, drive_no, &info);
649 if(ret || !info.has.sector_size)
650 {
651 stmp_printf(dev, "Cannot get sector size\n");
652 goto Lerr;
653 }
654 unsigned sector_size = info.sector_size;
655 stmp_debugf(dev, "Firmware sector size: %lu\n", (unsigned long)sector_size);
656 /* allocate a buffer for one sector */
657 sector = malloc(sector_size);
658 /* read the first sector to check it is correct and get the total size */
659 ret = stmp_read_logical_drive_sectors(dev, drive_no, 0, 1, sector, sector_size);
660 if(ret)
661 {
662 stmp_printf(dev, "Cannot read first sector: %d\n", ret);
663 goto Lerr;
664 }
665 uint32_t sig = *(uint32_t *)(sector + 0x14);
666 if(sig != 0x504d5453)
667 {
668 stmp_printf(dev, "There is something wrong: the first sector doesn't have the STMP signature.\n");
669 goto Lerr;
670 }
671 uint32_t fw_size = *(uint32_t *)(sector + 0x1c) * 16; /* see SB file format */
672 stmp_debugf(dev, "Firmware size: %#x\n", fw_size);
673 /* if fn is NULL, just return the size immediately */
674 if(fn != NULL)
675 {
676 /* read all sectors one by one */
677 for(int sec = 0; sec * sector_size < fw_size; sec++)
678 {
679 ret = stmp_read_logical_drive_sectors(dev, drive_no, sec, 1, sector, sector_size);
680 if(ret)
681 {
682 stmp_printf(dev, "Cannot read sector %d: %d\n", sec, ret);
683 goto Lerr;
684 }
685 int xfer_len = MIN(sector_size, fw_size - sec * sector_size);
686 ret = fn(user, sector, xfer_len);
687 if(ret != xfer_len)
688 {
689 stmp_printf(dev, "User write failed: %d\n", ret);
690 goto Lerr;
691 }
692 }
693 }
694 ret = fw_size;
695Lend:
696 free(table);
697 if(sector)
698 free(sector);
699 return ret;
700Lerr:
701 ret = -1;
702 goto Lend;
703}
704
705int stmp_write_firmware(stmp_device_t dev, void *user, stmp_fw_rw_fn_t fn)
706{
707 /* read logicial table */
708 struct stmp_logical_media_table_t *table = NULL;
709 int ret = stmp_get_logical_media_table(dev, &table);
710 if(ret)
711 {
712 stmp_printf(dev, "Cannot get logical table: %d\n", ret);
713 return -1;
714 }
715 /* locate firmware partition */
716 int entry = 0;
717 while(entry < table->header.count)
718 if(table->entry[entry].type == SCSI_STMP_DRIVE_TYPE_SYSTEM &&
719 table->entry[entry].tag == SCSI_STMP_DRIVE_TAG_SYSTEM_BOOT)
720 break;
721 else
722 entry++;
723 if(entry == table->header.count)
724 {
725 stmp_printf(dev, "Cannot find firmware partition\n");
726 goto Lerr;
727 }
728 uint8_t drive_no = table->entry[entry].drive_no;
729 uint64_t drive_sz = table->entry[entry].size;
730 stmp_debugf(dev, "Firmware drive: %#x\n", drive_no);
731 stmp_debugf(dev, "Firmware max size: %#llx\n", (unsigned long long)drive_sz);
732 /* get drive info */
733 struct stmp_logical_drive_info_t info;
734 ret = stmp_get_logical_drive_info(dev, drive_no, &info);
735 if(ret || !info.has.sector_size)
736 {
737 stmp_printf(dev, "Cannot get sector size\n");
738 goto Lerr;
739 }
740 unsigned sector_size = info.sector_size;
741 stmp_debugf(dev, "Firmware sector size: %lu\n", (unsigned long)sector_size);
742 /* allocate a buffer for one sector */
743 uint8_t *sector = malloc(sector_size);
744 /* read the first sector to check it is correct and get the total size */
745 ret = fn(user, sector, sector_size);
746 /* the whole file could be smaller than one sector, but it must be greater
747 * then the header size */
748 if(ret < 0x20)
749 {
750 stmp_printf(dev, "User read failed: %d\n", ret);
751 goto Lerr;
752 }
753 uint32_t sig = *(uint32_t *)(sector + 0x14);
754 if(sig != 0x504d5453)
755 {
756 stmp_printf(dev, "There is something wrong: the first sector doesn't have the STMP signature.\n");
757 goto Lerr;
758 }
759 uint32_t fw_size = *(uint32_t *)(sector + 0x1c) * 16; /* see SB file format */
760 stmp_debugf(dev, "Firmware size: %#x\n", fw_size);
761 /* write all sectors one by one */
762 for(int sec = 0; sec * sector_size < fw_size; sec++)
763 {
764 int xfer_len = MIN(sector_size, fw_size - sec * sector_size);
765 /* avoid rereading the first sector */
766 if(sec != 0)
767 ret = fn(user, sector, xfer_len);
768 if(ret != xfer_len)
769 {
770 stmp_printf(dev, "User read failed: %d\n", ret);
771 goto Lerr;
772 }
773 if(ret < (int)sector_size)
774 memset(sector + ret, 0, sector_size - ret);
775 ret = stmp_write_logical_drive_sectors(dev, drive_no, sec, 1, sector, sector_size);
776 if(ret)
777 {
778 stmp_printf(dev, "Cannot write sector %d: %d\n", sec, ret);
779 goto Lerr;
780 }
781 }
782 ret = fw_size;
783Lend:
784 free(table);
785 return ret;
786Lerr:
787 ret = -1;
788 goto Lend;
789}
diff --git a/utils/imxtools/scsitools/stmp_scsi.h b/utils/imxtools/scsitools/stmp_scsi.h
index 68d77daeec..56068b5d4c 100644
--- a/utils/imxtools/scsitools/stmp_scsi.h
+++ b/utils/imxtools/scsitools/stmp_scsi.h
@@ -355,6 +355,14 @@ int stmp_read_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t a
355 uint32_t count, void *buffer, int buffer_size); 355 uint32_t count, void *buffer, int buffer_size);
356int stmp_write_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address, 356int stmp_write_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address,
357 uint32_t count, void *buffer, int buffer_size); 357 uint32_t count, void *buffer, int buffer_size);
358/* return <0 on error, or firmware size in bytes otherwise,
359 * if not NULL, the read/write function will be called as many times as needed to provide
360 * the entire firmware, it should return number of bytes read/written on success or -1 on error
361 * in all cases, the total size of the firmware is based on the header
362 * if NULL for read, return firmware size */
363typedef int (*stmp_fw_rw_fn_t)(void *user, void *buf, size_t size);
364int stmp_read_firmware(stmp_device_t dev, void *user, stmp_fw_rw_fn_t fn);
365int stmp_write_firmware(stmp_device_t dev, void *user, stmp_fw_rw_fn_t fn);
358/* string helpers */ 366/* string helpers */
359const char *stmp_get_logical_media_type_string(uint32_t type); 367const char *stmp_get_logical_media_type_string(uint32_t type);
360const char *stmp_get_logical_media_vendor_string(uint32_t type); 368const char *stmp_get_logical_media_vendor_string(uint32_t type);