2010-09-08 01:42:32 -06:00
|
|
|
#include <linux/slab.h>
|
|
|
|
#include "usb.h"
|
|
|
|
#include "scsiglue.h"
|
|
|
|
#include "smcommon.h"
|
|
|
|
#include "smil.h"
|
|
|
|
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Conv_D_MediaAddr(struct us_data *, u32);
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Inc_D_MediaAddr(struct us_data *);
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Media_D_ReadOneSect(struct us_data *, u16, u8 *);
|
2013-11-01 07:49:57 -06:00
|
|
|
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Copy_D_BlockAll(struct us_data *, u32);
|
2013-11-01 07:49:57 -06:00
|
|
|
|
|
|
|
static int Assign_D_WriteBlock(void);
|
|
|
|
static int Release_D_ReadBlock(struct us_data *);
|
|
|
|
static int Release_D_WriteBlock(struct us_data *);
|
|
|
|
static int Release_D_CopySector(struct us_data *);
|
|
|
|
|
|
|
|
static int Copy_D_PhyOneSect(struct us_data *);
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Read_D_PhyOneSect(struct us_data *, u16, u8 *);
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Erase_D_PhyOneBlock(struct us_data *);
|
|
|
|
|
|
|
|
static int Set_D_PhyFmtValue(struct us_data *);
|
|
|
|
static int Search_D_CIS(struct us_data *);
|
|
|
|
static int Make_D_LogTable(struct us_data *);
|
|
|
|
|
|
|
|
static int MarkFail_D_PhyOneBlock(struct us_data *);
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2014-03-15 15:44:57 -06:00
|
|
|
static u32 ErrCode;
|
|
|
|
static u8 WorkBuf[SECTSIZE];
|
|
|
|
static u8 Redundant[REDTSIZE];
|
|
|
|
static u8 WorkRedund[REDTSIZE];
|
2013-05-17 02:06:05 -06:00
|
|
|
/* 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; */
|
2014-03-15 15:44:57 -06:00
|
|
|
static u16 *Log2Phy[MAX_ZONENUM];
|
|
|
|
static u8 Assign[MAX_ZONENUM][MAX_BLOCKNUM / 8];
|
|
|
|
static u16 AssignStart[MAX_ZONENUM];
|
|
|
|
u16 ReadBlock;
|
|
|
|
u16 WriteBlock;
|
|
|
|
u32 MediaChange;
|
|
|
|
static u32 SectCopyMode;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* BIT Control Macro */
|
2014-03-15 15:44:57 -06:00
|
|
|
static u8 BitData[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
|
|
|
#define Set_D_Bit(a, b) (a[(u8)((b) / 8)] |= BitData[(b) % 8])
|
|
|
|
#define Clr_D_Bit(a, b) (a[(u8)((b) / 8)] &= ~BitData[(b) % 8])
|
|
|
|
#define Chk_D_Bit(a, b) (a[(u8)((b) / 8)] & BitData[(b) % 8])
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- SM_FreeMem() ------------------------------------------------- */
|
2010-09-08 01:42:32 -06:00
|
|
|
int SM_FreeMem(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2011-04-01 00:38:42 -06:00
|
|
|
pr_info("SM_FreeMem start\n");
|
2013-05-17 02:04:33 -06:00
|
|
|
for (i = 0; i < MAX_ZONENUM; i++) {
|
|
|
|
if (Log2Phy[i] != NULL) {
|
2011-04-01 00:38:42 -06:00
|
|
|
pr_info("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
|
2010-09-08 01:42:32 -06:00
|
|
|
kfree(Log2Phy[i]);
|
|
|
|
Log2Phy[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-05-17 02:02:22 -06:00
|
|
|
return NO_ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Read/Write/Erase Function */
|
|
|
|
/* ----- Media_D_ReadSector() ------------------------------------------- */
|
2014-03-15 15:44:57 -06:00
|
|
|
int Media_D_ReadSector(struct us_data *us, u32 start, u16 count, u8 *buf)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u16 len, bn;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (Conv_D_MediaAddr(us, start))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:18 -06:00
|
|
|
while (1) {
|
2010-09-08 01:42:32 -06:00
|
|
|
len = Ssfdc.MaxSectors - Media.Sector;
|
|
|
|
if (count > len)
|
|
|
|
bn = len;
|
|
|
|
else
|
|
|
|
bn = count;
|
2013-05-17 02:05:51 -06:00
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Media_D_ReadOneSect(us, bn, buf)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_EccReadErr;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Media.Sector += bn;
|
|
|
|
count -= bn;
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (count <= 0)
|
2010-09-08 01:42:32 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
buf += bn * SECTSIZE;
|
|
|
|
|
|
|
|
if (Inc_D_MediaAddr(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return NO_ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-05-17 02:06:05 -06:00
|
|
|
/* here */
|
|
|
|
/* ----- Media_D_CopySector() ------------------------------------------ */
|
2014-03-15 15:44:57 -06:00
|
|
|
int Media_D_CopySector(struct us_data *us, u32 start, u16 count, u8 *buf)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u16 len, bn;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2011-04-01 00:38:42 -06:00
|
|
|
/* pr_info("Media_D_CopySector !!!\n"); */
|
2010-09-08 01:42:32 -06:00
|
|
|
if (Conv_D_MediaAddr(us, start))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:18 -06:00
|
|
|
while (1) {
|
2010-09-08 01:42:32 -06:00
|
|
|
if (Assign_D_WriteBlock())
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
len = Ssfdc.MaxSectors - Media.Sector;
|
|
|
|
if (count > len)
|
|
|
|
bn = len;
|
|
|
|
else
|
|
|
|
bn = count;
|
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Ssfdc_D_CopyBlock(us, bn, buf, Redundant)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_WriteFault;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Media.Sector = 0x1F;
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Release_D_CopySector(us)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_HwError) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_WriteFault;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
count -= bn;
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (count <= 0)
|
2010-09-08 01:42:32 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
buf += bn * SECTSIZE;
|
|
|
|
|
|
|
|
if (Inc_D_MediaAddr(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ErrCode;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
}
|
2013-05-17 02:02:22 -06:00
|
|
|
return NO_ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Format Test Subroutine */
|
|
|
|
/* ----- Check_D_MediaFmt() --------------------------------------------- */
|
2010-09-08 01:42:32 -06:00
|
|
|
int Check_D_MediaFmt(struct us_data *us)
|
|
|
|
{
|
2011-04-01 00:38:42 -06:00
|
|
|
pr_info("Check_D_MediaFmt\n");
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (!MediaChange)
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
MediaChange = ERROR;
|
|
|
|
SectCopyMode = COMPLETED;
|
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Set_D_PhyFmtValue(us)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_UnknownMedia;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-05-17 02:06:36 -06:00
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Search_D_CIS(us)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_IllegalFmt;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:19 -06:00
|
|
|
MediaChange = SMSUCCESS;
|
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-05-17 02:05:51 -06:00
|
|
|
|
2014-05-04 02:44:52 -06:00
|
|
|
/* ----- Release_D_CopySector() ------------------------------------------ */
|
|
|
|
static int Release_D_CopySector(struct us_data *us)
|
|
|
|
{
|
|
|
|
Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
|
|
|
|
Media.PhyBlock = ReadBlock;
|
|
|
|
|
|
|
|
if (Media.PhyBlock == NO_ASSIGN) {
|
|
|
|
Media.PhyBlock = WriteBlock;
|
|
|
|
return SMSUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
|
|
|
|
Media.PhyBlock = WriteBlock;
|
|
|
|
|
|
|
|
return SMSUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Address Control Subroutine */
|
|
|
|
/* ----- Conv_D_MediaAddr() --------------------------------------------- */
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Conv_D_MediaAddr(struct us_data *us, u32 addr)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u32 temp;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
temp = addr / Ssfdc.MaxSectors;
|
2014-03-15 15:44:57 -06:00
|
|
|
Media.Zone = (u8) (temp / Ssfdc.MaxLogBlocks);
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Log2Phy[Media.Zone] == NULL) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Make_D_LogTable(us)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_IllegalFmt;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-15 15:44:57 -06:00
|
|
|
Media.Sector = (u8) (addr % Ssfdc.MaxSectors);
|
|
|
|
Media.LogBlock = (u16) (temp % Ssfdc.MaxLogBlocks);
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Media.Zone < Ssfdc.MaxZones) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Clr_D_RedundantData(Redundant);
|
|
|
|
Set_D_LogBlockAddr(Redundant);
|
|
|
|
Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ErrCode = ERR_OutOfLBA;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Inc_D_MediaAddr() ---------------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Inc_D_MediaAddr(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u16 LogBlock = Media.LogBlock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (++Media.Sector < Ssfdc.MaxSectors)
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Log2Phy[Media.Zone] == NULL) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Make_D_LogTable(us)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_IllegalFmt;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.Sector = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
Media.LogBlock = LogBlock;
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (++Media.LogBlock < Ssfdc.MaxLogBlocks) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Clr_D_RedundantData(Redundant);
|
|
|
|
Set_D_LogBlockAddr(Redundant);
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.LogBlock = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (++Media.Zone < Ssfdc.MaxZones) {
|
|
|
|
if (Log2Phy[Media.Zone] == NULL) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Make_D_LogTable(us)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_IllegalFmt;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Media.LogBlock = 0;
|
|
|
|
|
|
|
|
Clr_D_RedundantData(Redundant);
|
|
|
|
Set_D_LogBlockAddr(Redundant);
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.Zone = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_OutOfLBA;
|
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Read/Write Subroutine with Retry */
|
|
|
|
/* ----- Media_D_ReadOneSect() ------------------------------------------ */
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Media_D_ReadOneSect(struct us_data *us, u16 count, u8 *buf)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u32 err, retry;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (!Read_D_PhyOneSect(us, count, buf))
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_HwError)
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_DataStatus)
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
#ifdef RDERR_REASSIGN
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Ssfdc.Attribute & MWP) {
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_CorReadErr)
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
err = ErrCode;
|
|
|
|
for (retry = 0; retry < 2; retry++) {
|
2013-05-17 02:06:49 -06:00
|
|
|
if (Copy_D_BlockAll(us,
|
|
|
|
(err == ERR_EccReadErr) ? REQ_FAIL : REQ_ERASE)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_HwError)
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrCode = err;
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_CorReadErr)
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
MediaChange = ERROR;
|
|
|
|
#else
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_CorReadErr)
|
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
#endif
|
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Sector Data Copy Subroutine */
|
|
|
|
/* ----- Copy_D_BlockAll() ---------------------------------------------- */
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Copy_D_BlockAll(struct us_data *us, u32 mode)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u8 sect;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
sect = Media.Sector;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (Assign_D_WriteBlock())
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2013-05-17 02:04:33 -06:00
|
|
|
if (mode == REQ_FAIL)
|
|
|
|
SectCopyMode = REQ_FAIL;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:49 -06:00
|
|
|
for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
|
|
|
|
Media.Sector++) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Copy_D_PhyOneSect(us)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_HwError)
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
if (Release_D_WriteBlock(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
ErrCode = ERR_WriteFault;
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = ReadBlock;
|
|
|
|
Media.Sector = sect;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Release_D_ReadBlock(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = WriteBlock;
|
|
|
|
Media.Sector = sect;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Block Assign/Release Subroutine */
|
|
|
|
/* ----- Assign_D_WriteBlock() ------------------------------------------ */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Assign_D_WriteBlock(void)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2013-05-17 02:04:33 -06:00
|
|
|
ReadBlock = Media.PhyBlock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:49 -06:00
|
|
|
for (WriteBlock = AssignStart[Media.Zone];
|
|
|
|
WriteBlock < Ssfdc.MaxBlocks; WriteBlock++) {
|
2013-05-17 02:04:02 -06:00
|
|
|
if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
|
|
|
|
Set_D_Bit(Assign[Media.Zone], WriteBlock);
|
2013-05-17 02:04:33 -06:00
|
|
|
AssignStart[Media.Zone] = WriteBlock + 1;
|
|
|
|
Media.PhyBlock = WriteBlock;
|
|
|
|
SectCopyMode = REQ_ERASE;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:49 -06:00
|
|
|
for (WriteBlock = 0;
|
|
|
|
WriteBlock < AssignStart[Media.Zone]; WriteBlock++) {
|
2013-05-17 02:04:02 -06:00
|
|
|
if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
|
|
|
|
Set_D_Bit(Assign[Media.Zone], WriteBlock);
|
2013-05-17 02:04:33 -06:00
|
|
|
AssignStart[Media.Zone] = WriteBlock + 1;
|
|
|
|
Media.PhyBlock = WriteBlock;
|
|
|
|
SectCopyMode = REQ_ERASE;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
WriteBlock = NO_ASSIGN;
|
2010-09-08 01:42:32 -06:00
|
|
|
ErrCode = ERR_WriteFault;
|
2013-05-17 02:05:51 -06:00
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Release_D_ReadBlock() ------------------------------------------ */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Release_D_ReadBlock(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u32 mode;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
mode = SectCopyMode;
|
|
|
|
SectCopyMode = COMPLETED;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (mode == COMPLETED)
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
|
|
|
|
Media.PhyBlock = ReadBlock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Media.PhyBlock == NO_ASSIGN) {
|
|
|
|
Media.PhyBlock = WriteBlock;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (mode == REQ_ERASE) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Erase_D_PhyOneBlock(us)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ErrCode == ERR_HwError)
|
|
|
|
return ERROR;
|
|
|
|
if (MarkFail_D_PhyOneBlock(us))
|
|
|
|
return ERROR;
|
2013-05-17 02:03:15 -06:00
|
|
|
} else
|
2013-05-17 02:04:02 -06:00
|
|
|
Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
|
2013-05-17 02:03:15 -06:00
|
|
|
} else if (MarkFail_D_PhyOneBlock(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = WriteBlock;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Release_D_WriteBlock() ----------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Release_D_WriteBlock(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2013-05-17 02:04:33 -06:00
|
|
|
SectCopyMode = COMPLETED;
|
|
|
|
Media.PhyBlock = WriteBlock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (MarkFail_D_PhyOneBlock(us))
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = ReadBlock;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Sector Data Copy Subroutine */
|
|
|
|
/* ----- Copy_D_PhyOneSect() -------------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Copy_D_PhyOneSect(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
|
|
|
int i;
|
2014-03-15 15:44:57 -06:00
|
|
|
u32 err, retry;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-12-12 06:22:59 -07:00
|
|
|
/* pr_info("Copy_D_PhyOneSect --- Sector = %x\n", Media.Sector); */
|
2013-05-17 02:04:33 -06:00
|
|
|
if (ReadBlock != NO_ASSIGN) {
|
|
|
|
Media.PhyBlock = ReadBlock;
|
|
|
|
for (retry = 0; retry < 2; retry++) {
|
|
|
|
if (retry != 0) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:06:49 -06:00
|
|
|
if (Ssfdc_D_ReadCisSect(us, WorkBuf,
|
|
|
|
WorkRedund)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Check_D_CISdata(WorkBuf, WorkRedund)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Ssfdc_D_ReadSect(us, WorkBuf, WorkRedund)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
if (Check_D_DataStatus(WorkRedund)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
err = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!Check_D_ReadError(WorkRedund)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
err = SMSUCCESS;
|
2013-05-17 02:02:50 -06:00
|
|
|
break;
|
|
|
|
}
|
2013-05-17 02:04:02 -06:00
|
|
|
if (!Check_D_Correct(WorkBuf, WorkRedund)) {
|
2013-05-17 02:04:33 -06:00
|
|
|
err = SMSUCCESS;
|
2013-05-17 02:02:50 -06:00
|
|
|
break;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
err = ERROR;
|
|
|
|
SectCopyMode = REQ_FAIL;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-05-17 02:03:15 -06:00
|
|
|
} else {
|
2013-05-17 02:04:33 -06:00
|
|
|
err = SMSUCCESS;
|
|
|
|
for (i = 0; i < SECTSIZE; i++)
|
|
|
|
WorkBuf[i] = DUMMY_DATA;
|
2010-09-08 01:42:32 -06:00
|
|
|
Clr_D_RedundantData(WorkRedund);
|
|
|
|
}
|
|
|
|
|
|
|
|
Set_D_LogBlockAddr(WorkRedund);
|
2013-05-17 02:04:33 -06:00
|
|
|
if (err == ERROR) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Set_D_RightECC(WorkRedund);
|
|
|
|
Set_D_DataStaus(WorkRedund);
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = WriteBlock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund)) {
|
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
if (Ssfdc_D_CheckStatus()) {
|
|
|
|
ErrCode = ERR_WriteFault;
|
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.PhyBlock = ReadBlock;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Sector Read/Write/Erase Subroutine */
|
|
|
|
/* ----- Read_D_PhyOneSect() -------------------------------------------- */
|
2014-03-15 15:44:57 -06:00
|
|
|
static int Read_D_PhyOneSect(struct us_data *us, u16 count, u8 *buf)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
|
|
|
int i;
|
2014-03-15 15:44:57 -06:00
|
|
|
u32 retry;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Media.PhyBlock == NO_ASSIGN) {
|
|
|
|
for (i = 0; i < SECTSIZE; i++)
|
|
|
|
*buf++ = DUMMY_DATA;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
for (retry = 0; retry < 2; retry++) {
|
|
|
|
if (retry != 0) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Ssfdc_D_ReadCisSect(us, WorkBuf, WorkRedund)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Check_D_CISdata(WorkBuf, WorkRedund)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Ssfdc_D_ReadBlock(us, count, buf, Redundant)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
if (Check_D_DataStatus(Redundant)) {
|
|
|
|
ErrCode = ERR_DataStatus;
|
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
if (!Check_D_ReadError(Redundant))
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (!Check_D_Correct(buf, Redundant)) {
|
2013-05-17 02:02:50 -06:00
|
|
|
ErrCode = ERR_CorReadErr;
|
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ErrCode = ERR_EccReadErr;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Erase_D_PhyOneBlock(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Ssfdc_D_EraseBlock(us)) {
|
|
|
|
ErrCode = ERR_HwError;
|
2013-05-17 02:04:33 -06:00
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:50 -06:00
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
if (Ssfdc_D_CheckStatus()) {
|
|
|
|
ErrCode = ERR_WriteFault;
|
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* SmartMedia Physical Format Check Local Subroutine */
|
|
|
|
/* ----- Set_D_PhyFmtValue() -------------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Set_D_PhyFmtValue(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2013-05-17 02:06:19 -06:00
|
|
|
if (Set_D_SsfdcModel(us->SM_DeviceID))
|
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:19 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Search_D_CIS() ------------------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Search_D_CIS(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.Zone = 0;
|
|
|
|
Media.Sector = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:49 -06:00
|
|
|
for (Media.PhyBlock = 0;
|
|
|
|
Media.PhyBlock < (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1);
|
|
|
|
Media.PhyBlock++) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Ssfdc_D_ReadRedtData(us, Redundant)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!Check_D_FailBlock(Redundant))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Media.PhyBlock == (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
while (Media.Sector < CIS_SEARCH_SECT) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Media.Sector) {
|
|
|
|
if (Ssfdc_D_ReadRedtData(us, Redundant)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
}
|
2013-05-17 02:02:50 -06:00
|
|
|
if (!Check_D_DataStatus(Redundant)) {
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Ssfdc_D_ReadSect(us, WorkBuf, Redundant)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:02 -06:00
|
|
|
if (Check_D_CISdata(WorkBuf, Redundant)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
CisArea.PhyBlock = Media.PhyBlock;
|
|
|
|
CisArea.Sector = Media.Sector;
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Media.Sector++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- Make_D_LogTable() ---------------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int Make_D_LogTable(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u16 phyblock, logblock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Log2Phy[Media.Zone] == NULL) {
|
2014-03-15 15:44:57 -06:00
|
|
|
Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK * sizeof(u16),
|
2013-05-17 02:06:49 -06:00
|
|
|
GFP_KERNEL);
|
2011-04-01 00:38:42 -06:00
|
|
|
/* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
|
|
|
|
Media.Zone, Log2Phy[Media.Zone]); */
|
2013-05-17 02:04:33 -06:00
|
|
|
if (Log2Phy[Media.Zone] == NULL)
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.Sector = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
/* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
|
|
|
|
Media.Zone); */
|
|
|
|
for (Media.LogBlock = 0; Media.LogBlock < Ssfdc.MaxLogBlocks;
|
|
|
|
Media.LogBlock++)
|
|
|
|
Log2Phy[Media.Zone][Media.LogBlock] = NO_ASSIGN;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
for (Media.PhyBlock = 0; Media.PhyBlock < (MAX_BLOCKNUM / 8);
|
|
|
|
Media.PhyBlock++)
|
|
|
|
Assign[Media.Zone][Media.PhyBlock] = 0x00;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
for (Media.PhyBlock = 0; Media.PhyBlock < Ssfdc.MaxBlocks;
|
|
|
|
Media.PhyBlock++) {
|
|
|
|
if ((!Media.Zone) && (Media.PhyBlock <= CisArea.PhyBlock)) {
|
2013-05-17 02:04:02 -06:00
|
|
|
Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
|
2013-06-06 10:10:50 -06:00
|
|
|
continue;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Ssfdc_D_ReadRedtData(us, Redundant)) {
|
|
|
|
Ssfdc_D_Reset(us);
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Check_D_DataBlank(Redundant))
|
|
|
|
continue;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Check_D_FailBlock(Redundant))
|
|
|
|
continue;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Load_D_LogBlockAddr(Redundant))
|
|
|
|
continue;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Media.LogBlock >= Ssfdc.MaxLogBlocks)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Log2Phy[Media.Zone][Media.LogBlock] == NO_ASSIGN) {
|
|
|
|
Log2Phy[Media.Zone][Media.LogBlock] = Media.PhyBlock;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
phyblock = Media.PhyBlock;
|
|
|
|
logblock = Media.LogBlock;
|
2014-03-15 15:44:57 -06:00
|
|
|
Media.Sector = (u8)(Ssfdc.MaxSectors - 1);
|
2013-06-06 10:10:50 -06:00
|
|
|
|
|
|
|
if (Ssfdc_D_ReadRedtData(us, Redundant)) {
|
|
|
|
Ssfdc_D_Reset(us);
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Load_D_LogBlockAddr(Redundant) &&
|
|
|
|
(Media.LogBlock == logblock)) {
|
|
|
|
Media.PhyBlock = Log2Phy[Media.Zone][logblock];
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Ssfdc_D_ReadRedtData(us, Redundant)) {
|
|
|
|
Ssfdc_D_Reset(us);
|
|
|
|
return ERROR;
|
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
Media.PhyBlock = phyblock;
|
|
|
|
|
2013-05-17 02:02:50 -06:00
|
|
|
if (!Load_D_LogBlockAddr(Redundant)) {
|
2013-06-06 10:10:50 -06:00
|
|
|
if (Media.LogBlock != logblock) {
|
2013-05-17 02:06:49 -06:00
|
|
|
Media.PhyBlock =
|
|
|
|
Log2Phy[Media.Zone][logblock];
|
2013-06-06 10:10:50 -06:00
|
|
|
Log2Phy[Media.Zone][logblock] =
|
|
|
|
phyblock;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-06-06 10:10:50 -06:00
|
|
|
} else {
|
|
|
|
Media.PhyBlock = Log2Phy[Media.Zone][logblock];
|
|
|
|
Log2Phy[Media.Zone][logblock] = phyblock;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
2013-06-06 10:10:50 -06:00
|
|
|
}
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
Media.Sector = 0;
|
|
|
|
Media.PhyBlock = phyblock;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-06-06 10:10:50 -06:00
|
|
|
AssignStart[Media.Zone] = 0;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
} /* End for (Media.Zone<MAX_ZONENUM) */
|
2010-09-08 01:42:32 -06:00
|
|
|
|
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
2013-05-17 02:06:05 -06:00
|
|
|
/* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
|
2013-11-01 07:49:57 -06:00
|
|
|
static int MarkFail_D_PhyOneBlock(struct us_data *us)
|
2010-09-08 01:42:32 -06:00
|
|
|
{
|
2014-03-15 15:44:57 -06:00
|
|
|
u8 sect;
|
2010-09-08 01:42:32 -06:00
|
|
|
|
2013-05-17 02:04:33 -06:00
|
|
|
sect = Media.Sector;
|
2010-09-08 01:42:32 -06:00
|
|
|
Set_D_FailBlock(WorkRedund);
|
|
|
|
|
2013-05-17 02:06:49 -06:00
|
|
|
for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
|
|
|
|
Media.Sector++) {
|
2013-05-17 02:02:50 -06:00
|
|
|
if (Ssfdc_D_WriteRedtData(us, WorkRedund)) {
|
2010-09-08 01:42:32 -06:00
|
|
|
Ssfdc_D_Reset(us);
|
|
|
|
Media.Sector = sect;
|
|
|
|
ErrCode = ERR_HwError;
|
|
|
|
MediaChange = ERROR;
|
2013-05-17 02:02:22 -06:00
|
|
|
return ERROR;
|
2013-05-17 02:06:05 -06:00
|
|
|
} /* NO Status Check */
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Ssfdc_D_Reset(us);
|
2013-05-17 02:04:33 -06:00
|
|
|
Media.Sector = sect;
|
2013-05-17 02:02:22 -06:00
|
|
|
return SMSUCCESS;
|
2010-09-08 01:42:32 -06:00
|
|
|
}
|