aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in43
-rw-r--r--libmpio/Makefile.am6
-rw-r--r--libmpio/defs.h37
-rw-r--r--libmpio/mpio.h11
-rw-r--r--libmpio/src/directory.c126
-rw-r--r--libmpio/src/directory.h3
-rw-r--r--libmpio/src/fat.c79
-rw-r--r--libmpio/src/io.c364
-rw-r--r--libmpio/src/io.h11
-rw-r--r--libmpio/src/mpio.c167
-rw-r--r--libmpio/src/smartmedia.c15
-rw-r--r--mpiosh/callback.c35
12 files changed, 761 insertions, 136 deletions
diff --git a/configure.in b/configure.in
index a455ecb..27ed75d 100644
--- a/configure.in
+++ b/configure.in
@@ -10,7 +10,7 @@ dnl AM_CONFIG_HEADER(src/config.h)
AC_CANONICAL_SYSTEM()
AC_MSG_RESULT(Building for a ${host} host.)
-AM_INIT_AUTOMAKE(mpio, 0.7.0)
+AM_INIT_AUTOMAKE(mpio, 0.7.1-2003101901)
dnl Checks for programs.
@@ -52,7 +52,46 @@ fi
AC_SUBST(MPLIB_INCLUDE)
AC_SUBST(MPLIB_CFLAGS)
-:
+
+dnl -- check for libusb
+dnl -- this is stolen from libgphoto2
+
+AC_PATH_PROG(LIBUSB_CONFIG,libusb-config)
+if test -n "${LIBUSB_CONFIG}"; then
+ CPPFLAGS_save="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS `$LIBUSB_CONFIG --cflags`"
+ AC_CHECK_HEADER(usb.h,[
+ LDFLAGS_orig="$LDFLAGS"
+ LDFLAGS="`$LIBUSB_CONFIG --libs`"
+ AC_CHECK_LIB(usb,usb_busses,[
+ usb_msg="yes"
+ IOLIB_SUBDIRS="$IOLIB_SUBDIRS usb"
+ USB_LIBS="`$LIBUSB_CONFIG --libs`"
+ USB_CFLAGS="`$LIBUSB_CONFIG --cflags`"
+ LIBUSB_VER="`$LIBUSB_CONFIG --version`"],[
+ usb_msg="no (available version too old)"])
+ LDFLAGS="$LDFLAGS_orig"])
+ CPPFLAGS="$CPPFLAGS_save"
+fi
+
+ # This 'test' call uses non-standard syntax and will fail on most
+ # systems, but it's just informational so any warning can be ignored.
+if test "$LIBUSB_VER" \< "0.1.6"; then
+ AC_MSG_WARN([
+*** You need at least version 0.1.6 of the libusb library for USB support
+*** http://sourceforge.net/projects/libusb/
+*** If you cannot find the appropriate version, try CVS
+ ])
+fi
+
+case "$usb_msg" in
+ yes*) AC_DEFINE(HAVE_USB,1,[Whether you have USB support enabled]);;
+ *) ;;
+esac
+
+AC_SUBST(USB_CFLAGS)
+AC_SUBST(USB_LIBS)
+
dnl --- check for kernel version
kernel_version=`uname -r 2>&1`
echo -n "checking for kernel version ... "
diff --git a/libmpio/Makefile.am b/libmpio/Makefile.am
index 373348d..2f2c5ca 100644
--- a/libmpio/Makefile.am
+++ b/libmpio/Makefile.am
@@ -1,6 +1,6 @@
-INCLUDES=@MPLIB_INCLUDE@
-AM_CFLAGS=@MPLIB_CFLAGS@
-AM_LDFLAGS=-version-info 1:0:0
+INCLUDES=@MPLIB_INCLUDE@
+AM_CFLAGS=@MPLIB_CFLAGS@ @USB_CFLAGS@
+AM_LDFLAGS=-version-info 1:0:0 @USB_LIBS@
lib_LTLIBRARIES=libmpio.la
diff --git a/libmpio/defs.h b/libmpio/defs.h
index 819ca88..38c1399 100644
--- a/libmpio/defs.h
+++ b/libmpio/defs.h
@@ -1,5 +1,5 @@
/*
- * $Id: defs.h,v 1.30 2003/09/22 19:15:37 germeier Exp $
+ * $Id: defs.h,v 1.31 2003/10/19 21:06:34 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -32,6 +32,10 @@
extern "C" {
#endif
+#ifdef HAVE_USB
+#include "usb.h"
+#endif
+
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
@@ -56,12 +60,13 @@ typedef enum { MPIO_MODEL_DME = 0x00,
/* USB commands */
typedef enum { GET_VERSION = 0x01,
- GET_BLOCK = 0x02,
+ GET_BLOCK = 0x02, /* GET_MEGABLOCK */
PUT_SECTOR = 0x03,
- DEL_BLOCK = 0x04,
+ DEL_BLOCK = 0x04, /* DEL_MEGABLOCK */
GET_SECTOR = 0x06,
GET_SPARE_AREA = 0x07,
PUT_BLOCK = 0x08,
+ PUT_MEGABLOCK = 0x30,
MODIFY_FIRMWARE = 0xa0 } mpio_cmd_t;
/* file types on internal memory */
@@ -74,6 +79,7 @@ typedef enum { FTYPE_CHAN = 0x00,
FTYPE_WAV = 'V',
FTYPE_ENTRY = 'R',
FTYPE_DIR = 'D',
+ FTYPE_DIR_RECURSION = 'r',
FTYPE_BROKEN = 'X', /* internal "dummy" type, used when
internal FAT is broken */
FTYPE_PLAIN = '-'} mpio_filetype_t;
@@ -120,6 +126,12 @@ typedef BYTE mpio_filename_t[MPIO_FILENAME_LEN];
#define BLOCK_SIZE (SECTOR_SIZE * BLOCK_SECTORS)
#define BLOCK_TRANS (BLOCK_SIZE + (SECTOR_ECC * BLOCK_SECTORS))
+#define MEGABLOCK_SECTORS 0x100
+#define MEGABLOCK_SIZE (SECTOR_SIZE * MEGABLOCK_SECTORS)
+#define MEGABLOCK_READ (MEGABLOCK_SIZE + (SECTOR_ECC * MEGABLOCK_SECTORS))
+#define MEGABLOCK_WRITE (MEGABLOCK_SIZE + (0x10 * MEGABLOCK_SECTORS))
+#define MEGABLOCK_TRANS_WRITE (BLOCK_SIZE + (0x10 * BLOCK_SECTORS))
+
#define DIR_NUM 0x10
#define DIR_SIZE (SECTOR_SIZE*DIR_NUM)
#define DIR_ENTRY_SIZE 0x20
@@ -152,9 +164,14 @@ typedef struct {
#define MPIO_ERR_DEVICE_NOT_READY -13
#define MPIO_ERR_OUT_OF_MEMORY -14
#define MPIO_ERR_INTERNAL -15
+#define MPIO_ERR_DIR_RECURSION -16
+#define MPIO_ERR_FILE_IS_A_DIR -17
+#define MPIO_ERR_USER_CANCEL -18
/* internal errors, occur when UI has errors! */
#define MPIO_ERR_INT_STRING_INVALID -101
+#define MPIO_USB_TIMEOUT 1000 /* in msec => 1 sec */
+
/* get formatted information, about the MPIO player */
typedef struct {
@@ -192,7 +209,7 @@ typedef struct {
struct mpio_directory_tx {
BYTE name[INFO_LINE];
- BYTE dir[BLOCK_SIZE];
+ BYTE dir[MEGABLOCK_SIZE];
BYTE *dentry;
@@ -245,6 +262,9 @@ typedef struct {
/* version of chips used */
BYTE version;
+ /* special "features" */
+ BYTE recursive_directory;
+
} mpio_smartmedia_t;
/* health status of a memory "card" */
@@ -256,6 +276,7 @@ typedef struct {
typedef struct {
BYTE num; /* number of chips or zones */
+ BYTE block_size; /* block size in KB */
/* internal: max 4 chips
* external: max 8 zones (128MB) -> max 8 */
mpio_health_single_t data[8];
@@ -266,6 +287,14 @@ typedef struct {
BYTE version[CMD_SIZE];
int fd;
+#ifdef HAVE_USB
+ int use_libusb;
+ struct usb_bus *usb_busses;
+ struct usb_bus *usb_bus;
+ struct usb_dev_handle *usb_handle;
+ int usb_out_ep;
+ int usb_in_ep;
+#endif
BYTE *charset; /* charset used for filename conversion */
BYTE id3; /* enable/disable ID3 rewriting support */
diff --git a/libmpio/mpio.h b/libmpio/mpio.h
index 6a1e18c..cb342c7 100644
--- a/libmpio/mpio.h
+++ b/libmpio/mpio.h
@@ -1,5 +1,5 @@
/*
- * $Id: mpio.h,v 1.22 2003/06/26 19:53:58 germeier Exp $
+ * $Id: mpio.h,v 1.23 2003/10/19 21:06:34 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -61,6 +61,11 @@ mpio_model_t mpio_get_model(mpio_t *);
/* retrieves free memory in bytes */
int mpio_memory_free(mpio_t *, mpio_mem_t, int *free);
+/* report sectors in block for this memory */
+int mpio_block_get_sectors(mpio_t *, mpio_mem_t);
+/* report size of block for this memory */
+int mpio_block_get_blocksize(mpio_t *, mpio_mem_t);
+
/*
* charset for filename encoding/converting
*/
@@ -198,6 +203,10 @@ char * mpio_strerror(int err);
/* prints the error message of the last error*/
void mpio_perror(char *prefix);
+/* set error code to given value */
+int mpio_error_set(int err);
+
+
/*
* debugging
*/
diff --git a/libmpio/src/directory.c b/libmpio/src/directory.c
index b4a1e44..e0065bd 100644
--- a/libmpio/src/directory.c
+++ b/libmpio/src/directory.c
@@ -1,5 +1,5 @@
/*
- * $Id: directory.c,v 1.11 2003/07/15 08:26:37 germeier Exp $
+ * $Id: directory.c,v 1.12 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -161,7 +161,8 @@ BYTE
mpio_directory_is_empty(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir)
{
mpio_dir_entry_t *dentry;
- BYTE r;
+ BYTE *p;
+ int size;
UNUSED(m);
UNUSED(mem);
@@ -169,11 +170,18 @@ mpio_directory_is_empty(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir)
dentry = (mpio_dir_entry_t *)dir->dir;
dentry += 2;
- r = MPIO_OK;
- if (dentry->name[0] != 0x00)
- r = !r;
+ if (dentry->name[0] == 0x00)
+ return MPIO_OK;
+
+ /* check for a single recursive entry */
+ p = dir->dir + 0x40;
+ size = mpio_dentry_get_size(m, mem, p);
+ hexdumpn(2, p, size);
+ if ((p[size-0x20+0x0b] == 0x1a) &&
+ (p[size] == 0x00))
+ return MPIO_OK;
- return r;
+ return MPIO_ERR_DIR_NOT_EMPTY;
}
@@ -246,15 +254,27 @@ mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir)
WORD self, parent;
struct tm tt;
time_t curr;
-
+ BYTE *p = NULL;
+ int size;
+
if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ /* check if filename already exists */
+ p = mpio_dentry_find_name(m, mem, dir);
+ if (!p)
+ p = mpio_dentry_find_name_8_3(m, mem, dir);
+ if (p)
+ {
+ debugn(2, "filename already exists\n");
+ return mpio_error_set(MPIO_ERR_FILE_EXISTS);
+ }
+
if ((strcmp(dir, "..") == 0) ||
(strcmp(dir, ".") == 0))
{
debugn(2, "directory name not allowed: %s\n", dir);
- return MPIO_ERR_DIR_NAME_ERROR;
+ return mpio_error_set(MPIO_ERR_DIR_NAME_ERROR);
}
/* find free sector */
@@ -262,7 +282,7 @@ mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir)
if (!f)
{
debug("could not free cluster for file!\n");
- return (MPIO_ERR_FAT_ERROR);
+ return mpio_error_set(MPIO_ERR_FAT_ERROR);
} else {
self=f->entry;
}
@@ -290,7 +310,7 @@ mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir)
current = mpio_dentry_get_startcluster(m, mem, sm->cdir->dentry);
if (!current) {
debugn(2, "error creating directory");
- return MPIO_ERR_FAT_ERROR;
+ return mpio_error_set(MPIO_ERR_FAT_ERROR);
}
if (mem==MPIO_INTERNAL_MEM)
@@ -303,16 +323,24 @@ mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir)
new = malloc(sizeof(mpio_directory_t));
- mpio_directory_init(m, mem, new, self, parent);
+ mpio_directory_init(m, mem, new, self, parent);
mpio_fatentry_set_eof(m ,mem, f);
- mpio_io_block_write(m, mem, f, new->dir);
time(&curr);
tt = * localtime(&curr);
mpio_dentry_put(m, mem,
- dir, strlen(dir),
- mktime(&tt),
- 0, self, 0x10);
+ dir, strlen(dir),
+ mktime(&tt),
+ 0, self, 0x10);
+
+ if (sm->recursive_directory) {
+ /* yuck, yuck, yuck */
+ p = mpio_dentry_find_name(m, mem, dir);
+ size=mpio_dentry_get_size(m, mem, p);
+ memcpy(new->dir+0x40, p, size);
+ memset(new->dir+0x40+size-0x20+0x0b, 0x1a, 1);
+ }
+ mpio_io_block_write(m, mem, f, new->dir);
free(new);
@@ -323,7 +351,10 @@ int
mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir)
{
mpio_smartmedia_t *sm;
+ mpio_fatentry_t *f1;
+ mpio_fatentry_t *f2;
BYTE *p;
+ BYTE ret;
BYTE month, day, hour, minute, type;
BYTE fname[100];
WORD year;
@@ -356,10 +387,9 @@ mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir)
if ((strlen(pwd) + strlen(dir) + 2) > INFO_LINE)
{
debugn(2, "directory name gets to long!\n");
- return MPIO_ERR_DIR_TOO_LONG;
+ return mpio_error_set(MPIO_ERR_DIR_TOO_LONG);
}
-
p = mpio_dentry_find_name(m, mem, dir);
/* second try */
@@ -369,9 +399,9 @@ mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir)
if (!p)
{
debugn(2, "could not find directory: %s\n", dir);
- return MPIO_ERR_DIR_NOT_FOUND;
- }
-
+ return mpio_error_set(MPIO_ERR_DIR_NOT_FOUND);
+ }
+
mpio_dentry_get(m, mem, p,
fname, 100,
&year, &month, &day,
@@ -381,9 +411,22 @@ mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir)
if (type != FTYPE_DIR)
{
debugn(2, "this is not a directory: %s\n", dir);
- return MPIO_ERR_DIR_NOT_A_DIR;
+ return mpio_error_set(MPIO_ERR_DIR_NOT_A_DIR);
}
+ if (sm->cdir->dentry) {
+ f1 = mpio_dentry_get_startcluster(m, mem, sm->cdir->dentry);
+ f2 = mpio_dentry_get_startcluster(m, mem, p);
+ ret = (f1->entry == f2->entry);
+ free(f1);
+ free(f2);
+ if (ret)
+ {
+ debugn(2, "this is a recursive direcotry entry: %s\n", dir);
+ return mpio_error_set(MPIO_ERR_DIR_RECURSION);
+ }
+ }
+
new = malloc(sizeof(mpio_directory_t));
strcpy(new->name, dir);
new->next = NULL;
@@ -805,6 +848,9 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer,
if (dentry->attr & 0x10) {
/* is this a directory? */
*type = FTYPE_DIR;
+ if ((dentry->attr & 0x08) &&
+ (dentry->attr & 0x02))
+ *type = FTYPE_DIR_RECURSION;
} else {
*type = FTYPE_PLAIN;
if (mem == MPIO_INTERNAL_MEM) {
@@ -827,17 +873,27 @@ int
mpio_rootdir_read (mpio_t *m, mpio_mem_t mem)
{
mpio_smartmedia_t *sm;
+ mpio_fatentry_t *f;
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), recvbuff))
+ if (sm->version) {
+ /* new chip */
+ f = mpio_fatentry_new(m, mem, 0x00, FTYPE_MUSIC);
+ if (!f)
return 1;
-
- memcpy(sm->root->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE);
+ mpio_io_block_read(m, mem, f, sm->root->dir);
+ free (f);
+ } else {
+ /* old chip */
+ for (i = 0; i < DIR_NUM; i++) {
+ if (mpio_io_sector_read(m, mem, (sm->dir_offset + i), recvbuff))
+ return 1;
+ memcpy(sm->root->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE);
+ }
}
return (0);
@@ -914,6 +970,26 @@ mpio_dentry_get_filesize(mpio_t *m, mpio_mem_t mem, BYTE *p)
return fsize;
}
+BYTE
+mpio_dentry_get_attrib(mpio_t *m, mpio_mem_t mem, BYTE *p)
+{
+ int s;
+ int fsize;
+ mpio_dir_entry_t *dentry;
+
+ s = mpio_dentry_get_size(m, mem, p);
+ s -= DIR_ENTRY_SIZE ;
+
+ dentry = (mpio_dir_entry_t *)p;
+
+ while (s != 0) {
+ dentry++;
+ s -= DIR_ENTRY_SIZE ;
+ }
+
+ return dentry->attr;
+}
+
long
mpio_dentry_get_time(mpio_t *m, mpio_mem_t mem, BYTE *p)
{
diff --git a/libmpio/src/directory.h b/libmpio/src/directory.h
index 2ae17ec..fd46bd6 100644
--- a/libmpio/src/directory.h
+++ b/libmpio/src/directory.h
@@ -1,5 +1,5 @@
/*
- * $Id: directory.h,v 1.3 2003/04/27 12:08:21 germeier Exp $
+ * $Id: directory.h,v 1.4 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -51,6 +51,7 @@ 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 *);
int mpio_dentry_get_filesize(mpio_t *, mpio_mem_t, BYTE *);
+BYTE mpio_dentry_get_attrib(mpio_t *, mpio_mem_t, BYTE *);
long mpio_dentry_get_time(mpio_t *, mpio_mem_t, BYTE *);
mpio_fatentry_t *mpio_dentry_get_startcluster(mpio_t *, mpio_mem_t, BYTE *);
BYTE mpio_dentry_is_dir(mpio_t *, mpio_mem_t, BYTE *);
diff --git a/libmpio/src/fat.c b/libmpio/src/fat.c
index 36ac6ac..4a166fe 100644
--- a/libmpio/src/fat.c
+++ b/libmpio/src/fat.c
@@ -1,5 +1,5 @@
/*
- * $Id: fat.c,v 1.4 2003/07/15 08:26:37 germeier Exp $
+ * $Id: fat.c,v 1.5 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -257,7 +257,7 @@ mpio_fatentry_hw2entry(mpio_t *m, mpio_fatentry_t *f)
chip++;
value &= 0xffffff;
- value /= 0x20;
+ value /= mpio_block_get_sectors(m, f->mem);
value += chip * (sm->max_cluster / sm->chips);
f->entry = value;
@@ -285,7 +285,7 @@ mpio_fatentry_entry2hw(mpio_t *m, mpio_fatentry_t *f)
chip = f->entry / (sm->max_cluster / sm->chips);
cluster = f->entry - ((sm->max_cluster / sm->chips) * chip);
- cluster *= 0x20;
+ cluster *= mpio_block_get_sectors(m, f->mem);
cluster += 0x01000000 * (1 << chip);
f->hw_address=cluster;
@@ -689,7 +689,7 @@ mpio_fatentry_find_free(mpio_t *m, mpio_mem_t mem, BYTE ftype)
{
mpio_fatentry_t *f;
- f = mpio_fatentry_new(m, mem, 1, ftype);
+ f = mpio_fatentry_new(m, mem, 0, ftype);
while(mpio_fatentry_plus_plus(f))
{
@@ -809,7 +809,7 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem)
{
mpio_smartmedia_t *sm;
mpio_fatentry_t *f;
- BYTE dummy[BLOCK_SIZE];
+ BYTE dummy[MEGABLOCK_SIZE];
WORD i;
DWORD block;
@@ -822,21 +822,35 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem)
mpio_io_block_delete(m, mem, f);
free(f);
- memset(dummy, 0x00, BLOCK_SIZE);
+ if (sm->version) {
+ /* write megablock */
+ f=mpio_fatentry_new(m, mem, 0, FTYPE_ENTRY);
+ /* another yuck! */
+ f->i_fat[0x01] = 1; /* file index number */
+ f->i_fat[0x0e] = 1; /* file index number */
+ f->i_fat[0x02] = 0;
+ f->i_fat[0x03] = 1; /* directory is one block long */
+ mpio_io_block_write(m, mem, f, sm->root->dir);
+ free(f);
+
+ } else {
+ memset(dummy, 0x00, MEGABLOCK_SIZE);
+
+ /* only write the root dir */
+ for (i= 0; i< 0x20; i++)
+ {
+
+ if (i<DIR_NUM)
+ {
+ mpio_io_sector_write(m, mem, i,
+ (sm->root->dir + SECTOR_SIZE * i));
+ } else {
+ /* fill the rest of the block with zeros */
+ mpio_io_sector_write(m, mem, i, dummy);
+ }
+ }
+ }
- /* only write the root dir */
- for (i= 0; i< 0x20; i++)
- {
-
- if (i<DIR_NUM)
- {
- mpio_io_sector_write(m, mem, i,
- (sm->root->dir + SECTOR_SIZE * i));
- } else {
- /* fill the rest of the block with zeros */
- mpio_io_sector_write(m, mem, i, dummy);
- }
- }
} else {
mpio_directory_write(m, mem, sm->cdir);
}
@@ -942,7 +956,7 @@ mpio_fatentry_set_defect(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
int
mpio_fatentry_is_defect(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
{
- int e;
+ int e, i, c;
mpio_smartmedia_t *sm;
if (mem == MPIO_INTERNAL_MEM)
@@ -952,8 +966,28 @@ mpio_fatentry_is_defect(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
if (mpio_fatentry_free(m, mem, f))
return 0;
/* check if this block became defective */
+ /* check for all bytes are zero */
+ c=1;
+ for (i=0;i<0x10;i++) {
+ if (sm->fat[e+i]!=0)
+ c=0;
+ }
+ if (c)
+ {
+ debug("defective block encountered, abort reading! (all bytes are zero)\n");
+ return 1;
+ }
+ /* check for file state marker */
+ if ((sm->fat[e+0x00] != 0xaa) &&
+ (sm->fat[e+0x00] != 0xee))
+ {
+ debug("defective block encountered, abort reading! (wrong file state marker)\n");
+ hexdumpn(0, (sm->fat+e), 0x10);
+ return 1;
+ }
if (m->model >= MPIO_MODEL_FD100) {
/* newer models */
+ /* magic marker not found, or file IDs are different */
if ((sm->fat[e+0x0f] != 0) ||
(sm->fat[e+0x01] != sm->fat[e+0x0e]))
{
@@ -961,10 +995,9 @@ mpio_fatentry_is_defect(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
return 1;
}
} else
+ /* magic marker not found */
if ((sm->fat[e+0x0e] != 'P') ||
- (sm->fat[e+0x0f] != 'C') ||
- ((sm->fat[e+0x00] != 0xaa) &&
- (sm->fat[e+0x00] != 0xee)))
+ (sm->fat[e+0x0f] != 'C'))
{
debug("defective block encountered, abort reading! (older models check)\n");
return 1;
diff --git a/libmpio/src/io.c b/libmpio/src/io.c
index 519e508..5ec0957 100644
--- a/libmpio/src/io.c
+++ b/libmpio/src/io.c
@@ -1,5 +1,5 @@
/*
- * $Id: io.c,v 1.6 2003/09/23 18:12:14 germeier Exp $
+ * $Id: io.c,v 1.7 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -36,6 +36,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "io.h"
#include "debug.h"
@@ -453,8 +455,146 @@ mpio_zone_block_get_logical(mpio_t *m, mpio_cmd_t mem, DWORD pblock)
}
+/*
+ * report sizes of selected memory
+ */
+
+int
+mpio_block_get_sectors(mpio_t *m, mpio_mem_t mem){
+ mpio_smartmedia_t *sm=0;
+ int sectors;
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ if (!sm)
+ {
+ debug("error in memory selection, aborting\n");
+ exit (-1);
+ }
+
+ sectors = BLOCK_SECTORS;
+ if (sm->version)
+ sectors = MEGABLOCK_SECTORS;
+
+ return sectors;
+}
+
+int
+mpio_block_get_blocksize(mpio_t *m, mpio_mem_t mem) {
+ mpio_smartmedia_t *sm=0;
+ int size;
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ if (!sm)
+ {
+ debug("error in memory selection, aborting\n");
+ exit (-1);
+ }
+
+ size = BLOCK_SIZE;
+ if (sm->version)
+ size = MEGABLOCK_SIZE;
+
+ return size;
+}
+
+/*
+ * open/closes the device
+ */
+int
+mpio_device_open(mpio_t *m){
+#ifdef HAVE_USB
+ struct usb_device *dev;
+ struct usb_interface_descriptor *interface;
+ struct usb_endpoint_descriptor *ep;
+ int ret, i;
+#endif
+
+ m->use_libusb=0;
+ m->fd = open(MPIO_DEVICE, O_RDWR);
+ if (m->fd > 0) {
+ debug ("using kernel module\n");
+ return MPIO_OK;
+ }
+
+#ifdef HAVE_USB
+ debug("trying libusb\n");
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ m->usb_busses = usb_get_busses();
+
+ for (m->usb_bus = m->usb_busses;
+ m->usb_bus;
+ m->usb_bus = m->usb_bus->next) {
+
+ for (dev = m->usb_bus->devices; dev; dev = dev->next) {
+ if (dev->descriptor.idVendor == 0x2735) {
+ if ((dev->descriptor.idProduct != 0x01) &&
+ (dev->descriptor.idProduct != 0x71))
+ debug("Found Product ID %02x, which is unknown. Proceeding anyway.\n",
+ dev->descriptor.idProduct);
+ m->usb_handle = usb_open(dev);
+ if (m->usb_handle) {
+ /* found and opened the device,
+ now find the communication endpoints */
+ m->usb_in_ep = m->usb_out_ep = 0;
+
+ ret = usb_claim_interface (m->usb_handle, 0);
+
+ if (ret < 0)
+ {
+ debug ("Error claiming device: %d \"%s\"\n", ret, usb_strerror());
+ return MPIO_ERR_PERMISSION_DENIED;
+ } else {
+ debug ("claimed interface 0\n");
+ }
+
+
+ interface = dev->config->interface->altsetting;
+
+ for (i = 0 ; i < interface->bNumEndpoints; i++) {
+ ep = &interface->endpoint[i];
+ debug("USB endpoint #%d (Addr:%02x, Attr:%02x)\n", i,
+ ep->bEndpointAddress, ep->bmAttributes);
+ if (ep->bmAttributes == 2) {
+ if (ep->bEndpointAddress & USB_ENDPOINT_IN) {
+ debug("FOUND incoming USB endpoint (%02x)\n", ep->bEndpointAddress);
+ m->usb_in_ep = ep->bEndpointAddress & ~(USB_ENDPOINT_IN);
+ } else {
+ debug("FOUND outgoing USB endpoint (%02x)\n", ep->bEndpointAddress);
+ m->usb_out_ep = ep->bEndpointAddress;
+ }
+ }
+ }
+
+ if (!(m->usb_in_ep && m->usb_out_ep)) {
+ debug("Did not find USB bulk endpoints");
+ return MPIO_ERR_PERMISSION_DENIED;
+ }
+
+ m->use_libusb=1;
+ return MPIO_OK;
+
+ }
+ }
+ }
+ }
+#endif
+ return MPIO_ERR_PERMISSION_DENIED;
+}
+int
+mpio_device_close(mpio_t *m) {
+ usb_close(m->usb_handle);
+
+ m->use_libusb = 0;
+
+ return MPIO_OK;
+}
/*
* low-low level functions
@@ -543,6 +683,17 @@ mpio_io_bulk_write(int fd, BYTE *block, int num_bytes)
return bytes_written;
}
+int
+mpio_io_write(mpio_t *m, BYTE *block, int num_bytes)
+{
+ if (m->use_libusb) {
+ return usb_bulk_write(m->usb_handle, m->usb_out_ep, block, num_bytes, MPIO_USB_TIMEOUT);
+ } else {
+ return mpio_io_bulk_write(m->fd, block, num_bytes);
+ }
+}
+
+
/*
* read chunk of data from MPIO filedescriptor
*
@@ -578,6 +729,16 @@ mpio_io_bulk_read (int fd, BYTE *block, int num_bytes)
return total_read;
}
+int
+mpio_io_read (mpio_t *m, BYTE *block, int num_bytes)
+{
+ if (m->use_libusb) {
+ return usb_bulk_read(m->usb_handle, m->usb_in_ep, block, num_bytes, MPIO_USB_TIMEOUT);
+ } else {
+ return mpio_io_bulk_read(m->fd, block, num_bytes);
+ }
+}
+
/*
* low level functions
*/
@@ -603,7 +764,7 @@ mpio_io_version_read(mpio_t *m, BYTE *buffer)
debugn (5, ">>> MPIO\n");
hexdump (cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40);
+ nwrite = mpio_io_write(m, cmdpacket, 0x40);
if (nwrite != CMD_SIZE)
{
@@ -613,7 +774,7 @@ mpio_io_version_read(mpio_t *m, BYTE *buffer)
}
/* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, status, 0x40);
+ nread = mpio_io_read(m, status, 0x40);
if (nread == -1 || nread != 0x40)
{
@@ -684,7 +845,7 @@ mpio_io_sector_read(mpio_t *m, BYTE mem, DWORD index, BYTE *output)
debugn (5, "\n>>> MPIO\n");
hexdump (cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40);
+ nwrite = mpio_io_write(m, cmdpacket, 0x40);
if(nwrite != CMD_SIZE)
{
@@ -694,7 +855,7 @@ mpio_io_sector_read(mpio_t *m, BYTE mem, DWORD index, BYTE *output)
}
/* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, recvbuff, SECTOR_TRANS);
+ nread = mpio_io_read(m, recvbuff, SECTOR_TRANS);
if(nread != SECTOR_TRANS)
{
@@ -823,7 +984,7 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input)
debugn (5, "\n>>> MPIO\n");
hexdump (cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40);
+ nwrite = mpio_io_write(m, cmdpacket, 0x40);
if(nwrite != CMD_SIZE)
{
@@ -876,7 +1037,7 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input)
hexdump(sendbuff, SECTOR_TRANS);
/* write sector MPIO */
- nwrite = mpio_io_bulk_write(m->fd, sendbuff, SECTOR_TRANS);
+ nwrite = mpio_io_write(m, sendbuff, SECTOR_TRANS);
if(nwrite != SECTOR_TRANS)
{
@@ -889,6 +1050,66 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input)
}
/*
+ * read/write of megablocks
+ */
+int
+mpio_io_megablock_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output)
+{
+ int i=0;
+ int j=0;
+ int nwrite, nread;
+ mpio_smartmedia_t *sm;
+ BYTE chip;
+ DWORD address;
+ BYTE cmdpacket[CMD_SIZE], recvbuff[BLOCK_TRANS];
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+
+ fatentry2hw(f, &chip, &address);
+
+ mpio_io_set_cmdpacket(m, GET_BLOCK, chip, address, sm->size, 0, cmdpacket);
+
+ debugn(5, "\n>>> MPIO\n");
+ hexdump(cmdpacket, sizeof(cmdpacket));
+
+ nwrite = mpio_io_write(m, cmdpacket, CMD_SIZE);
+
+/* hexdumpn(0, cmdpacket, 16); */
+
+ if(nwrite != CMD_SIZE)
+ {
+ debug ("\nFailed to send command.\n\n");
+ close (m->fd);
+ return 1;
+ }
+
+ /* Receive packets from MPIO */
+ for (i = 0; i < 8; i++)
+ {
+ nread = mpio_io_read(m, recvbuff, BLOCK_TRANS);
+
+ if(nread != BLOCK_TRANS)
+ {
+ debug ("\nFailed to read (sub-)block.\n%x\n",nread);
+ close (m->fd);
+ return 1;
+ }
+
+ debugn(5, "\n<<< MPIO (%d)\n", i);
+ hexdump(recvbuff, BLOCK_TRANS);
+
+ for (j = 0; j < BLOCK_SECTORS; j++) {
+ memcpy(output + (j * SECTOR_SIZE) + (i * BLOCK_SIZE),
+ recvbuff + (j * SECTOR_TRANS),
+ SECTOR_SIZE);
+ }
+ }
+
+ return 0;
+}
+
+/*
* read/write of blocks
*/
int
@@ -904,6 +1125,9 @@ mpio_io_block_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output)
if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ if (sm->version)
+ return mpio_io_megablock_read(m, mem, f, output);
+
fatentry2hw(f, &chip, &address);
mpio_io_set_cmdpacket(m, GET_BLOCK, chip, address, sm->size, 0, cmdpacket);
@@ -911,7 +1135,7 @@ mpio_io_block_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output)
debugn(5, "\n>>> MPIO\n");
hexdump(cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
+ nwrite = mpio_io_write(m, cmdpacket, CMD_SIZE);
if(nwrite != CMD_SIZE)
{
@@ -921,7 +1145,7 @@ mpio_io_block_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output)
}
/* Receive packet from MPIO */
- nread = mpio_io_bulk_read(m->fd, recvbuff, BLOCK_TRANS);
+ nread = mpio_io_read(m, recvbuff, BLOCK_TRANS);
if(nread != BLOCK_TRANS)
{
@@ -994,7 +1218,7 @@ mpio_io_spare_read(mpio_t *m, BYTE mem, DWORD index, WORD size,
debugn(5, "\n>>> MPIO\n");
hexdump(cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
+ nwrite = mpio_io_write(m, cmdpacket, CMD_SIZE);
if(nwrite != CMD_SIZE) {
debug ("\nFailed to send command.\n\n");
@@ -1005,10 +1229,10 @@ mpio_io_spare_read(mpio_t *m, BYTE mem, DWORD index, WORD size,
/* 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);
+ nread = mpio_io_read(m,
+ output + (i * CMD_SIZE) +
+ (toread / chips * (chip - 1)),
+ CMD_SIZE);
if ((progress_callback) && (i % 256))
(*progress_callback)(mem,
@@ -1059,6 +1283,7 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address)
mpio_smartmedia_t *sm;
int nwrite, nread;
BYTE cmdpacket[CMD_SIZE], status[CMD_SIZE];
+ BYTE CMD_OK, CMD_ERROR;
/* Send command packet to MPIO */
@@ -1075,12 +1300,20 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address)
mpio_zone_block_set_free_phys(m, chip, address);
}
+ if (sm->version) {
+ CMD_OK = 0xe0;
+ CMD_ERROR = 0xe1;
+ } else {
+ CMD_OK = 0xc0;
+ CMD_ERROR = 0xc1;
+ }
+
mpio_io_set_cmdpacket(m, DEL_BLOCK, chip, address, sm->size, 0, cmdpacket);
debugn (5, ">>> MPIO\n");
hexdump (cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40);
+ nwrite = mpio_io_write(m, cmdpacket, 0x40);
if (nwrite != CMD_SIZE)
{
@@ -1090,11 +1323,11 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address)
}
/* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, status, CMD_SIZE);
+ nread = mpio_io_read(m, status, CMD_SIZE);
if ((nread == -1) || (nread != CMD_SIZE))
{
- debug ("Failed to read Sector.\n%x\n",nread);
+ debug ("Failed to read Response.\n%x\n",nread);
close (m->fd);
return 0;
}
@@ -1102,21 +1335,101 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address)
debugn(5, "<<< MPIO\n");
hexdump(status, CMD_SIZE);
- if (status[0] != 0xc0)
+ if (status[0] != CMD_OK)
{
- debugn (2,"error formatting Block %02x:%06x\n",
- chip, address);
+ if (status[0] == CMD_ERROR) {
+ debugn (0, "error formatting Block %02x:%06x\n",
+ chip, address);
+ } else {
+ debugn (0,"UNKNOWN error (code: %02x) formatting Block %02x:%06x\n",
+ status[0], chip, address);
+ }
+
if (chip == MPIO_EXTERNAL_MEM)
{
sm = &m->external;
mpio_zone_block_set_defect_phys(m, chip, address);
}
+ return 0;
}
return CMD_SIZE;
}
int
+mpio_io_megablock_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
+{
+ mpio_smartmedia_t *sm;
+ int nwrite;
+ int i, j, k;
+ DWORD block_address, ba;
+ BYTE cmdpacket[CMD_SIZE], sendbuff[MEGABLOCK_TRANS_WRITE];
+ BYTE chip=0;
+ DWORD address;
+
+ if (mem == MPIO_INTERNAL_MEM)
+ {
+ sm = &m->internal;
+ fatentry2hw(f, &chip, &address);
+ }
+
+ if (mem == MPIO_EXTERNAL_MEM)
+ {
+ printf ("This should never happen!");
+ exit(1);
+ }
+
+ /* build and send cmd packet */
+ mpio_io_set_cmdpacket(m, PUT_MEGABLOCK, chip, address, sm->size, 0x10, cmdpacket);
+ cmdpacket[8] = 0x02; /* el yuck'o */
+
+ debugn(5, "\n>>> MPIO\n");
+ hexdump(cmdpacket, sizeof(cmdpacket));
+ hexdump(f->i_fat, 0x10);
+
+ nwrite = mpio_io_write(m, cmdpacket, CMD_SIZE);
+
+ if(nwrite != CMD_SIZE)
+ {
+ debug ("\nFailed to send command.\n\n");
+ close (m->fd);
+ return 1;
+ }
+
+ for (i = 0; i < 8 ; i++) {
+ /* build block for transfer to MPIO */
+ for (j = 0; j < 8; j++)
+ {
+ memcpy(sendbuff + (j * 0x840),
+ data + (j * 0x800) + (i * BLOCK_SIZE),
+ 0x800);
+ for (k = 0; k < 4; k++) {
+ memcpy((sendbuff + (j * 0x840) + 0x800 + (k * 0x10)),
+ f->i_fat, 0x10);
+ if (k)
+ memset((sendbuff + (j * 0x840) + 0x800 + (k * 0x10)), 0xee, 1);
+ }
+ }
+
+ /* send packet to MPIO */
+ debugn(5, "\n<<< MPIO (%d)\n", i);
+ hexdump(sendbuff, MEGABLOCK_TRANS_WRITE);
+
+ nwrite = mpio_io_write(m, sendbuff, MEGABLOCK_TRANS_WRITE);
+
+ if(nwrite != MEGABLOCK_TRANS_WRITE)
+ {
+ debug ("\nFailed to write block (%d).\n%x\n", i, nwrite);
+ close (m->fd);
+ return 1;
+ }
+
+ }
+
+ return 0;
+}
+
+int
mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
{
mpio_smartmedia_t *sm;
@@ -1130,12 +1443,19 @@ mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
if (mem == MPIO_INTERNAL_MEM)
{
sm = &m->internal;
+ if (sm->version)
+ return mpio_io_megablock_write(m, mem, f, data);
fatentry2hw(f, &chip, &address);
}
if (mem == MPIO_EXTERNAL_MEM)
{
sm = &m->external;
+ if (sm->version) {
+ printf ("This should never happen!");
+ exit(1);
+ }
+
/* find free physical block */
chip = MPIO_EXTERNAL_MEM;
address = mpio_zone_block_find_free_log(m, mem, f->entry);
@@ -1191,7 +1511,7 @@ mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
debugn(5, "\n>>> MPIO\n");
hexdump(cmdpacket, sizeof(cmdpacket));
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
+ nwrite = mpio_io_write(m, cmdpacket, CMD_SIZE);
if(nwrite != CMD_SIZE)
{
@@ -1203,7 +1523,7 @@ mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
/* send packet to MPIO */
debugn(5, "\n<<< MPIO\n");
hexdump(sendbuff, BLOCK_TRANS);
- nwrite = mpio_io_bulk_write (m->fd, sendbuff, BLOCK_TRANS);
+ nwrite = mpio_io_write(m, sendbuff, BLOCK_TRANS);
if(nwrite != BLOCK_TRANS)
{
diff --git a/libmpio/src/io.h b/libmpio/src/io.h
index 54b3bfd..0275506 100644
--- a/libmpio/src/io.h
+++ b/libmpio/src/io.h
@@ -1,5 +1,5 @@
/*
- * $Id: io.h,v 1.3 2003/04/27 12:08:21 germeier Exp $
+ * $Id: io.h,v 1.4 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -34,6 +34,10 @@
extern "C" {
#endif
+/* open/closes the device */
+int mpio_device_open(mpio_t *);
+int mpio_device_close(mpio_t *);
+
/* phys.<->log. block mapping */
int mpio_zone_init(mpio_t *, mpio_cmd_t);
/* context, memory bank, logical block */
@@ -83,6 +87,11 @@ int mpio_io_block_delete(mpio_t *, mpio_mem_t, mpio_fatentry_t *);
int mpio_io_block_delete_phys(mpio_t *, BYTE, DWORD);
/* */
+int mpio_io_megablock_read (mpio_t *, mpio_mem_t, mpio_fatentry_t *, BYTE *);
+/* */
+int mpio_io_megablock_write (mpio_t *, mpio_mem_t, mpio_fatentry_t *, BYTE *);
+
+/* */
int mpio_io_spare_read (mpio_t *, BYTE, DWORD, WORD, BYTE, BYTE *, int,
mpio_callback_init_t);
diff --git a/libmpio/src/mpio.c b/libmpio/src/mpio.c
index 9eed19a..99c3507 100644
--- a/libmpio/src/mpio.c
+++ b/libmpio/src/mpio.c
@@ -1,5 +1,5 @@
/*
- * $Id: mpio.c,v 1.9 2003/09/23 21:32:34 germeier Exp $
+ * $Id: mpio.c,v 1.10 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -101,6 +101,12 @@ static mpio_error_t mpio_errors[] = {
"Out of Memory." },
{ MPIO_ERR_INTERNAL,
"Oops, internal ERROR. :-(" },
+ { MPIO_ERR_DIR_RECURSION,
+ "Ignoring recursive directory entry!" },
+ { MPIO_ERR_FILE_IS_A_DIR ,
+ "Requested file is a directory!" },
+ { MPIO_ERR_USER_CANCEL ,
+ "Operation canceled by user!" },
{ MPIO_ERR_INT_STRING_INVALID,
"Internal Error: Supported is invalid!" }
};
@@ -116,6 +122,12 @@ static int _mpio_errno = 0;
MPIO_ERR_RETURN(MPIO_ERR_INT_STRING_INVALID); \
}
+int
+mpio_error_set(int err) {
+ _mpio_errno = err;
+ return -1;
+}
+
void
mpio_bail_out(void){
printf("I'm utterly confused and aborting now, sorry!");
@@ -190,13 +202,14 @@ mpio_init_internal(mpio_t *m)
/* read FAT information from spare area */
sm->max_cluster = (sm->size * 1024) / 16; /* 1 cluster == 16 KB */
+ /* the new chips seem to use some kind of mega-block (== 128KB) instead of 16KB */
+ if (sm->version)
+ sm->max_cluster /= 8;
sm->max_blocks = sm->max_cluster;
debugn(2, "max_cluster: %d\n", sm->max_cluster);
/* 16 bytes per cluster */
sm->fat_size = (sm->max_cluster * 16) / SECTOR_SIZE;
- /* the new chips seem to use some kind of mega-block (== 128KB) instead of 16KB */
- if (sm->version)
- sm->fat_size /= 8;
+
debugn(2, "fat_size: %04x\n", sm->fat_size * SECTOR_SIZE);
sm->fat = malloc(sm->fat_size * SECTOR_SIZE);
/* fat will be read in mpio_init, so we can more easily handle
@@ -212,16 +225,27 @@ mpio_init_internal(mpio_t *m)
/* Read directory from internal memory */
sm->dir_offset=0;
sm->root = malloc (sizeof(mpio_directory_t));
+ sm->root->dentry=0;
sm->root->name[0] = 0;
sm->root->next = NULL;
sm->root->prev = NULL;
mpio_rootdir_read(m, MPIO_INTERNAL_MEM);
sm->cdir = sm->root;
- if (sm->version)
- debug("Warning, your player has a new SmartMedia chip which is not yet supported\n"
- "Support for this chip is scheduled for the 0.7.1 release\n"
- "Watch http://mpio.sf.net for further announcements\n");
+ if (sm->version) {
+ printf("*******************************************\n");
+ printf("This is a work-in-progress version, so BEWARE!\n");
+ printf("The assumed status of this code is:\n");
+ printf(" * reading: assumed working\n");
+ printf(" * deleting: assumed working, needs further testing\n");
+ printf(" * writing: assumed working, needs further testing\n");
+ printf(" * formatting: assumed working, needs further testing\n");
+
+ /* special features */
+ sm->recursive_directory=1;
+ } else {
+ sm->recursive_directory=0;
+ }
}
void
@@ -274,10 +298,14 @@ mpio_init_external(mpio_t *m)
/* setup directory support */
sm->dir_offset=0;
sm->root = malloc (sizeof(mpio_directory_t));
+ sm->root->dentry=0;
sm->root->name[0] = 0;
sm->root->next = NULL;
sm->root->prev = NULL;
sm->cdir = sm->root;
+
+ /* special features */
+ sm->recursive_directory=0;
}
mpio_t *
@@ -295,9 +323,7 @@ mpio_init(mpio_callback_init_t progress_callback)
}
memset(new_mpio, 0, sizeof(mpio_t));
- new_mpio->fd = open(MPIO_DEVICE, O_RDWR);
-
- if (new_mpio->fd < 0) {
+ if (mpio_device_open(new_mpio) != MPIO_OK) {
_mpio_errno = MPIO_ERR_DEVICE_NOT_READY;
return NULL;
}
@@ -438,6 +464,8 @@ mpio_memory_free(mpio_t *m, mpio_mem_t mem, int *free)
return 0;
}
*free=mpio_fat_free_clusters(m, mem);
+ if (m->internal.version)
+ *free*=8;
return (m->internal.geo.SumSector
* SECTOR_SIZE / 1000 * m->internal.chips);
}
@@ -551,7 +579,7 @@ mpio_file_get_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
BYTE **memory)
{
mpio_smartmedia_t *sm;
- BYTE block[BLOCK_SIZE];
+ BYTE block[MEGABLOCK_SIZE];
int fd, towrite;
BYTE *p;
mpio_fatentry_t *f = 0;
@@ -560,12 +588,15 @@ mpio_file_get_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
DWORD filesize, fsize;
BYTE abort = 0;
int merror;
+ int block_size;
MPIO_CHECK_FILENAME(filename);
if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ block_size = mpio_block_get_blocksize(m, mem);
+
if(as==NULL) {
as = filename;
}
@@ -575,8 +606,11 @@ mpio_file_get_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
if (!p)
p = mpio_dentry_find_name_8_3(m, mem, filename);
- if (p)
+ if (p) {
f = mpio_dentry_get_startcluster(m, mem, p);
+ if (!mpio_dentry_is_dir(m, mem, p))
+ MPIO_ERR_RETURN(MPIO_ERR_FILE_IS_A_DIR);
+ }
if (f && p) {
filesize=fsize=mpio_dentry_get_filesize(m, mem, p);
@@ -592,8 +626,8 @@ mpio_file_get_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
{
mpio_io_block_read(m, mem, f, block);
- if (filesize > BLOCK_SIZE) {
- towrite = BLOCK_SIZE;
+ if (filesize > block_size) {
+ towrite = block_size;
} else {
towrite = filesize;
}
@@ -681,14 +715,15 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
mpio_smartmedia_t *sm;
mpio_fatentry_t *f, current, firstblock, backup;
WORD start;
- BYTE block[BLOCK_SIZE];
+ BYTE block[MEGABLOCK_SIZE];
BYTE use_filename[INFO_LINE];
int fd, toread;
struct stat file_stat;
struct tm tt;
time_t curr;
int id3;
-
+ int block_size;
+
BYTE *p = NULL;
DWORD filesize, fsize, free, blocks;
BYTE abort = 0;
@@ -702,6 +737,8 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
if (mem==MPIO_INTERNAL_MEM) sm=&m->internal;
if (mem==MPIO_EXTERNAL_MEM) sm=&m->external;
+ block_size = mpio_block_get_blocksize(m, mem);
+
if (memory)
{
fsize=filesize=memory_size;
@@ -756,8 +793,8 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
start = f->i_index;
/* number of blocks needed for file */
- blocks = filesize / 0x4000;
- if (filesize % 0x4000)
+ blocks = filesize / block_size;
+ if (filesize % block_size)
blocks++;
debugn(2, "blocks: %02x\n", blocks);
f->i_fat[0x02]=(blocks / 0x100) & 0xff;
@@ -775,10 +812,10 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
}
}
- while ((filesize>BLOCK_SIZE) && (!abort)) {
+ while ((filesize>block_size) && (!abort)) {
- if (filesize>=BLOCK_SIZE) {
- toread=BLOCK_SIZE;
+ if (filesize>=block_size) {
+ toread=block_size;
} else {
toread=filesize;
}
@@ -812,8 +849,8 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
/* handle the last block to write */
- if (filesize>=BLOCK_SIZE) {
- toread=BLOCK_SIZE;
+ if (filesize>=block_size) {
+ toread=block_size;
} else {
toread=filesize;
}
@@ -854,13 +891,16 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
while (mpio_fatentry_next_entry(m, mem, &current))
{
- mpio_io_block_delete(m, mem, &backup);
- mpio_fatentry_set_free(m, mem, &backup);
+ if (!mpio_io_block_delete(m, mem, &backup)) {
+ mpio_fatentry_set_defect(m, mem, &backup);
+ } else {
+ mpio_fatentry_set_free(m, mem, &backup);
+ }
memcpy(&backup, &current, sizeof(mpio_fatentry_t));
- if (filesize > BLOCK_SIZE)
+ if (filesize > block_size)
{
- filesize -= BLOCK_SIZE;
+ filesize -= block_size;
} else {
filesize -= filesize;
}
@@ -868,12 +908,15 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
if (progress_callback)
(*progress_callback)((fsize-filesize), fsize);
}
- mpio_io_block_delete(m, mem, &backup);
- mpio_fatentry_set_free(m, mem, &backup);
+ if (!mpio_io_block_delete(m, mem, &backup)) {
+ mpio_fatentry_set_defect(m, mem, &backup);
+ } else {
+ mpio_fatentry_set_free(m, mem, &backup);
+ }
- if (filesize > BLOCK_SIZE)
+ if (filesize > block_size)
{
- filesize -= BLOCK_SIZE;
+ filesize -= block_size;
} else {
filesize -= filesize;
}
@@ -927,6 +970,20 @@ mpio_file_rename(mpio_t *m, mpio_mem_t mem,
{
BYTE *p;
+ if ((strcmp(old, "..") == 0) ||
+ (strcmp(old, ".") == 0))
+ {
+ debugn(2, "directory name not allowed: %s\n", old);
+ MPIO_ERR_RETURN(MPIO_ERR_DIR_NAME_ERROR);
+ }
+
+ if ((strcmp(new, "..") == 0) ||
+ (strcmp(new, ".") == 0))
+ {
+ debugn(2, "directory name not allowed: %s\n", new);
+ MPIO_ERR_RETURN(MPIO_ERR_DIR_NAME_ERROR);
+ }
+
/* find files */
p = mpio_dentry_find_name(m, mem, old);
if (!p)
@@ -957,9 +1014,13 @@ int mpio_file_move(mpio_t *m,mpio_mem_t mem, mpio_filename_t file,
MPIO_ERR_RETURN(MPIO_ERR_FILE_NOT_FOUND);
}
}
+ debugn(2, " -- moving '%s' after '%s'\n",file,after);
+ } else {
+ debugn(2, " -- moving '%s' to the top\n",file);
}
+
+
- fprintf(stderr," -- moving '%s' after '%s'\n",file,after);
mpio_dentry_move(m,mem,p1,p2);
@@ -1104,12 +1165,15 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
mpio_fatentry_t *f, backup;
DWORD filesize, fsize;
BYTE abort=0;
+ int block_size;
MPIO_CHECK_FILENAME(filename);
if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ block_size = mpio_block_get_blocksize(m, mem);
+
if ((strcmp(filename, "..") == 0) ||
(strcmp(filename, ".") == 0))
{
@@ -1128,6 +1192,9 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
if (f && p) {
if (mpio_dentry_is_dir(m, mem, p) == MPIO_OK)
{
+ if (mpio_dentry_get_attrib(m, mem, p) == 0x1a) {
+ MPIO_ERR_RETURN(MPIO_ERR_DIR_RECURSION);
+ }
/* ugly */
mpio_directory_cd(m, mem, filename);
if (mpio_directory_is_empty(m, mem, sm->cdir) != MPIO_OK)
@@ -1137,6 +1204,7 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
} else {
mpio_directory_cd(m, mem, "..");
}
+
}
filesize=fsize=mpio_dentry_get_filesize(m, mem, p);
@@ -1151,9 +1219,9 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
memcpy(&backup, f, sizeof(mpio_fatentry_t));
- if (filesize > BLOCK_SIZE)
+ if (filesize > block_size)
{
- filesize -= BLOCK_SIZE;
+ filesize -= block_size;
} else {
filesize -= filesize;
}
@@ -1223,6 +1291,8 @@ mpio_health(mpio_t *m, mpio_mem_t mem, mpio_health_t *r)
{
sm = &m->internal;
r->num = sm->chips;
+
+ r->block_size = mpio_block_get_blocksize(m, mem) / 1024;
f = mpio_fatentry_new(m, mem, 0x00, FTYPE_MUSIC);
@@ -1248,10 +1318,11 @@ mpio_health(mpio_t *m, mpio_mem_t mem, mpio_health_t *r)
if (mem == MPIO_EXTERNAL_MEM)
{
- sm = &m->external;
+ sm = &m->external;
zones = sm->max_cluster / MPIO_ZONE_LBLOCKS + 1;
r->num = zones;
+ r->block_size = BLOCK_SIZE/1024;
for(i=0; i<zones; i++)
{
@@ -1278,13 +1349,29 @@ mpio_health(mpio_t *m, mpio_mem_t mem, mpio_health_t *r)
int
mpio_memory_dump(mpio_t *m, mpio_mem_t mem)
{
- BYTE block[BLOCK_SIZE];
+ BYTE block[MEGABLOCK_SIZE];
int i;
+ mpio_fatentry_t *f;
if (mem == MPIO_INTERNAL_MEM)
{
hexdump(m->internal.fat, m->internal.max_blocks*0x10);
hexdump(m->internal.root->dir, DIR_SIZE);
+ if (m->internal.version) {
+ /* new chip */
+ f = mpio_fatentry_new(m, mem, 0x00, FTYPE_MUSIC);
+ mpio_io_block_read(m, mem, f, block);
+ for (i = 0 ; i<=0x05 ; i++) {
+ mpio_fatentry_plus_plus(f);
+ mpio_io_block_read(m, mem, f, block);
+ }
+ free (f);
+ } else {
+ /* old chip */
+ for (i = 0 ; i<=0x100 ; i++)
+ mpio_io_sector_read(m, mem, i, block);
+ }
+
}
if (mem == MPIO_EXTERNAL_MEM)
@@ -1292,11 +1379,10 @@ mpio_memory_dump(mpio_t *m, mpio_mem_t mem)
hexdump(m->external.spare, m->external.max_blocks*0x10);
hexdump(m->external.fat, m->external.fat_size*SECTOR_SIZE);
hexdump(m->external.root->dir, DIR_SIZE);
+ for (i = 0 ; i<=0x100 ; i++)
+ mpio_io_sector_read(m, mem, i, block);
}
- for (i = 0 ; i<=0x100 ; i++)
- mpio_io_sector_read(m, mem, i, block);
-
return 0;
}
@@ -1336,3 +1422,4 @@ mpio_perror(char *prefix)
else
fprintf(stderr, "%s\n", msg);
}
+
diff --git a/libmpio/src/smartmedia.c b/libmpio/src/smartmedia.c
index bf700e9..b1b4aec 100644
--- a/libmpio/src/smartmedia.c
+++ b/libmpio/src/smartmedia.c
@@ -1,5 +1,5 @@
/*
- * $Id: smartmedia.c,v 1.5 2003/07/24 16:17:30 germeier Exp $
+ * $Id: smartmedia.c,v 1.6 2003/10/19 21:06:35 germeier Exp $
*
* libmpio - a library for accessing Digit@lways MPIO players
* Copyright (C) 2002, 2003 Markus Germeier
@@ -34,6 +34,7 @@ mpio_disk_phy_t MPIO_DISK_GEO_016={ 500, 4, 16, 32000 };
mpio_disk_phy_t MPIO_DISK_GEO_032={ 500, 8, 16, 64000 };
mpio_disk_phy_t MPIO_DISK_GEO_064={ 500, 8, 32, 128000 };
mpio_disk_phy_t MPIO_DISK_GEO_128={ 500,16, 32, 256000 };
+mpio_disk_phy_t MPIO_DISK_GEO_256={ 500,32, 32, 512000 }; /* guessed values -mager */
/* This comes from the Samsung documentation files */
@@ -69,11 +70,11 @@ mpio_id2mem(BYTE id)
i=64;
break;
case 0x79:
+ case 0xf1: /* new chip */
i=128;
break;
- case 0xf1:
- debug("Oops, non-standard chip ID, assuming chip is 128MB");
- i=128;
+ case 0xda: /* new chip */
+ i=256;
break;
default:
debug("This should never happen (id2mem)!\n");
@@ -139,10 +140,13 @@ mpio_id2geo(BYTE id, mpio_disk_phy_t *geo)
case 0x76:
*geo = MPIO_DISK_GEO_064;
break;
- case 0xf1: /* non-standard ID */
case 0x79:
+ case 0xf1: /* new chip */
*geo = MPIO_DISK_GEO_128;
break;
+ case 0xda: /* new chip */
+ *geo = MPIO_DISK_GEO_256;
+ break;
default:
debug("This should never happen!\n");
exit (1);
@@ -157,6 +161,7 @@ mpio_id2version(BYTE id)
switch(id)
{
case 0xf1: /* 128MB new Samsung */
+ case 0xda: /* 256MB new Samsung */
return 1;
default:
;
diff --git a/mpiosh/callback.c b/mpiosh/callback.c
index b7f4582..e7d2865 100644
--- a/mpiosh/callback.c
+++ b/mpiosh/callback.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Bsching <crunchy@tzi.de>
*
- * $Id: callback.c,v 1.46 2003/07/27 20:50:01 crunchy Exp $
+ * $Id: callback.c,v 1.47 2003/10/19 21:06:35 germeier Exp $
*
* Copyright (C) 2001 Andreas Bsching <crunchy@tzi.de>
*
@@ -51,6 +51,8 @@ mpiosh_ftype2ascii(BYTE ftype) {
case FTYPE_DIR:
case FTYPE_PLAIN:
return ftype;
+ case FTYPE_DIR_RECURSION:
+ return 'r';
case FTYPE_CHAN:
return 'c';
case FTYPE_MUSIC:
@@ -192,10 +194,15 @@ void
mpiosh_cmd_mkdir(char *args[])
{
BYTE pwd[INFO_LINE];
+ BYTE r;
MPIOSH_CHECK_CONNECTION_CLOSED;
- mpio_directory_make(mpiosh.dev, mpiosh.card, args[0]);
+ r=mpio_directory_make(mpiosh.dev, mpiosh.card, args[0]);
+ if (r != MPIO_OK)
+ {
+ mpio_perror("ERROR");
+ }
mpio_sync(mpiosh.dev, mpiosh.card);
}
@@ -204,14 +211,20 @@ void
mpiosh_cmd_cd(char *args[])
{
BYTE pwd[INFO_LINE];
+ BYTE r;
MPIOSH_CHECK_CONNECTION_CLOSED;
if ( args[ 0 ] != NULL )
- mpio_directory_cd(mpiosh.dev, mpiosh.card, args[0]);
+ r=mpio_directory_cd(mpiosh.dev, mpiosh.card, args[0]);
else
- mpio_directory_cd(mpiosh.dev, mpiosh.card, ".");
+ r=mpio_directory_cd(mpiosh.dev, mpiosh.card, ".");
+ if (r != MPIO_OK)
+ {
+ mpio_perror("ERROR");
+ }
+
mpio_directory_pwd(mpiosh.dev, mpiosh.card, pwd);
printf ("directory is now: %s\n", pwd);
@@ -370,7 +383,7 @@ void
mpiosh_cmd_mget(char *args[])
{
BYTE * p;
- int i = 0, error;
+ int i = 0, error, ret;
regex_t regex;
BYTE fname[100];
BYTE errortext[100];
@@ -401,9 +414,13 @@ mpiosh_cmd_mget(char *args[])
printf("getting '%s' ... \n", fname);
if ((mpio_file_get(mpiosh.dev, mpiosh.card,
fname, mpiosh_callback_get)) == -1) {
- debug("cancelled operation\n");
- mpio_perror("error");
- break;
+ if ((ret=mpio_errno()) == MPIO_ERR_USER_CANCEL) {
+ debug("cancelled operation\n");
+ mpio_perror("error");
+ break;
+ }
+ mpio_error_set(ret);
+ mpio_perror("error");
}
printf("\n");
if (mpiosh_cancel) {
@@ -839,7 +856,7 @@ mpiosh_cmd_health(char *args[])
lost+=health.data[i].broken;
}
if (lost)
- printf("You have lost %d KB due to bad blocks.\n", lost*16);
+ printf("You have lost %d KB due to bad blocks.\n", lost*health.block_size);
}
if (mpiosh.card == MPIO_EXTERNAL_MEM) {