From 2ce485fa24fb3ccba872e6dbd256c0485e1e7ed8 Mon Sep 17 00:00:00 2001 From: germeier Date: Sun, 19 Oct 2003 21:06:33 +0000 Subject: added support for the new internal chip added support for libusb if the kernel driver is not available --- configure.in | 43 +++++- libmpio/Makefile.am | 6 +- libmpio/defs.h | 37 ++++- libmpio/mpio.h | 11 +- libmpio/src/directory.c | 126 ++++++++++++---- libmpio/src/directory.h | 3 +- libmpio/src/fat.c | 79 +++++++--- libmpio/src/io.c | 364 ++++++++++++++++++++++++++++++++++++++++++++--- libmpio/src/io.h | 11 +- libmpio/src/mpio.c | 167 ++++++++++++++++------ libmpio/src/smartmedia.c | 15 +- mpiosh/callback.c | 35 +++-- 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 (iroot->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 (iroot->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 #include #include +#include +#include #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) { @@ -888,6 +1049,66 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) return 0; } +/* + * 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 */ @@ -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,20 +1335,100 @@ 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) { @@ -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 */ @@ -82,6 +86,11 @@ int mpio_io_block_delete(mpio_t *, mpio_mem_t, mpio_fatentry_t *); /* needed for formatting of external memory */ 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, ¤t)) { - 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, ¤t, 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; iinternal.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 Büsching * - * $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 Büsching * @@ -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) { -- cgit v1.2.3