aboutsummaryrefslogtreecommitdiff
path: root/libmpio/io.c
diff options
context:
space:
mode:
authorcrunchy <crunchy>2003-04-23 08:34:01 +0000
committercrunchy <crunchy>2003-04-23 08:34:01 +0000
commit4412ca091e6379def8bc836163c6b580df76619c (patch)
tree35f529177db9512ad1d195276dc9d818a8e23d87 /libmpio/io.c
parent16e3a07e9cdfe050819cc4fdd5061486cb48767d (diff)
downloadmpiosh-4412ca091e6379def8bc836163c6b580df76619c.tar.gz
mpiosh-4412ca091e6379def8bc836163c6b580df76619c.tar.bz2
mpiosh-4412ca091e6379def8bc836163c6b580df76619c.zip
start restructuring
Diffstat (limited to 'libmpio/io.c')
-rw-r--r--libmpio/io.c1213
1 files changed, 0 insertions, 1213 deletions
diff --git a/libmpio/io.c b/libmpio/io.c
deleted file mode 100644
index 0ef8258..0000000
--- a/libmpio/io.c
+++ /dev/null
@@ -1,1213 +0,0 @@
-/* -*- linux-c -*- */
-
-/*
- *
- * $Id: io.c,v 1.25 2003/04/18 13:53:01 germeier Exp $
- *
- * Library for USB MPIO-*
- *
- * Markus Germeier (mager@tzi.de)
- *
- * uses code from mpio_stat.c by
- * Yuji Touya (salmoon@users.sourceforge.net)
- *
- *
- * 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.
- *
- * */
-
-/*
- *
- * low level I/O
- *
- *
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "io.h"
-#include "debug.h"
-#include "ecc.h"
-
-BYTE model2externalmem(mpio_model_t);
-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 */
-BYTE
-model2externalmem(mpio_model_t model)
-{
- BYTE m;
-
- switch(model)
- {
- case MPIO_MODEL_DMG:
- case MPIO_MODEL_DMG_PLUS:
- m = 0x80;
- break;
- default:
- m = 0x10;
- }
-
- return m;
-}
-
-/* encoding and decoding of blockaddresses */
-
-DWORD
-blockaddress_encode(DWORD ba)
-{
- WORD addr;
- BYTE p = 0, c = 0;
- BYTE high, low;
-
- high = 0x10 | ((ba / 0x80) & 0x07);
- low = (ba * 2) & 0xff;
-
- c = high;
- while (c)
- {
- if (c & 0x01)
- p ^= 1;
- c /= 2;
- }
-
- c = low;
- while (c)
- {
- if (c & 0x01)
- p ^= 0x01;
- c /= 2;
- }
-
- addr = (high * 0x100) + low + p;
-
- return addr;
-}
-
-
-DWORD
-blockaddress_decode(BYTE *entry)
-{
- WORD ba;
- WORD value;
- BYTE p=0, high, low;
- int i, t;
-
- /* check for "easy" defect block */
- t=1;
- for(i=0; i<0x10; i++)
- if (entry[i] != 0)
- t=0;
- if (t)
- return MPIO_BLOCK_DEFECT;
-
- /* check for "easy" defect block */
- t=1;
- for(i=0; i<0x10; i++)
- if (entry[i] != 0xff)
- t=0;
- if (t)
- return MPIO_BLOCK_FREE;
-
- /* check for "strange" errors */
- if ((entry[6] != entry[11]) ||
- (entry[7] != entry[12]))
- {
- debug("error: different block addresses found:\n");
- hexdumpn(1, entry, 0x10);
- return MPIO_BLOCK_DEFECT;
- }
-
- ba = entry[6] * 0x100 + entry[7];
-
- /* special values */
- if (ba == 0xffff)
- return MPIO_BLOCK_DEFECT;
- if (ba == 0x0000)
- return MPIO_BLOCK_CIS;
-
- /* check parity */
- value = ba;
- while (value)
- {
- if (value & 0x01)
- p ^= 0x01;
-
- value /= 2;
- }
- if (p)
- {
- debug("parity error found in block address: %2x\n", ba);
- return MPIO_BLOCK_DEFECT;
- }
-
- high = ((ba / 0x100) & 0x07);
- low = ((ba & 0x0ff) / 2);
-
- return (high * 0x80 + low);
-}
-
-/* foobar */
-
-void
-fatentry2hw(mpio_fatentry_t *f, BYTE *chip, DWORD *address)
-{
- mpio_smartmedia_t *sm;
-
- if (f->mem == MPIO_INTERNAL_MEM)
- {
- sm = &f->m->internal;
- /* hexdump((char *)&f->entry, 4); */
- /* hexdump((char *)&f->hw_address, 4); */
- *chip = f->hw_address / 0x1000000;
- *address = f->hw_address & 0x0ffffff;
- }
- if (f->mem == MPIO_EXTERNAL_MEM)
- {
- sm = &f->m->external;
- *chip = MPIO_EXTERNAL_MEM;
- *address = mpio_zone_block_find_log(f->m, f->mem, f->entry);
- debugn(3, "mager: %06x (logical: %04x)\n", *address, f->entry);
- }
- return;
-}
-
-/*
- * zone management
- */
-
-int
-mpio_zone_init(mpio_t *m, mpio_cmd_t mem)
-{
- mpio_smartmedia_t *sm;
- int i;
- int zone, block, e;
-
- if (mem != MPIO_EXTERNAL_MEM)
- {
- debug("called function with wrong memory selection!\n");
- return -1;
- }
- sm = &m->external;
-
- for(i=0; i<sm->max_blocks; i++)
- {
- zone = i / MPIO_ZONE_PBLOCKS;
- block= i % MPIO_ZONE_PBLOCKS;
-
- e = i * 0x10;
-
- sm->zonetable[zone][block]=blockaddress_decode(sm->spare+e);
-
- hexdumpn(4, sm->spare+e, 0x10);
- debugn(2, "decoded: %04x\n", sm->zonetable[zone][block]);
- }
-
-}
-
-DWORD
-mpio_zone_block_find_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_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 = lblock / MPIO_ZONE_LBLOCKS;
- block = lblock % MPIO_ZONE_LBLOCKS;
- }
-
- f=0;
- for (i=(MPIO_ZONE_PBLOCKS-1); i >=0; i--)
- {
-
- if (sm->zonetable[zone][i]==block)
- {
- f++;
- v=i;
- }
- }
-
- if (f>1)
- debug("found more than one block, using first one\n");
-
- if (!f)
- {
- 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)
-{
- int zone, block, pb;
-
- pb = pblock / BLOCK_SECTORS;
- zone = pb / MPIO_ZONE_PBLOCKS;
- block = pb % MPIO_ZONE_PBLOCKS;
-
- m->external.zonetable[zone][block] = MPIO_BLOCK_FREE ;
-
-}
-
-DWORD
-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) && (i<MPIO_ZONE_PBLOCKS))
- i++;
-
- if (i==MPIO_ZONE_PBLOCKS)
- {
- debug("could not find free pysical block\n");
- return MPIO_BLOCK_NOT_FOUND;
- }
-
- debugn(2, "set new sector in zonetable, [%d][%d] = %4x\n", zone, i, block);
-
- sm->zonetable[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)
-{
- int zone, block, pb;
-
- pb = pblock / BLOCK_SECTORS;
- zone = pb / MPIO_ZONE_PBLOCKS;
- block = pb % MPIO_ZONE_PBLOCKS;
-
- return m->external.zonetable[zone][block];
-}
-
-
-
-
-
-/*
- * low-low level functions
- */
-
-/*
- * Set command packet
- *
- * parameter:
- *
- * cmd: commando code
- * mem: internal/external
- * index: sector/block
- * size: size of used memory chip
- * wsize: write size, only for PUT_BLOCK
- * buffer: output buffer of command packet
- *
- */
-
-int
-mpio_io_set_cmdpacket(mpio_t *m, mpio_cmd_t cmd, mpio_mem_t mem, DWORD index,
- WORD size, BYTE wsize, BYTE *buffer)
-{
- BYTE memory;
-
- /* clear cmdpacket*/
- memset(buffer, 0, 0x40);
-
- *buffer = cmd;
- memory = mem;
- if (mem == MPIO_EXTERNAL_MEM)
- memory = model2externalmem(m->model);
-
- *(buffer + 0x01) = memory;
- *(buffer + 0x03) = (BYTE) (index & 0x00ff);
- *(buffer + 0x04) = (BYTE)((index & 0xff00) >> 8);
- /* SM cards with less or equal 32 MB only need 2 Bytes
- * to address sectors or blocks.
- * The highest byte has to be 0xff in that case!
- */
- if (size <= 32)
- {
- *(buffer + 0x05) = 0xff;
- } else {
- *(buffer + 0x05) = (BYTE) (index >> 16);
- }
- /* is this always 0x48 in case of a block write ?? */
- *(buffer + 0x06) = wsize;
-
- memcpy((buffer + 0x3b), "jykim", 5);
-
- return (0);
-}
-
-/*
- * write chunk of data to MPIO filedescriptor
- *
- * parameter:
- *
- * fd: filedescriptor
- * block: data buffer (has to be num_bytes)
- * num_bytes: size of data buffer
- *
- */
-int
-mpio_io_bulk_write(int fd, BYTE *block, int num_bytes)
-{
- BYTE *p;
- int count, bytes_left, bytes_written;
-
- bytes_left = num_bytes;
- bytes_written = 0;
- p = block;
-
- do
- {
- count = write (fd, p, bytes_left);
- if (count > 0)
- {
- p += count;
- bytes_written += count;
- bytes_left -= count;
- }
- } while (bytes_left > 0 && count > 0);
-
- return bytes_written;
-}
-
-/*
- * read chunk of data from MPIO filedescriptor
- *
- * parameter:
- *
- * fd: filedescriptor
- * block: return buffer (has to be num_bytes)
- * num_bytes: size of return buffer
- *
- */
-int
-mpio_io_bulk_read (int fd, BYTE *block, int num_bytes)
-{
- int total_read, count, bytes_left;
- BYTE *p;
-
- total_read = 0;
- bytes_left = num_bytes;
- p = block;
-
- do
- {
- count = read (fd, p, bytes_left);
-
- if (count > 0)
- {
- total_read += count;
- bytes_left -= count;
- p += count;
- }
- } while (total_read < num_bytes && count > 0);
-
- return total_read;
-}
-
-/*
- * low level functions
- */
-
-/*
- * read version block from MPIO
- *
- * parameter:
- *
- * m: mpio context
- * buffer: return buffer (has to be CMD_SIZE)
- *
- */
-int
-mpio_io_version_read(mpio_t *m, BYTE *buffer)
-{
- int nwrite, nread;
- BYTE cmdpacket[CMD_SIZE], status[CMD_SIZE];
-
- /* Send command packet to MPIO */
- mpio_io_set_cmdpacket (m, GET_VERSION, 0, 0, 0xff, 0, cmdpacket);
-
- debugn (5, ">>> MPIO\n");
- hexdump (cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40);
-
- if (nwrite != CMD_SIZE)
- {
- debug ("Failed to send command.\n\n");
- close (m->fd);
- return 0;
- }
-
- /* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, status, 0x40);
-
- if (nread == -1 || nread != 0x40)
- {
- debug ("Failed to read Sector.\n%x\n",nread);
- close (m->fd);
- return 0;
- }
-
- debugn (5, "<<< MPIO\n");
- hexdump (status, 0x40);
-
- memcpy(buffer, status, 0x40);
-
- return CMD_SIZE;
-}
-
-/*
- * read sector from SmartMedia
- *
- * parameter:
- *
- * m: mpio context
- * mem: MPIO_{INTERNAL,EXTERNAL}_MEM
- * index: index number of sector to read
- * output: return buffer (has to be SECTOR_SIZE)
- *
- */
-
-/* right now we assume we only want to read single sectors from
- * the _first_ internal memory chip
- */
-
-int
-mpio_io_sector_read(mpio_t *m, BYTE mem, DWORD index, BYTE *output)
-{
- mpio_smartmedia_t *sm=0;
- DWORD sector;
- int nwrite, nread;
- BYTE cmdpacket[CMD_SIZE], recvbuff[SECTOR_TRANS];
-
- if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
- if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
- if (!sm)
- {
- debug("error in memory selection, aborting\n");
- exit (-1);
- }
-
- if (mem == MPIO_INTERNAL_MEM)
- {
- sector = index;
- } else {
- /* find the correct physical block first! */
- if ((index>=MPIO_BLOCK_CIS) && (index<(MPIO_BLOCK_CIS + BLOCK_SECTORS)))
- {
- sector = mpio_zone_block_find_seq(m, mem, MPIO_BLOCK_CIS);
- sector+= (index % MPIO_BLOCK_CIS);
- } else {
- sector = mpio_zone_block_find_seq(m, mem, (index / 0x20));
- sector+= (index % 0x20);
- }
- }
-
- debugn (2, "sector: %8x (%06x)\n", index, sector);
-
- mpio_io_set_cmdpacket (m, GET_SECTOR, mem, sector, sm->size, 0, cmdpacket);
-
- debugn (5, "\n>>> MPIO\n");
- hexdump (cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write (m->fd, cmdpacket, 0x40);
-
- if(nwrite != CMD_SIZE)
- {
- debug ("\nFailed to send command.\n\n");
- close (m->fd);
- return 1;
- }
-
- /* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, recvbuff, SECTOR_TRANS);
-
- if(nread != SECTOR_TRANS)
- {
- debug ("\nFailed to read Sector.\n%x\n", nread);
- close (m->fd);
- return 1;
- }
-
- /* check ECC Area information */
- if (mem==MPIO_EXTERNAL_MEM)
- {
- if (mpio_ecc_256_check (recvbuff,
- (recvbuff + SECTOR_SIZE + 13)) ||
- mpio_ecc_256_check ((recvbuff + (SECTOR_SIZE / 2)),
- (recvbuff + SECTOR_SIZE + 8)) )
- debug ("ECC error @ (%02x : %06x)\n", mem, index);
- }
-
- /* This should not be needed:
- * we don't have ECC information for the internal memory
- * we only read the directory through this function
- */
- /* if (mem==MPIO_INTERNAL_MEM) */
- /* { */
- /* debugn(2, "WARNING, code for internal FAT entry (in ECC area)" */
- /* " not yet in place!!\n"); */
- /* } */
-
- debugn (5, "\n<<< MPIO\n");
- hexdump (recvbuff, SECTOR_TRANS);
-
- memcpy(output, recvbuff, SECTOR_SIZE);
-
- return 0;
-}
-
-/*
- * write sector to SmartMedia
- *
- * parameter:
- *
- * m: mpio context
- * mem: MPIO_{INTERNAL,EXTERNAL}_MEM
- * index: index number of sector to read
- * input: data buffer (has to be SECTOR_SIZE)
- *
- */
-
-/* right now we assume we only want to write single sectors from
- * the _first_ internal memory chip
- */
-
-int
-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];
-
- if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
- if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
- if (!sm)
- {
- debug("error in memory selection, aborting\n");
- exit (-1);
- }
-
- /* we have to:
- * - find the physical block (or allocate a new one)
- * - calculate the logical block for zone management
- */
-
- if (mem == MPIO_EXTERNAL_MEM)
- {
- if (index==MPIO_BLOCK_DEFECT)
- {
- block_address = 0;
- pvalue = 0;
- } else {
- 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: 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);
- }
- }
- } else {
- pvalue = index;
- }
-
- mpio_io_set_cmdpacket(m, PUT_SECTOR, mem, pvalue, sm->size, 0, cmdpacket);
-
- debugn (5, "\n>>> MPIO\n");
- hexdump (cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40);
-
- if(nwrite != CMD_SIZE)
- {
- debug ("\nFailed to send command.\n\n");
- close (m->fd);
- return 1;
- }
-
- memset(sendbuff, 0, SECTOR_TRANS);
- memset(sendbuff + SECTOR_SIZE, 0xff, 0x10);
- memcpy(sendbuff, input, SECTOR_SIZE);
-
- if (mem==MPIO_EXTERNAL_MEM)
- {
- 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 ! */
- 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_DEFECT) {
- memset(sendbuff + SECTOR_SIZE, 0, 0x10);
- } else {
- 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 */
- if (mem==MPIO_INTERNAL_MEM)
- memcpy((sendbuff+SECTOR_SIZE), sm->fat, 0x10);
-
- debugn (5, "\n>>> MPIO\n");
- hexdump(sendbuff, SECTOR_TRANS);
-
- /* write sector MPIO */
- nwrite = mpio_io_bulk_write(m->fd, sendbuff, SECTOR_TRANS);
-
- if(nwrite != SECTOR_TRANS)
- {
- debug ("\nFailed to read Sector.\n%x\n", nwrite);
- close (m->fd);
- return 1;
- }
-
- return 0;
-}
-
-/*
- * read/write of blocks
- */
-int
-mpio_io_block_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *output)
-{
- int i=0;
- int nwrite, nread;
- mpio_smartmedia_t *sm;
- BYTE chip;
- DWORD address;
- BYTE cmdpacket[CMD_SIZE], recvbuff[BLOCK_TRANS];
-
- if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
- if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
-
- fatentry2hw(f, &chip, &address);
-
- mpio_io_set_cmdpacket(m, GET_BLOCK, chip, address, sm->size, 0, cmdpacket);
-
- debugn(5, "\n>>> MPIO\n");
- hexdump(cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
-
- if(nwrite != CMD_SIZE)
- {
- debug ("\nFailed to send command.\n\n");
- close (m->fd);
- return 1;
- }
-
- /* Receive packet from MPIO */
- nread = mpio_io_bulk_read(m->fd, recvbuff, BLOCK_TRANS);
-
- if(nread != BLOCK_TRANS)
- {
- debug ("\nFailed to read Block.\n%x\n",nread);
- close (m->fd);
- return 1;
- }
-
- debugn(5, "\n<<< MPIO\n");
- hexdump(recvbuff, BLOCK_TRANS);
-
- for (i = 0; i < BLOCK_SECTORS; i++)
- {
- /* check ECC Area information */
- if (mem==MPIO_EXTERNAL_MEM) {
- if (mpio_ecc_256_check ((recvbuff + (i * SECTOR_TRANS)),
- ((recvbuff +(i * SECTOR_TRANS)
- + SECTOR_SIZE +13))) ||
- mpio_ecc_256_check ((recvbuff + (i * SECTOR_TRANS)
- + (SECTOR_SIZE / 2)),
- ((recvbuff +(i * SECTOR_TRANS)
- + SECTOR_SIZE + 8))))
- debug ("ECC error @ (%02x : %06x)\n", chip, address);
- }
-
- memcpy(output + (i * SECTOR_SIZE),
- recvbuff + (i * SECTOR_TRANS),
- SECTOR_SIZE);
- }
-
- return 0;
-}
-
-/* Read spare is only usefull for the internal memory,
- * the FAT lies there. It is updated during the
- * mpio_io_{sector,block}_{read,write} operations.
- *
- * For external SmartMedia cards we have a "seperate" FAT
- * which is read and updated just like on a regular floppy
- * disc or hard drive.
- *
- */
-
-int
-mpio_io_spare_read(mpio_t *m, BYTE mem, DWORD index, WORD size,
- BYTE wsize, BYTE *output, int toread,
- mpio_callback_init_t progress_callback)
-{
- mpio_smartmedia_t *sm;
- int i;
- int nwrite, nread;
- int chip = 0;
- int chips = 0;
- BYTE cmdpacket[CMD_SIZE];
-
- if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
- if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
-
- chips = sm->chips;
-
- for (chip = 1; chip <= chips; chip++)
- {
- if (mem == MPIO_INTERNAL_MEM)
- mpio_io_set_cmdpacket(m, GET_SPARE_AREA, (1 << (chip-1)),
- index, (size / sm->chips),
- wsize, cmdpacket);
- if (mem == MPIO_EXTERNAL_MEM)
- mpio_io_set_cmdpacket(m, GET_SPARE_AREA, mem, index, size,
- wsize, cmdpacket);
- debugn(5, "\n>>> MPIO\n");
- hexdump(cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
-
- if(nwrite != CMD_SIZE) {
- debug ("\nFailed to send command.\n\n");
- close (m->fd);
- return 1;
- }
-
- /* Receive packet from MPIO */
- for (i = 0; i < (toread / chips / CMD_SIZE); i++)
- {
- nread = mpio_io_bulk_read (m->fd,
- output + (i * CMD_SIZE) +
- (toread / chips * (chip - 1)),
- CMD_SIZE);
-
- if ((progress_callback) && (i % 256))
- (*progress_callback)(mem,
- (i*CMD_SIZE+(toread/chips*(chip-1))),
- toread );
-
- if(nread != CMD_SIZE)
- {
- debug ("\nFailed to read Block.\n%x\n",nread);
- close (m->fd);
- return 1;
- }
- debugn(5, "\n<<< MPIO\n");
- hexdump(output + (i * CMD_SIZE) + (toread / chips * (chip - 1)),
- CMD_SIZE);
- }
- }
- if (progress_callback)
- (*progress_callback)(mem, toread, toread);
-
- return 0;
-}
-
-int
-mpio_io_block_delete(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
-{
- 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;
-
- fatentry2hw(f, &chip, &address);
-
- if (address == MPIO_BLOCK_NOT_FOUND)
- {
- debug("hmm, what happens here? (%4x)\n", f->entry);
- return 0;
- }
-
- 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;
- /* hack to support 2+4 internal chips
- * who ever allowed me to write code??? -mager
- */
- if (chip == (MPIO_INTERNAL_MEM+1)) sm = &m->internal;
- if (chip == (MPIO_INTERNAL_MEM+3)) sm = &m->internal;
- if (chip == (MPIO_INTERNAL_MEM+7)) sm = &m->internal;
- 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);
-
- debugn (5, ">>> MPIO\n");
- hexdump (cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, 0x40);
-
- if (nwrite != CMD_SIZE)
- {
- debug ("Failed to send command.\n\n");
- close (m->fd);
- return 0;
- }
-
-/* Receive packet from MPIO */
- nread = mpio_io_bulk_read (m->fd, status, CMD_SIZE);
-
- if ((nread == -1) || (nread != CMD_SIZE))
- {
- debug ("Failed to read Sector.\n%x\n",nread);
- close (m->fd);
- return 0;
- }
-
- debugn(5, "<<< MPIO\n");
- hexdump(status, CMD_SIZE);
-
- if (status[0] != 0xc0)
- {
- debugn (2,"error formatting Block %02x:%06x\n",
- chip, address);
- if (chip == MPIO_EXTERNAL_MEM)
- {
- sm = &m->external;
- mpio_zone_block_set_defect_phys(m, chip, address);
- }
- }
-
- return CMD_SIZE;
-}
-
-int
-mpio_io_block_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, BYTE *data)
-{
- mpio_smartmedia_t *sm;
- int nwrite;
- int i;
- DWORD block_address, ba;
- BYTE cmdpacket[CMD_SIZE], sendbuff[BLOCK_TRANS];
- BYTE chip=0;
- DWORD address;
-
- if (mem == MPIO_INTERNAL_MEM)
- {
- sm = &m->internal;
- fatentry2hw(f, &chip, &address);
- }
-
- if (mem == MPIO_EXTERNAL_MEM)
- {
- sm = &m->external;
- /* find free physical block */
- chip = MPIO_EXTERNAL_MEM;
- address = mpio_zone_block_find_free_log(m, mem, f->entry);
- }
-
- /* build block for transfer to MPIO */
- for (i = 0; i < BLOCK_SECTORS; i++)
- {
- memcpy(sendbuff + (i * SECTOR_TRANS),
- data + (i * SECTOR_SIZE),
- SECTOR_SIZE);
- memset(sendbuff + (i * SECTOR_TRANS) + SECTOR_SIZE,
- 0xff, CMD_SIZE);
-
- if (mem == MPIO_INTERNAL_MEM)
- {
- if (i == 0)
- {
- memcpy((sendbuff+SECTOR_SIZE+(i * SECTOR_TRANS)),
- f->i_fat, 0x10);
-/* debug("address %02x:%06x\n", chip, address); */
-/* hexdumpn(0, f->i_fat, 0x10); */
- }
- }
-
- /* fill in block information */
- if (mem == MPIO_EXTERNAL_MEM)
- {
- block_address = mpio_zone_block_get_logical(m, mem, address);
- block_address = blockaddress_encode(block_address);
-
- ba = (block_address / 0x100) & 0xff;
- sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x06] = ba;
- sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x0b] = ba;
-
- ba = block_address & 0xff;
- sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x07] = ba;
- sendbuff[(i * SECTOR_TRANS) + SECTOR_SIZE + 0x0c] = ba;
-
- /* generate ECC Area information */
- mpio_ecc_256_gen ((sendbuff + (i * SECTOR_TRANS)),
- ((sendbuff + (i * SECTOR_TRANS)
- + SECTOR_SIZE + 13)));
- mpio_ecc_256_gen ((sendbuff + (i * SECTOR_TRANS)
- + (SECTOR_SIZE / 2)),
- ((sendbuff + (i * SECTOR_TRANS)
- + SECTOR_SIZE + 8)));
- }
- }
-
- mpio_io_set_cmdpacket(m, PUT_BLOCK, chip, address, sm->size, 0x48 , cmdpacket);
-
- debugn(5, "\n>>> MPIO\n");
- hexdump(cmdpacket, sizeof(cmdpacket));
-
- nwrite = mpio_io_bulk_write(m->fd, cmdpacket, CMD_SIZE);
-
- if(nwrite != CMD_SIZE)
- {
- debug ("\nFailed to send command.\n\n");
- close (m->fd);
- return 1;
- }
-
- /* send packet to MPIO */
- debugn(5, "\n<<< MPIO\n");
- hexdump(sendbuff, BLOCK_TRANS);
- nwrite = mpio_io_bulk_write (m->fd, sendbuff, BLOCK_TRANS);
-
- if(nwrite != BLOCK_TRANS)
- {
- debug ("\nFailed to read Block.\n%x\n",nwrite);
- close (m->fd);
- return 1;
- }
-
- return 0;
-}