aboutsummaryrefslogtreecommitdiff
path: root/libmpio
diff options
context:
space:
mode:
Diffstat (limited to 'libmpio')
-rw-r--r--libmpio/Makefile.am6
-rw-r--r--libmpio/cis.c81
-rw-r--r--libmpio/cis.h34
-rw-r--r--libmpio/fat.c306
-rw-r--r--libmpio/fat.h13
-rw-r--r--libmpio/io.c98
-rw-r--r--libmpio/io.h10
-rw-r--r--libmpio/mpio.c101
8 files changed, 509 insertions, 140 deletions
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 <string.h>
#include <stdlib.h>
+/* 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);