system.c 6.27 KB

#include "ddwriteint.h"


/*
 * Prototypes
 */
static u32 makeError(void *buffer, u32 bufSize,
		     s32 startLba, u32 nblks, u32 fillData);
static u32 sectorWrite(void *vaddr, s32 lba, u32 secSize);


/*
 * ディスク内のフォーマットそのものの構造体
 */
typedef struct
{
  u32   country;
  u8    formatType;             /* 0x00 old, 0x10 new */
  u8    diskType;
  u16   iplSize;
  u8    defectData1[20];
  void  *loadAddr;
  u8    defectData2[160];

} __sysInfo_s;

typedef struct
{
  LEODiskID     diskID;
  u8            diskmanID[200];

} __idInfo_s;


u32 __ddWriteSystemBlock(__SystemInfo_s *sys, __DefectInfo_s *def, u32 formatType)
{
  __sysInfo_s	sysInfo;
  u32		result;


  bzero((void *)&sysInfo, sizeof(sysInfo));

  sysInfo.country = sys->country;
  sysInfo.formatType = (u8)formatType;
  sysInfo.diskType = (u8)( sys->diskType | formatType );
  sysInfo.iplSize = (u16)sys->iplSize;
  sysInfo.loadAddr = sys->loadAddr;
  
  bcopy( (void *)&(def->defectData1),
	(void *)&(sysInfo.defectData1), 20 );
  bcopy( (void *)&(def->defectData2),
	(void *)&(sysInfo.defectData2), 160 );

  if ( (result = sectorWrite((void *)&sysInfo, -22, 192)) != 0 )
    return result;
  if ( (result = sectorWrite((void *)&sysInfo, -21, 192)) != 0 )
    return result;
  if ( (result = sectorWrite((void *)&sysInfo, -14, 192)) != 0 )
    return result;
  if ( (result = sectorWrite((void *)&sysInfo, -13, 192)) != 0 )
    return result;
  

  return 0;

} /* __ddWriteSystemBlock() */


u32 __ddReadSystemBlock(__SystemInfo_s *sys, __DefectInfo_s *def, u32 *formatType)
{
  LEOCmd	cmdBlock;
  __sysInfo_s	*sysInfo;
  u32		error = 0;
  

  LeoSectorRead(&cmdBlock, -22, (void *)__ddBufp1,
		(u32)1, &__ddDiskQ);
  (void) osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK); 

  if(error)
    return error;


  sysInfo = (__sysInfo_s *)__ddBufp1;
  
  sys->country = sysInfo->country;
  *formatType = (u32)sysInfo->formatType;
  sys->diskType = (u32)(sysInfo->diskType & 0x0f);
  sys->iplSize = (u32)(sysInfo->iplSize);
  sys->loadAddr = sysInfo->loadAddr;
  
  bcopy( (void *)&(sysInfo->defectData1),
	(void *)&(def->defectData1), 20 );
  bcopy( (void *)&(sysInfo->defectData2),
	(void *)&(def->defectData2), 160 );
  
  return 0;

} /* __ddReadSystemBlock() */


u32 __ddWriteIDBlock(LEODiskID *id)
{
  __idInfo_s	idInfo;
  u32		result;
  
  bcopy( (void *)id, (void *)&(idInfo.diskID), sizeof(LEODiskID) );
  bzero( (void *)&(idInfo.diskmanID), 200 );

  if ( (result = sectorWrite((void *)&idInfo, -10, 232)) != 0 )
    return result;
  if ( (result = sectorWrite((void *)&idInfo, -9, 232)) != 0 )
    return result;
  
  return 0;

} /* __ddWriteSystemBlock() */


u32 __ddReadIDBlock(LEODiskID *id)
{
  LEOCmd	cmdBlock;
  u32		error = 0;
  __idInfo_s	*idInfo;

  LeoSectorRead(&cmdBlock, -10, (void *)__ddBufp1,
		(u32)1, &__ddDiskQ);
  (void) osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK); 

  if(error)
    return error;


  idInfo = (__idInfo_s *)__ddBufp1;

  bcopy( (void *)&(idInfo->diskID), (void *)id, sizeof(LEODiskID) );
  
  return 0;

} /* __ddReadSystemBlock() */


