| Index: emcore/trunk/tools/emcorefs/emcore.h | 
| — | — | @@ -106,7 +106,7 @@ | 
| 107 | 107 | int emcore_file_open(uint32_t* handle, const char* pathname, const int flags); | 
| 108 | 108 | int emcore_file_size(uint32_t* size, const uint32_t handle); | 
| 109 | 109 | int emcore_file_read(uint32_t* nread, const uint32_t handle, const uint32_t addr, const uint32_t size); | 
| 110 |  | -int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size);
 | 
|  | 110 | +int emcore_file_write(uint32_t* nwrite, const uint32_t handle, const uint32_t addr, const uint32_t size); | 
| 111 | 111 | int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence); | 
| 112 | 112 | int emcore_file_truncate(const uint32_t handle, const uint32_t length); | 
| 113 | 113 | int emcore_file_sync(const uint32_t handle); | 
| Index: emcore/trunk/tools/emcorefs/fuse.c | 
| — | — | @@ -346,6 +346,98 @@ | 
| 347 | 347 | return nread; | 
| 348 | 348 | } | 
| 349 | 349 |  | 
|  | 350 | +int emcorefs_write(const char* path, const char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi) { | 
|  | 351 | +    fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags); | 
|  | 352 | + | 
|  | 353 | +    int res; | 
|  | 354 | +    uint32_t emcore_errno_value, addr, nwrite = size; | 
|  | 355 | + | 
|  | 356 | +    if (!fi->fh) | 
|  | 357 | +    { | 
|  | 358 | +        return -EIO; | 
|  | 359 | +    } | 
|  | 360 | + | 
|  | 361 | +    res = emcore_malloc(&addr, size); | 
|  | 362 | + | 
|  | 363 | +    if (EMCORE_SUCCESS != res) | 
|  | 364 | +    { | 
|  | 365 | +        return -EIO; | 
|  | 366 | +    } | 
|  | 367 | + | 
|  | 368 | +    do { | 
|  | 369 | +        if (offset) { | 
|  | 370 | +            res = emcore_file_seek(fi->fh, offset, SEEK_SET); | 
|  | 371 | + | 
|  | 372 | +            if (EMCORE_ERROR_IO == res) | 
|  | 373 | +            { | 
|  | 374 | +                res = emcore_errno(&emcore_errno_value); | 
|  | 375 | + | 
|  | 376 | +                if (EMCORE_SUCCESS != res) | 
|  | 377 | +                { | 
|  | 378 | +                    nwrite = -EIO; | 
|  | 379 | +                    break; | 
|  | 380 | +                } | 
|  | 381 | + | 
|  | 382 | +                if (EMCORE_SUCCESS != emcore_errno_value) | 
|  | 383 | +                { | 
|  | 384 | +                    nwrite = -emcore_errno_value; | 
|  | 385 | +                    break; | 
|  | 386 | +                } | 
|  | 387 | +            } | 
|  | 388 | + | 
|  | 389 | +            if (EMCORE_SUCCESS != res) | 
|  | 390 | +            { | 
|  | 391 | +                nwrite = -EIO; | 
|  | 392 | +                break; | 
|  | 393 | +            } | 
|  | 394 | +        } | 
|  | 395 | + | 
|  | 396 | +        res = emcore_write(buf, addr, nwrite); | 
|  | 397 | + | 
|  | 398 | +        if (EMCORE_SUCCESS != res) | 
|  | 399 | +        { | 
|  | 400 | +            nwrite = -EIO; | 
|  | 401 | +            break; | 
|  | 402 | +        } | 
|  | 403 | + | 
|  | 404 | +        res = emcore_file_write(&nwrite, fi->fh, addr, size); | 
|  | 405 | + | 
|  | 406 | +        if (EMCORE_ERROR_IO == res) | 
|  | 407 | +        { | 
|  | 408 | +            res = emcore_errno(&emcore_errno_value); | 
|  | 409 | + | 
|  | 410 | +            if (EMCORE_SUCCESS != res) | 
|  | 411 | +            { | 
|  | 412 | +                nwrite = -EIO; | 
|  | 413 | +                break; | 
|  | 414 | +            } | 
|  | 415 | + | 
|  | 416 | +            if (EMCORE_SUCCESS != emcore_errno_value) | 
|  | 417 | +            { | 
|  | 418 | +                nwrite = -emcore_errno_value; | 
|  | 419 | +                break; | 
|  | 420 | +            } | 
|  | 421 | +        } | 
|  | 422 | + | 
|  | 423 | +        if (EMCORE_SUCCESS != res) | 
|  | 424 | +        { | 
|  | 425 | +            nwrite = -EIO; | 
|  | 426 | +        } | 
|  | 427 | +    } | 
|  | 428 | +    while(0); | 
|  | 429 | + | 
|  | 430 | +    res = emcore_free(addr); | 
|  | 431 | + | 
|  | 432 | +    if (EMCORE_SUCCESS != res) | 
|  | 433 | +    { | 
|  | 434 | +        return -EIO; | 
|  | 435 | +    } | 
|  | 436 | + | 
|  | 437 | +    cache_remove(path); | 
|  | 438 | + | 
|  | 439 | +    return nwrite; | 
|  | 440 | +} | 
|  | 441 | + | 
| 350 | 442 | int emcorefs_release(const char* path, struct fuse_file_info* fi) | 
| 351 | 443 | { | 
| 352 | 444 | int res; | 
| — | — | @@ -470,7 +562,6 @@ | 
| 471 | 563 |  | 
| 472 | 564 | int emcorefs_unlink(const char* path) | 
| 473 | 565 | { | 
| 474 |  | -    
 | 
| 475 | 566 | int res; | 
| 476 | 567 | uint32_t emcore_errno_value; | 
| 477 | 568 |  | 
| — | — | @@ -499,4 +590,95 @@ | 
| 500 | 591 | cache_remove(path); | 
| 501 | 592 |  | 
| 502 | 593 | return 0; | 
| 503 |  | -} | 
| \ No newline at end of file | 
|  | 594 | +} | 
|  | 595 | + | 
|  | 596 | +int emcorefs_rename(const char* path, const char* new_path) | 
|  | 597 | +{ | 
|  | 598 | +    int res; | 
|  | 599 | +    uint32_t emcore_errno_value; | 
|  | 600 | + | 
|  | 601 | +    res = emcore_file_rename(path, new_path); | 
|  | 602 | + | 
|  | 603 | +    if (EMCORE_ERROR_IO == res) | 
|  | 604 | +    { | 
|  | 605 | +        res = emcore_errno(&emcore_errno_value); | 
|  | 606 | + | 
|  | 607 | +        if (EMCORE_SUCCESS != res) | 
|  | 608 | +        { | 
|  | 609 | +            return -EIO; | 
|  | 610 | +        } | 
|  | 611 | + | 
|  | 612 | +        if (EMCORE_SUCCESS != emcore_errno_value) | 
|  | 613 | +        { | 
|  | 614 | +            return -emcore_errno_value; | 
|  | 615 | +        } | 
|  | 616 | +    } | 
|  | 617 | + | 
|  | 618 | +    if (EMCORE_SUCCESS != res) | 
|  | 619 | +    { | 
|  | 620 | +        return -EIO; | 
|  | 621 | +    } | 
|  | 622 | + | 
|  | 623 | +    cache_remove(path); | 
|  | 624 | + | 
|  | 625 | +    return 0; | 
|  | 626 | +} | 
|  | 627 | + | 
|  | 628 | +int emcorefs_truncate(const char* path, off_t size) | 
|  | 629 | +{ | 
|  | 630 | +    int res; | 
|  | 631 | +    struct fuse_file_info fi; | 
|  | 632 | + | 
|  | 633 | +    res = emcorefs_open(path, &fi); | 
|  | 634 | + | 
|  | 635 | +    if (0 != res) { | 
|  | 636 | +        return res; | 
|  | 637 | +    } | 
|  | 638 | + | 
|  | 639 | +    res = emcorefs_ftruncate(path, size, &fi); | 
|  | 640 | + | 
|  | 641 | +    if (0 != res) { | 
|  | 642 | +        return res; | 
|  | 643 | +    } | 
|  | 644 | + | 
|  | 645 | +    return emcorefs_release(path, &fi); | 
|  | 646 | +} | 
|  | 647 | + | 
|  | 648 | +int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi) | 
|  | 649 | +{ | 
|  | 650 | +    int res; | 
|  | 651 | +    uint32_t emcore_errno_value; | 
|  | 652 | +    (void)path; | 
|  | 653 | + | 
|  | 654 | +    if (!fi->fh) | 
|  | 655 | +    { | 
|  | 656 | +        return -EIO; | 
|  | 657 | +    } | 
|  | 658 | + | 
|  | 659 | +    res = emcore_file_truncate(fi->fh, size); | 
|  | 660 | + | 
|  | 661 | +    if (EMCORE_ERROR_IO == res) | 
|  | 662 | +    { | 
|  | 663 | +        res = emcore_errno(&emcore_errno_value); | 
|  | 664 | + | 
|  | 665 | +        if (EMCORE_SUCCESS != res) | 
|  | 666 | +        { | 
|  | 667 | +            return -EIO; | 
|  | 668 | +        } | 
|  | 669 | + | 
|  | 670 | +        if (EMCORE_SUCCESS != emcore_errno_value) | 
|  | 671 | +        { | 
|  | 672 | +            return -emcore_errno_value; | 
|  | 673 | +        } | 
|  | 674 | +    } | 
|  | 675 | + | 
|  | 676 | +    if (EMCORE_SUCCESS != res) | 
|  | 677 | +    { | 
|  | 678 | +        return -EIO; | 
|  | 679 | +    } | 
|  | 680 | + | 
|  | 681 | +    cache_remove(path); | 
|  | 682 | + | 
|  | 683 | +    return 0; | 
|  | 684 | +} | 
|  | 685 | + | 
| Index: emcore/trunk/tools/emcorefs/cache.c | 
| — | — | @@ -83,7 +83,12 @@ | 
| 84 | 84 | struct emcore_dir_entry* cache_entry; | 
| 85 | 85 | char* new_name; | 
| 86 | 86 | size_t new_name_len = 1; | 
| 87 |  | - | 
|  | 87 | + | 
|  | 88 | +    if (0 == strcmp(entry->name, ".") || 0 == strcmp(entry->name, "..")) | 
|  | 89 | +    { | 
|  | 90 | +        return; | 
|  | 91 | +    } | 
|  | 92 | + | 
| 88 | 93 | new_name_len += strlen(dir_name) + strlen(entry->name); | 
| 89 | 94 |  | 
| 90 | 95 | if (strcmp(dir_name, "/") != 0) | 
| — | — | @@ -204,7 +209,7 @@ | 
| 205 | 210 |  | 
| 206 | 211 | for (i = 0; i < emcore_dir_cache_length; ++i) | 
| 207 | 212 | { | 
| 208 |  | -        fprintf(stderr, "cache_dump: [%s] 0x%08x %d %d %lu\n", emcore_dir_entry_cache[i].name, emcore_dir_entry_cache[i].attributes, emcore_dir_entry_cache[i].size, emcore_dir_entry_cache[i].startcluster, fat_time_to_unix_ts(emcore_dir_entry_cache[i].wrtdate, emcore_dir_entry_cache[i].wrttime)); | 
|  | 213 | +        fprintf(stderr, "cache_dump: [%s] / attr: 0x%08x / size: %d / startcluster: %d / ts: %lu\n", emcore_dir_entry_cache[i].name, emcore_dir_entry_cache[i].attributes, emcore_dir_entry_cache[i].size, emcore_dir_entry_cache[i].startcluster, fat_time_to_unix_ts(emcore_dir_entry_cache[i].wrttime, emcore_dir_entry_cache[i].wrtdate)); | 
| 209 | 214 | } | 
| 210 | 215 | } | 
| 211 | 216 | #endif | 
| Index: emcore/trunk/tools/emcorefs/emcorefs.c | 
| — | — | @@ -34,17 +34,26 @@ | 
| 35 | 35 | struct fuse_operations emcorefs_oper = | 
| 36 | 36 | { | 
| 37 | 37 | .getattr    = emcorefs_getattr, | 
|  | 38 | + | 
| 38 | 39 | .opendir    = emcorefs_opendir, | 
| 39 | 40 | .readdir    = emcorefs_readdir, | 
| 40 | 41 | .releasedir = emcorefs_releasedir, | 
|  | 42 | + | 
| 41 | 43 | .open       = emcorefs_open, | 
| 42 | 44 | .read       = emcorefs_read, | 
|  | 45 | +    .write      = emcorefs_write, | 
| 43 | 46 | .release    = emcorefs_release, | 
|  | 47 | + | 
| 44 | 48 | .mkdir      = emcorefs_mkdir, | 
| 45 | 49 | .rmdir      = emcorefs_rmdir, | 
|  | 50 | + | 
| 46 | 51 | .create     = emcorefs_create, | 
| 47 | 52 | .mknod      = emcorefs_mknod, | 
| 48 | 53 | .unlink     = emcorefs_unlink, | 
|  | 54 | +    .rename     = emcorefs_rename, | 
|  | 55 | +    .truncate   = emcorefs_truncate, | 
|  | 56 | + | 
|  | 57 | +    .ftruncate  = emcorefs_ftruncate, | 
| 49 | 58 | }; | 
| 50 | 59 |  | 
| 51 | 60 | int main(int argc, char* argv[]) | 
| Index: emcore/trunk/tools/emcorefs/fuse.h | 
| — | — | @@ -33,6 +33,7 @@ | 
| 34 | 34 | int emcorefs_releasedir(const char* path, struct fuse_file_info* fi); | 
| 35 | 35 | int emcorefs_open(const char* path, struct fuse_file_info* fi); | 
| 36 | 36 | int emcorefs_read(const char* path, char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi); | 
|  | 37 | +int emcorefs_write(const char* path, const char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi); | 
| 37 | 38 | int emcorefs_release(const char* path, struct fuse_file_info* fi); | 
| 38 | 39 | int emcorefs_mkdir(const char* path, mode_t mode); | 
| 39 | 40 | int emcorefs_rmdir(const char* path); | 
| — | — | @@ -39,5 +40,8 @@ | 
| 40 | 41 | int emcorefs_create(const char* path, mode_t mode, struct fuse_file_info* fi); | 
| 41 | 42 | int emcorefs_mknod(const char* path, mode_t mode, dev_t dev); | 
| 42 | 43 | int emcorefs_unlink(const char* path); | 
|  | 44 | +int emcorefs_rename(const char* path, const char* new_path); | 
|  | 45 | +int emcorefs_truncate(const char* path, off_t size); | 
|  | 46 | +int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi); | 
| 43 | 47 |  | 
| 44 | 48 | #endif /* __FUSE_H__ */ | 
| Index: emcore/trunk/tools/emcorefs/emcore.c | 
| — | — | @@ -491,7 +491,7 @@ | 
| 492 | 492 | return EMCORE_SUCCESS; | 
| 493 | 493 | } | 
| 494 | 494 |  | 
| 495 |  | -int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size)
 | 
