From 1f791c254d58441a745681b76c925c534e2b3638 Mon Sep 17 00:00:00 2001 From: germeier Date: Sun, 6 Oct 2002 21:19:50 +0000 Subject: major changes to write support, BEWARE, some things might be broken in the progress (internal mem too!) added files cis.{c,h} --- ChangeLog | 10 ++ libmpio/Makefile.am | 6 +- libmpio/cis.c | 81 ++++++++++++++ libmpio/cis.h | 34 ++++++ libmpio/fat.c | 306 +++++++++++++++++++++++++++++++++++++++------------- libmpio/fat.h | 13 ++- libmpio/io.c | 98 ++++++++++++----- libmpio/io.h | 10 +- libmpio/mpio.c | 101 +++++++++++------ 9 files changed, 519 insertions(+), 140 deletions(-) create mode 100644 libmpio/cis.c create mode 100644 libmpio/cis.h diff --git a/ChangeLog b/ChangeLog index c3cb696..5fa66af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2002-10-05 Markus Germeier + * big changes to IO layer and updates to formating/writing + for external memory + * BEWARE: writing to external mem still does not work + and I might have damaged the internal support! + +2002-10-05 Markus Germeier + + * libmpio/cis.c: generate new CIS block for formatting + 2002-09-30 Markus Germeier * libmpio/mpio.c (mpio_init): fixed identification of diff --git a/libmpio/Makefile.am b/libmpio/Makefile.am index 0517b3a..d489a64 100644 --- a/libmpio/Makefile.am +++ b/libmpio/Makefile.am @@ -9,7 +9,8 @@ libmpio_la_SOURCES= \ smartmedia.c \ directory.c \ fat.c \ - ecc.c + ecc.c \ + cis.c pkginclude_HEADERS= \ mpio.h \ @@ -21,4 +22,5 @@ noinst_HEADERS= \ smartmedia.h \ directory.h \ fat.h \ - ecc.h + ecc.h \ + cis.h diff --git a/libmpio/cis.c b/libmpio/cis.c new file mode 100644 index 0000000..c30085b --- /dev/null +++ b/libmpio/cis.c @@ -0,0 +1,81 @@ +/* + * + * $Id: cis.c,v 1.1 2002/10/06 21:19:50 germeier Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#include "cis.h" + +/* This data is CIS block (Card Information System) of the SmartMedia + * cards, it can be found here: + * http://www.samsungelectronics.com/semiconductors/flash/technical_data/application_notes/SM_format.pdf (page 8 + 9) + * or on any Smartmedia card + * + * It is not believed to be some kind of trade secret or such, so ... + * ... if we are mistaken, please tell us so. + */ + +char cis_templ[0x80] = { + 0x01, 0x03, 0xd9, 0x01, 0xff, 0x18, 0x02, 0xdf, /* 0x00 */ + 0x01, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, + + 0x02, 0x04, 0x01, 0x22, 0x02, 0x01, 0x01, 0x22, /* 0x10 */ + 0x03, 0x02, 0x04, 0x07, 0x1a, 0x05, 0x01, 0x03, + + 0x00, 0x02, 0x0f, 0x1b, 0x08, 0xc0, 0xc0, 0xa1, /* 0x20 */ + 0x01, 0x55, 0x08, 0x00, 0x20, 0x1b, 0x0a, 0xc1, + + 0x41, 0x99, 0x01, 0x55, 0x64, 0xf0, 0xff, 0xff, /* 0x30 */ + 0x20, 0x1b, 0x0c, 0x82, 0x41, 0x18, 0xea, 0x61, + + 0xf0, 0x01, 0x07, 0xf6, 0x03, 0x01, 0xee, 0x1b, /* 0x40 */ + 0x0c, 0x83, 0x41, 0x18, 0xea, 0x61, 0x70, 0x01, + + 0x07, 0x76, 0x03, 0x01, 0xee, 0x15, 0x14, 0x05, /* 0x50 */ + 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + + 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x30, 0x2e, /* 0x60 */ + 0x30, 0x00, 0xff, 0x14, 0x00, 0xff, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + +BYTE * +mpio_cis_gen() +{ + BYTE *p; + + p = (BYTE *)malloc(SECTOR_SIZE); + + memset(p, 0, SECTOR_SIZE); + memcpy(p, cis_templ, 0x80); + memcpy(p+0x100, cis_templ, 0x80); + + return p; + +} + + + + diff --git a/libmpio/cis.h b/libmpio/cis.h new file mode 100644 index 0000000..2f3848c --- /dev/null +++ b/libmpio/cis.h @@ -0,0 +1,34 @@ +/* + * + * $Id: cis.h,v 1.1 2002/10/06 21:19:50 germeier Exp $ + * + * Library for USB MPIO-* + * + * Markus Germeier (mager@tzi.de) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * */ + +#ifndef _MPIO_CIS_H_ +#define _MPIO_CIS_H_ + +#include "defs.h" + +/* generate and return a fresh CIS block */ +BYTE *mpio_cis_gen(); + +#endif diff --git a/libmpio/fat.c b/libmpio/fat.c index 5690206..e8a7234 100644 --- a/libmpio/fat.c +++ b/libmpio/fat.c @@ -1,6 +1,6 @@ /* * - * $Id: fat.c,v 1.15 2002/09/28 00:32:41 germeier Exp $ + * $Id: fat.c,v 1.16 2002/10/06 21:19:50 germeier Exp $ * * Library for USB MPIO-* * @@ -30,6 +30,213 @@ #include #include +/* I'm lazy so I hard code all the values */ + +BYTE mpio_part_016[0x10] = { + 0x80, 0x02, 0x0a, 0x00, 0x01, 0x03, 0x50, 0xf3, + 0x29, 0x00, 0x00, 0x00, 0xd7, 0x7c, 0x00, 0x00 +}; +BYTE mpio_part_032[0x10] = { + 0x80, 0x02, 0x04, 0x00, 0x01, 0x07, 0x50, 0xf3, + 0x23, 0x00, 0x00, 0x00, 0xdd, 0xf9, 0x00, 0x00 +}; +BYTE mpio_part_064[0x10] = { + 0x80, 0x01, 0x18, 0x00, 0x01, 0x07, 0x60, 0xf3, + 0x37, 0x00, 0x00, 0x00, 0xc9, 0xf3, 0x01, 0x00 +}; +BYTE mpio_part_128[0x10] = { + 0x80, 0x01, 0x10, 0x00, 0x06, 0x0f, 0x60, 0xf3, + 0x2f, 0x00, 0x00, 0x00, 0xd1, 0xe7, 0x03, 0x00 +}; + +/* ------------------------- */ + +BYTE mpio_pbr_head[0x10] = { + 0xe9, 0x00, 0x00, 0x4d, 0x53, 0x44, 0x4f, 0x53, + 0x35, 0x2e, 0x30, 0x00, 0x02, 0x20, 0x01, 0x00 +}; +BYTE mpio_pbr_016[0x13] = { + 0x02, 0x00, 0x01, 0xd7, 0x7c, 0xf8, 0x03, 0x00, + 0x10, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; +BYTE mpio_pbr_032[0x13] = { + 0x02, 0x00, 0x01, 0xdd, 0xf9, 0xf8, 0x06, 0x00, + 0x10, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; +BYTE mpio_pbr_064[0x13] = { + 0x02, 0x00, 0x01, 0x00, 0x00, 0xf8, 0x0c, 0x00, + 0x20, 0x00, 0x08, 0x00, 0x37, 0x00, 0x00, 0x00, + 0xc9, 0xf3, 0x01 +}; +BYTE mpio_pbr_128[0x13] = { + 0x02, 0x00, 0x01, 0x00, 0x00, 0xf8, 0x20, 0x00, + 0x20, 0x00, 0x10, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0xd1, 0xe7, 0x03 +}; + +BYTE * +mpio_mbr_gen(BYTE size) +{ + BYTE *p; + + p = (BYTE *)malloc(SECTOR_SIZE); + memset(p, 0, SECTOR_SIZE); + + /* MBR signature */ + p[0x1fe] = 0x55; + p[0x1ff] = 0xaa; + + /* frist boot partition */ + switch(size) + { + case 16: + memcpy(p+0x1be, mpio_part_016, 0x10); + break; + case 32: + memcpy(p+0x1be, mpio_part_032, 0x10); + break; + case 64: + memcpy(p+0x1be, mpio_part_064, 0x10); + break; + case 128: + memcpy(p+0x1be, mpio_part_128, 0x10); + break; + default: + debug("This should never happen! (%d)\n", size); + exit(-1); + } + + /* all other partitions are set to zero */ + + return p; +} + +BYTE * +mpio_pbr_gen(BYTE size) +{ + BYTE *p; + + p = (BYTE *)malloc(SECTOR_SIZE); + memset(p, 0, SECTOR_SIZE); + + /* MBR signature */ + p[0x1fe] = 0x55; + p[0x1ff] = 0xaa; + + memcpy(p, mpio_pbr_head, 0x10); + /* BIOS parameter etc. */ + switch(size) + { + case 16: + memcpy(p+0x10, mpio_pbr_016, 0x13); + break; + case 32: + memcpy(p+0x10, mpio_pbr_032, 0x13); + break; + case 64: + memcpy(p+0x10, mpio_pbr_064, 0x13); + break; + case 128: + memcpy(p+0x10, mpio_pbr_128, 0x13); + break; + default: + debug("This should never happen! (%d)\n", size); + exit(-1); + } + + /* FAT id */ + if (size >=128) { + strcpy(p+0x36, "FAT16"); + } else { + strcpy(p+0x36, "FAT12"); + } + + return p; +} + +int +mpio_mbr_eval(mpio_smartmedia_t *sm) +{ + BYTE *pe; /* partition entry */ + int sector, head, cylinder; + + if ((sm->mbr[0x1fe] != 0x55) || (sm->mbr[0x1ff] != 0xaa)) + { + debug("This is not the MBR!\n"); + return 1; + } + + /* always use the first partition */ + /* we probably don't need to support others */ + pe = sm->mbr + 0x1be; + + head = (int)(*(pe+0x01) & 0xff); + sector = (int)(*(pe+0x02) & 0x3f); + cylinder = (int)((*(pe+0x02) >> 6) * 0x100 + *(pe + 0x03)); + + sm->pbr_offset=(cylinder * sm->geo.NumHead + head ) * + sm->geo.NumSector + sector - 1 /*+ OFFSET_MBR */; + + return 0; + +} + + +int +mpio_pbr_eval(mpio_smartmedia_t *sm) +{ + BYTE *bpb; /* BIOS Parameter Block */ + int total_sector; + long temp; + + if ((sm->pbr[0x1fe] != 0x55) || (sm->pbr[0x1ff] != 0xaa)) + { + debug("This is not the PBR!\n"); + return 1; + } + + if (strncmp((sm->pbr+0x36),"FAT", 3) != 0) + { + debug("Did not find an FAT signature, *not* good!\n"); + return 2; + } + + bpb = sm->pbr + 0x0b; + + total_sector = (*(sm->pbr+0x14) * 0x100 + *(sm->pbr + 0x13)); + if (!total_sector) + total_sector = (*(sm->pbr+0x23) * 0x1000000 + + *(sm->pbr+0x22) * 0x10000 + + *(sm->pbr+0x21) * 0x100 + + *(sm->pbr+0x20)); + + /* 128 MB need 2 Bytes instead of 1.5 */ + if (sm->size != 128) + { + temp = ((total_sector / 0x20 * 0x03 / 0x02 / 0x200) + 0x01); + } else { + temp = ((total_sector / 0x20 * 0x02 / 0x200) + 0x01); + } + + sm->fat_offset = sm->pbr_offset + 0x01; + sm->fat_size = temp; + sm->fat_nums = *(sm->pbr + 0x10); + sm->dir_offset = sm->pbr_offset + 0x01 + temp * 2; + sm->max_cluster = (total_sector / BLOCK_SECTORS); + /* fix max clusters */ + temp*=2; + while (temp>=0x10) + { + sm->max_cluster--; + temp-=BLOCK_SECTORS; + } + + return 0; +} + + void mpio_fatentry_hw2entry(mpio_t *m, mpio_fatentry_t *f) { @@ -95,13 +302,9 @@ mpio_fatentry_entry2hw(mpio_t *m, mpio_fatentry_t *f) int mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem) { - BYTE *pe; /* partition entry */ - BYTE *bpb; /* BIOS Parameter Block */ - mpio_smartmedia_t *sm=0; - int sector, head, cylinder, total_sector; - long temp; + int error; /* this should not be needed for internal memory, but ... */ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; @@ -109,6 +312,11 @@ mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem) if (!sm) return 1; + /* in case the external mem is defective we need this here! */ + sm->fat=0; + sm->fat_size=0; + sm->fat_nums=0; + /* TODO: check a few things more, just to be sure */ /* read CIS (just in case it might me usefull) */ @@ -126,22 +334,12 @@ mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem) return 1; } - if ((sm->mbr[0x1fe] != 0x55) || (sm->mbr[0x1ff] != 0xaa)) + if (error=mpio_mbr_eval(sm)) { - debug("This is not the MBR!\n"); + debug("problem with the MBR (#%d), so I won't try to access the card any" + "further.\n", error); return 1; } - - /* always use the first partition */ - /* we probably don't need to support others */ - pe = sm->mbr + 0x1be; - - head = (int)(*(pe+0x01) & 0xff); - sector = (int)(*(pe+0x02) & 0x3f); - cylinder = (int)((*(pe+0x02) >> 6) * 0x100 + *(pe + 0x03)); - - sm->pbr_offset=(cylinder * sm->geo.NumHead + head ) * - sm->geo.NumSector + sector - 1 /*+ OFFSET_MBR */; /* read PBR */ if (mpio_io_sector_read(m, mem, sm->pbr_offset, sm->pbr)) @@ -150,50 +348,12 @@ mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem) return 1; } - if ((sm->pbr[0x1fe] != 0x55) || (sm->pbr[0x1ff] != 0xaa)) + if (error=mpio_pbr_eval(sm)) { - debug("This is not the PBR!\n"); + debug("problem with the PBR (#%d), so I won't try to access the card any" + "further.\n", error); return 1; } - - if (strncmp((sm->pbr+0x36),"FAT", 3) != 0) - { - debug("Did not find an FAT signature, *not* good!, aborting!\n"); - exit (1); - } - - bpb = sm->pbr + 0x0b; - - total_sector = (*(sm->pbr+0x14) * 0x100 + *(sm->pbr + 0x13)); - if (!total_sector) - total_sector = (*(sm->pbr+0x23) * 0x1000000 + - *(sm->pbr+0x22) * 0x10000 + - *(sm->pbr+0x21) * 0x100 + - *(sm->pbr+0x20)); - - /* 128 MB need 2 Bytes instead of 1.5 */ - if (sm->size != 128) - { - temp = ((total_sector / 0x20 * 0x03 / 0x02 / 0x200) + 0x01); - } else { - temp = ((total_sector / 0x20 * 0x02 / 0x200) + 0x01); - } - - sm->fat_offset = sm->pbr_offset + 0x01; - sm->fat_size = temp; - sm->fat_nums = *(sm->pbr + 0x10); - sm->dir_offset = sm->pbr_offset + 0x01 + temp * 2; - sm->max_cluster = (total_sector / BLOCK_SECTORS); - /* fix max clusters */ - temp*=2; - while (temp>=0x10) - { - sm->max_cluster--; - temp-=BLOCK_SECTORS; - } - -/* debug("max_cluster: %d\n", sm->max_cluster); */ -/* debug("temp: %04x\n", temp); */ return 0; } @@ -638,7 +798,8 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) free(f); memset(dummy, 0x00, BLOCK_SIZE); - + + /* only write the FAT */ for (i= 0; i< 0x20; i++) { @@ -646,6 +807,7 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) { mpio_io_sector_write(m, mem, i, (sm->dir + SECTOR_SIZE * i)); } else { + /* fill the rest of the block with zeros */ mpio_io_sector_write(m, mem, i, dummy); } } @@ -656,27 +818,25 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) sm=&m->external; memset(dummy, 0xff, BLOCK_SIZE); - - for (i = 0x40; i < (sm->dir_offset + DIR_NUM) ; i++) { + + for (i = 0; i < (sm->dir_offset + DIR_NUM) ; i++) { + /* before writing to a new block delete it! */ if (((i / 0x20) * 0x20) == i) { - /* yuck */ - f=mpio_fatentry_new(m, mem, - ((i / 0x20) - - ((sm->dir_offset + DIR_NUM)/BLOCK_SECTORS - 2 )), - FTYPE_MUSIC); + f=mpio_fatentry_new(m, mem, i, FTYPE_MUSIC); mpio_io_block_delete(m, mem, f); free(f); } - - if (i == 0x40) - mpio_io_sector_write(m, mem, 0x40, sm->mbr); - if ((i > 0x40) && (i < sm->pbr_offset)) + + /* remeber: logical sector 0 is the MBR! */ + if (i == 0) + mpio_io_sector_write(m, mem, 0, sm->mbr); + if ((i > 0) && (i < sm->pbr_offset)) mpio_io_sector_write(m, mem, i, dummy); if (i == sm->pbr_offset) mpio_io_sector_write(m, mem, sm->pbr_offset, sm->pbr); - if ((i >= sm->fat_offset) && (i < (sm->fat_offset + (2 * sm->fat_size)))) + if ((i >= sm->fat_offset) && (i < (sm->fat_offset + (2*sm->fat_size)))) mpio_io_sector_write(m, mem, i, (sm->fat + SECTOR_SIZE * ((i - sm->fat_offset) % sm->fat_size))); diff --git a/libmpio/fat.h b/libmpio/fat.h index 65e0857..8255311 100644 --- a/libmpio/fat.h +++ b/libmpio/fat.h @@ -1,6 +1,6 @@ /* * - * $Id: fat.h,v 1.8 2002/09/24 15:38:03 germeier Exp $ + * $Id: fat.h,v 1.9 2002/10/06 21:19:50 germeier Exp $ * * Library for USB MPIO-* * @@ -28,14 +28,23 @@ #include "defs.h" +/* generate fresh boot sectors for formatting of external mem */ +BYTE *mpio_mbr_gen(BYTE); +BYTE *mpio_pbr_gen(BYTE); + +/* only needed for external memory */ int mpio_bootblocks_read(mpio_t *, mpio_mem_t); +int mpio_mbr_eval(mpio_smartmedia_t *); +int mpio_pbr_eval(mpio_smartmedia_t *); +/* functions on the FAT for internal *and* external */ int mpio_fat_read(mpio_t *, mpio_mem_t, mpio_callback_init_t); int mpio_fat_write(mpio_t *, mpio_mem_t); int mpio_fat_clear(mpio_t *, mpio_mem_t); int mpio_fat_free_clusters(mpio_t *, mpio_mem_t); int mpio_fat_free(mpio_t *, mpio_mem_t); +/* functions to iterate through the FAT linked list(s) */ mpio_fatentry_t *mpio_fatentry_new(mpio_t *, mpio_mem_t, DWORD, BYTE); int mpio_fatentry_plus_plus(mpio_fatentry_t *); @@ -57,9 +66,11 @@ int mpio_fatentry_set_eof(mpio_t *, mpio_mem_t, int mpio_fatentry_set_next(mpio_t *, mpio_mem_t, mpio_fatentry_t *, mpio_fatentry_t *); +/* finding a file is fundamental different for internal mem */ int mpio_fat_internal_find_startsector(mpio_t *, BYTE); BYTE mpio_fat_internal_find_fileindex(mpio_t *); +/* mapping logical <-> physical for internal memory only */ void mpio_fatentry_hw2entry(mpio_t *, mpio_fatentry_t *); void mpio_fatentry_entry2hw(mpio_t *, mpio_fatentry_t *); diff --git a/libmpio/io.c b/libmpio/io.c index 6a11866..50f856d 100644 --- a/libmpio/io.c +++ b/libmpio/io.c @@ -2,7 +2,7 @@ /* * - * $Id: io.c,v 1.17 2002/09/28 00:32:41 germeier Exp $ + * $Id: io.c,v 1.18 2002/10/06 21:19:50 germeier Exp $ * * Library for USB MPIO-* * @@ -241,7 +241,7 @@ mpio_zone_block_find(mpio_t *m, mpio_cmd_t mem, DWORD lblock) */ v = lblock + (sm->size/64); - if (lblock == MPIO_BLOCK_CIS) + if ((lblock>=MPIO_BLOCK_CIS) && (lblock<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) { zone = 0; block = MPIO_BLOCK_CIS; @@ -502,9 +502,10 @@ mpio_io_sector_read(mpio_t *m, BYTE mem, DWORD index, BYTE *output) sector = index; } else { /* find the correct physical block first! */ - if (index == MPIO_BLOCK_CIS) + if ((index>=MPIO_BLOCK_CIS) && (index<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) { - sector = mpio_zone_block_find(m, mem, index); + sector = mpio_zone_block_find(m, mem, MPIO_BLOCK_CIS); + sector+= (index % MPIO_BLOCK_CIS); } else { sector = mpio_zone_block_find(m, mem, /* yuck */ ((index / 0x20) - (sm->size/64))); @@ -598,6 +599,23 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) exit (-1); } + /* we have to: + * - find the physical block (or allocate a new one) + * - calculate the logical block for zone management + */ + block_address = index / MPIO_ZONE_LBLOCKS; /* easy! :-) */ + + if ((index % BLOCK_SECTORS) == 0) + { + /* this is the first write to the block, so allocate a new one */ + + /* mark it with the block_address */ + + } else { + /* find the block from the block list! */ + + } + mpio_io_set_cmdpacket(m, PUT_SECTOR, mem, index, sm->size, 0, cmdpacket); debugn (5, "\n>>> MPIO\n"); @@ -616,23 +634,32 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) memset(sendbuff + SECTOR_SIZE, 0xff, 0x10); memcpy(sendbuff, input, SECTOR_SIZE); -/* if (mem==MPIO_EXTERNAL_MEM) */ -/* block_address = cluster2blockaddress(index, sm->size); */ - + if (mem==MPIO_EXTERNAL_MEM) { - /* generate ECC information for spare area ! */ - mpio_ecc_256_gen(sendbuff, - sendbuff + SECTOR_SIZE + 0x0d); - mpio_ecc_256_gen(sendbuff + (SECTOR_SIZE / 2), - sendbuff + SECTOR_SIZE + 0x08); - - ba = (block_address / 0x100) & 0xff; - sendbuff[SECTOR_SIZE + 0x06] = ba; - sendbuff[SECTOR_SIZE + 0x0b] = ba; - - ba = block_address & 0xff; - sendbuff[SECTOR_SIZE + 0x07] = ba; - sendbuff[SECTOR_SIZE + 0x0c] = ba; + if (index == MPIO_BLOCK_DEFECT) { + memset(sendbuff + SECTOR_SIZE, 0, 0x10); + } else { + + /* generate ECC information for spare area ! */ + mpio_ecc_256_gen(sendbuff, + sendbuff + SECTOR_SIZE + 0x0d); + mpio_ecc_256_gen(sendbuff + (SECTOR_SIZE / 2), + sendbuff + SECTOR_SIZE + 0x08); + + if (index == MPIO_BLOCK_CIS) { + memset(sendbuff + SECTOR_SIZE + 0x06, 0, 2); + memset(sendbuff + SECTOR_SIZE + 0x0b, 0, 2); + } else { + ba = (block_address / 0x100) & 0xff; + sendbuff[SECTOR_SIZE + 0x06] = ba; + sendbuff[SECTOR_SIZE + 0x0b] = ba; + + ba = block_address & 0xff; + sendbuff[SECTOR_SIZE + 0x07] = ba; + sendbuff[SECTOR_SIZE + 0x0c] = ba; + } + + } } /* easy but working, we write back the FAT info we read before */ @@ -659,7 +686,7 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) * read/write of blocks */ int -mpio_io_block_read(mpio_t *m, BYTE mem, mpio_fatentry_t *f, BYTE *output) +mpio_io_block_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output) { int i=0; int nwrite, nread; @@ -797,13 +824,11 @@ mpio_io_spare_read(mpio_t *m, BYTE mem, DWORD index, BYTE size, } int -mpio_io_block_delete(mpio_t *m, BYTE mem, mpio_fatentry_t *f) +mpio_io_block_delete(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f) { - mpio_smartmedia_t *sm; - int nwrite, nread; - BYTE cmdpacket[CMD_SIZE], status[CMD_SIZE]; BYTE chip=0; DWORD address; + mpio_smartmedia_t *sm; if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; @@ -811,7 +836,22 @@ mpio_io_block_delete(mpio_t *m, BYTE mem, mpio_fatentry_t *f) fatentry2hw(f, &chip, &address); mpio_zone_block_free(m, mem, address); -/* Send command packet to MPIO */ + return (mpio_io_block_delete_phys(m, chip, address)); +} + +int +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]; + + /* Send command packet to MPIO */ + + if (chip == MPIO_INTERNAL_MEM) sm = &m->internal; + /* uhoh, this breaks if we have more than two internal chips! */ + if (chip == (MPIO_INTERNAL_MEM+1)) sm = &m->internal; + if (chip == MPIO_EXTERNAL_MEM) sm = &m->external; mpio_io_set_cmdpacket(m, DEL_BLOCK, chip, address, sm->size, 0, cmdpacket); @@ -842,8 +882,8 @@ mpio_io_block_delete(mpio_t *m, BYTE mem, mpio_fatentry_t *f) if (status[0] != 0xc0) { - debug ("error formatting Block (%04x) %02x:%06x\n", - f->entry, chip, address); + debug ("error formatting Block %02x:%06x\n", + chip, address); return 0; } @@ -851,7 +891,7 @@ mpio_io_block_delete(mpio_t *m, BYTE mem, mpio_fatentry_t *f) } int -mpio_io_block_write(mpio_t *m, BYTE mem, mpio_fatentry_t *f, BYTE *data) +mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data) { mpio_smartmedia_t *sm; int nwrite; diff --git a/libmpio/io.h b/libmpio/io.h index 44b3cbe..2b6d7d3 100644 --- a/libmpio/io.h +++ b/libmpio/io.h @@ -2,7 +2,7 @@ /* * - * $Id: io.h,v 1.9 2002/09/28 00:32:41 germeier Exp $ + * $Id: io.h,v 1.10 2002/10/06 21:19:50 germeier Exp $ * * Library for USB MPIO-* * @@ -61,9 +61,11 @@ int mpio_io_sector_read (mpio_t *, BYTE, DWORD, BYTE *); int mpio_io_sector_write(mpio_t *, BYTE, DWORD, BYTE *); /* */ -int mpio_io_block_read (mpio_t *, BYTE, mpio_fatentry_t *, BYTE *); -int mpio_io_block_write (mpio_t *, BYTE, mpio_fatentry_t *, BYTE *); -int mpio_io_block_delete(mpio_t *, BYTE, mpio_fatentry_t *); +int mpio_io_block_read (mpio_t *, mpio_mem_t, mpio_fatentry_t *, BYTE *); +int mpio_io_block_write (mpio_t *, mpio_mem_t, mpio_fatentry_t *, BYTE *); +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_spare_read (mpio_t *, BYTE, DWORD, BYTE, BYTE, BYTE *, int, diff --git a/libmpio/mpio.c b/libmpio/mpio.c index ec00f65..a20e46a 100644 --- a/libmpio/mpio.c +++ b/libmpio/mpio.c @@ -1,6 +1,6 @@ /* * - * $Id: mpio.c,v 1.29 2002/09/30 13:39:14 germeier Exp $ + * $Id: mpio.c,v 1.30 2002/10/06 21:19:50 germeier Exp $ * * Library for USB MPIO-* * @@ -291,9 +291,12 @@ mpio_init(mpio_callback_init_t progress_callback) mpio_zone_init(new_mpio, MPIO_EXTERNAL_MEM); mpio_bootblocks_read(new_mpio, MPIO_EXTERNAL_MEM); - sm->fat = malloc(SECTOR_SIZE*sm->fat_size); - mpio_fat_read(new_mpio, MPIO_EXTERNAL_MEM, NULL); - mpio_rootdir_read(new_mpio, MPIO_EXTERNAL_MEM); + if (sm->fat) /* card might be defect */ + { + sm->fat = malloc(SECTOR_SIZE*sm->fat_size); + mpio_fat_read(new_mpio, MPIO_EXTERNAL_MEM, NULL); + mpio_rootdir_read(new_mpio, MPIO_EXTERNAL_MEM); + } } return new_mpio; @@ -657,6 +660,8 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) mpio_fatentry_t *f; DWORD clusters; BYTE abort = 0; + BYTE *cis, *mbr, *pbr; + int i; if (mem == MPIO_INTERNAL_MEM) { @@ -672,41 +677,75 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) clusters = sm->size*128; - /* clear the fat before anything else, so we can mark clusters defective - * if we found a bad block - */ - mpio_fat_clear(m, mem); - f = mpio_fatentry_new(m, mem, data_offset, FTYPE_MUSIC); - do + if (mem==MPIO_INTERNAL_MEM) { - if (!mpio_io_block_delete(m, mem, f)) - mpio_fatentry_set_defect(m, mem, f); - - if (progress_callback) + /* clear the fat before anything else, so we can mark clusters defective + * if we found a bad block + */ + /* external mem must be handled diffrently, + * see comment(s) below! + */ + mpio_fat_clear(m, mem); + f = mpio_fatentry_new(m, mem, data_offset, FTYPE_MUSIC); + do { - if (!abort) - { - abort=(*progress_callback)(f->entry, sm->max_cluster + 1); - if (abort) - debug("received abort signal, but ignoring it!\n"); - } else { - (*progress_callback)(f->entry, sm->max_cluster + 1); - } - } - } while (mpio_fatentry_plus_plus(f)); - free(f); + if (!mpio_io_block_delete(m, mem, f)) + mpio_fatentry_set_defect(m, mem, f); + + if (progress_callback) + { + if (!abort) + { + abort=(*progress_callback)(f->entry, sm->max_cluster + 1); + if (abort) + debug("received abort signal, but ignoring it!\n"); + } else { + (*progress_callback)(f->entry, sm->max_cluster + 1); + } + } + + } while (mpio_fatentry_plus_plus(f)); + free(f); + } if (mem == MPIO_EXTERNAL_MEM) { + /* delete all blocks! */ + + i=1; /* leave the "defect" first block alone for now */ + while (i < sm->max_blocks) + { + mpio_io_block_delete_phys(m, mem, (i * BLOCK_SECTORS)); + i++; + } + /* format CIS area */ - f = mpio_fatentry_new(m, mem, /* yuck */ - (1-((sm->dir_offset + DIR_NUM)/BLOCK_SECTORS - 2)), - FTYPE_MUSIC); - mpio_io_block_delete(m, mem, f); + f = mpio_fatentry_new(m, mem, MPIO_BLOCK_CIS, FTYPE_MUSIC); + /* mpio_io_block_delete(m, mem, f); */ free(f); - mpio_io_sector_write(m, mem, 0x20, sm->cis); - mpio_io_sector_write(m, mem, 0x21, sm->cis); + cis = (BYTE *)mpio_cis_gen(); /* hmm, why this cast? */ + mpio_io_sector_write(m, mem, MPIO_BLOCK_CIS, cis); + mpio_io_sector_write(m, mem, MPIO_BLOCK_CIS+1, cis); + free(cis); + + /* generate boot blocks ... */ + mbr = (BYTE *)mpio_mbr_gen(m->external.size); + pbr = (BYTE *)mpio_pbr_gen(m->external.size); + /* ... copy the blocks to internal memory structurs ... */ + memcpy(sm->cis, cis, SECTOR_SIZE); + memcpy(sm->mbr, mbr, SECTOR_SIZE); + memcpy(sm->mbr, mbr, SECTOR_SIZE); + /* ... and set internal administration accordingly */ + mpio_mbr_eval(sm); + mpio_pbr_eval(sm); + if (!sm->fat) /* perhaps we have to build a new FAT */ + sm->fat=malloc(sm->fat_size*SECTOR_SIZE); + mpio_fat_clear(m, mem); + /* TODO: for external memory we have to work a little "magic" + * to identify and mark "bad blocks" (because we have a set of + * spare ones! + */ } mpio_rootdir_clear(m, mem); -- cgit v1.2.3