u32 __ddReadDefectBlock(__DefectInfo_s *def, u32 *formatType)
{
  LEOCmd		cmdBlock;
  __sysInfo_s		*sys;
  u32			error = 0;

  LeoSectorRead(&cmdBlock, -20, (void *)__ddBufp1,
		(u32)1, &__ddDiskQ);
  (void) osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK); 

  if(error)
    return error;


  sys = (__sysInfo_s *)__ddBufp1;
  bcopy( (void *)&(sys->defectData1), (void *)&(def->defectData1), 20 );
  bcopy( (void *)&(sys->defectData2), (void *)&(def->defectData2), 160 );
  
  *formatType = (u32)(sys->formatType);
  
  return 0;
  
} /* __ddReadDefectBlock() */


u32 __ddWriteErrorECC(void)
{
  LEOCmd	cmdBlock;
  u32		error = 0;
  
  bzero((void *)__ddBufp1, 232 * 85);
  
  LeoSysReadWrite(&cmdBlock, OS_WRITE, -12,
		    (void *)__ddBufp1, 1, &__ddDiskQ);
  osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK);
  
  return error;


} /* __ddWriteErrorECC() */



/*
 * ユーザエリアのアンフォーマット
 */
u32 __ddUnformatUserArea(void *buffer, u32 bufSize)
{
  
  return  makeError(buffer, bufSize, 0, 4292, 0xbfbfbfbfUL);


} /* __ddUnformatUserArea() */


/*
 * システム領域をディフェクト情報ブロック(-20, -19) と誤ECC を除いて全て
 * 読めなくします。誤ECC は読めるようにします。
 */
u32 __ddUnformatSystemArea(void *buffer, u32 bufSize)
{
  u32		result;

  /* エラーは 0xbf で埋めることで起させる */

  if ( (result = makeError(buffer, bufSize, -24, 4, 0xbfbfbfbfUL)) != 0 )
    return result;
  
  /*
   * ディフェクト情報ブロックはそのまま
   */
  if ( (result = makeError(buffer, bufSize, -18, 6, 0xbfbfbfbfUL)) != 0 )
    return result;

  if ( (result = __ddWriteErrorECC()) != 0 )
    return result;

  if ( (result = makeError(buffer, bufSize, -11, 11, 0xbfbfbfbfUL)) != 0 )
    return result;

  return 0;

} /* __ddUnformatSystemArea() */


/*
 * startLba から nblks ブロックを読めなくします。埋めるデータは 0xffff_ffff
 * か 0xbfbf_bfbf を指定してください。
 */
static u32 makeError(void *buffer, u32 bufSize,
		     s32 startLba, u32 nblks, u32 fillData)
{
  LEOCmd        cmdBlock;
  u32           nbytes, nblocks;
  s32           i;
  u32           error = 0;
  
  nbytes = __ddLba2Byte(0, startLba, nblks) + nblks * 680;
  if (nbytes > (u32)bufSize)
    nbytes = (u32)bufSize;
  
  /* nbytes は常に4の倍数になることに注意 */
  __ddBfill(buffer, nbytes, fillData);
  
  i = startLba;
  while(i < startLba + (s32)nblks)
  {

    nblocks = __ddGetnBlksInAreaLong(0, i, bufSize);

	if( nblocks < 1 ) return DDWRITE_ERROR_INSUFFICIENT_BUFFERSIZE;

    if ( nblocks > (u32)(startLba + (s32)nblks - i) )
      nblocks = (u32)(startLba + (s32)nblks - i);

    LeoReadWriteLong(&cmdBlock, OS_WRITE, i,
                     (void *)buffer, nblocks, 0, &__ddDiskQ);
    osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK);
  
    if(error)
      return error;

    i += (s32)nblocks;
    
  } /* while() */

  return 0;

} /* makeError() */


/*
 * セクターライト
 */
static u32 sectorWrite(void *vaddr, s32 lba, u32 secSize)
{
  u8		*pSys;
  LEOCmd	cmdBlock;
  u32		error = 0, i;
  
  pSys = (u8 *)__ddBufp1;

  for(i = 0; i < 85; i++)
  {
    bcopy(vaddr, (void *)pSys, (int)secSize);
    pSys += secSize;
  }
  
  LeoSysReadWrite(&cmdBlock, OS_WRITE, lba,
		  (void *)__ddBufp1, 1, &__ddDiskQ);
  (void) osRecvMesg(&__ddDiskQ, (OSMesg *)&error, OS_MESG_BLOCK);
  
  return error;


} /* sectorWrite() */