|  | 495 | +int emcore_file_write(uint32_t* nwrite, const uint32_t handle, const uint32_t addr, const uint32_t size) | 
| 496 | 496 | { | 
| 497 | 497 | int res; | 
| 498 | 498 | uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4]; | 
| — | — | @@ -512,6 +512,8 @@ | 
| 513 | 513 | return EMCORE_ERROR_IO; | 
| 514 | 514 | } | 
| 515 | 515 |  | 
|  | 516 | +    *nwrite = in[1]; | 
|  | 517 | + | 
| 516 | 518 | return EMCORE_SUCCESS; | 
| 517 | 519 | } | 
| 518 | 520 |  | 
| Index: emcore/trunk/tools/emcorefs/Makefile | 
| — | — | @@ -1,4 +1,4 @@ | 
| 2 |  | -CFLAGS := -O2 -Wall -Wextra -Werror $(shell pkg-config --cflags --libs libusb-1.0 fuse) | 
|  | 2 | +CFLAGS += -O2 -Wall -Wextra -Werror $(shell pkg-config --cflags --libs libusb-1.0 fuse) | 
| 3 | 3 | SOURCES = util.c usb.c emcore.c cache.c fuse.c emcorefs.c | 
| 4 | 4 | TARGET = build/emcorefs | 
| 5 | 5 |  | 
| Index: emcore/trunk/tools/emcorefs/README | 
| — | — | @@ -41,7 +41,7 @@ | 
| 42 | 42 |  | 
| 43 | 43 | Known bugs/issues | 
| 44 | 44 | ----------------- | 
| 45 |  | -* Read-only support at the moment.
 | 
|  | 45 | +* Write support not tested very well. | 
| 46 | 46 | * Running FUSE with multithreading breaks file reading because of | 
| 47 | 47 | the way these are implemented on emCORE's side. | 
| 48 | 48 | Workaround: use the "-s" option. | 
| — | — | @@ -51,7 +51,6 @@ | 
| 52 | 52 |  | 
| 53 | 53 | Future plans | 
| 54 | 54 | ------------ | 
| 55 |  | -* Implement write support.
 | 
| 56 | 55 | * Merge some functions that are doing similar tasks to reduce code | 
| 57 | 56 | duplication. Return proper error codes in FS operations. | 
| 58 | 57 |  |