From 141157486f76c858a3f983f3a2c3d63f452693fb Mon Sep 17 00:00:00 2001 From: germeier Date: Sun, 13 Oct 2002 08:57:31 +0000 Subject: finished formatting support for external memory --- ChangeLog | 7 ++ libmpio/fat.c | 52 ++++++++--- libmpio/io.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++-------- libmpio/io.h | 25 +++-- libmpio/mpio.c | 33 +++++-- mpiosh/callback.c | 4 +- 6 files changed, 329 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22c9aeb..ea0e704 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-10-13 Markus Germeier + + * libmpio/mpio.c (mpio_init): fixed segv when external memory + was selected + * formatting of external memory is now completly supported + (untested ATM) + 2002-10-12 Andreas Buesching * configure.in: changed version to 0.6.0 for the next release; diff --git a/libmpio/fat.c b/libmpio/fat.c index e8a7234..fdb6965 100644 --- a/libmpio/fat.c +++ b/libmpio/fat.c @@ -1,6 +1,6 @@ /* * - * $Id: fat.c,v 1.16 2002/10/06 21:19:50 germeier Exp $ + * $Id: fat.c,v 1.17 2002/10/13 08:57:31 germeier Exp $ * * Library for USB MPIO-* * @@ -175,9 +175,9 @@ mpio_mbr_eval(mpio_smartmedia_t *sm) 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 */; + sm->geo.NumSector + sector - 1; return 0; @@ -524,6 +524,13 @@ mpio_fatentry_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f ) if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + if (!sm->fat) + { + debug ("error, no space for FAT allocated!\n"); + return 0; + } + + if (sm->size == 128) { /* 2 Byte per entry */ e = f->entry * 2; @@ -649,15 +656,22 @@ mpio_fat_free_clusters(mpio_t *m, mpio_mem_t mem) int e = 0; int fsize; - f = mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC); - - do - { - if (mpio_fatentry_free(m, mem, f)) - e++; - } while (mpio_fatentry_plus_plus(f)); + if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; + if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; - free(f); + if (sm->fat) + { + f = mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC); + do + { + if (mpio_fatentry_free(m, mem, f)) + e++; + } while (mpio_fatentry_plus_plus(f)); + free(f); + } else { + f = 0; + } + return (e * 16); } @@ -789,6 +803,7 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) mpio_fatentry_t *f; BYTE dummy[BLOCK_SIZE]; WORD i; + DWORD block; if (mem == MPIO_INTERNAL_MEM) { sm = &m->internal; @@ -822,9 +837,18 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) for (i = 0; i < (sm->dir_offset + DIR_NUM) ; i++) { /* before writing to a new block delete it! */ if (((i / 0x20) * 0x20) == i) { - f=mpio_fatentry_new(m, mem, i, FTYPE_MUSIC); - mpio_io_block_delete(m, mem, f); - free(f); + block = mpio_zone_block_find_seq(m, mem, i); + if (block == MPIO_BLOCK_NOT_FOUND) + { + block = mpio_zone_block_find_free_seq(m, mem, i); + } + if (block == MPIO_BLOCK_NOT_FOUND) + { + debug("This should never happen!"); + exit(-1); + } + + mpio_io_block_delete_phys(m, mem, block); } /* remeber: logical sector 0 is the MBR! */ diff --git a/libmpio/io.c b/libmpio/io.c index 50f856d..856f453 100644 --- a/libmpio/io.c +++ b/libmpio/io.c @@ -2,7 +2,7 @@ /* * - * $Id: io.c,v 1.18 2002/10/06 21:19:50 germeier Exp $ + * $Id: io.c,v 1.19 2002/10/13 08:57:31 germeier Exp $ * * Library for USB MPIO-* * @@ -183,7 +183,7 @@ fatentry2hw(mpio_fatentry_t *f, BYTE *chip, DWORD *address) { sm = &f->m->external; *chip = MPIO_EXTERNAL_MEM; - *address = mpio_zone_block_find(f->m, f->mem, f->entry); + *address = mpio_zone_block_find_log(f->m, f->mem, f->entry); debugn(3, "mager: %06x (logical: %04x)\n", *address, f->entry); } return; @@ -223,31 +223,47 @@ mpio_zone_init(mpio_t *m, mpio_cmd_t mem) } DWORD -mpio_zone_block_find(mpio_t *m, mpio_cmd_t mem, DWORD lblock) +mpio_zone_block_find_log(mpio_t *m, mpio_cmd_t mem, DWORD lblock) { mpio_smartmedia_t *sm; - int i, f, v; - int zone, block; - + int v; + if (mem != MPIO_EXTERNAL_MEM) { debug("called function with wrong memory selection!\n"); return -1; } sm = &m->external; - + /* OK, I can't explain this right now, but it does work, * see Software Driver v3.0, page 31 */ v = lblock + (sm->size/64); + + return (mpio_zone_block_find_seq(m, mem, v)); +} + +DWORD +mpio_zone_block_find_seq(mpio_t *m, mpio_cmd_t mem, DWORD lblock) +{ + mpio_smartmedia_t *sm; + int i, f, v; + int zone, block; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return -1; + } + sm = &m->external; if ((lblock>=MPIO_BLOCK_CIS) && (lblock<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) { zone = 0; block = MPIO_BLOCK_CIS; } else { - zone = v / MPIO_ZONE_LBLOCKS; - block = v % MPIO_ZONE_LBLOCKS; + zone = lblock / MPIO_ZONE_LBLOCKS; + block = lblock % MPIO_ZONE_LBLOCKS; } f=0; @@ -266,13 +282,78 @@ mpio_zone_block_find(mpio_t *m, mpio_cmd_t mem, DWORD lblock) if (!f) { - debug("block not found\n"); + debugn(2, "block not found\n"); return MPIO_BLOCK_NOT_FOUND; } return ((zone * BLOCK_SECTORS * MPIO_ZONE_PBLOCKS ) + v * BLOCK_SECTORS); } +DWORD +mpio_zone_block_set_free(mpio_t *m, mpio_cmd_t mem, DWORD lblock) +{ + DWORD value; + int zone, block; + mpio_smartmedia_t *sm; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return -1; + } + sm = &m->external; + + value = mpio_zone_block_find_log(m, mem, lblock); + + mpio_zone_block_set_free_phys(m, mem, value); + + return value; +} + +void +mpio_zone_block_set_free_phys(mpio_t *m, mpio_cmd_t mem, DWORD value) +{ + int zone, block; + mpio_smartmedia_t *sm; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return; + } + sm = &m->external; + + zone = value / BLOCK_SECTORS; + block = zone % MPIO_ZONE_PBLOCKS; + zone = zone / MPIO_ZONE_PBLOCKS; + + sm->zonetable[zone][block] = MPIO_BLOCK_FREE; + + return; +} + +void +mpio_zone_block_set_defect_phys(mpio_t *m, mpio_cmd_t mem, DWORD value) +{ + int zone, block; + mpio_smartmedia_t *sm; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return; + } + sm = &m->external; + + zone = value / BLOCK_SECTORS; + block = zone % MPIO_ZONE_PBLOCKS; + zone = zone / MPIO_ZONE_PBLOCKS; + + sm->zonetable[zone][block] = MPIO_BLOCK_DEFECT; + + return; +} + void mpio_zone_block_set(mpio_t *m, mpio_cmd_t mem, DWORD pblock) { @@ -287,10 +368,86 @@ mpio_zone_block_set(mpio_t *m, mpio_cmd_t mem, DWORD pblock) } DWORD -mpio_zone_block_free(mpio_t *m, mpio_cmd_t mem, DWORD lblock) +mpio_zone_block_find_free_log(mpio_t *m, mpio_cmd_t mem, DWORD lblock) { + mpio_smartmedia_t *sm; + int v; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return -1; + } + sm = &m->external; + + /* OK, I can't explain this right now, but it does work, + * see Software Driver v3.0, page 31 + */ + v = lblock + (sm->size/64); + + return (mpio_zone_block_find_free_seq(m, mem, v)); } +DWORD +mpio_zone_block_find_free_seq(mpio_t *m, mpio_cmd_t mem, DWORD lblock) +{ + DWORD value; + int zone, block, i; + mpio_smartmedia_t *sm; + + if (mem != MPIO_EXTERNAL_MEM) + { + debug("called function with wrong memory selection!\n"); + return -1; + } + sm = &m->external; + + value = mpio_zone_block_find_seq(m, mem, lblock); + + if (value != MPIO_BLOCK_NOT_FOUND) + { + debug("logical block numbers is already assigned! (%4x)\n", lblock); + exit (-1); + } + + if ((lblock>=MPIO_BLOCK_CIS) && (lblock<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) + { + zone = 0; + block = MPIO_BLOCK_CIS; + } else { + zone = lblock / MPIO_ZONE_LBLOCKS; + block = lblock % MPIO_ZONE_LBLOCKS; + } + + i=0; + while ((sm->zonetable[zone][i]!=MPIO_BLOCK_FREE) && (izonetable[zone][i] = block; + + return ((zone * BLOCK_SECTORS * MPIO_ZONE_PBLOCKS ) + i * BLOCK_SECTORS); +} + + +WORD +mpio_zone_block_get_logical(mpio_t *m, mpio_cmd_t mem, DWORD pblock) +{ + + return 0; +} + + + + + /* * low-low level functions */ @@ -504,11 +661,10 @@ mpio_io_sector_read(mpio_t *m, BYTE mem, DWORD index, BYTE *output) /* find the correct physical block first! */ if ((index>=MPIO_BLOCK_CIS) && (index<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) { - sector = mpio_zone_block_find(m, mem, MPIO_BLOCK_CIS); + sector = mpio_zone_block_find_seq(m, mem, MPIO_BLOCK_CIS); sector+= (index % MPIO_BLOCK_CIS); } else { - sector = mpio_zone_block_find(m, mem, /* yuck */ - ((index / 0x20) - (sm->size/64))); + sector = mpio_zone_block_find_seq(m, mem, (index / 0x20)); sector+= (index % 0x20); } } @@ -588,6 +744,7 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) { int nwrite; mpio_smartmedia_t *sm; + DWORD pvalue; DWORD block_address, ba; BYTE cmdpacket[CMD_SIZE], sendbuff[SECTOR_TRANS]; @@ -603,20 +760,52 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) * - 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) + if (index==MPIO_BLOCK_DEFECT) { - /* this is the first write to the block, so allocate a new one */ - - /* mark it with the block_address */ - + block_address = 0; + pvalue = 0; } else { - /* find the block from the block list! */ + if ((index>=MPIO_BLOCK_CIS) && (index<(MPIO_BLOCK_CIS + BLOCK_SECTORS))) + { + block_address = 0; + if (index==MPIO_BLOCK_CIS) + { + pvalue=mpio_zone_block_find_free_seq(m, mem, index); + } else { + /* find the block from the block list! */ + pvalue=mpio_zone_block_find_seq(m, mem, MPIO_BLOCK_CIS); + } + if (pvalue != MPIO_BLOCK_NOT_FOUND) + pvalue = pvalue + index - MPIO_BLOCK_CIS; + + } else { + block_address = blockaddress_encode(index / BLOCK_SECTORS); + if ((index % BLOCK_SECTORS) == 0) + { + /* this is the first write to the block, so allocate a new one */ + /* ... and mark it with the block_address */ + pvalue=mpio_zone_block_find_free_seq(m, mem, + (index / BLOCK_SECTORS)); + } else { + /* find the block from the block list! */ + pvalue=mpio_zone_block_find_seq(m, mem, (index / BLOCK_SECTORS)); + } + if (pvalue != MPIO_BLOCK_NOT_FOUND) + pvalue = pvalue + (index % BLOCK_SECTORS); + + } + if (pvalue == MPIO_BLOCK_NOT_FOUND) + { + debug ("Oops, this should never happen! (%6x : %6x)\n", + index, block_address); + exit (-1); + } } + - mpio_io_set_cmdpacket(m, PUT_SECTOR, mem, index, sm->size, 0, cmdpacket); + mpio_io_set_cmdpacket(m, PUT_SECTOR, mem, pvalue, sm->size, 0, cmdpacket); debugn (5, "\n>>> MPIO\n"); hexdump (cmdpacket, sizeof(cmdpacket)); @@ -638,6 +827,7 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) { if (index == MPIO_BLOCK_DEFECT) { memset(sendbuff + SECTOR_SIZE, 0, 0x10); + mpio_zone_block_set_defect_phys(m, mem, pvalue); } else { /* generate ECC information for spare area ! */ @@ -645,18 +835,21 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input) 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); + if (index == MPIO_BLOCK_DEFECT) { + memset(sendbuff + SECTOR_SIZE, 0, 0x10); } 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; + 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; + } } } @@ -834,7 +1027,6 @@ mpio_io_block_delete(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f) if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; fatentry2hw(f, &chip, &address); - mpio_zone_block_free(m, mem, address); return (mpio_io_block_delete_phys(m, chip, address)); } @@ -851,7 +1043,11 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address) 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; + if (chip == MPIO_EXTERNAL_MEM) + { + sm = &m->external; + mpio_zone_block_set_free_phys(m, chip, address); + } mpio_io_set_cmdpacket(m, DEL_BLOCK, chip, address, sm->size, 0, cmdpacket); @@ -884,7 +1080,11 @@ mpio_io_block_delete_phys(mpio_t *m, BYTE chip, DWORD address) { debug ("error formatting Block %02x:%06x\n", chip, address); - return 0; + if (chip == MPIO_EXTERNAL_MEM) + { + sm = &m->external; + mpio_zone_block_set_free_phys(m, chip, address); + } } return CMD_SIZE; diff --git a/libmpio/io.h b/libmpio/io.h index 2b6d7d3..7536eee 100644 --- a/libmpio/io.h +++ b/libmpio/io.h @@ -2,7 +2,7 @@ /* * - * $Id: io.h,v 1.10 2002/10/06 21:19:50 germeier Exp $ + * $Id: io.h,v 1.11 2002/10/13 08:57:31 germeier Exp $ * * Library for USB MPIO-* * @@ -37,14 +37,27 @@ int mpio_zone_init(mpio_t *, mpio_cmd_t); /* context, memory bank, logical block */ /* returns address of physical block! */ -DWORD mpio_zone_block_find(mpio_t *, mpio_cmd_t, DWORD); -/* context, memory bank, logical block, physical address */ -/* mark physical block free (internal maintenance) */ -void mpio_zone_block_set(mpio_t *, mpio_cmd_t, DWORD); +DWORD mpio_zone_block_find_log(mpio_t *, mpio_cmd_t, DWORD); + /* context, memory bank, sequential block (for sector addressing) */ +/* returns address of physical block! */ +DWORD mpio_zone_block_find_seq(mpio_t *, mpio_cmd_t, DWORD); /* context, memory bank, logical block */ /* find used physical block and mark it as unused! */ /* returns address of physical block! (to delete the physical block!) */ -DWORD mpio_zone_block_free(mpio_t *, mpio_cmd_t, DWORD); +DWORD mpio_zone_block_set_free(mpio_t *, mpio_cmd_t, DWORD); +/* context, memory bank, physical block */ +void mpio_zone_block_set_free_phys(mpio_t *, mpio_cmd_t, DWORD); +/* context, memory bank, physical block */ +void mpio_zone_block_set_defect_phys(mpio_t *, mpio_cmd_t, DWORD); +/* context, memory bank, logical block */ +/* looks for a free physical block to be used for given logical block */ +/* mark the found block used for this logical block */ +/* returns address of physical block! */ +DWORD mpio_zone_block_find_free_log(mpio_t *, mpio_cmd_t, DWORD); +DWORD mpio_zone_block_find_free_seq(mpio_t *, mpio_cmd_t, DWORD); +/* return zone-logical block for a given physical block */ +WORD mpio_zone_block_get_logical(mpio_t *, mpio_cmd_t, DWORD); + /* real I/O */ int mpio_io_set_cmdpacket(mpio_t *, mpio_cmd_t, mpio_mem_t, diff --git a/libmpio/mpio.c b/libmpio/mpio.c index 8c792ce..8ca99e5 100644 --- a/libmpio/mpio.c +++ b/libmpio/mpio.c @@ -1,6 +1,6 @@ /* * - * $Id: mpio.c,v 1.31 2002/10/12 18:31:45 crunchy Exp $ + * $Id: mpio.c,v 1.32 2002/10/13 08:57:31 germeier Exp $ * * Library for USB MPIO-* * @@ -291,8 +291,8 @@ mpio_init(mpio_callback_init_t progress_callback) (sm->max_blocks * 0x10), progress_callback); mpio_zone_init(new_mpio, MPIO_EXTERNAL_MEM); - mpio_bootblocks_read(new_mpio, MPIO_EXTERNAL_MEM); - if (sm->fat) /* card might be defect */ + /* card might be defect */ + if (mpio_bootblocks_read(new_mpio, MPIO_EXTERNAL_MEM)==0) { sm->fat = malloc(SECTOR_SIZE*sm->fat_size); mpio_fat_read(new_mpio, MPIO_EXTERNAL_MEM, NULL); @@ -662,6 +662,7 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) DWORD clusters; BYTE abort = 0; BYTE *cis, *mbr, *pbr; + BYTE defect[SECTOR_SIZE]; int i; if (mem == MPIO_INTERNAL_MEM) @@ -679,6 +680,7 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) clusters = sm->size*128; + /* TODO: read and write "Config.dat" so the player does not become "dumb" */ if (mem==MPIO_INTERNAL_MEM) { /* clear the fat before anything else, so we can mark clusters defective @@ -714,12 +716,29 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) if (mem == MPIO_EXTERNAL_MEM) { /* delete all blocks! */ - i=1; /* leave the "defect" first block alone for now */ + i=0; while (i < sm->max_blocks) { mpio_io_block_delete_phys(m, mem, (i * BLOCK_SECTORS)); i++; + + if (progress_callback) + { + if (!abort) + { + abort=(*progress_callback)(i, sm->max_blocks); + if (abort) + debug("received abort signal, but ignoring it!\n"); + } else { + (*progress_callback)(i, sm->max_blocks); + } + } + + } + + /* generate "defect" first block */ + mpio_io_sector_write(m, mem, MPIO_BLOCK_DEFECT, defect); /* format CIS area */ f = mpio_fatentry_new(m, mem, MPIO_BLOCK_CIS, FTYPE_MUSIC); @@ -736,13 +755,15 @@ mpio_memory_format(mpio_t *m, mpio_mem_t mem, mpio_callback_t progress_callback) /* ... 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); + memcpy(sm->pbr, pbr, 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); + 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! diff --git a/mpiosh/callback.c b/mpiosh/callback.c index 65cfa49..3c59f4d 100644 --- a/mpiosh/callback.c +++ b/mpiosh/callback.c @@ -2,7 +2,7 @@ * * Author: Andreas Büsching * - * $Id: callback.c,v 1.22 2002/10/12 20:06:22 crunchy Exp $ + * $Id: callback.c,v 1.23 2002/10/13 08:57:31 germeier Exp $ * * Copyright (C) 2001 Andreas Büsching * @@ -183,7 +183,7 @@ mpiosh_cmd_mem(char *args[]) printf("reading : works (untested)\n"); printf("deleting : broken\n"); printf("writing : broken\n"); - printf("formatting: broken\n"); + printf("formatting: complete (untested)\n"); printf("external memory card is selected\n"); } else { printf("no external memory card is available\n"); -- cgit v1.2.3