aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--libmpio/defs.h19
-rw-r--r--libmpio/fat.c67
-rw-r--r--libmpio/fat.h4
-rw-r--r--libmpio/io.c16
-rw-r--r--libmpio/mpio.c67
-rw-r--r--libmpio/mpio.h19
-rw-r--r--mpiosh/callback.c54
-rw-r--r--mpiosh/callback.h3
-rw-r--r--mpiosh/global.c5
10 files changed, 218 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index a897993..e741030 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2003-04-18 Markus Germeier <mager@informatik.uni-bremen.de>
+
+ * mpiosh/callback.c (mpiosh_cmd_health):
+ libmpio/mpio.c (mpio_health): new functions to report
+ health status of SmartMedia cards.
+
2003-04-12 Markus Germeier <mager@tzi.de>
* small error messages changes
diff --git a/libmpio/defs.h b/libmpio/defs.h
index baecc7f..36a7361 100644
--- a/libmpio/defs.h
+++ b/libmpio/defs.h
@@ -1,7 +1,7 @@
/* -*- linux-c -*- */
/*
- * $Id: defs.h,v 1.20 2003/04/11 22:53:10 germeier Exp $
+ * $Id: defs.h,v 1.21 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -90,7 +90,7 @@ typedef BYTE (*mpio_callback_init_t)(mpio_mem_t, int, int) ;
#define MPIO_ZONE_MAX 8 /* 8* 16MB = 128MB */
#define MPIO_ZONE_PBLOCKS 1024 /* physical blocks per zone */
#define MPIO_ZONE_LBLOCKS 1000 /* logical blocks per zone */
-typedef WORD mpio_zonetable_t[MPIO_ZONE_MAX][MPIO_ZONE_PBLOCKS];
+typedef DWORD mpio_zonetable_t[MPIO_ZONE_MAX][MPIO_ZONE_PBLOCKS];
#define MPIO_BLOCK_FREE 0xffff
#define MPIO_BLOCK_DEFECT 0xffee
@@ -147,6 +147,7 @@ typedef struct {
#define MPIO_ERR_DIR_NOT_EMPTY -12
#define MPIO_ERR_DEVICE_NOT_READY -13
#define MPIO_ERR_OUT_OF_MEMORY -14
+#define MPIO_ERR_INTERNAL -15
/* internal errors, occur when UI has errors! */
#define MPIO_ERR_INT_STRING_INVALID -101
@@ -195,7 +196,6 @@ struct mpio_directory_tx {
struct mpio_directory_tx *next;
};
-
typedef struct mpio_directory_tx mpio_directory_t;
@@ -240,6 +240,19 @@ typedef struct {
} mpio_smartmedia_t;
+/* health status of a memory "card" */
+typedef struct {
+ WORD total; /* total blocks on "card" */
+ WORD spare; /* (available spare blocks */
+ WORD broken; /* broken blocks */
+} mpio_health_single_t;
+
+typedef struct {
+ BYTE num; /* number of chips or zones */
+ /* internal: max 4 chips
+ * external: max 8 zones (128MB) -> max 8 */
+ mpio_health_single_t data[8];
+} mpio_health_t;
/* view of the MPIO-* */
typedef struct {
diff --git a/libmpio/fat.c b/libmpio/fat.c
index c24f56e..f67c2c1 100644
--- a/libmpio/fat.c
+++ b/libmpio/fat.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: fat.c,v 1.26 2003/04/06 23:09:20 germeier Exp $
+ * $Id: fat.c,v 1.27 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -500,24 +500,8 @@ mpio_fatentry_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f )
if (mem == MPIO_INTERNAL_MEM) {
sm = &m->internal;
e = f->entry * 0x10;
- /* check if this block became defective */
- if (m->model >= MPIO_MODEL_FD100) {
- /* newer models */
- if ((sm->fat[e+0x0f] != 0) ||
- (sm->fat[e+0x01] != sm->fat[e+0x0e]))
- {
- debug("defective block encountered, abort reading! (newer models check)\n");
- return 0xffffffff;
- }
- } else
- if ((sm->fat[e+0x0e] != 'P') ||
- (sm->fat[e+0x0f] != 'C') ||
- ((sm->fat[e+0x00] != 0xaa) &&
- (sm->fat[e+0x00] != 0xee)))
- {
- debug("defective block encountered, abort reading! (older models check)\n");
- return 0xffffffff;
- }
+ if (mpio_fatentry_is_defect(m, mem, f))
+ return 0xffffffff;
/* this is a special system file! */
if((sm->fat[e+6] != FTYPE_MUSIC) &&
@@ -948,9 +932,7 @@ mpio_fatentry_set_defect(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
{
sm = &m->internal;
e = f->entry * 0x10;
- debug("Sorry, I don't now how to mark an internal block as"
- " defective yet.\n");
- /* memset((sm->fat+e), 0xff, 0x10); */
+ memset((sm->fat+e), 0xaa, 0x10);
}
if (mem == MPIO_EXTERNAL_MEM)
@@ -963,6 +945,47 @@ 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;
+ mpio_smartmedia_t *sm;
+
+ if (mem == MPIO_INTERNAL_MEM)
+ {
+ sm = &m->internal;
+ e = f->entry * 0x10;
+ if (mpio_fatentry_free(m, mem, f))
+ return 0;
+ /* check if this block became defective */
+ if (m->model >= MPIO_MODEL_FD100) {
+ /* newer models */
+ if ((sm->fat[e+0x0f] != 0) ||
+ (sm->fat[e+0x01] != sm->fat[e+0x0e]))
+ {
+ debug("defective block encountered, abort reading! (newer models check)\n");
+ return 1;
+ }
+ } else
+ if ((sm->fat[e+0x0e] != 'P') ||
+ (sm->fat[e+0x0f] != 'C') ||
+ ((sm->fat[e+0x00] != 0xaa) &&
+ (sm->fat[e+0x00] != 0xee)))
+ {
+ debug("defective block encountered, abort reading! (older models check)\n");
+ return 1;
+ }
+ }
+
+ if (mem == MPIO_EXTERNAL_MEM)
+ {
+ if (mpio_fatentry_read(m, mem, f)==0xfff7)
+ return 1;
+ }
+
+ return 0;
+}
+
+int
mpio_fatentry_set_eof(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
{
int e;
diff --git a/libmpio/fat.h b/libmpio/fat.h
index 5ab7617..6b7451f 100644
--- a/libmpio/fat.h
+++ b/libmpio/fat.h
@@ -1,6 +1,6 @@
/*
*
- * $Id: fat.h,v 1.10 2002/10/26 13:07:43 germeier Exp $
+ * $Id: fat.h,v 1.11 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -69,6 +69,8 @@ int mpio_fatentry_set_eof(mpio_t *, mpio_mem_t,
mpio_fatentry_t *);
int mpio_fatentry_set_next(mpio_t *, mpio_mem_t,
mpio_fatentry_t *, mpio_fatentry_t *);
+int mpio_fatentry_is_defect(mpio_t *, mpio_mem_t,
+ mpio_fatentry_t *);
/* finding a file is fundamental different for internal mem */
int mpio_fat_internal_find_startsector(mpio_t *, BYTE);
diff --git a/libmpio/io.c b/libmpio/io.c
index 1d1f213..0ef8258 100644
--- a/libmpio/io.c
+++ b/libmpio/io.c
@@ -2,7 +2,7 @@
/*
*
- * $Id: io.c,v 1.24 2003/04/04 22:03:05 germeier Exp $
+ * $Id: io.c,v 1.25 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -45,8 +45,8 @@
#include "ecc.h"
BYTE model2externalmem(mpio_model_t);
-WORD blockaddress_encode(WORD);
-WORD blockaddress_decode(BYTE *);
+DWORD blockaddress_encode(DWORD);
+DWORD blockaddress_decode(BYTE *);
void fatentry2hw(mpio_fatentry_t *, BYTE *, DWORD *);
/* small hack to handle external addressing on different MPIO models */
@@ -70,8 +70,8 @@ model2externalmem(mpio_model_t model)
/* encoding and decoding of blockaddresses */
-WORD
-blockaddress_encode(WORD ba)
+DWORD
+blockaddress_encode(DWORD ba)
{
WORD addr;
BYTE p = 0, c = 0;
@@ -102,7 +102,7 @@ blockaddress_encode(WORD ba)
}
-WORD
+DWORD
blockaddress_decode(BYTE *entry)
{
WORD ba;
@@ -217,7 +217,7 @@ mpio_zone_init(mpio_t *m, mpio_cmd_t mem)
sm->zonetable[zone][block]=blockaddress_decode(sm->spare+e);
hexdumpn(4, sm->spare+e, 0x10);
- debugn(2, "decoded: %03x\n", sm->zonetable[zone][block]);
+ debugn(2, "decoded: %04x\n", sm->zonetable[zone][block]);
}
}
@@ -1101,7 +1101,7 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address)
if (status[0] != 0xc0)
{
- debug ("error formatting Block %02x:%06x\n",
+ debugn (2,"error formatting Block %02x:%06x\n",
chip, address);
if (chip == MPIO_EXTERNAL_MEM)
{
diff --git a/libmpio/mpio.c b/libmpio/mpio.c
index a3b177b..444d328 100644
--- a/libmpio/mpio.c
+++ b/libmpio/mpio.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: mpio.c,v 1.50 2003/04/11 22:53:10 germeier Exp $
+ * $Id: mpio.c,v 1.51 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -97,6 +97,8 @@ static mpio_error_t mpio_errors[] = {
"your MPIO is\nconnected and powered up.\n" },
{ MPIO_ERR_OUT_OF_MEMORY,
"Out of Memory." },
+ { MPIO_ERR_INTERNAL,
+ "Oops, internal ERROR. :-(" },
{ MPIO_ERR_INT_STRING_INVALID,
"Internal Error: Supported is invalid!" }
};
@@ -1142,6 +1144,69 @@ mpio_sync(mpio_t *m, mpio_mem_t mem)
return mpio_fat_write(m, mem);
}
+int
+mpio_health(mpio_t *m, mpio_mem_t mem, mpio_health_t *r)
+{
+ mpio_smartmedia_t *sm;
+ int i, j, zones;
+ mpio_fatentry_t *f;
+
+ if (mem == MPIO_INTERNAL_MEM)
+ {
+ sm = &m->internal;
+ r->num = sm->chips;
+
+ f = mpio_fatentry_new(m, mem, 0x00, FTYPE_MUSIC);
+
+ for (i=0 ; i < sm->chips; i++)
+ {
+ r->data[i].spare = 0;
+ r->data[i].total = (sm->max_cluster / sm->chips);
+ r->data[i].broken = 0;
+ /* now count the broken blocks */
+ for(j=0; j<r->data[i].total; j++)
+ {
+ if (mpio_fatentry_is_defect(m, mem, f))
+ r->data[i].broken++;
+ mpio_fatentry_plus_plus(f);
+ }
+ }
+
+ free(f);
+
+ return MPIO_OK;
+ }
+
+
+ if (mem == MPIO_EXTERNAL_MEM)
+ {
+ sm = &m->external;
+
+ zones = sm->max_cluster / MPIO_ZONE_LBLOCKS + 1;
+ r->num = zones;
+
+ for(i=0; i<zones; i++)
+ {
+ r->data[i].spare = (i?24:22); /* first zone has only 23 due to CIS */
+ r->data[i].total = MPIO_ZONE_PBLOCKS;
+ r->data[i].broken = 0;
+ /* now count the broken blocks */
+ for(j=0; j<MPIO_ZONE_PBLOCKS; j++)
+ {
+ if (!i && !j)
+ continue; /* ignore "defective" first block */
+ if (sm->zonetable[i][j] == MPIO_BLOCK_DEFECT)
+ r->data[i].broken++;
+ }
+ if (r->data[i].spare < r->data[i].broken)
+ debug("(spare blocks<broken blocks) -> expect trouble!\n");
+ }
+ return MPIO_OK;
+ }
+
+ return MPIO_ERR_INTERNAL;
+}
+
int
mpio_memory_dump(mpio_t *m, mpio_mem_t mem)
{
diff --git a/libmpio/mpio.h b/libmpio/mpio.h
index 94db5af..c96888d 100644
--- a/libmpio/mpio.h
+++ b/libmpio/mpio.h
@@ -1,7 +1,7 @@
#/* -*- linux-c -*- */
/*
- * $Id: mpio.h,v 1.15 2003/04/06 23:09:20 germeier Exp $
+ * $Id: mpio.h,v 1.16 2003/04/18 13:53:01 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -154,10 +154,14 @@ int mpio_memory_format(mpio_t *, mpio_mem_t, mpio_callback_t);
* and thereby exhausting the SmartMedia chips
*/
/* context, memory bank */
-int mpio_sync(mpio_t *, mpio_mem_t);
+int mpio_sync(mpio_t *, mpio_mem_t);
-/* context, memory bank */
-int mpio_memory_dump(mpio_t *, mpio_mem_t);
+/*
+ * "special" functions
+ */
+
+/* returns health status of selected memory */
+int mpio_health(mpio_t *, mpio_mem_t, mpio_health_t *);
/*
* error handling
@@ -173,6 +177,13 @@ char * mpio_strerror(int err);
void mpio_perror(char *prefix);
/*
+ * debugging
+ */
+
+/* context, memory bank */
+int mpio_memory_dump(mpio_t *, mpio_mem_t);
+
+/*
* timeline:
* ---------
* 2004: some functions to change the order of files
diff --git a/mpiosh/callback.c b/mpiosh/callback.c
index 28c0284..b252f24 100644
--- a/mpiosh/callback.c
+++ b/mpiosh/callback.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Büsching <crunchy@tzi.de>
*
- * $Id: callback.c,v 1.37 2003/04/11 22:53:10 germeier Exp $
+ * $Id: callback.c,v 1.38 2003/04/18 13:53:01 germeier Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -709,6 +709,7 @@ mpiosh_cmd_format(char *args[])
}
}
+ mpiosh_cmd_health(NULL);
}
}
@@ -745,6 +746,57 @@ mpiosh_cmd_dump_mem(char *args[])
}
void
+mpiosh_cmd_health(char *args[])
+{
+ mpio_health_t health;
+ int i, lost;
+
+ UNUSED(args);
+
+ MPIOSH_CHECK_CONNECTION_CLOSED;
+
+ mpio_health(mpiosh.dev, mpiosh.card, &health);
+
+ if (mpiosh.card == MPIO_INTERNAL_MEM) {
+ lost=0;
+ printf("health status of internal memory:\n");
+ printf("=================================\n");
+ printf("%d chip%c (total/spare/broken)\n",
+ health.num, ((health.num==1)?' ':'s'));
+ for(i=0; i<health.num; i++) {
+ printf("chip #%d (%5d/%5d/%6d)\n", (i+1),
+ health.data[i].total,
+ health.data[i].spare,
+ health.data[i].broken);
+ lost+=health.data[i].broken;
+ }
+ if (lost)
+ printf("You have lost %d KB due to bad blocks.\n", lost*16);
+ }
+
+ if (mpiosh.card == MPIO_EXTERNAL_MEM) {
+ lost=0;
+ printf("health status of external memory:\n");
+ printf("=================================\n");
+ printf("%d zone%c (total/spare/broken)\n",
+ health.num, ((health.num==1)?' ':'s'));
+ for(i=0; i<health.num; i++) {
+ printf("zone #%d (%5d/%5d/%6d)\n", (i+1),
+ health.data[i].total,
+ health.data[i].spare,
+ health.data[i].broken);
+ if (health.data[i].spare<health.data[i].broken)
+ lost++;
+ }
+ if (lost)
+ printf("%d zone%s to many broken blocks, expect trouble! :-(\n", lost,
+ ((lost==1)?" has":"s have"));
+ }
+
+
+}
+
+void
mpiosh_cmd_config(char *args[])
{
BYTE *config_data;
diff --git a/mpiosh/callback.h b/mpiosh/callback.h
index ac9862c..b480105 100644
--- a/mpiosh/callback.h
+++ b/mpiosh/callback.h
@@ -2,7 +2,7 @@
*
* Author: Andreas Büsching <crunchy@tzi.de>
*
- * $Id: callback.h,v 1.8 2003/04/06 23:09:20 germeier Exp $
+ * $Id: callback.h,v 1.9 2003/04/18 13:53:02 germeier Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -50,6 +50,7 @@ void mpiosh_cmd_free(char *args[]);
void mpiosh_cmd_format(char *args[]);
void mpiosh_cmd_switch(char *args[]);
void mpiosh_cmd_dump_mem(char *args[]);
+void mpiosh_cmd_health(char *args[]);
void mpiosh_cmd_config(char *args[]);
void mpiosh_cmd_channel(char *args[]);
diff --git a/mpiosh/global.c b/mpiosh/global.c
index 4bfe7b5..7910eff 100644
--- a/mpiosh/global.c
+++ b/mpiosh/global.c
@@ -2,7 +2,7 @@
*
* Author: Andreas Buesching <crunchy@tzi.de>
*
- * $Id: global.c,v 1.8 2003/04/06 23:09:20 germeier Exp $
+ * $Id: global.c,v 1.9 2003/04/18 13:53:02 germeier Exp $
*
* Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de>
*
@@ -117,6 +117,9 @@ struct mpiosh_cmd_t commands[] = {
{ "lmkdir", NULL, NULL,
" create a local directory",
mpiosh_cmd_lmkdir, NULL },
+ { "health", NULL, NULL,
+ " show the health status from the selected memory",
+ mpiosh_cmd_health, NULL },
{ "dump_memory", NULL, NULL,
" dump FAT, directory, spare area and the first 0x100 of the\n"
" selected memory card",