freemyipod r770 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r769‎ | r770 | r771 >
Date:17:35, 3 September 2011
Author:user890104
Status:new
Tags:
Comment:
New tool: emCOREFS - a FUSE wrapper for emCORE's FS API. More info in README.
Modified paths:
  • /emcore/trunk/tools/emcorefs (added) (history)
  • /emcore/trunk/tools/emcorefs/Makefile (added) (history)
  • /emcore/trunk/tools/emcorefs/cache.c (added) (history)
  • /emcore/trunk/tools/emcorefs/cache.h (added) (history)
  • /emcore/trunk/tools/emcorefs/emcore.c (added) (history)
  • /emcore/trunk/tools/emcorefs/emcore.h (added) (history)
  • /emcore/trunk/tools/emcorefs/emcorefs.c (added) (history)
  • /emcore/trunk/tools/emcorefs/emcorefs.h (added) (history)
  • /emcore/trunk/tools/emcorefs/fuse.c (added) (history)
  • /emcore/trunk/tools/emcorefs/fuse.h (added) (history)
  • /emcore/trunk/tools/emcorefs/global.h (added) (history)
  • /emcore/trunk/tools/emcorefs/usb.c (added) (history)
  • /emcore/trunk/tools/emcorefs/usb.h (added) (history)
  • /emcore/trunk/tools/emcorefs/util.c (added) (history)
  • /emcore/trunk/tools/emcorefs/util.h (added) (history)

Diff [purge]

Index: emcore/trunk/tools/emcorefs/usb.h
@@ -0,0 +1,38 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __USB_H__
 26+#define __USB_H__
 27+
 28+#include "global.h"
 29+
 30+
 31+int usb_init(void);
 32+int usb_find(const uint16_t vendor_id, const uint16_t product_id, uint8_t* reattach);
 33+int usb_open(libusb_device* dev, uint8_t* reattach);
 34+int usb_bulk_transfer(const unsigned char endpoint, void* data, const int length);
 35+int usb_close(const uint8_t reattach);
 36+void usb_exit(void);
 37+int usb_destroy(const uint8_t reattach);
 38+
 39+#endif /* __USB_H__ */
Index: emcore/trunk/tools/emcorefs/emcore.h
@@ -0,0 +1,135 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __EMCORE_H__
 26+#define __EMCORE_H__
 27+
 28+#include "global.h"
 29+
 30+#define EMCORE_USB_VID 0xFFFF
 31+#define EMCORE_USB_PID 0xE000
 32+
 33+#define EMCORE_HEADER_SIZE 0x10
 34+
 35+
 36+struct emcore_usb_endpoints_addr
 37+{
 38+ uint8_t cout;
 39+ uint8_t cin;
 40+ uint8_t dout;
 41+ uint8_t din;
 42+};
 43+
 44+struct emcore_usb_endpoints_max_packet_size
 45+{
 46+ uint16_t cout;
 47+ uint16_t cin;
 48+ uint32_t dout;
 49+ uint32_t din;
 50+};
 51+
 52+struct emcore_dev_info
 53+{
 54+ uint32_t svn_revision;
 55+ uint8_t major, minor, patch, sw_type;
 56+ uint32_t hw_type;
 57+};
 58+
 59+struct emcore_user_mem_range
 60+{
 61+ uint32_t lower;
 62+ uint32_t upper;
 63+};
 64+
 65+struct emcore_dir_entry
 66+{
 67+ char* name;
 68+ uint32_t attributes;
 69+ uint32_t size;
 70+ uint32_t startcluster;
 71+ uint16_t wrtdate;
 72+ uint16_t wrttime;
 73+};
 74+
 75+enum emcore_error
 76+{
 77+ EMCORE_SUCCESS,
 78+ EMCORE_ERROR_INVALID,
 79+ EMCORE_ERROR_NOT_SUPPORTED,
 80+ EMCORE_ERROR_BUSY,
 81+ EMCORE_ERROR_NO_DEVICE,
 82+ EMCORE_ERROR_INCOMPLETE,
 83+ EMCORE_ERROR_OVERFLOW,
 84+ EMCORE_ERROR_NOT_IMPLEMENTED,
 85+ EMCORE_ERROR_NO_MORE_ENTRIES,
 86+ EMCORE_ERROR_IO,
 87+};
 88+
 89+int emcore_cout(const void* data, const uint32_t length);
 90+int emcore_cin(void* data, const uint32_t length);
 91+int emcore_dout(const void* data, const uint32_t length);
 92+int emcore_din(void* data, const uint32_t length);
 93+
 94+int emcore_monitor_command(const void* out, void* in, const uint32_t send_length, const uint32_t receive_length);
 95+
 96+int emcore_get_version(struct emcore_dev_info* dev_info);
 97+int emcore_get_packet_info(struct emcore_usb_endpoints_max_packet_size* max_packet_size);
 98+int emcore_get_user_mem_range(struct emcore_user_mem_range* mem_range);
 99+int emcore_reset(const uint8_t graceful);
 100+int emcore_poweroff(const uint8_t graceful);
 101+int emcore_readmem(void* data, const uint32_t addr, const uint32_t size);
 102+int emcore_writemem(const void* data, const uint32_t addr, const uint32_t size);
 103+int emcore_readdma(void* data, const uint32_t addr, const uint32_t size);
 104+int emcore_writedma(const void* data, const uint32_t addr, const uint32_t size);
 105+int emcore_readi2c(void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size);
 106+int emcore_writei2c(const void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size);
 107+int emcore_file_open(uint32_t* handle, const char* pathname, const int flags);
 108+int emcore_file_size(uint32_t* size, const uint32_t handle);
 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);
 111+int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence);
 112+int emcore_file_truncate(const uint32_t handle, const uint32_t length);
 113+int emcore_file_sync(const uint32_t handle);
 114+int emcore_file_close(const uint32_t handle);
 115+int emcore_file_close_all(uint32_t* count);
 116+int emcore_file_kill_all(const uint32_t volume);
 117+int emcore_file_unlink(const char* name);
 118+int emcore_file_rename(const char* path, const char* newpath);
 119+int emcore_dir_open(uint32_t* handle, const char* name);
 120+int emcore_dir_read(struct emcore_dir_entry* entry, const uint32_t handle);
 121+int emcore_dir_close(const uint32_t handle);
 122+int emcore_dir_close_all(uint32_t* count);
 123+int emcore_errno(uint32_t* emcore_errno_value);
 124+int emcore_malloc(uint32_t* ptr, const uint32_t size);
 125+int emcore_memalign(uint32_t* ptr, const uint32_t align, const uint32_t size);
 126+int emcore_realloc(uint32_t* new_ptr, const uint32_t ptr, const uint32_t size);
 127+int emcore_reownalloc(const uint32_t ptr, const uint32_t owner);
 128+int emcore_free(const uint32_t ptr);
 129+int emcore_free_all(void);
 130+
 131+int emcore_read(void* data, const uint32_t addr, const uint32_t size);
 132+int emcore_write(const void* data, const uint32_t addr, const uint32_t size);
 133+int emcore_ls(const uint32_t handle);
 134+int emcore_test(void);
 135+
 136+#endif /* __EMCORE_H__ */
