📄 smf_lpt.c
字号:
parit16_1 <<= 3;
parit32_2 <<= 4;
parit32_1 <<= 5;
parit64_2 <<= 6;
parit64_1 <<= 7;
p_ecc[0] = ~(parit64_1 | parit64_2 | parit32_1 | parit32_2 | parit16_1 | parit16_2 | parit8_1 | parit8_2);
p_ecc[1] = ~(parit1024_1 |parit1024_2 | parit512_1 | parit512_2 | parit256_1 | parit256_2 | parit128_1 | parit128_2);
p_ecc[2] = ~(parit4_1 | parit4_2 | parit2_1 | parit2_2 | parit1_1 | parit1_2);
return SM_OK;
}
/**********
* Function: sm_ECCCorrect
* Remarks:
* - adopted from source code that was corrected by SeoGyu Kim, Infomedia Lab. SEC.
**********/
ERR_CODE sm_ECCCorrect(const ubyte *p_data, const ubyte *ecc1, const ubyte *ecc2, ubyte *p_offset, ubyte *p_corrected)
{
int i;
ubyte tmp0_bit[8],tmp1_bit[8],tmp2_bit[8], tmp0, tmp1, tmp2;
ubyte comp0_bit[8],comp1_bit[8],comp2_bit[8];
ubyte ecc_bit[22];
ubyte ecc_gen[3];
ubyte ecc_sum=0;
ubyte ecc_value,find_byte,find_bit;
tmp0 = ~ecc1[0];
tmp1 = ~ecc1[1];
tmp2 = ~ecc1[2];
for (i = 0; i <= 2; ++i)
{
ecc_gen[i] = ~ecc2[i];
}
tmp0_bit[0]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[1]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[2]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[3]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[4]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[5]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[6]= tmp0 & 0x01;
tmp0 >>= 1;
tmp0_bit[7]= tmp0 & 0x01;
tmp1_bit[0]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[1]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[2]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[3]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[4]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[5]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[6]= tmp1 & 0x01;
tmp1 >>= 1;
tmp1_bit[7]= tmp1 & 0x01;
tmp2_bit[0]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[1]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[2]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[3]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[4]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[5]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[6]= tmp2 & 0x01;
tmp2 >>= 1;
tmp2_bit[7]= tmp2 & 0x01;
comp0_bit[0]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[1]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[2]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[3]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[4]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[5]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[6]= ecc_gen[0] & 0x01;
ecc_gen[0] >>= 1;
comp0_bit[7]= ecc_gen[0] & 0x01;
comp1_bit[0]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[1]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[2]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[3]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[4]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[5]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[6]= ecc_gen[1] & 0x01;
ecc_gen[1] >>= 1;
comp1_bit[7]= ecc_gen[1] & 0x01;
comp2_bit[0]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[1]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[2]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[3]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[4]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[5]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[6]= ecc_gen[2] & 0x01;
ecc_gen[2] >>= 1;
comp2_bit[7]= ecc_gen[2] & 0x01;
for (i = 0; i <= 5; ++i)
{
ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
}
for (i = 0; i <= 7; ++i)
{
ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
}
for (i = 0; i <= 7; ++i)
{
ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
}
for (i = 0; i <= 21; ++i)
{
ecc_sum += ecc_bit[i];
}
if (ecc_sum == 11)
{
find_byte = (ecc_bit[21] << 7) + (ecc_bit[19] << 6) + (ecc_bit[17] << 5) + (ecc_bit[15] << 4) + (ecc_bit[13] << 3) + (ecc_bit[11] << 2) + (ecc_bit[9] << 1) + ecc_bit[7];
find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
ecc_value = (p_data[find_byte] >> find_bit) & 0x01;
if (ecc_value == 0)
ecc_value = 1;
else
ecc_value = 0;
*p_offset = find_byte;
*p_corrected = p_data[find_byte];
tmp0_bit[0] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[1] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[2] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[3] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[4] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[5] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[6] = *p_corrected & 0x01;
*p_corrected >>= 1;
tmp0_bit[7] = *p_corrected & 0x01;
tmp0_bit[find_bit] = ecc_value;
*p_corrected = (tmp0_bit[7] << 7) + (tmp0_bit[6] << 6) + (tmp0_bit[5] << 5) + (tmp0_bit[4] << 4) + (tmp0_bit[3] << 3) + (tmp0_bit[2] << 2) + (tmp0_bit[1] << 1) + tmp0_bit[0];
return ERR_ECC_CORRECTABLE;
}
else if ((ecc_sum == 0) || (ecc_sum == 1))
{
return SM_OK;
}
else
{
return ERR_ECC;
}
return SM_OK;
}
/**********
* Function: sm_ECCDecode
* Remarks:
* - 1 bit error correction is implemented
**********/
ERR_CODE sm_ECCDecode(const ubyte* p_buf, const ubyte* p_ecc)
{
ubyte ecc_data[3];
ubyte offset;
ubyte corrected;
udword ret_val;
sm_ECCEncode(p_buf, ecc_data);
if ((p_ecc[0] != ecc_data[0]) || (p_ecc[1] != ecc_data[1]) || (p_ecc[2] != ecc_data[2]))
{
ret_val = sm_ECCCorrect(p_buf, p_ecc, ecc_data, &offset, &corrected);
if (ret_val == ERR_ECC_CORRECTABLE)
{
*((ubyte*)p_buf + offset) = corrected;
}
else if (ret_val == ERR_ECC)
return ERR_ECC;
}
return SM_OK;
}
/**********
* Function: sm_ReadBlock
* Remarks:
* - read data within 1 block
* - cannot read beyond the block boundary
* - if there is an ECC error, p_buf is filled with flash data as in the normal case, but return value is ERR_ECC
**********/
ERR_CODE sm_ReadBlock(udword drv_no, udword lblock_no, udword offset, void* p_buf, udword read_size)
{
udword pba;
pba = GET_LB_TBL(drv_no, lblock_no);
return sm_ReadPhysBlock(drv_no, pba, offset, p_buf, read_size);
}
/**********
* Function: sm_ReadPhysBlock
* Remarks:
* - read data within 1 block
* - cannot read beyond the block boundary
* - if there is an ECC error, p_buf is filled with flash data as in the normal case, but return value is ERR_ECC
**********/
ERR_CODE sm_ReadPhysBlock(udword drv_no, udword pba, udword offset, void* p_buf, udword read_size)
{
udword i;
udword addr;
udword page_size;
#ifndef ECC_DECODE_DISABLE
ubyte spare[16];
bool b_ecc_error = FALSE;
#endif
udword first_read_size = 0;
udword last_read_size = 0;
udword temp_read_size;
/*
* check if the (offset + read_size) is beyond the block boundary
* if(offset + read_size > SECTOR_SIZE * conDevInfo[sDevID[drv_no].device].SpB)
* return ERR_INVALID_PARAM;
*/
if ((pba >= s_devInfo[s_devID[drv_no].device].PBpV) || (pba == UNUSED_LBLOCK))
{
return ERR_INVALID_BLOCK;
}
addr = pba * SECTOR_SIZE * s_devInfo[s_devID[drv_no].device].SpB + offset;
page_size = s_devInfo[s_devID[drv_no].device].szP;
/* read head side until the first sector boundary or until the read_size */
if (offset & (SECTOR_SIZE - 1)) /* <= (offset % SECTOR_SIZE) */
{
first_read_size = SECTOR_SIZE - (offset & (SECTOR_SIZE - 1)); /* <= (offset % SECTOR_SIZE); */
/* check if the first_read_size is beyond read_size */
if (first_read_size > read_size)
{
first_read_size = read_size;
}
if (page_size == 256)
{
/* check if the start & end are on the different pages */
if ((offset / 256) != ((offset + first_read_size) / 256))
{
temp_read_size = first_read_size - ((offset + first_read_size) % 256);
s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, temp_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
s_smlErr = smpFlashReadPage(drv_no, addr + temp_read_size, (ubyte*)p_buf + temp_read_size, first_read_size - temp_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
else
{
s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, first_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
}
else if (page_size == 512)
{
if ((offset & (SECTOR_SIZE - 1)) < 256) /* <= ((offset % SECTOR_SIZE) < 256) */
{
s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, first_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
else
{
s_smlErr = smpFlashReadPage2(drv_no, addr, (ubyte*)p_buf, first_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
}
addr += first_read_size;
p_buf = (ubyte*)p_buf + first_read_size;
read_size -= first_read_size;
}
/* read tail side from the last sector boundary */
if (read_size & (SECTOR_SIZE - 1)) /* <= (read_size % SECTOR_SIZE) */
{
last_read_size = read_size & (SECTOR_SIZE - 1); /* <= read_size % SECTOR_SIZE; */
if (page_size == 256)
{
if (last_read_size < 256)
{
s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, last_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
else
{
s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, 256);
if (s_smlErr != SM_OK)
return s_smlErr;
s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size + 256, (ubyte*)p_buf + read_size - last_read_size + 256, last_read_size - 256);
if (s_smlErr != SM_OK)
return s_smlErr;
}
}
else if (page_size == 512)
{
s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, last_read_size);
if (s_smlErr != SM_OK)
return s_smlErr;
}
read_size -= last_read_size;
}
/*
* now, offset and (offset + read_size) is on the sector boundary.
* (if not, there was an error in the upper processing)
*/
if (read_size > 0)
{
for (i = 0; i < read_size; i += SECTOR_SIZE, addr += SECTOR_SIZE, p_buf = (ubyte*)p_buf + SECTOR_SIZE)
{
if (page_size == 256)
{
s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, 256);
if (s_smlErr != SM_OK)
return s_smlErr;
s_smlErr = smpFlashReadPage(drv_no, addr + 256, (ubyte*)p_buf + 256, 256);
if (s_smlErr != SM_OK)
return s_smlErr;
#ifndef ECC_DECODE_DISABLE
s_smlErr = smpFlashReadSpare(drv_no, addr + 256, spare, 8);
if (s_smlErr != SM_OK)
return s_smlErr;
if (sm_ECCDecode((const ubyte*)p_buf, spare + 5) != SM_OK)
b_ecc_error = TRUE;
if (sm_ECCDecode((ubyte*)p_buf + 256, spare) != SM_OK)
b_ecc_error = TRUE;
#endif
}
else if(page_size == 512)
{
s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, 512);
if (s_smlErr != SM_OK)
return s_smlErr;
#ifndef ECC_DECODE_DISABLE
s_smlErr = smpFlashReadSpare(drv_no, addr, spare, 16);
if (s_smlErr != SM_OK)
return s_smlErr;
if (sm_ECCDecode((const ubyte*)p_buf, spare + 13) != SM_OK)
b_ecc_error = TRUE;
if (sm_ECCDecode((const ubyte*)p_buf + 256, spare + 8) != SM_OK)
b_ecc_error = TRUE;
#endif
}
}
}
#ifndef ECC_DECODE_DISABLE
if (b_ecc_error)
return ERR_ECC;
#endif
return SM_OK;
}
/**********
* Function: sm_WriteCISBlock
* Remarks:
* - write CIS data to the defined physical block
**********/
ERR_CODE sm_WriteCISBlock(udword drv_no, udword pblock_no)
{
udword sector;
udword page_size;
ubyte spare[16];
ubyte* acLPTBuf = SMB_ALLOC_BUF();
if (!acLPTBuf)
return ERR_OUT_OF_MEMORY;
sector = pblock_no * s_devInfo[s_devID[drv_no].device].SpB;
page_size = s_devInfo[s_devID[drv_no].device].szP;
SM_MEMSET(spare, 0xff, 16);
spare[5] = 0xff;
spare[6] = spare[7] = spare[11] = spare[12] = 0;
/* first sector */
SM_MEMSET(acLPTBuf, 0, SECTOR_SIZE);
SM_MEMCPY(acLPTBuf, s_cis, sizeof(s_cis));
#ifndef ECC_ENCODE_DISABLE
sm_ECCEncode(acLPTBuf, spare + 13);
sm_ECCEncode(acLPTBuf + 256, spare + 8);
#endif
s_smlErr = smpFlashWriteSector(drv_no, sector, acLPTBuf, spare);
if (s_smlErr != SM_OK)
{
SMB_FREE_BUF(acLPTBuf);
LPT_RETURN(drv_no, s_smlErr);
}
SMB_FREE_BUF(acLPTBuf);
LPT_RETURN(drv_no, SM_OK);
}
/**********
* Function: sm_MakeBAA
* Remarks:
* - get the value that should be saved to SmartMedia from the logical block number
**********/
uword sm_MakeBAA(udword lblock_no)
{
udword converted_lba;
udword parity;
udword i;
converted_lba = lblock_no % L_ZONE_MAX;
parity = 1;
for (i = 0; i < 10; ++i)
{
parity ^= (converted_lba >> i) & 0x01;
}
converted_lba = 0x1000 | (converted_lba << 1) | parity;
return (uword)converted_lba;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -