diff options
| author | salmoon <salmoon> | 2002-08-28 16:10:44 +0000 | 
|---|---|---|
| committer | salmoon <salmoon> | 2002-08-28 16:10:44 +0000 | 
| commit | 0d8d92cf4631f4a0a88fe04817d375f9e73408e4 (patch) | |
| tree | 66c43b0aec21aaa2ea6643fe38b71fac12b91fe4 /libmpio | |
| download | mpiosh-0d8d92cf4631f4a0a88fe04817d375f9e73408e4.tar.gz mpiosh-0d8d92cf4631f4a0a88fe04817d375f9e73408e4.tar.bz2 mpiosh-0d8d92cf4631f4a0a88fe04817d375f9e73408e4.zip  | |
Initial revision
Diffstat (limited to 'libmpio')
| -rw-r--r-- | libmpio/Makefile.am | 24 | ||||
| -rw-r--r-- | libmpio/Makefile.in | 372 | ||||
| -rw-r--r-- | libmpio/debug.c | 293 | ||||
| -rw-r--r-- | libmpio/debug.h | 102 | ||||
| -rw-r--r-- | libmpio/defs.h | 192 | ||||
| -rw-r--r-- | libmpio/directory.c | 509 | ||||
| -rw-r--r-- | libmpio/directory.h | 50 | ||||
| -rw-r--r-- | libmpio/ecc.c | 203 | ||||
| -rw-r--r-- | libmpio/ecc.h | 36 | ||||
| -rw-r--r-- | libmpio/fat.c | 414 | ||||
| -rw-r--r-- | libmpio/fat.h | 47 | ||||
| -rw-r--r-- | libmpio/io.c | 618 | ||||
| -rw-r--r-- | libmpio/io.h | 58 | ||||
| -rw-r--r-- | libmpio/mpio.c | 769 | ||||
| -rw-r--r-- | libmpio/mpio.h | 97 | ||||
| -rw-r--r-- | libmpio/smartmedia.c | 153 | ||||
| -rw-r--r-- | libmpio/smartmedia.h | 39 | 
17 files changed, 3976 insertions, 0 deletions
diff --git a/libmpio/Makefile.am b/libmpio/Makefile.am new file mode 100644 index 0000000..0517b3a --- /dev/null +++ b/libmpio/Makefile.am @@ -0,0 +1,24 @@ +INCLUDES= + +lib_LTLIBRARIES=libmpio.la + +libmpio_la_SOURCES= \ +		mpio.c \ +		io.c \ +		debug.c \ +		smartmedia.c \ +		directory.c \ +		fat.c \ +		ecc.c + +pkginclude_HEADERS= \ +		mpio.h \ +		defs.h + +noinst_HEADERS= \ +		io.h \ +		debug.h \ +		smartmedia.h \ +		directory.h \ +		fat.h \ +		ecc.h diff --git a/libmpio/Makefile.in b/libmpio/Makefile.in new file mode 100644 index 0000000..b555d58 --- /dev/null +++ b/libmpio/Makefile.in @@ -0,0 +1,372 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AS = @AS@ +CC = @CC@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EXEEXT = @EXEEXT@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ + +INCLUDES =  + +lib_LTLIBRARIES = libmpio.la + +libmpio_la_SOURCES = \ +		mpio.c \ +		io.c \ +		debug.c \ +		smartmedia.c \ +		directory.c \ +		fat.c \ +		ecc.c + + +pkginclude_HEADERS = \ +		mpio.h \ +		defs.h + + +noinst_HEADERS = \ +		io.h \ +		debug.h \ +		smartmedia.h \ +		directory.h \ +		fat.h \ +		ecc.h + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES =  +LTLIBRARIES =  $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir)  +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libmpio_la_LDFLAGS =  +libmpio_la_LIBADD =  +libmpio_la_OBJECTS =  mpio.lo io.lo debug.lo smartmedia.lo directory.lo \ +fat.lo ecc.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS =  $(noinst_HEADERS) $(pkginclude_HEADERS) + +DIST_COMMON =  Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libmpio_la_SOURCES) +OBJECTS = $(libmpio_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)  +	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps libmpio/Makefile + +Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status +	cd $(top_builddir) \ +	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: +	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) +	@$(NORMAL_INSTALL) +	$(mkinstalldirs) $(DESTDIR)$(libdir) +	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \ +	  if test -f $$p; then \ +	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ +	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ +	  else :; fi; \ +	done + +uninstall-libLTLIBRARIES: +	@$(NORMAL_UNINSTALL) +	list='$(lib_LTLIBRARIES)'; for p in $$list; do \ +	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ +	done + +.c.o: +	$(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: +	$(COMPILE) -c `cygpath -w $<` + +.s.o: +	$(COMPILE) -c $< + +.S.o: +	$(COMPILE) -c $< + +mostlyclean-compile: +	-rm -f *.o core *.core +	-rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: +	-rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: +	$(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: +	$(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: +	$(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: +	-rm -f *.lo + +clean-libtool: +	-rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libmpio.la: $(libmpio_la_OBJECTS) $(libmpio_la_DEPENDENCIES) +	$(LINK) -rpath $(libdir) $(libmpio_la_LDFLAGS) $(libmpio_la_OBJECTS) $(libmpio_la_LIBADD) $(LIBS) + +install-pkgincludeHEADERS: $(pkginclude_HEADERS) +	@$(NORMAL_INSTALL) +	$(mkinstalldirs) $(DESTDIR)$(pkgincludedir) +	@list='$(pkginclude_HEADERS)'; for p in $$list; do \ +	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ +	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p"; \ +	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p; \ +	done + +uninstall-pkgincludeHEADERS: +	@$(NORMAL_UNINSTALL) +	list='$(pkginclude_HEADERS)'; for p in $$list; do \ +	  rm -f $(DESTDIR)$(pkgincludedir)/$$p; \ +	done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) +	list='$(SOURCES) $(HEADERS)'; \ +	unique=`for i in $$list; do echo $$i; done | \ +	  awk '    { files[$$0] = 1; } \ +	       END { for (i in files) print i; }'`; \ +	here=`pwd` && cd $(srcdir) \ +	  && mkid -f$$here/ID $$unique $(LISP) + +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP) +	tags=; \ +	here=`pwd`; \ +	list='$(SOURCES) $(HEADERS)'; \ +	unique=`for i in $$list; do echo $$i; done | \ +	  awk '    { files[$$0] = 1; } \ +	       END { for (i in files) print i; }'`; \ +	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ +	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: +	-rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libmpio + +distdir: $(DISTFILES) +	@for file in $(DISTFILES); do \ +	  d=$(srcdir); \ +	  if test -d $$d/$$file; then \ +	    cp -pr $$d/$$file $(distdir)/$$file; \ +	  else \ +	    test -f $(distdir)/$$file \ +	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ +	    || cp -p $$d/$$file $(distdir)/$$file || :; \ +	  fi; \ +	done +debug.lo debug.o : debug.c debug.h +directory.lo directory.o : directory.c debug.h io.h defs.h mpio.h \ +	directory.h +ecc.lo ecc.o : ecc.c ecc.h defs.h debug.h +fat.lo fat.o : fat.c fat.h defs.h io.h debug.h +io.lo io.o : io.c io.h defs.h debug.h ecc.h +mpio.lo mpio.o : mpio.c defs.h debug.h directory.h io.h mpio.h \ +	smartmedia.h fat.h +mpio_io.lo mpio_io.o : mpio_io.c mpio_io.h mpio_defs.h +smartmedia.lo smartmedia.o : smartmedia.c smartmedia.h defs.h debug.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: install-pkgincludeHEADERS +install-data: install-data-am + +install-am: all-am +	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: +	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: +	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(pkgincludedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: +	-rm -f Makefile $(CONFIG_CLEAN_FILES) +	-rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \ +		mostlyclean-libtool mostlyclean-tags \ +		mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ +		clean-generic mostlyclean-am + +clean: clean-am + +distclean-am:  distclean-libLTLIBRARIES distclean-compile \ +		distclean-libtool distclean-tags distclean-generic \ +		clean-am +	-rm -f libtool + +distclean: distclean-am + +maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \ +		maintainer-clean-compile maintainer-clean-libtool \ +		maintainer-clean-tags maintainer-clean-generic \ +		distclean-am +	@echo "This command is intended for maintainers to use;" +	@echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool uninstall-pkgincludeHEADERS \ +install-pkgincludeHEADERS tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libmpio/debug.c b/libmpio/debug.c new file mode 100644 index 0000000..2de85eb --- /dev/null +++ b/libmpio/debug.c @@ -0,0 +1,293 @@ +/*  + * debug.c + * + * Authors: Dirk Meyer  <dmeyer@tzi.de> + *          Andreas Büsching <crunchy@tzi.de> + * + * $Id: debug.c,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + */ + +#include "debug.h" + +#include <ctype.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> + +#define DCOLOR "_color" +#define DFILE "_file" +#define DSUFFIX "_debug" +#define LEVEL_HEXDUMP 5 + +char *__debug_color = NULL; +int __debug_level = 0; +FILE *__debug_fd; + +void  +debug_init(void) { +  char *env_var = malloc(strlen(DPACKAGE) + strlen(DFILE) + 1); +  const char *env; +   +  /* check debug output file */ +  strcpy(env_var, DPACKAGE); +  strcat(env_var, DFILE); + +  if ((env = getenv(env_var))) { +    if (__debug_fd && fileno(__debug_fd) != -1) { +      fclose(__debug_fd); +    } +     +    __debug_fd = fopen(env, "a"); +    if (!__debug_fd) { +      __debug_fd = stderr; +    } +  } else { +    __debug_fd = stderr; +  } + +  free(env_var); + +  /* check debug level */ +  env_var = malloc(strlen(DPACKAGE) + strlen(DSUFFIX) + 1); +  strcpy(env_var, DPACKAGE); +  strcat(env_var, DSUFFIX); +   +  if ((env = getenv(env_var))) +    if (isdigit(env[0])) +      __debug_level = strtol(env, NULL, 10); +    else +      __debug_level = 1; +  else +    __debug_level = -1; + +  free(env_var); + +  /* check debug color */ +  env_var = malloc(strlen(DPACKAGE) + strlen(DCOLOR) + 1); +   +  strcpy(env_var, DPACKAGE); +  strcat(env_var, DCOLOR); +   +  if (__debug_color) free(__debug_color); +  __debug_color = NULL; +   +  if ((env = getenv(env_var))) { +    if (env[0] != '\0') { +      __debug_color = malloc(4 + strlen(env)); +      sprintf(__debug_color, "\033[%sm", env); +    } else  +      __debug_color = malloc(6); +    strcpy(__debug_color, "\033[32m"); +  } else { +    __debug_color = NULL; +  } +   +  free(env_var); +} + +int +debug_file(char *filename) +{ +  if (__debug_fd && fileno(__debug_fd) != -1) { +    fclose(__debug_fd); +  } + +  __debug_fd = fopen(filename, "a"); +  if (!__debug_fd) { +    perror("fopen:"); +    __debug_fd = stderr; +    return 0; +  } + +  return 1; +} + +int +debug_level(int level) +{ +  int tmp = __debug_level; +   +  __debug_level = level; +   +  return tmp; +} + +int +debug_level_get(void) +{ +  return __debug_level; +} + + +void +_hexdump (const char *package, const char* file, int line,  +	  const char* function, const char* data, int len) +{ +  char buf[17]; +  int i; + +  if (_use_debug(LEVEL_HEXDUMP)) { +    fprintf (__debug_fd, "%s%s:\033[m %s(%d): %s: data=%p len=%d\n",  +	    __debug_color, package, file, line, function, data, len); +    for (i = 0; data != NULL && i < len; i++) { +      if (i % 16 == 0)  +	fprintf(__debug_fd, "\033[30m%s:\033[m %04x: ", package, i); +      fprintf(__debug_fd, "%02x ", (unsigned int)(unsigned char)data[i]); +      buf[i % 16] = (data[i] >= 32 && data[i] <= 126) ? data[i] : '.'; +      buf[i % 16 + 1] = '\0'; +      if (i % 4 == 3) fprintf(__debug_fd, " "); +      if (i % 16 == 15) fprintf(__debug_fd, "%s\n", buf); +    } +    if (i % 16 != 0) { +      for (; i % 16 != 0; i++)  +	fprintf (__debug_fd, (i % 4 == 3) ? "    " : "   "); +      fprintf(__debug_fd, "%s\n", buf); +    } +  } +} + +void +_hexdump_n (const char *package, const int n, const char* file, int line,  +	  const char* function, const char* data, int len) +{ +  char buf[17]; +  int i; + +  if (_use_debug(n)) { +    fprintf (__debug_fd, "%s%s:\033[m %s(%d): %s: data=%p len=%d\n",  +	    __debug_color, package, file, line, function, data, len); +    for (i = 0; data != NULL && i < len; i++) { +      if (i % 16 == 0)  +	fprintf(__debug_fd, "\033[30m%s:\033[m %04x: ", package, i); +      fprintf(__debug_fd, "%02x ", (unsigned int)(unsigned char)data[i]); +      buf[i % 16] = (data[i] >= 32 && data[i] <= 126) ? data[i] : '.'; +      buf[i % 16 + 1] = '\0'; +      if (i % 4 == 3) fprintf(__debug_fd, " "); +      if (i % 16 == 15) fprintf(__debug_fd, "%s\n", buf); +    } +    if (i % 16 != 0) { +      for (; i % 16 != 0; i++)  +	fprintf (__debug_fd, (i % 4 == 3) ? "    " : "   "); +      fprintf(__debug_fd, "%s\n", buf); +    } +  } +} + + +void +_hexdump_text (const char *text, +	       const char *package, const char *file, int line,  +	       const char *function, const char *data, int len) +{ +  if (_use_debug(LEVEL_HEXDUMP)) { +    fprintf(__debug_fd, "%s%s: %s(%d): %s: %s\033[m", __debug_color,  +	   package, file, line, function, text); +    _hexdump(package, file, line, function, data, len); +  } +} + + + +void +_error(const char *package, const char *file, int line,  +       const char *function, int fatal, const char *format, ...)  +{ +  char foo[2048]; +  va_list ap; +  va_start(ap, format); +   +  vsnprintf(foo, sizeof(foo) - strlen(format) - 1, format, ap); +  if (_use_debug(0))  +    fprintf(__debug_fd, "\033[31m%s: %s(%d): %s: %s\033[m",  +	   package, file, line, function, foo); +  else +    fprintf(__debug_fd, "%s: %s(%d): %s: %s",  +	   package, file, line, function, foo); +  fflush(__debug_fd); + +  if (fatal) { +    fprintf(__debug_fd, "\033[31mfatal error -- exit programm\033[m\n"); +    exit(1); +  } +   +  va_end(ap); +} + +void +_debug(const char *package, const char *file, int line,  +       const char *function, const char *format, ...) +{ +  char foo[2048]; +  va_list ap; +  va_start(ap, format); +   +  vsnprintf(foo, sizeof(foo) - strlen(format) - 1, format, ap); +   +  if (_use_debug(0)) { +    fprintf(__debug_fd, "%s%s: %s(%d): %s: %s\033[m", +	    ( __debug_color ? __debug_color : ""),  +	    package, file, line, function, foo); +    fflush(__debug_fd); +  } +   +  va_end(ap); +} + +void +_debug_n(const char *package, const int n, const char *file,  +	 int line, const char *function, const char *format, ...) +{ +  char foo[2048]; +  va_list ap; +  va_start(ap, format); +   +  vsnprintf(foo, sizeof(foo) - strlen(format) - 1, format, ap); +   +  if (_use_debug(n)) { +    fprintf(__debug_fd, "%s%s: %s(%d): %s: %s\033[m", +	    ( __debug_color ? __debug_color : ""),  +	    package, file, line, function, foo); +    fflush(__debug_fd); +  } +   +  va_end(ap); +} + +void +_octetstr(const char *package, const char *file, int line,  +	  const char *function, const uint8_t *str, +	  const unsigned int len, const char *what) +{ +  if (_use_debug(LEVEL_HEXDUMP)) { +    unsigned int i; +     +    fprintf(__debug_fd, "%s%s: %s(%d): %s: ",  +	    package, file, function, line, (what?what:"")); +    for (i = 0; i < len; i++) { +      if (i < (len - 1)) +	fprintf(__debug_fd, "%03d.", str [i]); +      else +	fprintf(__debug_fd, "%03d", str [i]); +    } +  } +} + +int +_use_debug(int level) +{ +  if (__debug_level == -1) return 0; +   +  if (level <= __debug_level) { +    return 1; +  } +     +  return 0; +} + +/* end of debug.c */ + + + + + diff --git a/libmpio/debug.h b/libmpio/debug.h new file mode 100644 index 0000000..4c7df21 --- /dev/null +++ b/libmpio/debug.h @@ -0,0 +1,102 @@ +/*  + * debug.h + * + * Author: Dirk Meyer  <dmeyer@tzi.de> + *         Andreas Büsching <crunchy@tzi.de> + * + * $Id: debug.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + */ + +#ifndef _MPIO_DEBUG_H_ +#define _MPIO_DEBUG_H_ + +// if DPACKAGE is not definied use PACKAGE or "unknown" + +#ifndef DPACKAGE + +#ifdef PACKAGE +#define DPACKAGE PACKAGE +#else +#define DPACKAGE unknown +#endif + +#endif + +#include <stdio.h> + +#ifdef sun +#include <sys/int_types.h> +#else +#include <stdint.h> +#endif + +#ifndef PBOOL +#define PBOOL(x) (x)?"True":"False" +#endif + +#define UNUSED(x) (x = x) + +#define debugn(n,args...) \ +   _debug_n(DPACKAGE, n, __FILE__, __LINE__, __FUNCTION__, args) + +#define debug(args...) \ +   _debug(DPACKAGE, __FILE__, __LINE__, __FUNCTION__, args) + +#define debug_error(fatal,args...) \ +   _error(DPACKAGE, __FILE__, __LINE__, __FUNCTION__, fatal, args) + +#define hexdump(data,len) \ +   _hexdump(DPACKAGE, __FILE__, __LINE__, __FUNCTION__, data, len) + +#define hexdumpn(n,data,len) \ +  _hexdump_n(DPACKAGE, n, __FILE__, __LINE__, __FUNCTION__, data, len) + +#define hexdump_text(text,data,len) \ +   _hexdump_text(text, DPACKAGE, __FILE__, __LINE__, __FUNCTION__, data, len) + +#define octetstrdump(data,len) \ +   _octetstr(DPACKAGE, __FILE__, __LINE__, __FUNCTION__, data, len) + +#define ipadr_dump(data,len,text) \ +   _octetstr(DPACKAGE, __FILE__, __LINE__, __FUNCTION__, data, len, text) + +#define use_debug() \ +   use_debug(DPACKAGE) + + +#define with_special_debug(what) \ +   _use_debug(DPACKAGE, what) + +void debug_init(void); +int debug_file(char *filename); +int debug_level(int level); +int debug_level_get(void); + +void _debug(const char *package, const char* file, int line,  +	    const char* function, const char *format, ...); + +void _debug_n(const char *package, const int n, const char* file,  +	      int line, const char* function, const char *format, ...); + +void _hexdump (const char *package, const char* file, int line,  +	       const char* function, const char* data, int len); + +void _hexdump_n (const char *package, const int n, const char* file, int line,  +		 const char* function, const char* data, int len); + +void _hexdump_text (const char *text,  +		    const char *package, const char* file, int line,  +		    const char* function, const char* data, int len); + +void _error(const char *package, const char* file, int line,  +	    const char* function, int fatal, const char *format, ...); + +void _octetstr(const char *package, const char* file, int line,  +	       const char* function, const uint8_t *str,  +	       const unsigned int len, const char *what); + +int _use_debug(int level); + +#endif /* _MPIO_DEBUG_H_ */ + +/* end of debug.h */ diff --git a/libmpio/defs.h b/libmpio/defs.h new file mode 100644 index 0000000..8498f22 --- /dev/null +++ b/libmpio/defs.h @@ -0,0 +1,192 @@ +/* -*- linux-c -*- */ + +/*  + * $Id: defs.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * uses code from mpio_stat.c by + * Yuji Touya (salmoon@users.sourceforge.net) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_DEFS_H_ +#define _MPIO_DEFS_H_ + +typedef unsigned char  BYTE; +typedef unsigned short WORD; +typedef unsigned int   DWORD; + +/* Memory selection */ +typedef enum { MPIO_INTERNAL_MEM = 0x01, +	       MPIO_EXTERNAL_MEM = 0x10 } mpio_mem_t; + +/* USB commands */ +typedef enum { GET_VERSION      = 0x01, +	       GET_BLOCK        = 0x02, +               PUT_SECTOR       = 0x03, +               DEL_BLOCK        = 0x04, +               GET_SECTOR       = 0x06, +               GET_SPARE_AREA   = 0x07, +               PUT_BLOCK        = 0x08 } mpio_cmd_t; + +/* file types on internal memory */ +/* found in the code of salmoon, are these needed? -mager */ +typedef enum { FTYPE_CONF  = 'C', +	       FTYPE_FONT  = 'F', +               FTYPE_OTHER = 'H', +               FTYPE_ENTRY = 'R' } mpio_file_t; + +#ifndef NULL +#define NULL             0 +#endif + +#define MPIO_DEVICE "/dev/usb/mpio" + +#define SECTOR_SIZE      0x200 +#define SECTOR_ECC       0x040 +#define SECTOR_TRANS     (SECTOR_SIZE + SECTOR_ECC) + +#define BLOCK_SECTORS    0x20 +#define BLOCK_SIZE       (SECTOR_SIZE * BLOCK_SECTORS) +#define BLOCK_TRANS      (BLOCK_SIZE + (SECTOR_ECC * BLOCK_SECTORS)) + +#define DIR_NUM          0x10 +#define DIR_SIZE         (SECTOR_SIZE*DIR_NUM) +#define DIR_ENTRY_SIZE   0x20 + +#define SMALL_MEM        0x02 + +#define CMD_SIZE         0x40 + +#define OFFSET_CIS       0x20 +#define OFFSET_MBR       0x40 + +#define INFO_LINE        81 + +/* get formatted information, about the MPIO player */ + +typedef struct { +  BYTE firmware_id[INFO_LINE]; +  BYTE firmware_version[INFO_LINE]; +  BYTE firmware_date[INFO_LINE]; + +  BYTE firmware_mem_internal[INFO_LINE]; +  BYTE firmware_mem_external[INFO_LINE]; +   +} mpio_info_t; + +/* view of the MPIO firmware */ +typedef struct { +  /* everything we get from GET_VERSION */ +  BYTE id[12]; +  BYTE major[3]; +  BYTE minor[3]; +  BYTE year[5]; +  BYTE month[3]; +  BYTE day[3];   +} mpio_firmware_t; + +/* */ +typedef struct { +  DWORD  NumCylinder; +  DWORD  NumHead; +  DWORD  NumSector; +  DWORD  SumSector; +} mpio_disk_phy_t; + +/* view of a SmartMedia(tm) card */ +typedef struct { +  BYTE		id; +  BYTE		manufacturer; +  BYTE		size;		/* MB */     +  BYTE          chips;          /* this is the hack for +                                   MPIO internal representation, because +				   there might be two chips involved */ +   +  /*  only needed for external SmartMedia cards */ +  mpio_disk_phy_t geo; +   +  BYTE cis[SECTOR_SIZE];        +  BYTE mbr[SECTOR_SIZE];	/* Master Boot Record */ +  BYTE pbr[SECTOR_SIZE];	/* Partition Boot Record */ + +  int  pbr_offset;             /* sector offset for the PBR */ +  int  fat_offset;             /* sector offset for the FAT */ +  int  dir_offset; + +  /* these are needed for internal and external cards */ +  int  max_cluster;            /* # of clusters actually available */ +  int  fat_size;               /* # sectors for FAT */   +  int  fat_nums;               /* # of FATs */ +  BYTE * fat;                  /* *real FAT (like in block allocation :-) */ + +  /* seems to be a fixed size according to the  +     Samsung documentation */ +  BYTE dir[DIR_SIZE];                  /* file index */ +} mpio_smartmedia_t; + + +/* view of the MPIO-* */ +typedef struct { +  BYTE version[CMD_SIZE]; +   +  int fd; + +  mpio_firmware_t firmware;   + +  mpio_smartmedia_t internal; +  mpio_smartmedia_t external; +} mpio_t; + +/* these are copied from: + * http://www.linuxhq.com/kernel/v2.4/doc/filesystems/vfat.txt.html + * + */ + +typedef struct  { // Short 8.3 names  +  unsigned char name[8];          // file name  +  unsigned char ext[3];           // file extension  +  unsigned char attr;             // attribute byte  +  unsigned char lcase;		// Case for base and extension +  unsigned char ctime_ms;		// Creation time, milliseconds +  unsigned char ctime[2];		// Creation time +  unsigned char cdate[2];		// Creation date +  unsigned char adate[2];		// Last access date +  unsigned char reserved[2];	// reserved values (ignored)  +  unsigned char time[2];          // time stamp  +  unsigned char date[2];          // date stamp  +  unsigned char start[2];         // starting cluster number  +  unsigned char size[4];          // size of the file  +} mpio_dir_entry_t; + +typedef struct  { // Up to 13 characters of a long name  +  unsigned char id;               // sequence number for slot  +  unsigned char name0_4[10];      // first 5 characters in name  +  unsigned char attr;             // attribute byte +  unsigned char reserved;         // always 0  +  unsigned char alias_checksum;   // checksum for 8.3 alias  +  unsigned char name5_10[12];     // 6 more characters in name +  unsigned char start[2];         // starting cluster number +  unsigned char name11_12[4];     // last 2 characters in name +} mpio_dir_slot_t; + +#endif /* _MPIO_DEFS_H_ */ + diff --git a/libmpio/directory.c b/libmpio/directory.c new file mode 100644 index 0000000..b14dd6d --- /dev/null +++ b/libmpio/directory.c @@ -0,0 +1,509 @@ +/*  + * + * $Id: directory.c,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include <unistd.h> +#include <iconv.h> + +#include "debug.h" +#include "io.h" +#include "mpio.h" +#include "directory.h" + +/* directory operations */ +BYTE * +mpio_directory_open(mpio_t *m, BYTE mem) +{   +  BYTE *out;   +  if (mem == MPIO_EXTERNAL_MEM) { +    if (m->external.id)  {  +      out = m->external.dir; +    } else { +      return NULL; +    } +  } else {     +    out = m->internal.dir; +  } + +  if (out[0] == 0x00) +    return NULL; +   +  return out;   +} + +int +mpio_dentry_get_size(mpio_t *m, BYTE *buffer) +{ +  mpio_dir_entry_t *dentry; + +  if (!buffer) +    return -1;   + +  UNUSED(m); +   +  dentry = (mpio_dir_entry_t *)buffer; + +  if ((dentry->name[0] & 0x40)    &&  +      (dentry->attr == 0x0f)      && +      (dentry->start[0] == 0x00)  && +      (dentry->start[1] == 0x00)) { +    dentry++;     +    while ((dentry->attr == 0x0f)      && +	   (dentry->start[0] == 0x00)  && +	   (dentry->start[1] == 0x00)) { +      /* this/these are vfat slots */ +      dentry++; +    } +  }   +  dentry++; +   +  return(((BYTE *)dentry) - buffer); +}   + +BYTE* +mpio_dentry_next(mpio_t *m, BYTE *buffer) +{ +  int size; +  BYTE *out; +   +  size = mpio_dentry_get_size(m, buffer); +  if (size<0) +    return NULL; +   +  out = buffer + size; +   +  if (*out == 0x00) +    return NULL;   +   +  return out; +}       + +int  +mpio_dentry_get_raw(mpio_t *m, BYTE *dentry, BYTE *buffer, int bufsize) +{ +  int size; +   +  size = mpio_dentry_get_size(m, buffer); +   +  if (size < 0) +    return size; +   +  if (size > bufsize) +    return -2; +   +  memcpy(buffer, dentry, size); +   +  return size; +} + +void +mpio_dentry_copy_from_slot(BYTE *buffer, mpio_dir_slot_t *slot) +{ +  memcpy(buffer, slot->name0_4, 10); +  memcpy(buffer + 10, slot->name5_10, 12); +  memcpy(buffer + 22, slot->name11_12, 4); +} + +void +mpio_dentry_copy_to_slot(BYTE *buffer, mpio_dir_slot_t *slot) +{ +  memcpy(slot->name0_4, buffer, 10); +  memcpy(slot->name5_10, buffer + 10, 12); +  memcpy(slot->name11_12, buffer + 22, 4); +} + +int +mpio_dentry_get(mpio_t *m, BYTE *buffer,                    +		BYTE *filename, int filename_size, +		WORD *year, BYTE *month, BYTE *day, +		BYTE *hour, BYTE *minute, DWORD *fsize) +{ +  BYTE filename_8_3[12]; +   +  return mpio_dentry_get_real(m, buffer, filename, filename_size,  +			      filename_8_3, +			      year, month, day, hour, minute, fsize); +} +   +/* TODO: please clean me up !!! */ +int +mpio_dentry_get_real(mpio_t *m, BYTE *buffer,                    +		     BYTE *filename, int filename_size, +		     BYTE filename_8_3[12], +		     WORD *year, BYTE *month, BYTE *day, +		     BYTE *hour, BYTE *minute, DWORD *fsize) +{ +  int date, time;   +  int vfat = 0;   +  int num_slots = 0;   +  int slots = 0; +  int in = 0, out = 0; +  mpio_dir_entry_t *dentry; +  mpio_dir_slot_t  *slot; +  BYTE *unicode = 0; +  BYTE *uc; +  BYTE *fname = 0; +  iconv_t ic; +   +  if (buffer == NULL) +    return -1;   + +  dentry = (mpio_dir_entry_t *)buffer; + +  if ((dentry->name[0] & 0x40)    &&  +      (dentry->attr == 0x0f)      && +      (dentry->start[0] == 0x00)  && +      (dentry->start[1] == 0x00)) { +    num_slots = (mpio_dentry_get_size(m, buffer) / 0x20) - 1; +    slots = num_slots - 1; +    dentry++; +    vfat++;     +    unicode = malloc(256); +    uc = unicode; +    fname = filename; +    slot = (mpio_dir_slot_t *)buffer; +    mpio_dentry_copy_from_slot(unicode + (26 * slots), slot); +    slots--; + +    while ((dentry->attr == 0x0f)      && +	   (dentry->start[0] == 0x00)  && +	   (dentry->start[1] == 0x00)) { +      /* this/these are vfat slots */ +      slot = (mpio_dir_slot_t *)dentry; +      mpio_dentry_copy_from_slot((unicode + (26 * slots)), slot); +      dentry++; +      slots--; +    } +  }   + +  if (vfat) { +    ic = iconv_open("ASCII", "UNICODE"); +    in = num_slots * 26; +    out = num_slots * 13; +    memset(fname, 0, filename_size); +    iconv(ic, (char **)&uc, &in, (char **)&fname, &out); +    iconv_close(ic); +    free(unicode); +  } else { +    memcpy(filename_8_3, dentry->name, 8); +    filename_8_3[0x08] = '.';	 +    memcpy(filename_8_3 + 0x09, dentry->ext, 3); +    filename_8_3[0x0c] = 0; + +    if (filename_size >= 12) { +      snprintf(filename, 13, "%s", filename_8_3);	     +    } else { +      snprintf(filename, 12, "%s", "ERROR"); +    } + +  } + +  date  = (dentry->date[1] * 0x100) + dentry->date[0]; +  *year  = date / 512 + 1980; +  *month = (date / 32) & 0xf; +  *day   = date & 0x1f; +   +  time  = (dentry->time[1] * 0x100) + dentry->time[0]; +  *hour  = time / 2048; +  *minute= (time / 32) & 0x3f; + +  *fsize = dentry->size[3]; +  *fsize *= 0x100; +  *fsize += dentry->size[2]; +  *fsize *= 0x100; +  *fsize += dentry->size[1]; +  *fsize *= 0x100; +  *fsize += dentry->size[0]; +   +  return(((BYTE *)dentry) - buffer); +} + +/* read "size" sectors of fat into the provided buffer */ +int +mpio_rootdir_read (mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm;   +  BYTE recvbuff[SECTOR_SIZE]; +  int i; + +  if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; +  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; +   +  for (i = 0; i < DIR_NUM; i++) { +    if (mpio_io_sector_read(m, mem, +			    (sm->dir_offset + i), sm->size, 0, recvbuff)) +      return 1; + +    memcpy(sm->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE); +  } + +  return (0); +} + +int +mpio_rootdir_clear (mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm;   + +  if (mem == MPIO_INTERNAL_MEM) sm=&m->internal; +  if (mem==MPIO_EXTERNAL_MEM) sm=&m->external; + +  memset(sm->dir, 0x00, DIR_SIZE); + +  return 0; +} + +WORD +mpio_dentry_get_startsector(mpio_t *m, BYTE *p) +{ +  int s; +  int sektor; +  mpio_dir_slot_t *dentry; + +  s = mpio_dentry_get_size(m, p); +  s -= DIR_ENTRY_SIZE ; + +  dentry = (mpio_dir_slot_t *)p; + +  while (s != 0) { +    dentry++; +    s -= DIR_ENTRY_SIZE ; +  } + +  sektor = dentry->start[1] * 0x100 + dentry->start[0]; + +  return sektor;  +} + +int +mpio_dentry_put(mpio_t *m, BYTE mem, +		BYTE *filename, int filename_size, +		WORD year, BYTE month, BYTE day, +		BYTE hour, BYTE minute, DWORD fsize, WORD ssector) +{ +  BYTE *unicode = 0; +  BYTE *back, *fback; +  BYTE *fname = 0; +  iconv_t ic; +  int in = 0, out = 0; +  int fin = 0, fout = 0; +  int count = 0; +  BYTE index; +   +  BYTE *p; +  mpio_dir_entry_t *dentry; +  mpio_dir_slot_t  *slot; +   +  p = mpio_directory_open(m, mem); +  if (p) { +    while (*p != 0x00) +      p += 0x20; +  } else { +    if (mem == MPIO_EXTERNAL_MEM)  +      p = m->external.dir; +    if (mem == MPIO_INTERNAL_MEM)  +      p = m->internal.dir; +  } + +  /* generate vfat filename in UNICODE */ +  ic = iconv_open("UNICODE", "ASCII"); +  fin = in = filename_size + 1; +  fout = out = filename_size * 2 + 2 + 26; +  fname = malloc(in); +  fback = fname; +  unicode = malloc(out); +  back = unicode; + +  memset(fname, 0, in); +  snprintf(fname, in, "%s", filename); +  memset(unicode, 0xff, out); +  iconv(ic, (char **)&fback, &fin, (char **)&back, &fout); +  iconv_close(ic); +  hexdump(fname, in); +  hexdump(unicode, out); + +  back = unicode + 2; +   +  count = filename_size / 13; +  if (filename_size % 13) +    count++; + +  slot = (mpio_dir_slot_t *)p; + +  index = 0x40 + count; +  while (count > 0) { +    mpio_dentry_copy_to_slot(back + ((count - 1) * 26), slot); +    hexdump((char *)back + ((count - 1) * 26), 0x20); +    slot->id = index; +    slot->attr = 0x0f; +    slot->reserved = 0x00; +    slot->start[0] = 0x00; +    slot->start[1] = 0x00; +    /* FIXME: */ +    slot->alias_checksum = 0x00;   // checksum for 8.3 alias  + +    hexdump((char *)slot, 0x20); +     +    slot++; +    count--; +    index = count; +  } + +/*   memcpy(p, m->internal.dir+0x220, 0x20); */ + +/*   p+=0x20; */ +  dentry = (mpio_dir_entry_t *)slot; +  memcpy(dentry->name,"AAAAAAAA",8); +  memcpy(dentry->ext,"MP3",3); +  dentry->attr = 0x20; +  dentry->lcase = 0x00; +  dentry->ctime_ms = 0x00; +  dentry->ctime[0] = 0x37; +  dentry->ctime[1] = 0x7b; +  dentry->cdate[0] = 0xfb; +  dentry->cdate[1] = 0x2c; +  dentry->adate[0] = 0xfd; +  dentry->adate[1] = 0x2c; +  dentry->reserved[0] = 0x00; +  dentry->reserved[1] = 0x00;   +  dentry->time[0] = 0x38; +  dentry->time[1] = 0x7b; +  dentry->date[0] = 0xfb; +  dentry->date[1] = 0x2c; +  dentry->size[0] = fsize & 0xff; +  dentry->size[1] = (fsize / 0x100) & 0xff; +  dentry->size[2] = (fsize / 0x10000) & 0xff; +  dentry->size[3] = (fsize / 0x1000000) & 0xff; +  dentry->start[0] = ssector & 0xff; +  dentry->start[1] = ssector / 0x100; + +  free(unicode); +  free(fname); + +  /* what do we want to return? */ +  return 0; +} + +BYTE * +mpio_dentry_find_name_8_3(mpio_t *m, BYTE mem, BYTE *filename) +{ +  BYTE *p; +  BYTE bdummy; +  WORD wdummy; +  BYTE fname[129]; +  BYTE fname_8_3[13]; +  DWORD ddummy; +  BYTE *found = 0; +   +  p = mpio_directory_open(m, mem); +  while ((p) && (!found)) { +    mpio_dentry_get_real (m, p, +			  fname, 128, +			  fname_8_3, +			  &wdummy, &bdummy, &bdummy, +			  &bdummy, &bdummy, &ddummy); +    if ((strcmp(fname_8_3, filename) == 0) && +	(strcmp(filename,fname_8_3) == 0)) { +      found = p; +      p = NULL; +    } +     +    p = mpio_dentry_next(m, p); +  } +	  +  return found; +} + +BYTE * +mpio_dentry_find_name(mpio_t *m, BYTE mem, BYTE *filename) +{ +  BYTE *p; +  BYTE bdummy; +  WORD wdummy; +  BYTE fname[129]; +  DWORD ddummy; +  BYTE *found = 0; +   +  p = mpio_directory_open(m, mem); +  while ((p) && (!found)) { +    mpio_dentry_get (m, p, +		     fname, 128, +		     &wdummy, &bdummy, &bdummy, +		     &bdummy, &bdummy, &ddummy); +    if ((strcmp(fname,filename) == 0) && (strcmp(filename,fname) == 0)) { +      found = p; +      p = NULL; +    } +     +    p = mpio_dentry_next(m, p); +  } +	  +  return found; +} + + +int	 +mpio_dentry_delete(mpio_t *m, BYTE mem, BYTE *filename) +{ +  mpio_smartmedia_t *sm; +  BYTE *start; +  int  size; +  BYTE tmp[DIR_SIZE]; + +  if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; +  if (mem==MPIO_EXTERNAL_MEM) sm = &m->external; + +  start = mpio_dentry_find_name(m, mem, filename); +   +  /* second try */ +  if (!start) +    start = mpio_dentry_find_name_8_3(m, mem, filename); + +  if (!start) { +    debug("could not find file: %s\n", filename); +    return 0;     +  }  + +  size = mpio_dentry_get_size(m, start); +   +  if (size <= 0) { +    debug("fatal error in mpio_dentry_delete\n"); +    return 0;     +  } + +  debugn(5, "size: %2x\n", size); + +  /* clear new buffer */ +  memset(tmp, 0, DIR_SIZE); +  /* copy before delete */ +  if (start != sm->dir) +    memcpy(tmp, sm->dir, (start - (sm->dir))); +  /* copy after delete */ +  memcpy(tmp + (start - (sm->dir)), (start + size), +	 (sm->dir + DIR_SIZE - (start + size))); + +  memcpy(sm->dir, tmp, DIR_SIZE); +   +  return 0; +} diff --git a/libmpio/directory.h b/libmpio/directory.h new file mode 100644 index 0000000..ddce24c --- /dev/null +++ b/libmpio/directory.h @@ -0,0 +1,50 @@ +/*  + * + * $Id: directory.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_DIRECTORY_H_ +#define _MPIO_DIRECTORY_H_ + +/* root directory operations */ +int     mpio_rootdir_read (mpio_t *, mpio_mem_t); +int	mpio_rootdir_clear (mpio_t *, mpio_mem_t); +int     mpio_rootdir_format(mpio_t *, mpio_mem_t); + +/* operations on a single directory entry */ +int	mpio_dentry_get_size(mpio_t *, BYTE *); +int	mpio_dentry_get_raw(mpio_t *, BYTE *, BYTE *, int); +WORD    mpio_dentry_get_startsector(mpio_t *, BYTE *); +int	mpio_dentry_put(mpio_t *, BYTE, BYTE *, int, +			WORD, BYTE, BYTE, BYTE, BYTE, DWORD, WORD); +BYTE *	mpio_dentry_find_name_8_3(mpio_t *, BYTE, BYTE *); +BYTE *	mpio_dentry_find_name(mpio_t *, BYTE, BYTE *); +int	mpio_dentry_delete(mpio_t *, BYTE, BYTE *); + +/* helper functions */ +void    mpio_dentry_copy_from_slot(BYTE *, mpio_dir_slot_t *); +void    mpio_dentry_copy_to_slot(BYTE *, mpio_dir_slot_t *); +int	mpio_dentry_get_real(mpio_t *, BYTE *, BYTE *, int, BYTE[12], +			     WORD *, BYTE *, BYTE *, BYTE *, BYTE *, DWORD *); + +#endif /* _MPIO_DIRECTORY_H_ */ diff --git a/libmpio/ecc.c b/libmpio/ecc.c new file mode 100644 index 0000000..e7429a5 --- /dev/null +++ b/libmpio/ecc.c @@ -0,0 +1,203 @@ +/*  + * + * $Id: ecc.c,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include "ecc.h" +#include "debug.h" + +BYTE get_bit(BYTE, int); + +/* TODO: fix correctable errors */ + +inline BYTE  +get_bit(BYTE d, int offset) +{ +  return ((d >> offset) & 0x01 ); +} + +int  +mpio_ecc_256_gen(BYTE *data, BYTE *ecc) +{ +  BYTE p1, p1_; +  BYTE p2, p2_; +  BYTE p4, p4_; + +  BYTE p08, p08_; +  BYTE p16, p16_; +  BYTE p32, p32_; +  BYTE p64, p64_; + +  BYTE p0128, p0128_; +  BYTE p0256, p0256_; +  BYTE p0512, p0512_; +  BYTE p1024, p1024_; + +  int i, j; + +  /* init */ +  p1=p1_=0; +  p2=p2_=0; +  p4=p4_=0; + +  p08=p08_=0; +  p16=p16_=0; +  p32=p32_=0; +  p64=p64_=0; + +  p0128=p0128_=0; +  p0256=p0256_=0; +  p0512=p0512_=0; +  p1024=p1024_=0; + +  /* vertical */ +  for (i=0; i<256; i++) { +     +    /* p1, p1_ */ +    p1 ^= (get_bit(data[i], 7) ^ +	   get_bit(data[i], 5) ^ +	   get_bit(data[i], 3) ^ +	   get_bit(data[i], 1)); +    p1_^= (get_bit(data[i], 6) ^ +	   get_bit(data[i], 4) ^ +	   get_bit(data[i], 2) ^ +	   get_bit(data[i], 0)); + +    /* p2, p2_ */ +    p2 ^= (get_bit(data[i], 7) ^ +	   get_bit(data[i], 6) ^ +	   get_bit(data[i], 3) ^ +	   get_bit(data[i], 2)); +    p2_^= (get_bit(data[i], 5) ^ +	   get_bit(data[i], 4) ^ +	   get_bit(data[i], 1) ^ +	   get_bit(data[i], 0)); + +    /* p4, p4_ */ +    p4 ^= (get_bit(data[i], 7) ^ +	   get_bit(data[i], 6) ^ +	   get_bit(data[i], 5) ^ +	   get_bit(data[i], 4)); +    p4_^= (get_bit(data[i], 3) ^ +	   get_bit(data[i], 2) ^ +	   get_bit(data[i], 1) ^ +	   get_bit(data[i], 0)); +  } + +  /* horizontal */ +  for (i=0; i<8; i++) { +     +    for (j=0; j<256; j++) { +   +      /* p08, p08_ */ +      if ((j & 0x01) == 0)  +	p08_^= get_bit(data[j], i); +      if ((j & 0x01) == 1)  +	p08 ^= get_bit(data[j], i); +       +      /* p16, p16_ */ +      if (((j/2) & 0x01) == 0) +	p16_^= get_bit(data[j], i); +      if (((j/2) & 0x01) == 1) +	p16^= get_bit(data[j], i); + +      /* p32, p32_ */ +      if (((j/4) & 0x01) == 0) +	p32_^= get_bit(data[j], i); +      if (((j/4) & 0x01) == 1) +	p32^= get_bit(data[j], i); + +      /* p64, p64_ */ +      if (((j/8) & 0x01) == 0) +	p64_^= get_bit(data[j], i); +      if (((j/8) & 0x01) == 1) +	p64^= get_bit(data[j], i); + + +      /* p0128, p0128_ */ +      if (((j/16) & 0x01) == 0)  +	p0128_^= get_bit(data[j], i); +      if (((j/16) & 0x01) == 1)  +	p0128 ^= get_bit(data[j], i); +       +      /* p0256, p0256_ */ +      if (((j/32) & 0x01) == 0) +	p0256_^= get_bit(data[j], i); +      if (((j/32) & 0x01) == 1) +	p0256^= get_bit(data[j], i); + +      /* p0512, p0512_ */ +      if (((j/64) & 0x01) == 0) +	p0512_^= get_bit(data[j], i); +      if (((j/64) & 0x01) == 1) +	p0512^= get_bit(data[j], i); + +      /* p1024, p1024_ */ +      if (((j/128) & 0x01) == 0) +	p1024_^= get_bit(data[j], i); +      if (((j/128) & 0x01) == 1) +	p1024^= get_bit(data[j], i); + +    } +  }   + +  ecc[0]=~((p64 << 7) | (p64_ << 6) |  +	   (p32 << 5) | (p32_ << 4) | +	   (p16 << 3) | (p16_ << 2) | +	   (p08 << 1) | (p08_ << 0));   + +  ecc[1]=~((p1024 << 7) | (p1024_ << 6) |  +	   (p0512 << 5) | (p0512_ << 4) | +	   (p0256 << 3) | (p0256_ << 2) | +	   (p0128 << 1) | (p0128_ << 0));   + +  ecc[2]=~((p4 << 7) | (p4_ << 6) |  +	   (p2 << 5) | (p2_ << 4) | +	   (p1 << 3) | (p1_ << 2));   + +  return 0; +} + + +int +mpio_ecc_256_check(BYTE *data, BYTE *ecc) +{ +  BYTE own_ecc[3]; +  mpio_ecc_256_gen(data, own_ecc); +  if ((own_ecc[0]^ecc[0])| +      (own_ecc[1]^ecc[1])| +      (own_ecc[2]^ecc[2])) { +    debug("ECC %2x %2x %2x vs. %2x %2x %2x\n",  +	  ecc[0], ecc[1], ecc[2], own_ecc[0], own_ecc[1], own_ecc[2]); +    debugn(2, "ECC Error detected\n"); +    debugn(2, "ECC Correction code not in place yet, Sorry\n"); +    debugn(3, "got   ECC: %2x %2x %2x\n", ecc[0], ecc[1], ecc[2]); +    debugn(3, "calc. ECC: %2x %2x %2x\n", own_ecc[0], own_ecc[1], own_ecc[2]); +  } +   +  return 0;   +} + + +   + diff --git a/libmpio/ecc.h b/libmpio/ecc.h new file mode 100644 index 0000000..8ac98ad --- /dev/null +++ b/libmpio/ecc.h @@ -0,0 +1,36 @@ +/*  + * + * $Id: ecc.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_ECC_H_ +#define _MPIO_ECC_H_ + +#include "defs.h" + +/* 256 Bytes Data, 3 Byte ECC to generate */ +int	mpio_ecc_256_gen(BYTE *, BYTE *); +/* 256 Bytes Data, 3 Bytes ECC to check and possibly correct */ +int	mpio_ecc_256_check(BYTE *, BYTE*); + +#endif diff --git a/libmpio/fat.c b/libmpio/fat.c new file mode 100644 index 0000000..c978b2b --- /dev/null +++ b/libmpio/fat.c @@ -0,0 +1,414 @@ +/*  + * + * $Id: fat.c,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include "fat.h" +#include "io.h" +#include "debug.h" + +#include <string.h> +#include <stdlib.h> + +int +mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem) +{ +  BYTE *pe;  /* partition entry */ +  BYTE *bpb; /* BIOS Parameter Block */ + +  mpio_smartmedia_t *sm;   + +  int sector, head, cylinder, total_sector; +  long temp; + +  if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; +  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + +  /* TODO: check a few things more, just to be sure */ + +  /* read CIS (just in case it might me usefull) */ +  /* fixed @ offset 0x20 */ +  if (mpio_io_sector_read(m, mem, 0x20, sm->size, 0, sm->cis)) { +    debug("error reading CIS\n");     +    return 1; +  } + +  /* read MBR */ +  /* fixed @ offset 0x40 */ +  if (mpio_io_sector_read(m, mem, 0x40, sm->size, 0, sm->mbr)) { +    debug("error reading MBR\n");     +    return 1; +  } + +  if ((sm->mbr[0x1fe] != 0x55) || (sm->mbr[0x1ff] != 0xaa)) { +    debug("This is not the MBR!\n"); +    return 1; +  } +   +  /* always use the first partition */ +  /* we probably don't need to support others */ +  pe = sm->mbr + 0x1be; +   +  head = (int)(*(pe+0x01) & 0xff); +  sector = (int)(*(pe+0x02) & 0x3f); +  cylinder = (int)((*(pe+0x02) >> 6) * 0x100 + *(pe + 0x03)); +   +  sm->pbr_offset=(cylinder * sm->geo.NumHead + head ) * +    sm->geo.NumSector + sector - 1 + OFFSET_MBR;  + +  /* read PBR */ +  if (mpio_io_sector_read(m, mem, sm->pbr_offset, sm->size, 0, sm->pbr)) +      return 1; + +  if ((sm->pbr[0x1fe] != 0x55) || (sm->pbr[0x1ff] != 0xaa)) { +    debug("This is not the PBR!\n"); +    return 1; +  } + +  if (strncmp((sm->pbr+0x36),"FAT", 3) != 0) { +    debug("Did not find an FAT signature, *not* good!, aborting!\n"); +    exit (1); +  } + +  bpb = sm->pbr + 0x0b; +   +  total_sector = (*(sm->pbr+0x14) * 0x100 + *(sm->pbr + 0x13)); +  if (!total_sector) +      total_sector = (*(sm->pbr+0x23) * 0x1000000 +  +		      *(sm->pbr+0x22) * 0x10000   + +		      *(sm->pbr+0x21) * 0x100     + +		      *(sm->pbr+0x20)); + +   /* 128 MB need 2 Bytes instead of 1.5 */ +   if (sm->size != 128) +     temp = ((total_sector / 0x20 * 0x03 / 0x02 / 0x200) + 0x01);    +   else +     temp = ((total_sector / 0x20 * 0x02 / 0x200) + 0x01);    + +  sm->max_cluster = (total_sector / BLOCK_SECTORS); +  debugn(2,"max_cluster: %d\n", sm->max_cluster); +  sm->fat_offset = sm->pbr_offset + 0x01; +  sm->fat_size = temp; +  sm->fat_nums = *(sm->pbr + 0x10); +  sm->dir_offset = sm->pbr_offset + 0x01 +  temp * 2; + +  return 0;   +} + +/* read "fat_size" sectors of fat into the provided buffer */ +int +mpio_fat_read (mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm; +  BYTE recvbuff[SECTOR_SIZE]; +  int i; + +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    if (mpio_io_spare_read(m, mem, 0, (sm->size / sm->chips), 0, sm->fat, +			   (sm->fat_size * SECTOR_SIZE))) +      return 1; +    return 0; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; +   +  for (i = 0; i < sm->fat_size; i++) { +    if (mpio_io_sector_read(m, mem, (sm->fat_offset + i), +			    sm->size, 0, recvbuff)) +      return 1; + +    memcpy(sm->fat + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE); +  } + +  return (0); +} + +int +mpio_fat_entry_free(mpio_t *m, mpio_mem_t mem, int entry ) +{ +  int e; +  mpio_smartmedia_t *sm; +   +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    e = entry * 0x10; + +    if((sm->fat[e+0] == 0xff) && +       (sm->fat[e+1] == 0xff) && +       (sm->fat[e+2] == 0xff)) +      return 1; +  } + +  if (mem == MPIO_EXTERNAL_MEM) {     +    sm = &m->internal; +    if (mpio_fat_entry_read(m, mem, entry) == 0) +      return 1; +  } + +  return 0; +} + +int +mpio_fat_entry_read(mpio_t *m, mpio_mem_t mem, int entry ) +{ +  mpio_smartmedia_t *sm;   +  int e;   +  int v; +   +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    e = entry;     +    e = e * 0x10 + 7; +    if((sm->fat[e+0] == 0xff) && +       (sm->fat[e+1] == 0xff) && +       (sm->fat[e+2] == 0xff) && +       (sm->fat[e+3] == 0xff)) +      return 0xffffffff; +        +    v = (sm->fat[e+1] * 0x10000 + +	 sm->fat[e+2] * 0x100 + +	 sm->fat[e+3]) / 0x20 + sm->fat[e+0] * 0x1000000;     +   +    return v;  +  } +   +  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + +  if (sm->size == 128) { +    /* 2 Byte per entry */ +    e = entry * 2; +    v = sm->fat[e + 1] * 0x100 + sm->fat[e]; +  } else { +    /* 1.5 Byte per entry */ +    /* Nibble order: x321 */ +    e = (entry * 3 / 2); +/*     printf("mager: byte (%d/%d)\n", e, e+1); */ +    if ((entry & 0x01) == 0) { +      /* LLxH */ +      /* 21x3 */ +      v = (sm->fat[e + 1] & 0x0f) * 0x100 + sm->fat[e]; +    } else { +      /* 1x32 */ +      v = (sm->fat[e + 1] * 0x10) + (sm->fat[e] >> 4); +    }     +  } + +  return v;   +} + +int  +mpio_fat_entry_write(mpio_t *m, mpio_mem_t mem, int entry, WORD value) +{ +  mpio_smartmedia_t *sm;   +  int e; +  BYTE backup; + +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +  } +  if (sm->size == 128) { +    /* 2 Byte per entry */ +    e = entry * 2; +    sm->fat[e]   = value & 0xff; +    sm->fat[e + 1] = (value >> 8 ) & 0xff; +     +  } else { +    /* 1.5 Byte per entry */ +    e = (entry * 3 / 2); +    if ((entry & 0x01) == 0) { +      /* 21x3 */ +      sm->fat[e]   = value & 0xff; +      backup       = sm->fat[e + 1] & 0xf0; +      sm->fat[e + 1] = backup | (( value / 0x100  ) & 0x0f); +    } else { +      /* 1x32 */ +      sm->fat[e + 1] = (value / 0x10) & 0xff; +      backup       = sm->fat[e] & 0x0f; +      sm->fat[e]   = backup | ( (value * 0x10) & 0xf0 ); +    }     +       +  } + +  return 0; +} + +int  +mpio_fat_internal_find_startsector(mpio_t *m, BYTE start) +{ +  int i = 0; +  int found = 0; +  mpio_smartmedia_t *sm = &m->internal; + +  while ((i < sm->max_cluster) && (!found)) { +    if ((sm->fat[i * 0x10]  == 0xaa) && +	(sm->fat[i * 0x10 + 1] == start)) { +      found = i; +    } +    i++;       +  } + +  return found; +} + +int   +mpio_fat_free_clusters(mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm;   +  int i; +  int e = 0; +  int fsize; +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +     +    for (i = 0; i < sm->max_cluster; i++) +      if (mpio_fat_entry_free(m, mem, i)) e++;	 +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +    fsize = sm->fat_size * SECTOR_SIZE; + +    if (sm->size == 128) { +      fsize /= 2; +    } else { +      fsize *= 2; +      fsize /= 3; +    } +    for (i = 0; i < (sm->max_cluster - 1); i++) +      if (mpio_fat_entry_read(m, mem, i) == 0) e++;	 +  } +     +  return (e * 16); +} + +int   +mpio_fat_find_free(mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm;   +  int i; +  int fsize; +  int found = 0; + +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +     +    for (i = 2; ((i < sm->max_cluster) && (!found)); i++) +      if (mpio_fat_entry_free(m, mem, i)) found = i;	 +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +    fsize = sm->fat_size * SECTOR_SIZE; + +    if (sm->size == 128) { +      fsize /= 2; +    } else { +      fsize *= 2; +      fsize /= 3; +    } +    for (i = 2; ((i < (sm->max_cluster-1)) && (!found)); i++) +      if (mpio_fat_entry_read(m, mem, i)==0)	found = i;	 +  } + +  return found; +} + +int +mpio_fat_clear(mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm; +   +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    debug("clearing of the internal FAT not yet supported , sorry\n"); +    return 0; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +    memset(sm->fat, 0x00, (sm->fat_size * SECTOR_SIZE)); +    sm->fat[0] = 0xf8; +    sm->fat[1] = 0xff; +    sm->fat[2] = 0xff; +    /* for FAT 16 */ +    if (sm->size == 128)       +      sm->fat[3] = 0xff; +  } +   +  return 0; +} + +/*  + * This function acutally writes both, + * the FAT _and_ the root directory + * + */ + +int  +mpio_fat_write(mpio_t *m, mpio_mem_t mem) +{ +  mpio_smartmedia_t *sm; +  BYTE dummy[BLOCK_SIZE]; +  WORD i; +   +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    debug("writing of the internal FAT is not yet supported, sorry\n"); +    return 0; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) sm=&m->external; + +  memset(dummy, 0xff, BLOCK_SIZE); +   +  for (i = 0x40; i < (sm->dir_offset + DIR_NUM) ; i++) { +    if (((i / 0x20) * 0x20) == i) { +/*       debug("formatting: %2x\n", i); */ +      mpio_io_block_delete(m, mem, i, sm->size); +    } +     +    if (i == 0x40) +      mpio_io_sector_write(m, mem, 0x40, sm->size, 0, sm->mbr); +    if ((i > 0x40) && (i < sm->pbr_offset)) +      mpio_io_sector_write(m, mem, i, sm->size, 0, dummy); +       +    if (i == sm->pbr_offset) +      mpio_io_sector_write(m, mem, sm->pbr_offset, sm->size, 0, sm->pbr); +     +    if ((i >= sm->fat_offset) && (i < (sm->fat_offset + (2 * sm->fat_size))))  +      mpio_io_sector_write(m, mem, i, sm->size, 0,  +			   (sm->fat + SECTOR_SIZE * +			    ((i - sm->fat_offset) % sm->fat_size))); +     +    if (i>=sm->dir_offset) +      mpio_io_sector_write(m, mem, i, sm->size, 0,  +			   (sm->dir + (i - sm->dir_offset) * SECTOR_SIZE)); +  } +     +  return 0; +} diff --git a/libmpio/fat.h b/libmpio/fat.h new file mode 100644 index 0000000..dc6c6d0 --- /dev/null +++ b/libmpio/fat.h @@ -0,0 +1,47 @@ +/*  + * + * $Id: fat.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_FAT_H_ +#define _MPIO_FAT_H_ + +#include "defs.h" + + +int	mpio_bootblocks_read(mpio_t *, mpio_mem_t); + +int	mpio_fat_read(mpio_t *, mpio_mem_t); +int	mpio_fat_write(mpio_t *, mpio_mem_t); +int	mpio_fat_clear(mpio_t *, mpio_mem_t); + +int	mpio_fat_entry_read(mpio_t *, mpio_mem_t, int); +int	mpio_fat_entry_write(mpio_t *, mpio_mem_t, int, WORD); +int	mpio_fat_entry_free(mpio_t *, mpio_mem_t, int); + +int	mpio_fat_free_clusters(mpio_t *, mpio_mem_t); +int	mpio_fat_find_free(mpio_t *, mpio_mem_t); + +int	mpio_fat_internal_find_startsector(mpio_t *, BYTE); + +#endif /* _MPIO_FAT_H_ */ diff --git a/libmpio/io.c b/libmpio/io.c new file mode 100644 index 0000000..1e49a27 --- /dev/null +++ b/libmpio/io.c @@ -0,0 +1,618 @@ +/* -*- linux-c -*- */ + +/*  + * + * $Id: io.c,v 1.1 2002/08/28 16:10:50 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * uses code from mpio_stat.c by + * Yuji Touya (salmoon@users.sourceforge.net) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +/*  + * + * low level I/O  + * + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "io.h" +#include "debug.h" +#include "ecc.h" + +WORD index2blockaddress(WORD); + +WORD index2blockaddress(WORD ba) +{ +  WORD addr; +  BYTE p = 0, c = 0; +  BYTE high, low; + +  high = 0x10 | ((ba / 0x80) & 0x07); +  low  = (ba * 2) & 0xff; +     +  c = high; +  while (c) { +    if (c & 0x01) +      p ^= 1; +    c /= 2; +  } + +  c = low; +  while (c) { +    if (c & 0x01) +      p ^= 0x01; +    c /= 2; +  }   +   +  addr = (high * 0x100) + low + p; + +  return addr; +} + +/* + * low-low level functions + */ + +/*  + * Set command packet   + * + * parameter: + * + * cmd:       commando code + * mem:       internal/external + * index:     sector/block + * small:     FAT with less or equal 32MB + * wsize:     write size, only for PUT_BLOCK + * + * + */ + +int +mpio_io_set_cmdpacket(mpio_cmd_t cmd, mpio_mem_t mem, DWORD index, +		      BYTE small, BYTE wsize, BYTE *buffer)  +{ + +  /* clear cmdpacket*/ +  memset(buffer, 0, 0x40);   + +  *buffer = cmd; +  *(buffer + 0x01) =   mem; +  *(buffer + 0x03) =   (BYTE) (index & 0x00ff); +  *(buffer + 0x04) =   (BYTE)((index & 0xff00) >> 8); +  /*  SM cards with less or equal 32 MB only need 2 Bytes +   *  to address sectors or blocks. +   *  The highest byte has to be 0xff in that case! +   */ +  if (small <= 32) { +    *(buffer + 0x05) = 0xff; +  } else {   +    *(buffer + 0x05) = (BYTE) (index >> 16); +  }   +  *(buffer + 0x06) = wsize;  /* is this always 0x48 in case of a write ?? */ + +  memcpy((buffer + 0x3b), "jykim", 5); +   + +  return (0); +} + +/* + * write chunk of data to MPIO filedescriptor + * + * parameter: + * + * fd:        filedescriptor + * block:     data buffer (has to be num_bytes) + * num_bytes: size of data buffer + * + */ +int +mpio_io_bulk_write(int fd, BYTE *block, int num_bytes) +{ +  BYTE *p; +  int count, bytes_left, bytes_written; + +  bytes_left = num_bytes; +  bytes_written = 0; +  p = block; + +  do +  { +    count = write (fd, p, bytes_left); +    if (count > 0) +    { +      p += count; +      bytes_written += count; +      bytes_left -= count; +    } +  } while (bytes_left > 0 && count > 0); + +  return bytes_written; +} + +/* + * read chunk of data from MPIO filedescriptor + * + * parameter: + * + * fd:        filedescriptor + * block:     return buffer (has to be num_bytes) + * num_bytes: size of return buffer + * + */ +int +mpio_io_bulk_read (int fd, BYTE *block, int num_bytes) +{ +  int total_read, count, bytes_left; +  BYTE *p; + +  total_read = 0; +  bytes_left = num_bytes; +  p = block; + +  do +  { +    count = read (fd, p, bytes_left); + +    if (count > 0) +      { +        total_read += count; +	bytes_left -= count; +	p += count; +      } +  } while (total_read < num_bytes && count > 0); + +  return total_read; +} + +/* + * low level functions + */ + +/*  + * read version block from MPIO + * + * parameter: + * + * m:         mpio context + * buffer:    return buffer (has to be CMD_SIZE) + * + */ +int +mpio_io_version_read(mpio_t *m, BYTE *buffer) +{ +  int nwrite, nread; +  BYTE cmdpacket[CMD_SIZE], status[CMD_SIZE]; + +  /*  Send command packet to MPIO  */ +  mpio_io_set_cmdpacket (GET_VERSION, 0, 0, 0xff, 0, cmdpacket); + +  debugn  (5, ">>> MPIO\n"); +  hexdump (cmdpacket, sizeof(cmdpacket)); + +  nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40); + +  if (nwrite != CMD_SIZE) { +    debug ("Failed to send command.\n\n"); +    close (m->fd); +    return 0;     +  } + +  /*  Receive packet from MPIO  */ +  nread = mpio_io_bulk_read (m->fd, status, 0x40); + +  if (nread == -1 || nread != 0x40) { +      debug ("Failed to read Sector.\n%x\n",nread); +    close (m->fd); +    return 0;     +  } + +  debugn (5, "<<< MPIO\n"); +  hexdump (status, 0x40); + +  memcpy(buffer, status, 0x40); +   +  return CMD_SIZE; +} + +/*  + * read sector from SmartMedia + * + * parameter: + * + * m:         mpio context + * area:      MPIO_{INTERNAL,EXTERNAL}_MEM + * index:     index number of sector to read + * small:     size of memory chip to read from + * wsize:     dummy + * output:    return buffer (has to be SECTOR_SIZE) + * + */ +int +mpio_io_sector_read(mpio_t *m, BYTE area, DWORD index, BYTE small, +		    BYTE wsize, BYTE *output) +{ +  int nwrite, nread; +  BYTE cmdpacket[CMD_SIZE], recvbuff[SECTOR_TRANS]; + +  mpio_io_set_cmdpacket (GET_SECTOR, area, index, small, wsize, cmdpacket); + +  debugn (5, "\n>>> MPIO\n"); +  hexdump (cmdpacket, sizeof(cmdpacket)); +     +  nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40); + +  if(nwrite != CMD_SIZE) { +    debug ("\nFailed to send command.\n\n"); +    close (m->fd); +    return 1; +  } + +  /*  Receive packet from MPIO   */ +  nread = mpio_io_bulk_read (m->fd, recvbuff, SECTOR_TRANS); + +  if(nread != SECTOR_TRANS) { +    debug ("\nFailed to read Sector.\n%x\n", nread); +    close (m->fd); +    return 1; +  } + +  /* check ECC Area information */ +  if (area==MPIO_EXTERNAL_MEM) {     +    mpio_ecc_256_check (recvbuff, +		  (recvbuff + SECTOR_SIZE + 13)); +    mpio_ecc_256_check ((recvbuff + (SECTOR_SIZE / 2)), +		  (recvbuff + SECTOR_SIZE + 8)); +  } +   +  debugn (5, "\n<<< MPIO\n"); +  hexdump (recvbuff, SECTOR_TRANS); + +  memcpy(output, recvbuff, SECTOR_SIZE);   + +  return 0;   +} + +/*  + * write sector to SmartMedia + * + * parameter: + * + * m:         mpio context + * area:      MPIO_{INTERNAL,EXTERNAL}_MEM + * index:     index number of sector to read + * small:     size of memory chip to read from + * wsize:     dummy + * input:     data buffer (has to be SECTOR_SIZE) + * + */ +int   +mpio_io_sector_write(mpio_t *m, BYTE area, DWORD index, BYTE small, +		     BYTE wsize, BYTE *input) +{ +  DWORD block_address, ba; +  int nwrite; +  BYTE cmdpacket[CMD_SIZE], sendbuff[SECTOR_TRANS]; + +  mpio_io_set_cmdpacket(PUT_SECTOR, area, index, small, wsize, cmdpacket); + +  debugn (5, "\n>>> MPIO\n"); +  hexdump (cmdpacket, sizeof(cmdpacket)); +     +  nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40); + +  if(nwrite != CMD_SIZE) { +    debug ("\nFailed to send command.\n\n"); +    close (m->fd); +    return 1; +  } + +  memset(sendbuff, 0, SECTOR_TRANS); +  memset(sendbuff + SECTOR_SIZE, 0xff, 0x10); +  memcpy(sendbuff, input, SECTOR_SIZE); +   +  if (index<0x40) { +    block_address=0; +  } else {   +    ba= (index /0x20) - 2; +    debugn(2, "foobar: %4x\n", ba); +    block_address= index2blockaddress(ba); +    debugn(2, "foobar: %4x\n", block_address); +  } +   +  /* generate ECC information for spare area ! */ +  mpio_ecc_256_gen(sendbuff,  +	     sendbuff + SECTOR_SIZE + 0x0d); +  mpio_ecc_256_gen(sendbuff + (SECTOR_SIZE / 2),  +	     sendbuff + SECTOR_SIZE + 0x08); +   +  ba = (block_address / 0x100) & 0xff; +  sendbuff[SECTOR_SIZE + 0x06] = ba; +  sendbuff[SECTOR_SIZE + 0x0b] = ba; +   +  ba = block_address & 0xff; +  sendbuff[SECTOR_SIZE + 0x07] = ba; +  sendbuff[SECTOR_SIZE + 0x0c] = ba; + +  debugn (5, "\n>>> MPIO\n"); +  hexdump(sendbuff, SECTOR_TRANS); + +  /*  write sector MPIO   */ +  nwrite = mpio_io_bulk_write(m->fd, sendbuff, SECTOR_TRANS); + +  if(nwrite != SECTOR_TRANS) { +    debug ("\nFailed to read Sector.\n%x\n", nwrite); +    close (m->fd); +    return 1; +  } + +  return 0;   +} + +/* + * read/write of blocks + */ +int +mpio_io_block_read(mpio_t *m, BYTE area, DWORD index, BYTE small, +		   BYTE wsize, BYTE *output) +{ +  int i=0; +  int nwrite, nread; +  DWORD rarea=0; +  BYTE cmdpacket[CMD_SIZE], recvbuff[BLOCK_TRANS]; + +  if (area == MPIO_INTERNAL_MEM) { +    rarea = index / 0x1000000;     +    index &= 0xffffff; +  } +  if (area == MPIO_EXTERNAL_MEM) { +    rarea = area; +  } + +  index *= BLOCK_SECTORS; + +  mpio_io_set_cmdpacket(GET_BLOCK, rarea, index, small, wsize, cmdpacket); + +  debugn(5, "\n>>> MPIO\n"); +  hexdump(cmdpacket, sizeof(cmdpacket)); +     +  nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE); + +  if(nwrite != CMD_SIZE) { +    debug ("\nFailed to send command.\n\n"); +    close (m->fd); +    return 1; +  } + +  /*  Receive packet from MPIO   */ +  nread = mpio_io_bulk_read(m->fd, recvbuff, BLOCK_TRANS); + +  if(nread != BLOCK_TRANS) { +    debug ("\nFailed to read Block.\n%x\n",nread); +    close (m->fd); +    return 1; +  } + +  debugn(5, "\n<<< MPIO\n"); +  hexdump(recvbuff, BLOCK_TRANS); + +  for (i = 0; i < BLOCK_SECTORS; i++) { +    /* check ECC Area information */ +    if (area==MPIO_EXTERNAL_MEM) {       +      mpio_ecc_256_check ((recvbuff + (i * SECTOR_TRANS)),                    +		    ((recvbuff + (i * SECTOR_TRANS) + SECTOR_SIZE + 13))); +      mpio_ecc_256_check ((recvbuff + (i * SECTOR_TRANS) + (SECTOR_SIZE / 2)),  +		    ((recvbuff + (i * SECTOR_TRANS) + SECTOR_SIZE + 8))); +    } +     +    memcpy(output + (i * SECTOR_SIZE),  +	   recvbuff + (i * SECTOR_TRANS),  +	   SECTOR_SIZE); +  } + +  return 0;   +} + +/* Read spare is only usefull for the internal memory, + * the FAT lies there. + *  + * For external SmartMedia cards we get and write the + * informatione during {read,write}_{sector,block} + * + */ + +int +mpio_io_spare_read(mpio_t *m, BYTE area, DWORD index, BYTE small, +		   BYTE wsize, BYTE *output, int toread) +{ +  int i; +  int nwrite, nread; +  int chip = 0; +  int chips = 0; +  BYTE cmdpacket[CMD_SIZE]; + +  if (area != MPIO_INTERNAL_MEM) { +    debug("Something fishy happened, aborting!n"); +    exit(1); +  } + +  chips = m->internal.chips;   +   +  for (chip = 1; chip <= chips; chip++) {     +    mpio_io_set_cmdpacket(GET_SPARE_AREA, chip, index, small,  +			  wsize, cmdpacket); +    debugn(5, "\n>>> MPIO\n"); +    hexdump(cmdpacket, sizeof(cmdpacket)); +     +    nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE); +     +    if(nwrite != CMD_SIZE) { +      debug ("\nFailed to send command.\n\n"); +      close (m->fd); +      return 1; +    } +     +    /*  Receive packet from MPIO   */ +    for (i = 0; i < (toread / chips / CMD_SIZE); i++) { +       +      nread = mpio_io_bulk_read (m->fd, +				 output + (i * CMD_SIZE) + +				 (toread / chips * (chip - 1)), +				 CMD_SIZE); +       +      if(nread != CMD_SIZE) { +	debug ("\nFailed to read Block.\n%x\n",nread); +	close (m->fd); +	return 1; +      } +      debugn(5, "\n<<< MPIO\n"); +      hexdump(output + (i * CMD_SIZE) + (toread / chips * (chip - 1)),  +	      CMD_SIZE); +    } +  } + +  return 0;   +} + +int   +mpio_io_block_delete(mpio_t *m, BYTE mem, DWORD index, BYTE small) +{ +  int nwrite, nread; +  BYTE cmdpacket[CMD_SIZE], status[CMD_SIZE]; + +/*  Send command packet to MPIO  */ + +  mpio_io_set_cmdpacket(DEL_BLOCK, mem, index, small, 0, cmdpacket); + +  debugn  (5, ">>> MPIO\n"); +  hexdump (cmdpacket, sizeof(cmdpacket)); + +  nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40); + +  if (nwrite != CMD_SIZE) { +    debug ("Failed to send command.\n\n"); +    close (m->fd); +    return 0; +  } + +/*  Receive packet from MPIO  */ +  nread = mpio_io_bulk_read (m->fd, status, CMD_SIZE); + +  if ((nread == -1) || (nread != CMD_SIZE)) { +      debug ("Failed to read Sector.\n%x\n",nread); +    close (m->fd); +    return 0; +  } + +  if (status[0] != 0xc0) debug ("error formatting Block %04x\n", index); +  debugn(5, "<<< MPIO\n"); +  hexdump(status, CMD_SIZE); +   +  return CMD_SIZE; +} + +int   +mpio_io_block_write(mpio_t *m, BYTE area, DWORD index, BYTE small,  +		    BYTE wsize, BYTE *data) +{ +  int i = 0; +  int nwrite; +  DWORD block_address, ba; +  DWORD rarea = 0; +  BYTE cmdpacket[CMD_SIZE], sendbuff[BLOCK_TRANS]; + +  if (area == MPIO_INTERNAL_MEM) { +    rarea = index / 0x1000000;     +    index &= 0xffffff; +  } +  if (area == MPIO_EXTERNAL_MEM) { +    rarea = area; +  } + +  index *= BLOCK_SECTORS;   + +  /* build block for transfer to MPIO */ +  for (i = 0; i < BLOCK_SECTORS; i++) { +    memcpy(sendbuff + (i * SECTOR_TRANS),  +	   data + (i * SECTOR_SIZE),	    +	   SECTOR_SIZE); +    memset(sendbuff + (i * SECTOR_TRANS) + SECTOR_SIZE, +	   0xff, CMD_SIZE); +    /* fill in block information */ +    if (index < 0x40) { +      block_address = 0; +    } else {   +      ba = (index / 0x20) - 2; +/*       debugn(2, "foobar: %4x\n", ba); */ +      block_address = index2blockaddress(ba); +/*       debugn(2, "foobar: %4x\n", block_address); */ +    } + +    ba = (block_address / 0x100) & 0xff; +    sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x06] = ba; +    sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x0b] = ba; +     +    ba = block_address & 0xff; +    sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x07] = ba; +    sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x0c] = ba; + +    /* generate ECC Area information */ +    if (area == MPIO_EXTERNAL_MEM) {       +      mpio_ecc_256_gen ((sendbuff + (i * SECTOR_TRANS)),                    +			((sendbuff + (i * SECTOR_TRANS) + SECTOR_SIZE + 13))); +      mpio_ecc_256_gen ((sendbuff + (i * SECTOR_TRANS) + (SECTOR_SIZE / 2)),  +			((sendbuff + (i * SECTOR_TRANS) + SECTOR_SIZE + 8))); +    } +  } + +  mpio_io_set_cmdpacket(PUT_BLOCK, rarea, index, small, wsize, cmdpacket); + +  debugn(5, "\n>>> MPIO\n"); +  hexdump(cmdpacket, sizeof(cmdpacket)); +     +  nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE); + +  if(nwrite != CMD_SIZE) { +    debug ("\nFailed to send command.\n\n"); +    close (m->fd); +    return 1; +  } + +  /*  send packet to MPIO   */ +  debugn(5, "\n<<< MPIO\n"); +  hexdump(sendbuff, BLOCK_TRANS); +  nwrite = mpio_io_bulk_write (m->fd, sendbuff, BLOCK_TRANS); + +  if(nwrite != BLOCK_TRANS) { +    debug ("\nFailed to read Block.\n%x\n",nwrite); +    close (m->fd); +    return 1; +  } + +  return 0; +} diff --git a/libmpio/io.h b/libmpio/io.h new file mode 100644 index 0000000..d682967 --- /dev/null +++ b/libmpio/io.h @@ -0,0 +1,58 @@ +/* -*- linux-c -*- */ + +/*  + * + * $Id: io.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * uses code from mpio_stat.c by + * Yuji Touya (salmoon@users.sourceforge.net) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_IO_H_ +#define _MPIO_IO_H_ + +#include "defs.h" + +/* real I/O */ +int	mpio_io_set_cmdpacket(mpio_cmd_t, mpio_mem_t, +			      DWORD, BYTE, BYTE, BYTE *); + +int	mpio_io_bulk_read(int, BYTE *, int); +int	mpio_io_bulk_write(int, BYTE *, int); + +/* read version block into memory */ +int	mpio_io_version_read(mpio_t *, BYTE *); + +/* */ +int	mpio_io_sector_read(mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *); +int	mpio_io_sector_write(mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *); + +/* */ +int	mpio_io_block_read(mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *); +int	mpio_io_block_write(mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *); +int	mpio_io_block_delete(mpio_t *, BYTE, DWORD, BYTE); + +/* */ +int	mpio_io_spare_read  (mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *, int); + +#endif /* _MPIO_IO_H_ */ diff --git a/libmpio/mpio.c b/libmpio/mpio.c new file mode 100644 index 0000000..ce16963 --- /dev/null +++ b/libmpio/mpio.c @@ -0,0 +1,769 @@ +/*  + * + * $Id: mpio.c,v 1.1 2002/08/28 16:10:50 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * uses code from mpio_stat.c by + * Yuji Touya (salmoon@users.sourceforge.net) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "defs.h" +#include "debug.h" +#include "directory.h" +#include "io.h" +#include "mpio.h" +#include "smartmedia.h" +#include "fat.h" + +#define DSTRING 100 + +int sector_hack(int mem, int sector); +void mpio_init_internal(mpio_t *); +void mpio_init_external(mpio_t *); + +void  +mpio_init_internal(mpio_t *m) +{ +  BYTE i_offset = 0x18; +  /* init main memory parameters */ +  m->internal.manufacturer = m->version[i_offset]; +  m->internal.id = m->version[i_offset+1]; +  m->internal.size = mpio_id2mem(m->internal.id); +  m->internal.max_cluster = m->internal.size/16*1024; +  m->internal.chips = 1; +   +  /* look for a second installed memory chip */ +  if (mpio_id_valid(m->version[i_offset+2])) +    {     +      if(mpio_id2mem(m->internal.id) != mpio_id2mem(m->version[i_offset+3])) +	{ +	  printf("Found a MPIO with two chips with different size!"); +	  printf("I'm utterly confused and aborting now, sorry!"); +	  printf("Please report this to: mpio-devel@lists.sourceforge.net\n"); +	  exit(1);	   +	} +    m->internal.size = 2 * mpio_id2mem(m->internal.id); +    m->internal.chips = 2; +  } +   +  mpio_id2geo(m->internal.id, &m->internal.geo); + +  /* read FAT information from spare area */ +  m->internal.fat_size=m->internal.size*2; +  m->internal.fat=malloc(m->internal.fat_size*SECTOR_SIZE); +  mpio_fat_read(m, MPIO_INTERNAL_MEM); + +  /* Read directory from internal memory */ +  m->internal.dir_offset=0; +  mpio_rootdir_read(m, MPIO_INTERNAL_MEM); +} + +void +mpio_init_external(mpio_t *m) +{ +  BYTE e_offset=0x20; + +  /* heuristic to find the right offset for the external memory */ +  while((e_offset<0x3a) && !(mpio_id_valid(m->version[e_offset]))) +    e_offset++; +   +  if (mpio_id_valid(m->version[e_offset])) +    { +      m->external.manufacturer=m->version[e_offset]; +      m->external.id=m->version[e_offset+1]; +    } else { +      m->external.manufacturer=0; +      m->external.id=0; +    }   + +  if (m->external.id!=0) { + +    m->external.fat=0; +    /* Read things from external memory (if available) */ +    m->external.size = mpio_id2mem(m->external.id); +    m->external.chips = 1; /* external is always _one_ chip !! */     +    mpio_id2geo(m->external.id, &m->external.geo); +     +    if (m->external.size < 16) { +      printf("Sorry, I don't believe this software works with "  +	    "SmartMedia Cards less than 16MB\n" +	    "Proceed with care and send any findings to: " +	     "mpio-devel@lists.sourceforge.net\n"); +    } +     +    mpio_bootblocks_read(m, MPIO_EXTERNAL_MEM); +    m->external.fat = malloc(SECTOR_SIZE*m->external.fat_size); +    mpio_fat_read(m, MPIO_EXTERNAL_MEM); +    mpio_rootdir_read(m, MPIO_EXTERNAL_MEM); +  }   + + + +} + +mpio_t * +mpio_init(void)  +{ +  mpio_t *new_mpio; + +  new_mpio = malloc(sizeof(mpio_t)); +  if (!new_mpio) { +    debug ("Error allocating memory for mpio_t"); +    return NULL; +  }   + +  new_mpio->fd = open(MPIO_DEVICE, O_RDWR); + +  if (new_mpio->fd < 0) { +     +    debug ("Could not open %s\n" +	   "Verify that the mpio module is loaded and " +	   "your MPIO is\nconnected and powered up.\n\n" , MPIO_DEVICE); +     +    return NULL;     +  } +   +  /* Read Version Information */ +  mpio_io_version_read(new_mpio, new_mpio->version);   + +  /* fill in values */ +  /* TODO: check for different versions !! */ +  snprintf(new_mpio->firmware.id, 12, "%s", new_mpio->version); +  snprintf(new_mpio->firmware.major, 3, "%s", new_mpio->version + 0x0c); +  snprintf(new_mpio->firmware.minor, 3, "%s", new_mpio->version + 0x0e); +  snprintf(new_mpio->firmware.year, 5, "%s", new_mpio->version + 0x10); +  snprintf(new_mpio->firmware.month, 3, "%s", new_mpio->version + 0x14); +  snprintf(new_mpio->firmware.day, 3, "%s", new_mpio->version + 0x16); + +  /* internal init */ +  mpio_init_internal(new_mpio); + +  /* external init */ +  mpio_init_external(new_mpio); + +  return new_mpio;   +} + +/*  + * returns available memory + * + * free:  give back free memory size + * + */ +int +mpio_memory_free(mpio_t *m, mpio_mem_t mem, int *free) +{ +  *free=mpio_fat_free_clusters(m, mem); +  if (mem==MPIO_INTERNAL_MEM) {     +    return (m->internal.geo.SumSector * SECTOR_SIZE / 1000);     +  } +   +  if (mem==MPIO_EXTERNAL_MEM) { +    return (m->external.geo.SumSector * SECTOR_SIZE / 1000);     +  } + +  return 0; +} + +void +mpio_close(mpio_t *m)  +{ +  close(m->fd); +   +  if(m->internal.fat) +    free(m->internal.fat); +  if(m->external.fat) +    free(m->external.fat); +   +  free(m); +   +} + +void     +mpio_get_info(mpio_t *m, mpio_info_t *info) +{ +  int max=INFO_LINE-1; +  snprintf(info->firmware_id, max,      "\"%s\"", m->firmware.id); +  snprintf(info->firmware_version, max, "%s.%s",  +	   m->firmware.major, m->firmware.minor); +  snprintf(info->firmware_date, max,    "%s.%s.%s",  +	   m->firmware.day, m->firmware.month, m->firmware.year); +   +  if (m->internal.chips == 1) {     +    snprintf(info->firmware_mem_internal, max, "%3dMB (%s)",  +	     mpio_id2mem(m->internal.id),  +	     mpio_id2manufacturer(m->internal.manufacturer)); +  } else { +    snprintf(info->firmware_mem_internal, max, "%3dMB (%s) - %d chips",  +	     mpio_id2mem(m->internal.id),  +	     mpio_id2manufacturer(m->internal.manufacturer), +	     m->internal.chips); +  } + +  snprintf(info->firmware_mem_external, max, "%3dMB (%s)",  +	   mpio_id2mem(m->external.id),  +	   mpio_id2manufacturer(m->external.manufacturer)); +} + +/* void */ +/* mpio_print_version(mpio_t *m) */ +/* { */ +/*   printf("Firmware Id:      \"%s\"\n", m->firmware.id); */ +/*   printf("Firmware Version:  %s.%s\n", m->firmware.major,  */ +/* 	 m->firmware.minor); */ +/*   printf("Firmware Date:     %s.%s.%s\n", m->firmware.day, */ +/* 	 m->firmware.month, */ +/* 	 m->firmware.year); */ + +/*   printf("internal Memory:   %3dMB (%s)\n",  */ +/* 	 mpio_id2mem(m->internal.id),  */ +/* 	 mpio_id2manufacturer(m->internal.manufacturer)); */ +/*   if (m->external.id!=0) {     */ +/*     printf("external Memory:   %3dMB (%s)\n",  */ +/* 	   mpio_id2mem(m->external.id), */ +/* 	   mpio_id2manufacturer(m->external.manufacturer)); */ +/*   } else { */ +/*     printf("external Memory:   %3dMB (%s)\n", 0, "not available"); */ +/*   } */ +/* } */ + +/* + * + * foo + * + */ + +/* + * HELP! + * + * somebody explain me these values!!! + * + */ + +int  +sector_hack(int mem, int sector) +{ +  int a = sector; + +  /* No Zone-based block management for SmartMedia below 32MB !!*/ + +  if (mem == 64) { +    /* I'm so large in *not* knowing! */ +    if (sector >= 89) +      a++; +    if (a >= 1000) +      a += 21;     +    if (a >= 2021) +      a += 24; +    if (a >= 3045) +      a += 24;     +    /* WHAT? */ +    if (a >= 3755) +      a++; +         +  } +  if ((mem == 128) || (mem == 32)) { +    /* two blocks are already spent elsewhere */ +    /* question is: where (CIS and ??) */ +    if (sector >= 998)  +      a += 22; +    /* ... and then add 24 empty blocks every 1000 sectors */ +    a += ((sector - 998) / 1000 * 24); +/*     if (a>=2020) */ +/*       a+=24; */ +/*     if (a>=3044) */ +/*       a+=24; */ +/*     if (a>=4068) */ +/*       a+=24; */ +/*     if (a>=5092) */ +/*       a+=24; */ +/*     if (a>=6116) */ +/*       a+=24; */ +/*     if (a>=7140) */ +/*       a+=24; */ +  }   +   +  return a; +} +   +int +mpio_file_get(mpio_t *m, mpio_mem_t mem, BYTE *filename,  +	      BYTE (*progress_callback)(int, int)) +{ +  BYTE *p; +  BYTE bdummy; +  WORD wdummy; + +  mpio_smartmedia_t *sm; +  int data_offset; +  BYTE fname[129]; +  BYTE block[BLOCK_SIZE]; +  DWORD startsector = 0, sector; +  DWORD realsector = 0; +  int fd, towrite; +   +  DWORD filesize, fsize; +  DWORD fat_and; +  DWORD fat_end;  +  BYTE abort = 0; +   +  /* please fix me sometime */ +  /* the system entry are kind of special ! */ +  if (strncmp("sysdum", filename, 6) == 0) +    return 0;   + +  if (mem == MPIO_INTERNAL_MEM) {     +    sm = &m->internal; +    data_offset = 0x00; +    fat_and = 0xffffffff; +    fat_end = 0xffffffff; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +    data_offset = sm->dir_offset + DIR_NUM - (2 * BLOCK_SECTORS);     +    /* FAT 16 vs. FAT 12 */   +    if (sm->size==128) { +      fat_and = 0xffff; +      fat_end = 0xfff8; +    } else { +      fat_and = 0xfff; +      fat_end = 0xff8; +    }  +  } + +  p = mpio_directory_open(m, mem); +  while (p) { +    mpio_dentry_get (m, p, +		     fname, 128, +		     &wdummy, &bdummy, &bdummy, +		     &bdummy, &bdummy, &filesize); +    fsize = filesize; +    if ((strcmp(fname,filename) == 0) && (strcmp(filename,fname) == 0)) { +      startsector = mpio_dentry_get_startsector(m, p);       +      p = NULL; +    } +     +    p = mpio_dentry_next(m, p); +  } +   +  /* grr, of curse these are clusters not sectors */ +  /* must code while awake, must ... */ +  if (startsector) {     +    fd = open(filename, (O_RDWR | O_CREAT), (S_IRWXU | S_IRGRP | S_IROTH));     +    debugn(2, "startsector: %4x\n", startsector);   +    sector = startsector; +    if (mem == MPIO_INTERNAL_MEM) {     +      realsector = mpio_fat_internal_find_startsector(m, sector); +      realsector = realsector+         /* chose the right bank */   +	(0x01000000 * ((realsector / (sm->size / 16 * 1000 / sm->chips)) + 1)); +      sector=realsector; +      debugn(2, "startsector (real): %4x\n", sector);   +    } else { +      realsector=sector_hack(sm->size, sector); +    } +     +    mpio_io_block_read(m, mem, realsector + (data_offset / BLOCK_SECTORS), +		       sm->size, 0, block); + +    if (filesize > BLOCK_SIZE) { +      towrite = BLOCK_SIZE; +    } else { +      towrite = filesize; +    }     +     +    if (write(fd, block, towrite) != towrite) { +      debug("error writing file data\n"); +      close(fd); +      return -1; +    }  +     +    filesize -= towrite; + +    debugn(5, "sector: (%6x) %4x\n",  +	  (sector&0xffffff), mpio_fat_entry_read(m, mem, sector&0xffffff)); + +     + +    while((((mpio_fat_entry_read(m, mem, (sector & 0xffffff)) & fat_and) +	    < fat_end)) && (filesize > 0) && (!abort)) {     +	sector=mpio_fat_entry_read(m, mem, sector & 0xffffff);	 +	debugn(2,"next sector: %4x\n", sector);  +	if (mem == MPIO_INTERNAL_MEM) { +	  realsector = sector; +	} else { +	  realsector = sector_hack(sm->size, sector); +	} +	     +	debugn(2," realsector: %4x\n", realsector);  +	 +	mpio_io_block_read(m, mem, +			   (realsector + (data_offset / BLOCK_SECTORS)), +			   sm->size, 0, block); +	if (filesize > BLOCK_SIZE) { +	  towrite=BLOCK_SIZE; +	} else { +	  towrite=filesize; +	}     +	 +	if (write(fd, block, towrite)!=towrite) { +	  debug("error writing file data\n"); +	  close(fd); +	  return -1; +	}     +	filesize-=towrite; +	 +	if (progress_callback) +	  abort=(*progress_callback)((fsize-filesize), fsize); + +      } + +    close (fd);     +  } else { +    debug("unable to locate the file: %s\n", filename); +  } +   +  return (fsize-filesize); +} + +int +mpio_file_put(mpio_t *m, mpio_mem_t mem, BYTE *filename,  +	      BYTE (*progress_callback)(int, int)) +{ +  mpio_smartmedia_t *sm; +  int data_offset; +  BYTE block[BLOCK_SIZE]; +  DWORD startsector=0, sector, nextsector; +  DWORD realsector=0; +  int fd, toread; +  struct stat file_stat; +   +  DWORD filesize, fsize; +  DWORD fat_and; +  DWORD fat_end;   +  BYTE abort=0; +   + +  if (mem==MPIO_INTERNAL_MEM) {     +    sm=&m->internal; +    data_offset=0x00; +    fat_and=0xffffffff; +    fat_end=0xffffffff; +    debug("writing to internal memory is not yet supported, sorry\n");     +    return 0;     +  } +   +  if (mem==MPIO_EXTERNAL_MEM) { +    sm=&m->external; +    data_offset=sm->dir_offset+DIR_NUM-(2*BLOCK_SECTORS);     +    /* FAT 16 vs. FAT 12 */   +    if (sm->size==128) { +      fat_and=0xffff; +      fat_end=0xfff8; +    } else { +      fat_and=0xfff; +      fat_end=0xff8; +    }  +  } + +  if (stat((const char *)filename, &file_stat)!=0) { +    debug("could not find file: %s\n", filename); +    return 0; +  } +   +  fsize=filesize=file_stat.st_size; +  debugn(2, "filesize: %d\n", fsize); + +  fd = open(filename, O_RDONLY);     +  if (fd==-1) { +    debug("could not find file: %s\n", filename); +    return 0; +  } + +  while ((filesize>0) & (!abort)) { + +    if (filesize>=BLOCK_SIZE) {       +      toread=BLOCK_SIZE; +    } else { +      toread=filesize; +    } +     +    if (read(fd, block, toread)!=toread) { +      debug("error reading file data\n"); +      close(fd); +      return -1; +    } + +    if (!startsector) { +      startsector=mpio_fat_find_free(m, mem); +      if (!startsector) { +	debug("could not find startsector for file!\n"); +	close(fd); +	return 0;	 +      } +      sector=startsector; +      debugn(2, "startsector: %d\n", startsector); +      /* evil hacks are us ;-) */ +      mpio_fat_entry_write(m, mem, startsector, fat_and); +    } else { +      nextsector=mpio_fat_find_free(m, mem); +      if (!nextsector){ +	debug("no more free blocks, short write!\n"); +	close(fd); +	return (fsize-filesize); +      } +      debugn(2, " nextsector: %d\n", nextsector); + +      mpio_fat_entry_write(m, mem, sector, nextsector); +      sector=nextsector; +      /* evil hacks are us ;-) */ +      mpio_fat_entry_write(m, mem, sector, fat_and); + +    } + +    if (mem==MPIO_INTERNAL_MEM) {     +/*       realsector=fat_internal_find_startsector(m, sector);       */ +/*       realsector=realsector+         /\* chose the right bank *\/   */ +/* 	(0x01000000*((realsector/(sm->size/16*1000/sm->chips))+1));     */ +/*       sector=realsector; */ +/*       debugn(2, "startsector (real): %4x\n", sector);   */ +    } else { +      realsector=sector_hack(sm->size, sector); +    } + +/*     debug("mager: %04x : %3d\n", realsector*BLOCK_SECTORS, realsector); */ +    mpio_io_block_delete(m, mem, ((realsector*BLOCK_SECTORS) + data_offset), +			 sm->size); +    mpio_io_block_write(m, mem, realsector + (data_offset/BLOCK_SECTORS),  +			sm->size, 0x48, block); + +    filesize -= toread; +	 +    if (progress_callback) +      abort=(*progress_callback)((fsize-filesize), fsize); +  } + +  close(fd); + +  /* FIXEME: add real values here!!! */ +  mpio_dentry_put(m, mem, +		  filename, strlen(filename), +		  2002, 8, 13, +		  2, 12, fsize, startsector); + +  mpio_fat_write(m, mem); + +  return fsize-filesize; +} + +int +mpio_memory_format(mpio_t *m, mpio_mem_t mem,  +	      BYTE (*progress_callback)(int, int)) +{ +  int data_offset; +  mpio_smartmedia_t *sm; +  DWORD clusters; +  DWORD i; +   +  if (mem == MPIO_INTERNAL_MEM) {     +    sm=&m->internal; +    data_offset=0x00; +    debug("formatting of internal memory is not yet supported, sorry\n"); +    return 0; +  } +   +  if (mem == MPIO_EXTERNAL_MEM) { +    sm = &m->external; +    data_offset = sm->dir_offset+DIR_NUM;     +  } +/*   debug("mager: %2x\n", data_offset); */ + +  clusters = sm->size*128; +   +/*   debug("Clusters: %4x\n", sm->size*128); */ + +  for (i = data_offset; i < clusters; i += 0x20) { +    mpio_io_block_delete(m, mem, i, sm->size); +    if (progress_callback) +      (*progress_callback)(i, clusters + 1); +  } + +  /* format CIS area */ +  mpio_io_block_delete(m, mem, 0x20, sm->size); +  mpio_io_sector_write(m, mem, 0x20, sm->size, 0, sm->cis); +  mpio_io_sector_write(m, mem, 0x21, sm->size, 0, sm->cis); + +  mpio_fat_clear(m, mem); +  mpio_rootdir_clear(m, mem); +  mpio_fat_write(m, mem); + +  if (progress_callback) +    (*progress_callback)(clusters+1, clusters+1); + +  return 0; +} + + +/* can we share code with mpio_file_get ??? */ +int  +mpio_file_del(mpio_t *m, mpio_mem_t mem, BYTE *filename,  +	      BYTE (*progress_callback)(int, int)) +{ +  BYTE *p; +  BYTE bdummy; +  WORD wdummy; + +  mpio_smartmedia_t *sm; +  int data_offset; +  BYTE fname[129]; +  DWORD startsector=0, sector; +  DWORD realsector=0, oldsector=0; +  int towrite; +   +  DWORD filesize, fsize; +  DWORD fat_and; +  DWORD fat_end;   +  BYTE abort=0; +   +  /* please fix me sometime */ +  /* the system entry are kind of special ! */ +  if (strncmp("sysdum", filename, 6)==0) +    return 0;   + +  if (mem==MPIO_INTERNAL_MEM) {     +    sm=&m->internal; +    data_offset=0x00; +    fat_and=0xffffffff; +    fat_end=0xffffffff; +    debug("deleting from files of internal memory" +	  " is not yet supported, sorry\n"); +    return 0; +  } +   +  if (mem==MPIO_EXTERNAL_MEM) { +    sm=&m->external; +    data_offset=sm->dir_offset+DIR_NUM-(2*BLOCK_SECTORS);     +    /* FAT 16 vs. FAT 12 */   +    if (sm->size==128) { +      fat_and=0xffff; +      fat_end=0xfff8; +    } else { +      fat_and=0xfff; +      fat_end=0xff8; +    }  +  } + + +  p=mpio_directory_open(m, mem); +  while (p) { + +    mpio_dentry_get (m, p, +		     fname, 128, +		     &wdummy, &bdummy, &bdummy, +		     &bdummy, &bdummy, &filesize); +    fsize=filesize; +    if ((strcmp(fname,filename)==0) && (strcmp(filename,fname)==0)) { +      startsector=mpio_dentry_get_startsector(m, p);       +      p=NULL; +    } +     +    p=mpio_dentry_next(m, p); +  } +   +  /* grr, of curse these are clusters not sectors */ +  /* must code while awake, must ... */ +  if (startsector) {     +    debugn(2, "startsector: %4x\n", startsector);   +    sector = startsector; +    if (mem == MPIO_INTERNAL_MEM) {     +      realsector = mpio_fat_internal_find_startsector(m, sector);       +      realsector = realsector+         /* chose the right bank */   +	(0x01000000*((realsector / (sm->size / 16 * 1000 / sm->chips)) + 1)); +      sector = realsector; +      debugn(2, "startsector (real): %4x\n", sector);   +    } else { +      realsector = sector_hack(sm->size, sector); +    } + +    mpio_io_block_delete(m, mem, (realsector * BLOCK_SECTORS) + data_offset, +			 sm->size); + +    if (filesize > BLOCK_SIZE) { +      towrite = BLOCK_SIZE; +    } else { +      towrite = filesize; +    }     +     +    filesize -= towrite; + +    debugn(5, "sector: (%6x) %4x\n",  +	  (sector&0xffffff), mpio_fat_entry_read(m, mem, sector&0xffffff)); + +    while((((mpio_fat_entry_read(m, mem, (sector & 0xffffff)) & fat_and) +	    < fat_end)) && (filesize>0) && (!abort)) {     +	oldsector = sector; +	sector = mpio_fat_entry_read(m, mem, sector & 0xffffff);	 +	mpio_fat_entry_write(m, mem, oldsector, 0); +	debugn(2,"next sector: %4x\n", sector);  +	if (mem == MPIO_INTERNAL_MEM) {     +	  realsector = sector; +	} else { +	  realsector = sector_hack(sm->size, sector); +	} +	     +	debugn(2," realsector: %4x\n", realsector);  +	 +	mpio_io_block_delete(m, mem, +			     ((realsector * BLOCK_SECTORS) + data_offset), +			     sm->size); +	if (filesize > BLOCK_SIZE) { +	  towrite = BLOCK_SIZE; +	} else { +	  towrite = filesize; +	}     +	 +	filesize -= towrite; +	 +	if (progress_callback) +	  abort=(*progress_callback)((fsize-filesize), fsize); +      } +    mpio_fat_entry_write(m, mem, sector, 0); + +  } else { +    debug("unable to locate the file: %s\n", filename); +  } + +  /* TODO: delete directory entry */ +  mpio_dentry_delete(m, mem, filename); + +  mpio_fat_write(m, mem); +   +  return (fsize-filesize); +} + + +   diff --git a/libmpio/mpio.h b/libmpio/mpio.h new file mode 100644 index 0000000..c373ce2 --- /dev/null +++ b/libmpio/mpio.h @@ -0,0 +1,97 @@ +/* -*- linux-c -*- */ + +/*  + * $Id: mpio.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * uses code from mpio_stat.c by + * Yuji Touya (salmoon@users.sourceforge.net) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_H_ +#define _MPIO_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +#include "defs.h" + +/*  + *init and shutdown  + */ + +mpio_t *mpio_init(void); +void	mpio_close(mpio_t *); + +/* + * request information + */ + +/* get version */ +void	mpio_get_info(mpio_t *, mpio_info_t *); +/* print version: deprecated */ +//void    mpio_print_version(mpio_t *); +/* retrieves free memory in bytes */ +int	mpio_memory_free(mpio_t *, mpio_mem_t, int *free); + +/*  + * directory operations  + */ + +/* context, memory bank */ +BYTE*	mpio_directory_open(mpio_t *, BYTE); +/* context, dir context */ +BYTE*	mpio_dentry_next(mpio_t *, BYTE *); +/* context, dir context */ +int	mpio_dentry_get(mpio_t *, BYTE *, BYTE *, int,WORD *, BYTE *, BYTE *, +			BYTE *, BYTE *, DWORD *); + +/* context, memory bank, filename, callback */ +int	mpio_file_get(mpio_t *, mpio_mem_t, BYTE *, BYTE (*)(int, int));  + +/* context, memory bank, filename, callback */ +int	mpio_file_put(mpio_t *, mpio_mem_t, BYTE *, BYTE (*)(int, int));  + +/* context, memory bank, filename, callback */ +int	mpio_file_del(mpio_t *, mpio_mem_t, BYTE *, BYTE (*)(int, int));  + + +/* context, memory bank, callback */ +int	mpio_memory_format(mpio_t *, mpio_mem_t, BYTE (*)(int, int));  + + +/*  + * timeline: + * --------- + * 2004: some functions to change the order of files + * 2005: read mp3 tags of the files + */ +   +#endif /* _MPIO_H_ */ + + diff --git a/libmpio/smartmedia.c b/libmpio/smartmedia.c new file mode 100644 index 0000000..64e89b1 --- /dev/null +++ b/libmpio/smartmedia.c @@ -0,0 +1,153 @@ +/* -*- linux-c -*- */ + +/*  + * + * $Id: smartmedia.c,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include <stdio.h> +#include <stdlib.h> + +#include "smartmedia.h" +#include "debug.h" + +mpio_disk_phy_t MPIO_DISK_GEO_002={ 125, 4,  8,   4000 }; +mpio_disk_phy_t MPIO_DISK_GEO_004={ 250, 4,  8,   8000 }; +mpio_disk_phy_t MPIO_DISK_GEO_008={ 250, 4, 16,  16000 }; +mpio_disk_phy_t MPIO_DISK_GEO_016={ 500, 4, 16,  32000 }; +mpio_disk_phy_t MPIO_DISK_GEO_032={ 500, 4, 16,  64000 }; +mpio_disk_phy_t MPIO_DISK_GEO_064={ 500, 4, 32, 128000 }; +mpio_disk_phy_t MPIO_DISK_GEO_128={ 500, 4, 32, 256000 }; + +/* This comes from the Samsung documentation files */ + +/* a small warning: only use this function (mpio_id2mem) in the very + * beginning of MPIO model detection. After that use the values + * of size and chips! -mager + */ + +int +mpio_id2mem(BYTE id) +{ +  int i=0; +   +  switch(id)  +    { +    case 0xea: +      i=2; +      break; +    case 0xe3:  /* Samsung */ +    case 0xe5:  /* Toshiba */ +      i=4; +      break; +    case 0xe6: +      i=8; +      break; +    case 0x73: +      i=16; +      break; +    case 0x75: +      i=32; +      break; +    case 0x76: +      i=64;       +      break; +    case 0x79: +      i=128; +      break; +    default: +      debug("This should never happen (id2mem)!\n");       +      exit (1); +    } +  return i; +}       + +BYTE * +mpio_id2manufacturer(BYTE id) +{ +  BYTE *m; +  switch(id)  +    { +    case 0xec: +      m="Samsung";       +      break; +    case 0x98: +      m="Toshiba"; +      break; +    default: +      m="unknown"; +    }   +  return m; +} + +BYTE +mpio_id_valid(BYTE id) +{ +  switch(id) { +  case 0xec:   /* Samsung */ +  case 0x98:   /* Toshiba */ +    return 1;       +  default: +    ; +  }   + +  return 0; +} + +void +mpio_id2geo(BYTE id, mpio_disk_phy_t *geo) +{ +  switch(id) { +    case 0xea: +      *geo = MPIO_DISK_GEO_002; +      break; +    case 0xe3:  /* Samsung */ +    case 0xe5:  /* Toshiba */ +      *geo = MPIO_DISK_GEO_004; +      break; +    case 0xe6: +      *geo = MPIO_DISK_GEO_008; +      break; +    case 0x73: +      *geo = MPIO_DISK_GEO_016; +      break; +    case 0x75: +      *geo = MPIO_DISK_GEO_032; +      break; +    case 0x76: +      *geo = MPIO_DISK_GEO_064; +      break; +    case 0x79: +      *geo = MPIO_DISK_GEO_128; +      break; +    default: +      debug("This should never happen!\n");       +      exit (1);       +  } + +  return; +} + +     +   diff --git a/libmpio/smartmedia.h b/libmpio/smartmedia.h new file mode 100644 index 0000000..1d01a07 --- /dev/null +++ b/libmpio/smartmedia.h @@ -0,0 +1,39 @@ +/* -*- linux-c -*- */ + +/*  + * + * $Id: smartmedia.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + *  + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_SMARTMEDIA_H_ +#define _MPIO_SMARTMEDIA_H_ + +#include "defs.h" + +/* get our configuration for SmartMedia cards right */ +int	mpio_id2mem (BYTE); +BYTE *	mpio_id2manufacturer(BYTE); +void	mpio_id2geo(BYTE, mpio_disk_phy_t *); +BYTE	mpio_id_valid(BYTE); + +#endif /* _MPIO_SMARTMEDIA_H_ */  | 