Index: emcore/trunk/tools/emcorefs/fuse.c
@@ -0,0 +1,356 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "fuse.h"
 28+#include "util.h"
 29+#include "cache.h"
 30+#include "emcore.h"
 31+
 32+
 33+int emcorefs_getattr(const char* path, struct stat* stbuf)
 34+{
 35+ int res = 0;
 36+ struct emcore_dir_entry *entry = NULL, curr_entry;
 37+ uint32_t dir_handle;
 38+ char *parent, *filename;
 39+
 40+ memset(stbuf, 0, sizeof(*stbuf));
 41+
 42+ entry = cache_get(path);
 43+
 44+ if (NULL == entry)
 45+ {
 46+ parent = strdup(path);
 47+ dirname(parent);
 48+ filename = basename((char*)path);
 49+
 50+ res = emcore_dir_open(&dir_handle, parent);
 51+
 52+ if (EMCORE_SUCCESS == res)
 53+ {
 54+ while (1)
 55+ {
 56+ res = emcore_dir_read(&curr_entry, dir_handle);
 57+
 58+ if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
 59+ {
 60+ break;
 61+ }
 62+
 63+ if (EMCORE_SUCCESS != res)
 64+ {
 65+ break;
 66+ }
 67+
 68+ cache_insert(parent, &curr_entry);
 69+
 70+ if (0 == strcmp(filename, curr_entry.name))
 71+ {
 72+ entry = malloc(sizeof(*entry));
 73+
 74+ memcpy(entry, &curr_entry, sizeof(curr_entry));
 75+
 76+ break;
 77+ }
 78+ };
 79+
 80+ emcore_dir_close(dir_handle);
 81+ }
 82+
 83+ free(parent);
 84+ }
 85+
 86+ if (NULL == entry) {
 87+ if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
 88+ {
 89+ return -ENOENT;
 90+ }
 91+
 92+ return -EIO;
 93+ }
 94+ else
 95+ {
 96+ stbuf->st_uid = getuid();
 97+ stbuf->st_gid = getgid();
 98+ stbuf->st_mtime = fat_time_to_unix_ts(entry->wrttime, entry->wrtdate);
 99+
 100+ if (entry->attributes & 0x10)
 101+ {
 102+ stbuf->st_mode = S_IFDIR | 0755;
 103+ stbuf->st_nlink = 2;
 104+ stbuf->st_size = 0x1000;
 105+ }
 106+ else
 107+ {
 108+ stbuf->st_mode = S_IFREG | 0644;
 109+ stbuf->st_nlink = 1;
 110+ stbuf->st_size = entry->size;
 111+ }
 112+ }
 113+
 114+ return 0;
 115+}
 116+
 117+int emcorefs_opendir(const char* path, struct fuse_file_info* fi)
 118+{
 119+ int res;
 120+ uint32_t handle;
 121+
 122+ res = emcore_dir_open(&handle, path);
 123+
 124+ if (EMCORE_SUCCESS != res)
 125+ {
 126+ return -EIO;
 127+ }
 128+
 129+ fi->fh = handle;
 130+
 131+ return 0;
 132+}
 133+
 134+int emcorefs_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi)
 135+{
 136+ int res;
 137+ struct emcore_dir_entry entry;
 138+ (void) offset;
 139+ (void) fi;
 140+
 141+ if (strcmp(path, "/") == 0)
 142+ {
 143+ filler(buf, ".", NULL, 0);
 144+ filler(buf, "..", NULL, 0);
 145+ }
 146+
 147+ while (1)
 148+ {
 149+ res = emcore_dir_read(&entry, fi->fh);
 150+
 151+ if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
 152+ {
 153+ break;
 154+ }
 155+
 156+ if (EMCORE_SUCCESS != res)
 157+ {
 158+ return -EIO;
 159+ }
 160+
 161+ cache_insert(path, &entry);
 162+
 163+ filler(buf, entry.name, NULL, 0);
 164+ }
 165+
 166+ return 0;
 167+}
 168+
 169+int emcorefs_releasedir(const char* path, struct fuse_file_info* fi)
 170+{
 171+ int res;
 172+ uint32_t emcore_errno_value;
 173+ (void)path;
 174+
 175+ res = emcore_dir_close(fi->fh);
 176+
 177+ if (EMCORE_ERROR_IO == res)
 178+ {
 179+ res = emcore_errno(&emcore_errno_value);
 180+
 181+ if (EMCORE_SUCCESS != res)
 182+ {
 183+ return -EIO;
 184+ }
 185+
 186+ if (EMCORE_SUCCESS != emcore_errno_value)
 187+ {
 188+ return -emcore_errno_value;
 189+ }
 190+ }
 191+
 192+ if (EMCORE_SUCCESS != res)
 193+ {
 194+ return -EIO;
 195+ }
 196+
 197+ return 0;
 198+}
 199+
 200+int emcorefs_open(const char* path, struct fuse_file_info* fi)
 201+{
 202+ int res;
 203+ uint32_t handle, emcore_errno_value;
 204+
 205+ res = emcore_file_open(&handle, path, fi->flags);
 206+
 207+ if (EMCORE_ERROR_IO == res)
 208+ {
 209+ res = emcore_errno(&emcore_errno_value);
 210+
 211+ if (EMCORE_SUCCESS != res)
 212+ {
 213+ return -EIO;
 214+ }
 215+
 216+ if (EMCORE_SUCCESS != emcore_errno_value)
 217+ {
 218+ return -emcore_errno_value;
 219+ }
 220+ }
 221+
 222+ if (EMCORE_SUCCESS != res)
 223+ {
 224+ return -EIO;
 225+ }
 226+
 227+ fi->fh = handle;
 228+
 229+ return 0;
 230+}
 231+
 232+int emcorefs_read(const char* path, char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi) {
 233+ fprintf(stderr, "FUSE_READ: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
 234+
 235+ int res;
 236+ uint32_t emcore_errno_value, addr, nread = size;
 237+
 238+ if (!fi->fh)
 239+ {
 240+ return -EIO;
 241+ }
 242+
 243+ res = emcore_malloc(&addr, size);
 244+
 245+ if (EMCORE_SUCCESS != res)
 246+ {
 247+ return -EIO;
 248+ }
 249+
 250+ do {
 251+ if (offset) {
 252+ res = emcore_file_seek(fi->fh, offset, SEEK_SET);
 253+
 254+ if (EMCORE_ERROR_IO == res)
 255+ {
 256+ res = emcore_errno(&emcore_errno_value);
 257+
 258+ if (EMCORE_SUCCESS != res)
 259+ {
 260+ nread = -EIO;
 261+ break;
 262+ }
 263+
 264+ if (EMCORE_SUCCESS != emcore_errno_value)
 265+ {
 266+ nread = -emcore_errno_value;
 267+ break;
 268+ }
 269+ }
 270+
 271+ if (EMCORE_SUCCESS != res)
 272+ {
 273+ nread = -EIO;
 274+ break;
 275+ }
 276+ }
 277+
 278+ res = emcore_file_read(&nread, fi->fh, addr, size);
 279+
 280+ if (EMCORE_ERROR_IO == res)
 281+ {
 282+ res = emcore_errno(&emcore_errno_value);
 283+
 284+ if (EMCORE_SUCCESS != res)
 285+ {
 286+ nread = -EIO;
 287+ break;
 288+ }
 289+
 290+ if (EMCORE_SUCCESS != emcore_errno_value)
 291+ {
 292+ nread = -emcore_errno_value;
 293+ break;
 294+ }
 295+ }
 296+
 297+ if (EMCORE_SUCCESS != res)
 298+ {
 299+ nread = -EIO;
 300+ break;
 301+ }
 302+
 303+ res = emcore_read(buf, addr, nread);
 304+
 305+ if (EMCORE_SUCCESS != res)
 306+ {
 307+ nread = -EIO;
 308+ }
 309+
 310+ }
 311+ while(0);
 312+
 313+ res = emcore_free(addr);
 314+
 315+ if (EMCORE_SUCCESS != res)
 316+ {
 317+ return -EIO;
 318+ }
 319+
 320+ return nread;
 321+}
 322+
 323+int emcorefs_release(const char* path, struct fuse_file_info* fi)
 324+{
 325+ int res;
 326+ uint32_t emcore_errno_value;
 327+ (void)path;
 328+
 329+ if (!fi->fh)
 330+ {
 331+ return -EIO;
 332+ }
 333+
 334+ res = emcore_file_close(fi->fh);
 335+
 336+ if (EMCORE_ERROR_IO == res)
 337+ {
 338+ res = emcore_errno(&emcore_errno_value);
 339+
 340+ if (EMCORE_SUCCESS != res)
 341+ {
 342+ return -EIO;
 343+ }
 344+
 345+ if (EMCORE_SUCCESS != emcore_errno_value)
 346+ {
 347+ return -emcore_errno_value;
 348+ }
 349+ }
 350+
 351+ if (EMCORE_SUCCESS != res)
 352+ {
 353+ return -EIO;
 354+ }
 355+
 356+ return 0;
 357+}
Index: emcore/trunk/tools/emcorefs/util.h
@@ -0,0 +1,45 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __MISC_H__
 26+#define __MISC_H__
 27+
 28+#include "global.h"
 29+
 30+#define MIN(a,b) ((a)>(b)?(b):(a))
 31+
 32+
 33+struct alignsizes
 34+{
 35+ uint32_t head;
 36+ uint32_t body;
 37+ uint32_t tail;
 38+};
 39+
 40+void dump_packet(const void* data, const uint32_t length);
 41+void alignsplit(struct alignsizes* sizeptr, const uint32_t addr, const uint32_t size, const uint32_t blksize, const uint32_t align);
 42+time_t fat_time_to_unix_ts(const short wrttime, const short wrtdate);
 43+int32_t unix_ts_to_fat_time(const time_t datetime);
 44+void print_error(const int code);
 45+
 46+#endif /* __MISC_H__ */
Index: emcore/trunk/tools/emcorefs/cache.c
@@ -0,0 +1,155 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "cache.h"
 28+#include "emcore.h"
 29+#include "util.h"
 30+
 31+
 32+struct emcore_dir_entry* emcore_dir_entry_cache = NULL;
 33+size_t emcore_dir_cache_length = 0;
 34+
 35+void cache_init(void)
 36+{
 37+ int32_t datetime = unix_ts_to_fat_time(time(NULL));
 38+#ifdef DEBUG
 39+ fprintf(stderr, "Init cache...\n");
 40+#endif
 41+ emcore_dir_entry_cache = calloc(sizeof(*emcore_dir_entry_cache), 1);
 42+
 43+ emcore_dir_entry_cache->name = strdup("/");
 44+ emcore_dir_entry_cache->attributes = 0x10;
 45+ emcore_dir_entry_cache->size = 0x1000;
 46+ emcore_dir_entry_cache->wrtdate = datetime >> 0x10;
 47+ emcore_dir_entry_cache->wrttime = datetime & 0xffff;
 48+
 49+ emcore_dir_cache_length = 1;
 50+#ifdef DEBUG
 51+ fprintf(stderr, "Cache init done!\n");
 52+#endif
 53+}
 54+
 55+struct emcore_dir_entry* cache_get(const char* name)
 56+{
 57+ size_t i;
 58+
 59+ if (!emcore_dir_cache_length)
 60+ {
 61+ return NULL;
 62+ }
 63+
 64+ for (i = 0; i < emcore_dir_cache_length; ++i)
 65+ {
 66+#ifdef DEBUG2
 67+ fprintf(stderr, "strcmp([%s], [%s]) == %d\n", name, emcore_dir_entry_cache[i].name, strcmp(name, emcore_dir_entry_cache[i].name));
 68+#endif
 69+ if (0 == strcmp(name, emcore_dir_entry_cache[i].name))
 70+ {
 71+ return &emcore_dir_entry_cache[i];
 72+ }
 73+ }
 74+
 75+ return NULL;
 76+}
 77+
 78+void cache_insert(const char* dir_name, const struct emcore_dir_entry* entry)
 79+{
 80+#ifdef DEBUG2
 81+ fprintf(stderr, "CACHE INSERT: dir=[%s], entry=[%s]\n", dir_name, entry->name);
 82+#endif
 83+ void* new_ptr;
 84+ struct emcore_dir_entry* cache_entry;
 85+ char* new_name;
 86+ size_t new_name_len = 1;
 87+
 88+ new_name_len += strlen(dir_name) + strlen(entry->name);
 89+
 90+ if (strcmp(dir_name, "/") != 0)
 91+ {
 92+ ++new_name_len;
 93+ }
 94+
 95+ new_name = calloc(sizeof(char), new_name_len);
 96+ strcat(new_name, dir_name);
 97+
 98+ if (strcmp(dir_name, "/") != 0)
 99+ {
 100+ strcat(new_name, "/");
 101+ }
 102+
 103+ strcat(new_name, entry->name);
 104+
 105+ if (cache_get(new_name))
 106+ {
 107+ free(new_name);
 108+ return;
 109+ }
 110+
 111+ new_ptr = realloc(emcore_dir_entry_cache,
 112+ sizeof(*emcore_dir_entry_cache) * (emcore_dir_cache_length + 1));
 113+
 114+ if (!new_ptr)
 115+ {
 116+ free(new_name);
 117+ return;
 118+ }
 119+
 120+ emcore_dir_entry_cache = new_ptr;
 121+
 122+ cache_entry = malloc(sizeof(*cache_entry));
 123+
 124+ if (!cache_entry)
 125+ {
 126+ free(new_name);
 127+ return;
 128+ }
 129+
 130+ memcpy(cache_entry, entry, sizeof(*entry));
 131+
 132+ cache_entry->name = new_name;
 133+
 134+ memcpy(emcore_dir_entry_cache + emcore_dir_cache_length, cache_entry, sizeof(*cache_entry));
 135+
 136+#ifdef DEBUG
 137+ fprintf(stderr, "Inserting [%s] to cache\n", emcore_dir_entry_cache[emcore_dir_cache_length].name);
 138+#endif
 139+ ++emcore_dir_cache_length;
 140+}
 141+
 142+void cache_destroy(void)
 143+{
 144+#ifdef DEBUG
 145+ fprintf(stderr, "Destroying cache...\n");
 146+#endif
 147+ while (emcore_dir_cache_length)
 148+ {
 149+ free(emcore_dir_entry_cache[--emcore_dir_cache_length].name);
 150+ }
 151+
 152+ free(emcore_dir_entry_cache);
 153+#ifdef DEBUG
 154+ fprintf(stderr, "Cache destroyed!\n");
 155+#endif
 156+}
Index: emcore/trunk/tools/emcorefs/emcorefs.c
@@ -0,0 +1,114 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "usb.h"
 28+#include "cache.h"
 29+#include "emcore.h"
 30+#include "fuse.h"
 31+#include "util.h"
 32+#include "emcorefs.h"
 33+
 34+
 35+struct fuse_operations emcorefs_oper =
 36+{
 37+ .getattr = emcorefs_getattr,
 38+ .opendir = emcorefs_opendir,
 39+ .readdir = emcorefs_readdir,
 40+ .releasedir = emcorefs_releasedir,
 41+ .open = emcorefs_open,
 42+ .read = emcorefs_read,
 43+ .release = emcorefs_release,
 44+};
 45+
 46+int emcorefs_init(void)
 47+{
 48+ int res;
 49+ uint32_t count;
 50+
 51+ res = emcore_file_close_all(&count);
 52+
 53+ if (EMCORE_SUCCESS != res)
 54+ {
 55+ return res;
 56+ }
 57+
 58+ res = emcore_dir_close_all(&count);
 59+
 60+ return res;
 61+}
 62+
 63+int main(int argc, char* argv[])
 64+{
 65+ int res, res2;
 66+ uint8_t reattach = 0;
 67+
 68+ res = usb_init();
 69+
 70+ if (LIBUSB_SUCCESS == res)
 71+ {
 72+ res = usb_find(EMCORE_USB_VID, EMCORE_USB_PID, &reattach);
 73+ }
 74+
 75+ if (LIBUSB_SUCCESS == res)
 76+ {
 77+ res = emcorefs_init();
 78+ }
 79+
 80+ if (EMCORE_SUCCESS == res)
 81+ {
 82+#ifdef TEST_ONLY
 83+ /* gcc complains about unused vars */
 84+ (void)(argc);
 85+ (void)(argv);
 86+
 87+ res = emcore_test();
 88+#else
 89+ cache_init();
 90+
 91+ res = fuse_main(argc, argv, &emcorefs_oper, NULL);
 92+
 93+ cache_destroy();
 94+#endif
 95+ }
 96+
 97+ if (EMCORE_SUCCESS != res)
 98+ {
 99+ print_error(res);
 100+ }
 101+
 102+ res2 = usb_destroy(reattach);
 103+
 104+ if (LIBUSB_SUCCESS != res2)
 105+ {
 106+ print_error(res2);
 107+ }
 108+
 109+ if (res < 0)
 110+ {
 111+ res = -res;
 112+ }
 113+
 114+ return res;
 115+}
Index: emcore/trunk/tools/emcorefs/global.h
@@ -0,0 +1,43 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __GLOBAL_H__
 26+#define __GLOBAL_H__
 27+
 28+#include <stdlib.h>
 29+#include <stdint.h>
 30+#include <errno.h>
 31+#include <fcntl.h>
 32+#include <stdio.h>
 33+#include <unistd.h>
 34+#include <libgen.h>
 35+
 36+#define _GNU_SOURCE
 37+#include <string.h>
 38+
 39+#include <libusb.h>
 40+
 41+#define FUSE_USE_VERSION 28
 42+#include <fuse.h>
 43+
 44+#endif /* __GLOBAL_H__ */
Index: emcore/trunk/tools/emcorefs/fuse.h
@@ -0,0 +1,38 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __FUSE_H__
 26+#define __FUSE_H__
 27+
 28+#include "global.h"
 29+
 30+
 31+int emcorefs_getattr(const char* path, struct stat* stbuf);
 32+int emcorefs_opendir(const char* path, struct fuse_file_info* fi);
 33+int emcorefs_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi);
 34+int emcorefs_releasedir(const char* path, struct fuse_file_info* fi);
 35+int emcorefs_open(const char* path, struct fuse_file_info* fi);
 36+int emcorefs_read(const char* path, char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi);
 37+int emcorefs_release(const char* path, struct fuse_file_info* fi);
 38+
 39+#endif /* __FUSE_H__ */
