diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | libmpio/defs.h | 19 | ||||
-rw-r--r-- | libmpio/fat.c | 67 | ||||
-rw-r--r-- | libmpio/fat.h | 4 | ||||
-rw-r--r-- | libmpio/io.c | 16 | ||||
-rw-r--r-- | libmpio/mpio.c | 67 | ||||
-rw-r--r-- | libmpio/mpio.h | 19 | ||||
-rw-r--r-- | mpiosh/callback.c | 54 | ||||
-rw-r--r-- | mpiosh/callback.h | 3 | ||||
-rw-r--r-- | mpiosh/global.c | 5 |
10 files changed, 218 insertions, 42 deletions
@@ -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", |