Index: emcore/trunk/tools/emcorefs/cache.h
@@ -0,0 +1,35 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __CACHE_H__
 26+#define __CACHE_H__
 27+
 28+#include "global.h"
 29+
 30+
 31+void cache_init(void);
 32+struct emcore_dir_entry* cache_get(const char* name);
 33+void cache_insert(const char* dir_name, const struct emcore_dir_entry* entry);
 34+void cache_destroy(void);
 35+
 36+#endif /* __CACHE_H__ */
Index: emcore/trunk/tools/emcorefs/emcorefs.h
@@ -0,0 +1,33 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __EMCOREFS_H__
 26+#define __EMCOREFS_H__
 27+
 28+#include "global.h"
 29+
 30+
 31+int emcorefs_init(void);
 32+int main(int argc, char* argv[]);
 33+
 34+#endif /* __EMCOREFS_H__ */
Index: emcore/trunk/tools/emcorefs/usb.c
@@ -0,0 +1,382 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "emcore.h"
 28+#include "util.h"
 29+#include "usb.h"
 30+
 31+
 32+libusb_context* usb_ctx = NULL;
 33+libusb_device_handle* usb_handle = NULL;
 34+
 35+extern struct emcore_usb_endpoints_addr emcore_usb_eps_addr;
 36+extern struct emcore_usb_endpoints_max_packet_size emcore_usb_eps_mps;
 37+
 38+int usb_init(void)
 39+{
 40+ int res;
 41+
 42+#ifdef DEBUG
 43+ fprintf(stderr, "Initialising USB library...\n");
 44+#endif
 45+
 46+ res = libusb_init(&usb_ctx);
 47+
 48+ if (LIBUSB_SUCCESS != res)
 49+ {
 50+ return res;
 51+ }
 52+
 53+#ifdef DEBUG
 54+ fprintf(stderr, "USB library initialized!\n");
 55+ libusb_set_debug(usb_ctx, 3);
 56+
 57+#endif
 58+
 59+ return LIBUSB_SUCCESS;
 60+}
 61+
 62+int usb_find(const uint16_t vendor_id, const uint16_t product_id, uint8_t* reattach)
 63+{
 64+ libusb_device **devs, *dev;
 65+ ssize_t devs_cnt;
 66+ int res, i;
 67+ struct libusb_device_descriptor dev_desc;
 68+ uint8_t found = 0;
 69+ struct libusb_config_descriptor* cfg_desc;
 70+ const struct libusb_interface* iface;
 71+ const struct libusb_interface_descriptor* iface_desc;
 72+ const struct libusb_endpoint_descriptor* ep_desc;
 73+
 74+#ifdef DEBUG
 75+ fprintf(stderr, "Getting USB device list...\n");
 76+#endif
 77+
 78+ devs_cnt = libusb_get_device_list(usb_ctx, &devs);
 79+
 80+ if (devs_cnt < 0)
 81+ {
 82+ return devs_cnt;
 83+ }
 84+
 85+#ifdef DEBUG
 86+ fprintf(stderr, "Found %d USB devices!\n", devs_cnt);
 87+#endif
 88+ for (i = 0; i < devs_cnt; ++i)
 89+ {
 90+ dev = devs[i];
 91+#ifdef DEBUG
 92+ fprintf(stderr, "Getting device descriptor of USB device %d...\n", i);
 93+#endif
 94+ res = libusb_get_device_descriptor(dev, &dev_desc);
 95+
 96+ if (LIBUSB_SUCCESS != res)
 97+ {
 98+#ifdef DEBUG
 99+ fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
 100+#endif
 101+ continue;
 102+ }
 103+
 104+#ifdef DEBUG
 105+ fprintf(stderr, "[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
 106+ dev_desc.idProduct, libusb_get_bus_number(dev),
 107+ libusb_get_device_address(dev), dev_desc.bcdUSB);
 108+#endif
 109+ if (vendor_id == dev_desc.idVendor && product_id == dev_desc.idProduct)
 110+ {
 111+#ifdef DEBUG
 112+ fprintf(stderr, "Found emCORE USB device!\n");
 113+#endif
 114+ if (1 != dev_desc.bNumConfigurations)
 115+ {
 116+#ifdef DEBUG
 117+ fprintf(stderr, "Number of configs is different than 1, not the right device...\n");
 118+#endif
 119+ continue;
 120+ }
 121+
 122+#ifdef DEBUG
 123+ fprintf(stderr, "Getting config descriptor 0 of device...\n");
 124+#endif
 125+
 126+ res = libusb_get_config_descriptor(dev, 0, &cfg_desc);
 127+
 128+ if (LIBUSB_SUCCESS != res)
 129+ {
 130+ return res;
 131+ }
 132+
 133+ if (1 != cfg_desc->bNumInterfaces)
 134+ {
 135+#ifdef DEBUG
 136+ fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n");
 137+#endif
 138+
 139+ continue;
 140+ }
 141+
 142+ iface = &cfg_desc->interface[0];
 143+
 144+ if (1 != iface->num_altsetting)
 145+ {
 146+#ifdef DEBUG
 147+ fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n");
 148+#endif
 149+
 150+ continue;
 151+ }
 152+
 153+ iface_desc = &iface->altsetting[0];
 154+
 155+ if (4 != iface_desc->bNumEndpoints)
 156+ {
 157+#ifdef DEBUG
 158+ fprintf(stderr, "Wrong USB device, it should have exactly 4 endpoints\n");
 159+#endif
 160+
 161+ continue;
 162+ }
 163+
 164+#ifdef DEBUG
 165+ fprintf(stderr, "Endpoints:");
 166+#endif
 167+
 168+ for (i = 0; i < 4; ++i)
 169+ {
 170+ ep_desc = &iface_desc->endpoint[i];
 171+
 172+#ifdef DEBUG
 173+ fprintf(stderr, " %d at 0x%02x", i, ep_desc->bEndpointAddress);
 174+#endif
 175+
 176+ switch (i) {
 177+ case 0:
 178+ emcore_usb_eps_addr.cout = ep_desc->bEndpointAddress;
 179+ break;
 180+ case 1:
 181+ emcore_usb_eps_addr.cin = ep_desc->bEndpointAddress;
 182+ break;
 183+ case 2:
 184+ emcore_usb_eps_addr.dout = ep_desc->bEndpointAddress;
 185+ break;
 186+ case 3:
 187+ emcore_usb_eps_addr.din = ep_desc->bEndpointAddress;
 188+ break;
 189+ }
 190+ }
 191+
 192+#ifdef DEBUG
 193+ fprintf(stderr, "\n");
 194+#endif
 195+
 196+ found = 1;
 197+ }
 198+ }
 199+
 200+ if (found)
 201+ {
 202+ res = usb_open(dev, reattach);
 203+ }
 204+ else
 205+ {
 206+ fprintf(stderr, "USB device with VID=%4x and PID=%4x not found!\n",
 207+ vendor_id, product_id);
 208+
 209+ res = EMCORE_ERROR_NO_DEVICE;
 210+ }
 211+
 212+#ifdef DEBUG
 213+ fprintf(stderr, "Freeing device list...\n");
 214+#endif
 215+ libusb_free_device_list(devs, 1);
 216+
 217+ return res;
 218+}
 219+
 220+int usb_open(libusb_device* dev, uint8_t* reattach)
 221+{
 222+ int res;
 223+
 224+#ifdef DEBUG
 225+ fprintf(stderr, "Opening USB device...\n");
 226+#endif
 227+ res = libusb_open(dev, &usb_handle);
 228+
 229+ if (LIBUSB_SUCCESS != res)
 230+ {
 231+ return res;
 232+ }
 233+#ifdef DEBUG
 234+ fprintf(stderr, "USB device opened!\n");
 235+ fprintf(stderr, "Setting USB configuration 1...\n");
 236+#endif
 237+
 238+ res = libusb_set_configuration(usb_handle, 1);
 239+
 240+ if (LIBUSB_SUCCESS != res)
 241+ {
 242+ return res;
 243+ }
 244+#ifdef DEBUG
 245+ fprintf(stderr, "USB configuration set!\n");
 246+#endif
 247+ res = libusb_kernel_driver_active(usb_handle, 0);
 248+
 249+ if (1 == res)
 250+ {
 251+ *reattach = 1;
 252+
 253+ res = libusb_detach_kernel_driver(usb_handle, 0);
 254+ }
 255+
 256+ if (LIBUSB_SUCCESS != res)
 257+ {
 258+ return res;
 259+ }
 260+
 261+#ifdef DEBUG
 262+ fprintf(stderr, "Claiming interface 0...\n");
 263+#endif
 264+ res = libusb_claim_interface(usb_handle, 0);
 265+
 266+ if (LIBUSB_SUCCESS != res)
 267+ {
 268+ return res;
 269+ }
 270+
 271+#ifdef DEBUG
 272+ fprintf(stderr, "Interface claimed successfully!\n");
 273+ fprintf(stderr, "Getting endpoints max size...\n");
 274+#endif
 275+
 276+ res = emcore_get_packet_info(&emcore_usb_eps_mps);
 277+
 278+ if (EMCORE_SUCCESS != res)
 279+ {
 280+ return res;
 281+ }
 282+
 283+#ifdef DEBUG
 284+ fprintf(stderr, "Got endpoint max size!\n");
 285+ fprintf(stderr, "COUT max pckt: %d, CIN max pckt: %d, DOUT max pckt: %d, DIN max pckt: %d\n",
 286+ emcore_usb_eps_mps.cout, emcore_usb_eps_mps.cin, emcore_usb_eps_mps.dout, emcore_usb_eps_mps.din
 287+ );
 288+#endif
 289+
 290+ return LIBUSB_SUCCESS;
 291+}
 292+
 293+int usb_bulk_transfer(const unsigned char endpoint, void* data, const int length)
 294+{
 295+ int transferred;
 296+ int res;
 297+
 298+ res = libusb_bulk_transfer(usb_handle, endpoint, (unsigned char*)data, length, &transferred, 30000);
 299+
 300+ if (LIBUSB_SUCCESS != res)
 301+ {
 302+ return res;
 303+ }
 304+
 305+ if (transferred != length)
 306+ {
 307+ return EMCORE_ERROR_INCOMPLETE;
 308+ }
 309+
 310+ return LIBUSB_SUCCESS;
 311+}
 312+
 313+int usb_close(const uint8_t reattach) {
 314+ int res;
 315+
 316+#ifdef DEBUG
 317+ fprintf(stderr, "Releasing USB interface...\n");
 318+#endif
 319+ res = libusb_release_interface(usb_handle, 0);
 320+
 321+ if (LIBUSB_SUCCESS != res)
 322+ {
 323+ return res;
 324+ }
 325+
 326+#ifdef DEBUG
 327+ fprintf(stderr, "Released interface successfully!\n");
 328+#endif
 329+
 330+ if (reattach)
 331+ {
 332+#ifdef DEBUG
 333+ fprintf(stderr, "Reattaching kernel driver...\n");
 334+#endif
 335+
 336+ res = libusb_attach_kernel_driver(usb_handle, 0);
 337+
 338+ if (LIBUSB_SUCCESS == res)
 339+ {
 340+#ifdef DEBUG
 341+ fprintf(stderr, "Reattached successfully!\n");
 342+#endif
 343+ }
 344+ else
 345+ {
 346+ print_error(res);
 347+
 348+ res = LIBUSB_SUCCESS;
 349+ }
 350+ }
 351+#ifdef DEBUG
 352+ fprintf(stderr, "Closing USB device handle...\n");
 353+#endif
 354+ libusb_close(usb_handle);
 355+
 356+ return res;
 357+}
 358+
 359+void usb_exit(void)
 360+{
 361+#ifdef DEBUG
 362+ fprintf(stderr, "Deinitializing USB library...\n");
 363+#endif
 364+
 365+ libusb_exit(usb_ctx);
 366+}
 367+
 368+int usb_destroy(const uint8_t reattach)
 369+{
 370+ int res = LIBUSB_SUCCESS;
 371+
 372+ if (usb_handle)
 373+ {
 374+ res = usb_close(reattach);
 375+ }
 376+
 377+ if (usb_ctx)
 378+ {
 379+ usb_exit();
 380+ }
 381+
 382+ return res;
 383+}
Index: emcore/trunk/tools/emcorefs/emcore.c
@@ -0,0 +1,1304 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "emcore.h"
 28+#include "util.h"
 29+#include "usb.h"
 30+
 31+
 32+struct emcore_usb_endpoints_addr emcore_usb_eps_addr;
 33+struct emcore_usb_endpoints_max_packet_size emcore_usb_eps_mps;
 34+
 35+int emcore_cout(const void* data, const uint32_t length)
 36+{
 37+ return usb_bulk_transfer(emcore_usb_eps_addr.cout, (void*)data, length);
 38+}
 39+
 40+int emcore_cin(void* data, const uint32_t length)
 41+{
 42+ return usb_bulk_transfer(emcore_usb_eps_addr.cin, data, length);
 43+}
 44+
 45+int emcore_dout(const void* data, const uint32_t length)
 46+{
 47+ return usb_bulk_transfer(emcore_usb_eps_addr.dout, (void*)data, length);
 48+}
 49+
 50+int emcore_din(void* data, const uint32_t length)
 51+{
 52+ return usb_bulk_transfer(emcore_usb_eps_addr.din, data, length);
 53+}
 54+
 55+int emcore_monitor_command(const void* out, void* in,
 56+ const uint32_t send_length, const uint32_t receive_length)
 57+{
 58+ int res;
 59+ uint32_t status;
 60+
 61+#ifdef DEBUG_USB_PACKETS
 62+ fprintf(stderr, "--------------------------------------------\n");
 63+ fprintf(stderr, "Sending %d bytes...\n", send_length);
 64+
 65+ dump_packet(out, send_length);
 66+
 67+#endif
 68+ res = emcore_cout(out, send_length);
 69+
 70+ if (LIBUSB_SUCCESS != res)
 71+ {
 72+ return res;
 73+ }
 74+
 75+ if (in && receive_length)
 76+ {
 77+#ifdef DEBUG_USB_PACKETS
 78+ fprintf(stderr, "Receiving %d bytes...\n", receive_length);
 79+
 80+#endif
 81+ res = emcore_cin(in, receive_length);
 82+
 83+ if (LIBUSB_SUCCESS != res)
 84+ {
 85+ return res;
 86+ }
 87+
 88+#ifdef DEBUG_USB_PACKETS
 89+ dump_packet(in, receive_length);
 90+
 91+#endif
 92+ status = *((int *)(in));
 93+ }
 94+ else
 95+ {
 96+ status = EMCORE_SUCCESS;
 97+ }
 98+
 99+#ifdef DEBUG_USB_PACKETS
 100+ fprintf(stderr, "--------------------------------------------\n");
 101+
 102+#endif
 103+ switch (status)
 104+ {
 105+ case 0:
 106+ return EMCORE_ERROR_INVALID;
 107+ break;
 108+ case 1:
 109+ return EMCORE_SUCCESS;
 110+ break;
 111+ case 2:
 112+ return EMCORE_ERROR_NOT_SUPPORTED;
 113+ break;
 114+ case 3:
 115+ return EMCORE_ERROR_BUSY;
 116+ break;
 117+ default:
 118+ return EMCORE_ERROR_INVALID;
 119+ break;
 120+ }
 121+}
 122+
 123+int emcore_get_version(struct emcore_dev_info* dev_info)
 124+{
 125+ int res;
 126+ uint32_t out[4] = { 1, 0, 0, 0 }, in[4];
 127+
 128+ res = emcore_monitor_command(out, in, 16, 16);
 129+
 130+ if (EMCORE_SUCCESS != res)
 131+ {
 132+ return res;
 133+ }
 134+
 135+ memcpy(dev_info, &in[1], sizeof(*dev_info));
 136+
 137+ return EMCORE_SUCCESS;
 138+}
 139+
 140+int emcore_get_packet_info(struct emcore_usb_endpoints_max_packet_size* max_packet_size)
 141+{
 142+ int res;
 143+ uint32_t out[4] = { 1, 1, 0, 0 }, in[4];
 144+
 145+ res = emcore_monitor_command(out, in, 16, 16);
 146+
 147+ if (EMCORE_SUCCESS != res)
 148+ {
 149+ return res;
 150+ }
 151+
 152+ memcpy(max_packet_size, &in[1], sizeof(*max_packet_size));
 153+
 154+ return EMCORE_SUCCESS;
 155+}
 156+
 157+int emcore_get_user_mem_range(struct emcore_user_mem_range* mem_range)
 158+{
 159+ int res;
 160+ uint32_t out[4] = { 1, 2, 0, 0 }, in[4];
 161+
 162+ res = emcore_monitor_command(out, in, 16, 16);
 163+
 164+ if (EMCORE_SUCCESS != res)
 165+ {
 166+ return res;
 167+ }
 168+
 169+ memcpy(mem_range, &in[1], sizeof(*mem_range));
 170+
 171+ return EMCORE_SUCCESS;
 172+}
 173+
 174+int emcore_reset(const uint8_t graceful)
 175+{
 176+ int res;
 177+ uint32_t out[4] = { 2, 0xdeadbeef, 0, 0 }, in[4];
 178+
 179+ out[1] = graceful;
 180+
 181+ res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
 182+
 183+ if (EMCORE_SUCCESS != res)
 184+ {
 185+ return res;
 186+ }
 187+
 188+ return EMCORE_SUCCESS;
 189+}
 190+
 191+int emcore_poweroff(const uint8_t graceful)
 192+{
 193+ int res;
 194+ uint32_t out[4] = { 3, 0xdeadbeef, 0, 0 }, in[4];
 195+
 196+ out[1] = graceful;
 197+
 198+ res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
 199+
 200+ if (EMCORE_SUCCESS != res)
 201+ {
 202+ return res;
 203+ }
 204+
 205+ return EMCORE_SUCCESS;
 206+}
 207+
 208+int emcore_readmem(void* data, const uint32_t addr, const uint32_t size)
 209+{
 210+ int res;
 211+ uint32_t data_length, out[4] = { 4, 0xdeadbeef, 0xdeadbeef, 0 };
 212+ void* in;
 213+
 214+ out[1] = addr;
 215+ out[2] = size;
 216+
 217+ if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
 218+ {
 219+ return EMCORE_ERROR_OVERFLOW;
 220+ }
 221+
 222+ data_length = size + EMCORE_HEADER_SIZE;
 223+ in = malloc(data_length);
 224+
 225+ res = emcore_monitor_command(out, in, 16, data_length);
 226+
 227+ if (EMCORE_SUCCESS != res)
 228+ {
 229+ return res;
 230+ }
 231+
 232+ memcpy(data, in + EMCORE_HEADER_SIZE, size);
 233+
 234+ return EMCORE_SUCCESS;
 235+}
 236+
 237+int emcore_writemem(const void* data, const uint32_t addr, const uint32_t size)
 238+{
 239+ int res;
 240+ uint32_t data_length, in[4], *out;
 241+
 242+ if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
 243+ {
 244+ return EMCORE_ERROR_OVERFLOW;
 245+ }
 246+
 247+ data_length = size + EMCORE_HEADER_SIZE;
 248+ out = malloc(data_length);
 249+
 250+ *(out) = 5;
 251+ *(out + 1) = addr;
 252+ *(out + 2) = size;
 253+ *(out + 3) = 0;
 254+ memcpy(out + 4, data, size);
 255+
 256+ res = emcore_monitor_command(out, in, data_length, 16);
 257+
 258+ if (EMCORE_SUCCESS != res)
 259+ {
 260+ return res;
 261+ }
 262+
 263+ return EMCORE_SUCCESS;
 264+}
 265+
 266+int emcore_readdma(void* data, const uint32_t addr, const uint32_t size)
 267+{
 268+ int res;
 269+ uint32_t out[4] = { 6, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 270+
 271+ out[1] = addr;
 272+ out[2] = size;
 273+
 274+ if (size > emcore_usb_eps_mps.din)
 275+ {
 276+ return EMCORE_ERROR_OVERFLOW;
 277+ }
 278+
 279+ res = emcore_monitor_command(out, in, 16, 16);
 280+
 281+ if (EMCORE_SUCCESS != res)
 282+ {
 283+ return res;
 284+ }
 285+
 286+ res = emcore_din(data, size);
 287+
 288+ return EMCORE_SUCCESS;
 289+}
 290+
 291+int emcore_writedma(const void* data, const uint32_t addr, const uint32_t size)
 292+{
 293+ int res;
 294+ uint32_t out[4] = { 7, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 295+
 296+ out[1] = addr;
 297+ out[2] = size;
 298+
 299+ if (size > emcore_usb_eps_mps.dout)
 300+ {
 301+ return EMCORE_ERROR_OVERFLOW;
 302+ }
 303+
 304+ res = emcore_monitor_command(out, in, 16, 16);
 305+
 306+ if (EMCORE_SUCCESS != res)
 307+ {
 308+ return res;
 309+ }
 310+
 311+ res = emcore_dout(data, size);
 312+
 313+ return EMCORE_SUCCESS;
 314+}
 315+
 316+int emcore_readi2c(void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
 317+{
 318+ int res;
 319+ uint32_t data_length, out[4] = { 8, 0xdeadbeef, 0, 0 };
 320+ void* in;
 321+
 322+ out[1] = bus | (slave << 8) | (addr << 16) | (size << 24);
 323+
 324+ if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
 325+ {
 326+ return EMCORE_ERROR_OVERFLOW;
 327+ }
 328+
 329+ data_length = 16 + size;
 330+ in = malloc(data_length);
 331+
 332+ res = emcore_monitor_command(out, in, 16, data_length);
 333+
 334+ if (EMCORE_SUCCESS != res)
 335+ {
 336+ return res;
 337+ }
 338+
 339+ memcpy(data, in + 16, size);
 340+
 341+ return EMCORE_SUCCESS;
 342+}
 343+
 344+int emcore_writei2c(const void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
 345+{
 346+ int res;
 347+ uint32_t data_length, in[4], *out;
 348+
 349+ if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
 350+ {
 351+ return EMCORE_ERROR_OVERFLOW;
 352+ }
 353+
 354+ data_length = 16 + size;
 355+ out = calloc(data_length, 1);
 356+
 357+ *(out) = 9; // bytes 0-3
 358+ *(out + 4) = bus;
 359+ *(out + 5) = slave;
 360+ *(out + 6) = addr;
 361+ *(out + 7) = size;
 362+
 363+ memcpy(out + 16, data, size); // bytes 16+
 364+
 365+ res = emcore_monitor_command(out, in, data_length, 16);
 366+
 367+ if (EMCORE_SUCCESS != res)
 368+ {
 369+ return res;
 370+ }
 371+
 372+ return EMCORE_SUCCESS;
 373+}
 374+
 375+int emcore_file_open(uint32_t* handle, const char* path, const int flags)
 376+{
 377+ int res;
 378+ uint32_t str_length, data_length, in[4], *out;
 379+
 380+ *handle = 0;
 381+
 382+ str_length = strlen(path);
 383+ data_length = str_length + 1 + EMCORE_HEADER_SIZE;
 384+
 385+ if (data_length > emcore_usb_eps_mps.cout)
 386+ {
 387+ return EMCORE_ERROR_OVERFLOW;
 388+ }
 389+
 390+ out = calloc(sizeof(char), data_length);
 391+
 392+ *(out) = 30;
 393+ *(out + 1) = flags;
 394+
 395+ strncpy(((char*)(out + 4)), path, str_length);
 396+
 397+ res = emcore_monitor_command(out, in, data_length, 16);
 398+
 399+ if (EMCORE_SUCCESS != res)
 400+ {
 401+ return res;
 402+ }
 403+
 404+ if (in[1] > 0x80000000)
 405+ {
 406+ return EMCORE_ERROR_IO;
 407+ }
 408+
 409+ *handle = in[1];
 410+
 411+ return EMCORE_SUCCESS;
 412+}
 413+
 414+int emcore_file_size(uint32_t* size, const uint32_t handle)
 415+{
 416+ int res;
 417+ uint32_t out[4] = { 31, 0xdeadbeef, 0, 0 }, in[4];
 418+
 419+ out[1] = handle;
 420+
 421+ res = emcore_monitor_command(out, in, 16, 16);
 422+
 423+ if (EMCORE_SUCCESS != res)
 424+ {
 425+ return res;
 426+ }
 427+
 428+ if (in[1] > 0x80000000)
 429+ {
 430+ return EMCORE_ERROR_IO;
 431+ }
 432+
 433+ *size = in[1];
 434+
 435+ return EMCORE_SUCCESS;
 436+}
 437+
 438+int emcore_file_read(uint32_t* nread, const uint32_t handle, const uint32_t addr, const uint32_t size)
 439+{
 440+ int res;
 441+ uint32_t out[4] = { 32, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
 442+
 443+ out[1] = handle;
 444+ out[2] = addr;
 445+ out[3] = size;
 446+
 447+ res = emcore_monitor_command(out, in, 16, 16);
 448+
 449+ if (EMCORE_SUCCESS != res)
 450+ {
 451+ return res;
 452+ }
 453+
 454+ if (in[1] > 0x80000000)
 455+ {
 456+ return EMCORE_ERROR_IO;
 457+ }
 458+
 459+ *nread = in[1];
 460+
 461+ return EMCORE_SUCCESS;
 462+}
 463+
 464+int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size)
 465+{
 466+ int res;
 467+ uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
 468+
 469+ out[1] = handle;
 470+ out[2] = addr;
 471+ out[3] = size;
 472+
 473+ res = emcore_monitor_command(out, in, 16, 16);
 474+
 475+ if (EMCORE_SUCCESS != res)
 476+ {
 477+ return res;
 478+ }
 479+
 480+ if (in[1] > 0x80000000)
 481+ {
 482+ return EMCORE_ERROR_IO;
 483+ }
 484+
 485+ return EMCORE_SUCCESS;
 486+}
 487+
 488+int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence)
 489+{
 490+ int res;
 491+ uint32_t out[4] = { 34, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
 492+
 493+ out[1] = handle;
 494+ out[2] = offset;
 495+ out[3] = whence;
 496+
 497+ res = emcore_monitor_command(out, in, 16, 16);
 498+
 499+ if (EMCORE_SUCCESS != res)
 500+ {
 501+ return res;
 502+ }
 503+
 504+ if (in[1] > 0x80000000)
 505+ {
 506+ return EMCORE_ERROR_IO;
 507+ }
 508+
 509+ return EMCORE_SUCCESS;
 510+}
 511+
 512+int emcore_file_truncate(const uint32_t handle, const uint32_t length)
 513+{
 514+ int res;
 515+ uint32_t out[4] = { 35, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 516+
 517+ out[1] = handle;
 518+ out[2] = length;
 519+
 520+ res = emcore_monitor_command(out, in, 16, 16);
 521+
 522+ if (EMCORE_SUCCESS != res)
 523+ {
 524+ return res;
 525+ }
 526+
 527+ if (in[1] > 0x80000000)
 528+ {
 529+ return EMCORE_ERROR_IO;
 530+ }
 531+
 532+ return EMCORE_SUCCESS;
 533+}
 534+
 535+int emcore_file_sync(const uint32_t handle)
 536+{
 537+ int res;
 538+ uint32_t out[4] = { 36, 0xdeadbeef, 0, 0 }, in[4];
 539+
 540+ out[1] = handle;
 541+
 542+ res = emcore_monitor_command(out, in, 16, 16);
 543+
 544+ if (EMCORE_SUCCESS != res)
 545+ {
 546+ return res;
 547+ }
 548+
 549+ if (in[1] > 0x80000000)
 550+ {
 551+ return EMCORE_ERROR_IO;
 552+ }
 553+
 554+ return EMCORE_SUCCESS;
 555+}
 556+
 557+int emcore_file_close(const uint32_t handle)
 558+{
 559+ int res;
 560+ uint32_t out[4] = { 37, 0xdeadbeef, 0, 0 }, in[4];
 561+
 562+ out[1] = handle;
 563+
 564+ res = emcore_monitor_command(out, in, 16, 16);
 565+
 566+ if (EMCORE_SUCCESS != res)
 567+ {
 568+ return res;
 569+ }
 570+
 571+ if (in[1] > 0x80000000)
 572+ {
 573+ return EMCORE_ERROR_IO;
 574+ }
 575+
 576+ return EMCORE_SUCCESS;
 577+}
 578+
 579+int emcore_file_close_all(uint32_t* count)
 580+{
 581+ int res;
 582+ uint32_t out[4] = { 38, 0, 0, 0 }, in[4];
 583+
 584+ res = emcore_monitor_command(out, in, 16, 16);
 585+
 586+ if (EMCORE_SUCCESS != res)
 587+ {
 588+ return res;
 589+ }
 590+
 591+ if (in[1] > 0x80000000)
 592+ {
 593+ return EMCORE_ERROR_IO;
 594+ }
 595+
 596+ *count = in[1];
 597+
 598+ return EMCORE_SUCCESS;
 599+}
 600+
 601+int emcore_file_kill_all(const uint32_t volume)
 602+{
 603+ int res;
 604+ uint32_t out[4] = { 39, 0xdeadbeef, 0, 0 }, in[4];
 605+
 606+ out[1] = volume;
 607+
 608+ res = emcore_monitor_command(out, in, 16, 16);
 609+
 610+ if (EMCORE_SUCCESS != res)
 611+ {
 612+ return res;
 613+ }
 614+
 615+ if (in[1] > 0x80000000)
 616+ {
 617+ return EMCORE_ERROR_IO;
 618+ }
 619+
 620+ return EMCORE_SUCCESS;
 621+}
 622+
 623+int emcore_file_unlink(const char* name)
 624+{
 625+ int res;
 626+ uint32_t str_length, data_length, in[4], *out;
 627+
 628+ str_length = strlen(name);
 629+ data_length = str_length + 1 + EMCORE_HEADER_SIZE;
 630+
 631+ if (data_length > emcore_usb_eps_mps.cout)
 632+ {
 633+ return EMCORE_ERROR_OVERFLOW;
 634+ }
 635+
 636+ out = calloc(sizeof(char), data_length);
 637+
 638+ *(out) = 40;
 639+
 640+ strncpy(((char*)(out + 4)), name, str_length);
 641+
 642+ res = emcore_monitor_command(out, in, data_length, 16);
 643+
 644+ if (EMCORE_SUCCESS != res)
 645+ {
 646+ return res;
 647+ }
 648+
 649+ if (in[1] > 0x80000000)
 650+ {
 651+ return EMCORE_ERROR_IO;
 652+ }
 653+
 654+ return EMCORE_SUCCESS;
 655+}
 656+
 657+int emcore_file_rename(const char* path, const char* newpath)
 658+{
 659+ int res;
 660+ uint32_t str_length, data_length, in[4], *out;
 661+
 662+ if (strlen(path) > 247)
 663+ {
 664+ return EMCORE_ERROR_OVERFLOW;
 665+ }
 666+
 667+ str_length = MIN(247, strlen(newpath));
 668+ data_length = str_length + 1 + 248 + EMCORE_HEADER_SIZE;
 669+
 670+ if (data_length > emcore_usb_eps_mps.cout)
 671+ {
 672+ return EMCORE_ERROR_OVERFLOW;
 673+ }
 674+
 675+ out = calloc(sizeof(char), data_length);
 676+
 677+ *(out) = 41;
 678+
 679+ strncpy(((char*)(out + 4)), path, strlen(path));
 680+ strncpy(((char*)(out) + 248), newpath, str_length);
 681+
 682+ res = emcore_monitor_command(out, in, data_length, 16);
 683+
 684+ if (EMCORE_SUCCESS != res)
 685+ {
 686+ return res;
 687+ }
 688+
 689+ if (in[1] > 0x80000000)
 690+ {
 691+ return EMCORE_ERROR_IO;
 692+ }
 693+
 694+ return EMCORE_SUCCESS;
 695+}
 696+
 697+int emcore_dir_open(uint32_t* handle, const char* name)
 698+{
 699+ int res;
 700+ size_t name_length;
 701+ uint32_t data_length, in[4], *out;
 702+
 703+ name_length = strlen(name);
 704+ data_length = name_length + 1 + EMCORE_HEADER_SIZE;
 705+ out = calloc(data_length, 1);
 706+
 707+ *out = 42;
 708+ strncpy(((char*)(out + 4)), name, name_length + 1);
 709+
 710+ res = emcore_monitor_command(out, in, data_length, 16);
 711+
 712+ if (EMCORE_SUCCESS != res)
 713+ {
 714+ return res;
 715+ }
 716+
 717+ *handle = in[1];
 718+
 719+ return EMCORE_SUCCESS;
 720+}
 721+
 722+int emcore_dir_read(struct emcore_dir_entry* entry, const uint32_t handle)
 723+{
 724+ int res;
 725+ uint32_t maxpath, ptr, dirent_size, emcore_errno_value, filename_buf_len,
 726+ out[4] = { 43, 0xdeadbeef, 0, 0 }, in[4];
 727+ void *buf;
 728+
 729+ memset(entry, 0, sizeof(*entry));
 730+
 731+ out[1] = handle;
 732+
 733+ res = emcore_monitor_command(out, in, 16, 16);
 734+
 735+ if (EMCORE_SUCCESS != res)
 736+ {
 737+ return res;
 738+ }
 739+
 740+ ptr = in[3];
 741+
 742+ if (0 == ptr)
 743+ {
 744+ res = emcore_errno(&emcore_errno_value);
 745+
 746+ if (EMCORE_SUCCESS != res)
 747+ {
 748+ return res;
 749+ }
 750+
 751+ if (EMCORE_SUCCESS != emcore_errno_value)
 752+ {
 753+ return EMCORE_ERROR_IO;
 754+ }
 755+
 756+ return EMCORE_ERROR_NO_MORE_ENTRIES;
 757+ }
 758+
 759+ if (1 != in[1]) // version
 760+ {
 761+ return EMCORE_ERROR_NOT_IMPLEMENTED;
 762+ }
 763+
 764+ maxpath = in[2];
 765+
 766+ dirent_size = maxpath + 16;
 767+
 768+ buf = malloc(dirent_size);
 769+
 770+ res = emcore_read(buf, ptr, dirent_size);
 771+
 772+ if (EMCORE_SUCCESS != res)
 773+ {
 774+ return res;
 775+ }
 776+
 777+ filename_buf_len = strlen((char*)buf) + 1;
 778+
 779+ entry->name = malloc(filename_buf_len);
 780+ strncpy(entry->name, buf, filename_buf_len);
 781+ memcpy(&entry->attributes, buf + maxpath, 16);
 782+
 783+#ifdef DEBUG_DIR_ENTRIES
 784+ fprintf(stderr, "Read directory entry: %s\n", entry->name);
 785+ fprintf(stderr, "Attributes: 0x%08x\n", entry->attributes);
 786+ fprintf(stderr, "Size: %d\n", entry->size);
 787+ fprintf(stderr, "Start cluster: %d\n", entry->startcluster);
 788+ fprintf(stderr, "Last written date: 0x%04x\n", entry->wrtdate);
 789+ fprintf(stderr, "Last written time: 0x%04x\n", entry->wrttime);
 790+ fprintf(stderr, "Last written TS: %lu\n",
 791+ (unsigned long) fat_time_to_unix_ts(entry->wrttime, entry->wrtdate));
 792+#endif
 793+ return EMCORE_SUCCESS;
 794+}
 795+
 796+int emcore_dir_close(const uint32_t handle)
 797+{
 798+ int res;
 799+ uint32_t out[4] = { 44, 0xdeadbeef, 0, 0 }, in[4];
 800+
 801+ out[1] = handle;
 802+
 803+ res = emcore_monitor_command(out, in, 16, 16);
 804+
 805+ if (EMCORE_SUCCESS != res)
 806+ {
 807+ return res;
 808+ }
 809+
 810+ if (in[1] > 0x80000000)
 811+ {
 812+ return EMCORE_ERROR_IO;
 813+ }
 814+
 815+ return EMCORE_SUCCESS;
 816+}
 817+
 818+int emcore_dir_close_all(uint32_t* count)
 819+{
 820+ int res;
 821+ uint32_t out[4] = { 45, 0, 0, 0 }, in[4];
 822+
 823+ res = emcore_monitor_command(out, in, 16, 16);
 824+
 825+ if (EMCORE_SUCCESS != res)
 826+ {
 827+ return res;
 828+ }
 829+
 830+ if (in[1] > 0x80000000)
 831+ {
 832+ return EMCORE_ERROR_IO;
 833+ }
 834+
 835+ *count = in[1];
 836+
 837+ return EMCORE_SUCCESS;
 838+}
 839+
 840+int emcore_errno(uint32_t* emcore_errno_value)
 841+{
 842+ int res;
 843+ uint32_t out[4] = { 49, 0, 0, 0 }, in[4];
 844+
 845+ res = emcore_monitor_command(out, in, 16, 16);
 846+
 847+ if (EMCORE_SUCCESS != res)
 848+ {
 849+ return res;
 850+ }
 851+
 852+ *emcore_errno_value = in[1];
 853+
 854+ return EMCORE_SUCCESS;
 855+}
 856+
 857+int emcore_malloc(uint32_t* ptr, const uint32_t size)
 858+{
 859+ int res;
 860+ uint32_t out[4] = { 52, 0xdeadbeef, 0, 0 }, in[4];
 861+
 862+ out[1] = size;
 863+
 864+ res = emcore_monitor_command(out, in, 16, 16);
 865+
 866+ if (EMCORE_SUCCESS != res)
 867+ {
 868+ return res;
 869+ }
 870+
 871+ *ptr = in[1];
 872+
 873+ return EMCORE_SUCCESS;
 874+}
 875+
 876+int emcore_memalign(uint32_t* ptr, const uint32_t align, const uint32_t size)
 877+{
 878+ int res;
 879+ uint32_t out[4] = { 53, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 880+
 881+ out[1] = align;
 882+ out[2] = size;
 883+
 884+ res = emcore_monitor_command(out, in, 16, 16);
 885+
 886+ if (EMCORE_SUCCESS != res)
 887+ {
 888+ return res;
 889+ }
 890+
 891+ *ptr = in[1];
 892+
 893+ return EMCORE_SUCCESS;
 894+}
 895+
 896+int emcore_realloc(uint32_t* new_ptr, const uint32_t ptr, const uint32_t size)
 897+{
 898+ int res;
 899+ uint32_t out[4] = { 54, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 900+
 901+ out[1] = ptr;
 902+ out[2] = size;
 903+
 904+ res = emcore_monitor_command(out, in, 16, 16);
 905+
 906+ if (EMCORE_SUCCESS != res)
 907+ {
 908+ return res;
 909+ }
 910+
 911+ *new_ptr = in[1];
 912+
 913+ return EMCORE_SUCCESS;
 914+}
 915+
 916+int emcore_reownalloc(const uint32_t ptr, const uint32_t owner)
 917+{
 918+ uint32_t out[4] = { 55, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
 919+
 920+ out[1] = ptr;
 921+ out[2] = owner;
 922+
 923+ return emcore_monitor_command(out, in, 16, 16);
 924+}
 925+
 926+int emcore_free(const uint32_t ptr)
 927+{
 928+ uint32_t out[4] = { 56, 0xdeadbeef, 0, 0 }, in[4];
 929+
 930+ out[1] = ptr;
 931+
 932+ return emcore_monitor_command(out, in, 16, 16);
 933+}
 934+
 935+int emcore_free_all(void)
 936+{
 937+ uint32_t out[4] = { 57, 0, 0, 0 }, in[4];
 938+
 939+ return emcore_monitor_command(out, in, 16, 16);
 940+}
 941+
 942+int emcore_read(void* data, const uint32_t addr, const uint32_t size)
 943+{
 944+ int res;
 945+ struct alignsizes* sizes;
 946+ uint32_t cin_maxsize, readsize, curraddr;
 947+
 948+ cin_maxsize = emcore_usb_eps_mps.cin - EMCORE_HEADER_SIZE;
 949+ sizes = malloc(sizeof(*sizes));
 950+
 951+ alignsplit(sizes, addr, size, cin_maxsize, 16);
 952+#ifdef DEBUG_ALIGN_SPLIT
 953+ fprintf(stderr, "Downloading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
 954+ size, addr, sizes->head, sizes->body, sizes->tail);
 955+
 956+#endif
 957+ curraddr = addr;
 958+
 959+ if (sizes->head > 0)
 960+ {
 961+ res = emcore_readmem(data, curraddr, sizes->head);
 962+
 963+ if (EMCORE_SUCCESS != res)
 964+ {
 965+ return res;
 966+ }
 967+
 968+ data += sizes->head;
 969+ curraddr += sizes->head;
 970+ }
 971+
 972+ while (sizes->body > 0)
 973+ {
 974+ if (sizes->body >= cin_maxsize * 2)
 975+ {
 976+ readsize = MIN(sizes->body, emcore_usb_eps_mps.din);
 977+ res = emcore_readdma(data, curraddr, readsize);
 978+ }
 979+ else
 980+ {
 981+ readsize = MIN(sizes->body, cin_maxsize);
 982+ res = emcore_readmem(data, curraddr, readsize);
 983+ }
 984+
 985+ if (EMCORE_SUCCESS != res)
 986+ {
 987+ return res;
 988+ }
 989+
 990+ data += readsize;
 991+ curraddr += readsize;
 992+ sizes->body -= readsize;
 993+ }
 994+
 995+ if (sizes->tail > 0)
 996+ {
 997+ res = emcore_readmem(data, curraddr, sizes->tail);
 998+
 999+ if (EMCORE_SUCCESS != res)
 1000+ {
 1001+ return res;
 1002+ }
 1003+
 1004+ data += sizes->tail;
 1005+ }
 1006+
 1007+ return EMCORE_SUCCESS;
 1008+}
 1009+
 1010+int emcore_write(const void* data, const uint32_t addr, const uint32_t size)
 1011+{
 1012+ int res;
 1013+ struct alignsizes* sizes;
 1014+ uint32_t cout_maxsize, writesize, curraddr;
 1015+
 1016+ cout_maxsize = emcore_usb_eps_mps.cout - 16;
 1017+ sizes = malloc(sizeof(*sizes));
 1018+
 1019+ alignsplit(sizes, addr, size, cout_maxsize, 16);
 1020+#ifdef DEBUG_ALIGN_SPLIT
 1021+ fprintf(stderr, "Uploading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
 1022+ size, addr, sizes->head, sizes->body, sizes->tail);
 1023+
 1024+#endif
 1025+ curraddr = addr;
 1026+
 1027+ if (sizes->head > 0)
 1028+ {
 1029+ res = emcore_writemem(data, curraddr, sizes->head);
 1030+
 1031+ if (EMCORE_SUCCESS != res)
 1032+ {
 1033+ return res;
 1034+ }
 1035+
 1036+ data += sizes->head;
 1037+ curraddr += sizes->head;
 1038+ }
 1039+
 1040+ while (sizes->body > 0)
 1041+ {
 1042+ if (sizes->body >= 2 * cout_maxsize)
 1043+ {
 1044+ writesize = MIN(sizes->body, emcore_usb_eps_mps.dout);
 1045+ res = emcore_writedma(data, curraddr, writesize);
 1046+ }
 1047+ else
 1048+ {
 1049+ writesize = MIN(sizes->body, cout_maxsize);
 1050+ res = emcore_writemem(data, curraddr, writesize);
 1051+ }
 1052+
 1053+ if (EMCORE_SUCCESS != res)
 1054+ {
 1055+ return res;
 1056+ }
 1057+
 1058+ data += writesize;
 1059+ curraddr += writesize;
 1060+ sizes->body -= writesize;
 1061+ }
 1062+
 1063+ if (sizes->tail > 0)
 1064+ {
 1065+ res = emcore_writemem(data, curraddr, sizes->tail);
 1066+
 1067+ if (EMCORE_SUCCESS != res)
 1068+ {
 1069+ return res;
 1070+ }
 1071+
 1072+ data += sizes->tail;
 1073+ }
 1074+
 1075+ return EMCORE_SUCCESS;
 1076+}
 1077+
 1078+int emcore_ls(const uint32_t handle)
 1079+{
 1080+ int res = 0;
 1081+ struct emcore_dir_entry entry;
 1082+
 1083+ while (1)
 1084+ {
 1085+ res = emcore_dir_read(&entry, handle);
 1086+
 1087+ if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
 1088+ {
 1089+ res = EMCORE_SUCCESS;
 1090+ break;
 1091+ }
 1092+
 1093+ if (EMCORE_SUCCESS != res)
 1094+ {
 1095+ return res;
 1096+ }
 1097+
 1098+#ifdef DEBUG_DIR_ENTRIES
 1099+ fprintf(stderr, "Read directory entry:\n");
 1100+ fprintf(stderr, "Name: %s\n", entry.name);
 1101+ fprintf(stderr, "Attributes: 0x%08x\n", entry.attributes);
 1102+ fprintf(stderr, "Size: %d\n", entry.size);
 1103+ fprintf(stderr, "Start cluster: %d\n", entry.startcluster);
 1104+ fprintf(stderr, "Last written date: 0x%04x\n", entry.wrtdate);
 1105+ fprintf(stderr, "Last written time: 0x%04x\n", entry.wrttime);
 1106+ fprintf(stderr, "Last written TS: %lu\n",
 1107+ (unsigned long) fat_time_to_unix_ts(entry.wrttime, entry.wrtdate));
 1108+#endif
 1109+ if (entry.attributes & 0x10)
 1110+ {
 1111+ printf(" [DIR]");
 1112+ }
 1113+ else
 1114+ {
 1115+ printf("%10d", entry.size);
 1116+ }
 1117+
 1118+ printf(" %s\n", entry.name);
 1119+ }
 1120+
 1121+ return res;
 1122+}
 1123+
 1124+int emcore_test(void)
 1125+{
 1126+ int res;
 1127+
 1128+ /* emcore_get_version */
 1129+ struct emcore_dev_info dev_info;
 1130+ char *hw_type;
 1131+
 1132+ /* emcore_get_packet_info */
 1133+ struct emcore_usb_endpoints_max_packet_size max_packet_size;
 1134+
 1135+ /* emcore_get_user_mem_range */
 1136+ struct emcore_user_mem_range mem_range;
 1137+
 1138+ /* emcore_readmem */
 1139+ void* buf;
 1140+ uint16_t buf_size;
 1141+ uint32_t read_addr;
 1142+
 1143+ /* emcore_readi2c */
 1144+ /* uint8_t i2cdata; */
 1145+
 1146+ /* emcore_dir_open */
 1147+ uint32_t dir_handle;
 1148+
 1149+ /* emcore_dir_close_all */
 1150+ uint32_t count;
 1151+
 1152+ res = emcore_get_version(&dev_info);
 1153+
 1154+ if (EMCORE_SUCCESS != res)
 1155+ {
 1156+ return res;
 1157+ }
 1158+
 1159+ hw_type = malloc(5);
 1160+
 1161+ strncpy(hw_type, ((char*)&dev_info.hw_type), 4);
 1162+
 1163+ printf("Connected to %4s running %s v%d.%d.%d r%d\n",
 1164+ hw_type, (1 == dev_info.sw_type ? "emBIOS" : (2 == dev_info.sw_type ? "emCORE" : "UNKNOWN")),
 1165+ dev_info.major, dev_info.minor, dev_info.patch, dev_info.svn_revision
 1166+ );
 1167+
 1168+ free(hw_type);
 1169+
 1170+ res = emcore_get_packet_info(&max_packet_size);
 1171+
 1172+ if (EMCORE_SUCCESS != res)
 1173+ {
 1174+ return res;
 1175+ }
 1176+
 1177+ printf("COUT max pckt: %d, CIN max pckt: %d, DOUT max pckt: %d, DIN max pckt: %d\n",
 1178+ max_packet_size.cout, max_packet_size.cin, max_packet_size.dout, max_packet_size.din
 1179+ );
 1180+
 1181+ res = emcore_get_user_mem_range(&mem_range);
 1182+
 1183+ if (EMCORE_SUCCESS != res)
 1184+ {
 1185+ return res;
 1186+ }
 1187+
 1188+ printf("User mem range: 0x%08x - 0x%08x\n", mem_range.lower, mem_range.upper);
 1189+
 1190+ read_addr = 0x09000000;
 1191+ buf_size = 0x1000;
 1192+ buf = malloc(buf_size);
 1193+
 1194+ printf("Reading 0x%08x bytes from 0x%08x\n", buf_size, read_addr);
 1195+
 1196+ res = emcore_read(buf, read_addr, buf_size);
 1197+
 1198+ if (EMCORE_SUCCESS != res)
 1199+ {
 1200+ return res;
 1201+ }
 1202+
 1203+#ifdef DEBUG
 1204+ dump_packet(buf, buf_size);
 1205+
 1206+#endif
 1207+ printf("Writing 0x%08x bytes to 0x%08x\n", buf_size, read_addr);
 1208+
 1209+ res = emcore_write(buf, read_addr, buf_size);
 1210+
 1211+ if (EMCORE_SUCCESS != res)
 1212+ {
 1213+ return res;
 1214+ }
 1215+
 1216+ free(buf);
 1217+
 1218+ /*
 1219+ printf("Reading 1 byte from I2C\n");
 1220+
 1221+ res = emcore_readi2c(&i2cdata, 0, 0xe6, 0x29, 1);
 1222+
 1223+ if (EMCORE_SUCCESS != res)
 1224+ {
 1225+ return res;
 1226+ }
 1227+
 1228+#ifdef DEBUG
 1229+ dump_packet(&i2cdata, 1);
 1230+
 1231+#endif
 1232+ */
 1233+ /* nano2g - turns on/off the backlight */
 1234+ /*
 1235+ i2cdata = 1;
 1236+
 1237+ printf("Writing 1 byte to I2C\n");
 1238+
 1239+ res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
 1240+
 1241+ if (EMCORE_SUCCESS != res)
 1242+ {
 1243+ return res;
 1244+ }
 1245+
 1246+ sleep(1);
 1247+
 1248+ i2cdata = 0;
 1249+
 1250+ printf("Writing 1 byte to I2C\n");
 1251+
 1252+ res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
 1253+
 1254+ if (EMCORE_SUCCESS != res)
 1255+ {
 1256+ return res;
 1257+ }
 1258+ */
 1259+ res = emcore_dir_open(&dir_handle, "/");
 1260+
 1261+ if (EMCORE_SUCCESS != res)
 1262+ {
 1263+ return res;
 1264+ }
 1265+
 1266+ printf("Opened dir handle: 0x%08x\n", dir_handle);
 1267+
 1268+ res = emcore_ls(dir_handle);
 1269+
 1270+ if (EMCORE_SUCCESS != res)
 1271+ {
 1272+ return res;
 1273+ }
 1274+
 1275+ printf("Listed dir handle: 0x%08x\n", dir_handle);
 1276+
 1277+ res = emcore_dir_close(dir_handle);
 1278+
 1279+ if (EMCORE_SUCCESS != res)
 1280+ {
 1281+ return res;
 1282+ }
 1283+
 1284+ printf("Closed dir handle 0x%08x\n", dir_handle);
 1285+
 1286+ res = emcore_dir_close_all(&count);
 1287+
 1288+ if (EMCORE_SUCCESS != res)
 1289+ {
 1290+ return res;
 1291+ }
 1292+
 1293+ printf("Closed %d dir handles\n", count);
 1294+ /* powers off the device - graceful
 1295+ res = emcore_poweroff(1);
 1296+
 1297+ if (EMCORE_SUCCESS != res)
 1298+ {
 1299+ return res;
 1300+ }
 1301+
 1302+ printf("Device powered off successfully!\n");
 1303+ */
 1304+ return EMCORE_SUCCESS;
 1305+}
Index: emcore/trunk/tools/emcorefs/Makefile
@@ -0,0 +1,28 @@
 2+CFLAGS := -O2 -Wall -Wextra -Werror $(shell pkg-config --cflags --libs libusb-1.0 fuse)
 3+SOURCES = util.c usb.c emcore.c cache.c fuse.c emcorefs.c
 4+TARGET = build/emcorefs
 5+
 6+all: build emcorefs
 7+
 8+emcorefs:
 9+ gcc $(CFLAGS) -o $(TARGET) $(SOURCES)
 10+
 11+build:
 12+ @mkdir $@
 13+
 14+testonly:
 15+ gcc $(CFLAGS) -DTEST_ONLY -DDEBUG -g -o $(TARGET) $(SOURCES)
 16+
 17+debug:
 18+ gcc $(CFLAGS) -DDEBUG -g -o $(TARGET) $(SOURCES)
 19+
 20+test:
 21+ @mkdir -p mountpoint
 22+ $(TARGET) -s mountpoint/
 23+
 24+testdebug:
 25+ @mkdir -p mountpoint
 26+ $(TARGET) -d -s mountpoint/
 27+
 28+clean:
 29+ @rm -rf build
Index: emcore/trunk/tools/emcorefs/util.c
@@ -0,0 +1,179 @@
 2+//
 3+//
 4+// Copyright 2011 user890104
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emCORE is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+
 27+#include "util.h"
 28+
 29+
 30+const char* libusb_error_messages[13] =
 31+{
 32+ "No error", /* LIBUSB_SUCCESS = 0 */
 33+ "Input/output error", /* LIBUSB_ERROR_IO = -1 */
 34+ "Invalid parameter", /* LIBUSB_ERROR_INVALID_PARAM = -2 */
 35+ "Access denied", /* LIBUSB_ERROR_ACCESS = -3 */
 36+ "No such device", /* LIBUSB_ERROR_NO_DEVICE = -4 */
 37+ "Entity not found", /* LIBUSB_ERROR_NOT_FOUND = -5 */
 38+ "Resource busy", /* LIBUSB_ERROR_BUSY = -6 */
 39+ "Operation timed out", /* LIBUSB_ERROR_TIMEOUT = -7 */
 40+ "Overflow", /* LIBUSB_ERROR_OVERFLOW = -8 */
 41+ "Pipe error", /* LIBUSB_ERROR_PIPE = -9 */
 42+ "System call interrupted", /* LIBUSB_ERROR_INTERRUPTED = -10 */
 43+ "Insufficient memory", /* LIBUSB_ERROR_NO_MEM = -11 */
 44+ "Operation not supported", /* LIBUSB_ERROR_NOT_SUPPORTED = -12 */
 45+};
 46+
 47+const char* emcore_error_messages[10] =
 48+{
 49+ "No error", /* EMCORE_SUCCESS = 0 */
 50+ "Invalid command", /* EMCORE_ERROR_INVALID = 1 */
 51+ "Command not supported", /* EMCORE_ERROR_NOT_SUPPORTED = 2 */
 52+ "Device is busy", /* EMCORE_ERROR_BUSY = 3 */
 53+ "No such device", /* EMCORE_ERROR_NO_DEVICE = 4 */
 54+ "Incomplete transfer", /* EMCORE_ERROR_INCOMPLETE = 5 */
 55+ "Overflow", /* EMCORE_ERROR_OVERFLOW = 6 */
 56+ "Not implemented", /* EMCORE_ERROR_NOT_IMPLEMENTED = 7 */
 57+ "No more entries in dir", /* EMCORE_ERROR_NO_MORE_ENTRIES = 8 */
 58+ "I/O error", /* EMCORE_ERROR_IO = 9 */
 59+};
 60+
 61+void dump_packet(const void* data, const size_t length)
 62+{
 63+ static size_t i;
 64+
 65+ for (i = 0; i < length; ++i)
 66+ {
 67+ fprintf(stderr, "%02x ", *((uint8_t*)(data + i)));
 68+
 69+ if (i % 4 == 3)
 70+ {
 71+ fprintf(stderr, " ");
 72+ }
 73+
 74+ if (i % 16 == 15 && i + 1 < length)
 75+ {
 76+ fprintf(stderr, "\n");
 77+ }
 78+ }
 79+
 80+ fprintf(stderr, "\n");
 81+}
 82+
 83+void alignsplit(struct alignsizes* sizeptr, const uint32_t addr,
 84+ const uint32_t size, const uint32_t blksize, const uint32_t align)
 85+{
 86+ uint32_t end, bodyaddr, tailaddr;
 87+
 88+ if (size <= blksize)
 89+ {
 90+ sizeptr->head = size;
 91+ sizeptr->body = 0;
 92+ sizeptr->tail = 0;
 93+
 94+ return;
 95+ }
 96+
 97+ end = addr + size;
 98+
 99+ if (addr & (align -1))
 100+ {
 101+ bodyaddr = (addr + MIN(size, blksize)) & ~(align - 1);
 102+ }
 103+ else
 104+ {
 105+ bodyaddr = addr;
 106+ }
 107+
 108+ sizeptr->head = bodyaddr - addr;
 109+
 110+ if ((size - sizeptr->head) & (align - 1))
 111+ {
 112+ tailaddr = ((end - MIN(end - bodyaddr, blksize) + align - 1) & ~(align - 1));
 113+ }
 114+ else
 115+ {
 116+ tailaddr = end;
 117+ }
 118+
 119+ sizeptr->tail = end - tailaddr;
 120+ sizeptr->body = tailaddr - bodyaddr;
 121+
 122+ return;
 123+}
 124+
 125+time_t fat_time_to_unix_ts(const short wrttime, const short wrtdate)
 126+{
 127+ struct tm result;
 128+ /*
 129+ Example time: 0x9365
 130+ in memory:
 131+ M M M S S S S S H H H H H M M M
 132+ as a number:
 133+ H H H H H M M M M M M S S S S S
 134+
 135+ Example date: 0x3d37
 136+ in memory:
 137+ M M M D D D D D Y Y Y Y Y Y Y M
 138+ as a number:
 139+ Y Y Y Y Y Y Y M M M M D D D D D
 140+ */
 141+
 142+ result.tm_sec = ((wrttime & 0x1f) << 1);
 143+ result.tm_min = (wrttime >> 5) & 0x3f;
 144+ result.tm_hour = (wrttime >> 11) & 0x1f;
 145+ result.tm_mday = wrtdate & 0x1f;
 146+ result.tm_mon = ((wrtdate >> 5) & 0xf) - 1;
 147+ result.tm_year = ((wrtdate >> 9) & 0x7f) + 80;
 148+
 149+ return mktime(&result);
 150+}
 151+
 152+int32_t unix_ts_to_fat_time(const time_t datetime)
 153+{
 154+ struct tm* tm_ptr;
 155+
 156+ tm_ptr = localtime(&datetime);
 157+
 158+ return (tm_ptr->tm_sec >> 1) |
 159+ (tm_ptr->tm_min << 5) |
 160+ (tm_ptr->tm_hour << 0xb) |
 161+ (tm_ptr->tm_mday << 0x10) |
 162+ ((tm_ptr->tm_mon + 1) << 0x15) |
 163+ ((tm_ptr->tm_year - 80) << 0x19);
 164+}
 165+
 166+void print_error(const int code)
 167+{
 168+ if (code > 0)
 169+ {
 170+ fprintf(stderr, "emcore error: %s\n", emcore_error_messages[code]);
 171+ }
 172+ else
 173+ {
 174+ fprintf(stderr, "libusb error: %s\n", (
 175+ LIBUSB_ERROR_OTHER == code ?
 176+ "Other error" :
 177+ libusb_error_messages[-code]
 178+ ));
 179+ }
 180+}
Index: emcore/trunk/tools/emcorefs
Property changes on: emcore/trunk/tools/emcorefs
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,2 ##
 181+build
 182+mountpoint