diff options
Diffstat (limited to 'drivers/staging/keucr/smilsub.c')
-rw-r--r-- | drivers/staging/keucr/smilsub.c | 1661 |
1 files changed, 1661 insertions, 0 deletions
diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c new file mode 100644 index 000000000000..844b65988636 --- /dev/null +++ b/drivers/staging/keucr/smilsub.c @@ -0,0 +1,1661 @@ +#include <linux/slab.h> +#include "usb.h" +#include "scsiglue.h" +#include "transport.h" +//#include "init.h" + +//#include "stdlib.h" +//#include "EUCR6SK.h" +#include "smcommon.h" +#include "smil.h" + +void _Set_D_SsfdcRdCmd (BYTE); +void _Set_D_SsfdcRdAddr (BYTE); +void _Set_D_SsfdcRdChip (void); +void _Set_D_SsfdcRdStandby (void); +void _Start_D_SsfdcRdHwECC (void); +void _Stop_D_SsfdcRdHwECC (void); +void _Load_D_SsfdcRdHwECC (BYTE); +void _Set_D_SsfdcWrCmd (BYTE); +void _Set_D_SsfdcWrAddr (BYTE); +void _Set_D_SsfdcWrBlock (void); +void _Set_D_SsfdcWrStandby (void); +void _Start_D_SsfdcWrHwECC (void); +void _Load_D_SsfdcWrHwECC (BYTE); +int _Check_D_SsfdcBusy (WORD); +int _Check_D_SsfdcStatus (void); +void _Reset_D_SsfdcErr (void); +void _Read_D_SsfdcBuf (BYTE *); +void _Write_D_SsfdcBuf (BYTE *); +void _Read_D_SsfdcByte (BYTE *); +void _ReadRedt_D_SsfdcBuf (BYTE *); +void _WriteRedt_D_SsfdcBuf (BYTE *); +BYTE _Check_D_DevCode (BYTE); + +void _Set_D_ECCdata (BYTE,BYTE *); +void _Calc_D_ECCdata (BYTE *); + +//void SM_ReadDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD); +//void SM_WriteDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD); +// +struct SSFDCTYPE Ssfdc; +struct ADDRESS Media; +struct CIS_AREA CisArea; + +BYTE EccBuf[6]; +extern PBYTE SMHostAddr; +extern BYTE IsSSFDCCompliance; +extern BYTE IsXDCompliance; +extern DWORD ErrXDCode; + +extern WORD ReadBlock; +extern WORD WriteBlock; + +//KEVENT SM_DMADoneEvent; + +#define EVEN 0 // Even Page for 256byte/page +#define ODD 1 // Odd Page for 256byte/page + + +//SmartMedia Redundant buffer data Controll Subroutine +//----- Check_D_DataBlank() -------------------------------------------- +int Check_D_DataBlank(BYTE *redundant) +{ + char i; + + for(i=0; i<REDTSIZE; i++) + if (*redundant++!=0xFF) + return(ERROR); + + return(SUCCESS); +} + +//----- Check_D_FailBlock() -------------------------------------------- +int Check_D_FailBlock(BYTE *redundant) +{ + redundant+=REDT_BLOCK; + + if (*redundant==0xFF) + return(SUCCESS); + if (!*redundant) + return(ERROR); + if (Bit_D_Count(*redundant)<7) + return(ERROR); + + return(SUCCESS); +} + +//----- Check_D_DataStatus() ------------------------------------------- +int Check_D_DataStatus(BYTE *redundant) +{ + redundant+=REDT_DATA; + + if (*redundant==0xFF) + return(SUCCESS); + if (!*redundant) + { + ErrXDCode = ERR_DataStatus; + return(ERROR); + } + else + ErrXDCode = NO_ERROR; + + if (Bit_D_Count(*redundant)<5) + return(ERROR); + + return(SUCCESS); +} + +//----- Load_D_LogBlockAddr() ------------------------------------------ +int Load_D_LogBlockAddr(BYTE *redundant) +{ + WORD addr1,addr2; + //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; + //ADDRESS_T bb = (ADDRESS_T) &Media; + + addr1=(WORD)*(redundant+REDT_ADDR1H)*0x0100+(WORD)*(redundant+REDT_ADDR1L); + addr2=(WORD)*(redundant+REDT_ADDR2H)*0x0100+(WORD)*(redundant+REDT_ADDR2L); + + if (addr1==addr2) + if ((addr1 &0xF000)==0x1000) + { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } + + if (Bit_D_CountWord((WORD)(addr1^addr2))!=0x01) return(ERROR); + + if ((addr1 &0xF000)==0x1000) + if (!(Bit_D_CountWord(addr1) &0x01)) + { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } + + if ((addr2 &0xF000)==0x1000) + if (!(Bit_D_CountWord(addr2) &0x01)) + { Media.LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); } + + return(ERROR); +} + +//----- Clr_D_RedundantData() ------------------------------------------ +void Clr_D_RedundantData(BYTE *redundant) +{ + char i; + + for(i=0; i<REDTSIZE; i++) + *(redundant+i)=0xFF; +} + +//----- Set_D_LogBlockAddr() ------------------------------------------- +void Set_D_LogBlockAddr(BYTE *redundant) +{ + WORD addr; + + *(redundant+REDT_BLOCK)=0xFF; + *(redundant+REDT_DATA) =0xFF; + addr=Media.LogBlock*2+0x1000; + + if ((Bit_D_CountWord(addr)%2)) + addr++; + + *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=(BYTE)(addr/0x0100); + *(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(BYTE)addr; +} + +//----- Set_D_FailBlock() ---------------------------------------------- +void Set_D_FailBlock(BYTE *redundant) +{ + char i; + + for(i=0; i<REDTSIZE; i++) + *redundant++=(BYTE)((i==REDT_BLOCK)?0xF0:0xFF); +} + +//----- Set_D_DataStaus() ---------------------------------------------- +void Set_D_DataStaus(BYTE *redundant) +{ + redundant+=REDT_DATA; + *redundant=0x00; +} + +//SmartMedia Function Command Subroutine +// 6250 CMD 6 +//----- Ssfdc_D_Reset() ------------------------------------------------ +void Ssfdc_D_Reset(struct us_data *us) +{ + //NTSTATUS ntStatus = STATUS_SUCCESS; + //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + //BYTE buf[0x200]; + + //printk("Ssfdc_D_Reset --- But do nothing !!\n"); + return; +/* RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); + pBulkCbw->dCBWSignature = CBW_SIGNTURE; + pBulkCbw->bCBWLun = CBW_LUN; + //pBulkCbw->dCBWDataTransferLength = 0x200; + pBulkCbw->bmCBWFlags = 0x80; + pBulkCbw->CBWCb[0] = 0xF2; + pBulkCbw->CBWCb[1] = 0x07; + + ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, NULL); + + if (!NT_SUCCESS(ntStatus)) + { + ENE_Print("Ssfdc_D_Reset Fail !!\n"); + //return ntStatus; + }*/ +} + +//----- Ssfdc_D_ReadCisSect() ------------------------------------------ +int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf,BYTE *redundant) +{ + BYTE zone,sector; + WORD block; + //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; + //ADDRESS_T bb = (ADDRESS_T) &Media; + + zone=Media.Zone; block=Media.PhyBlock; sector=Media.Sector; + Media.Zone=0; + Media.PhyBlock=CisArea.PhyBlock; + Media.Sector=CisArea.Sector; + + if (Ssfdc_D_ReadSect(us,buf,redundant)) + { + Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector; + return(ERROR); + } + + Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector; + return(SUCCESS); +} +/* +////----- Ssfdc_D_WriteRedtMode() ---------------------------------------- +//void Ssfdc_D_WriteRedtMode(void) +//{ +// _Set_D_SsfdcRdCmd (RST_CHIP); +// _Check_D_SsfdcBusy (BUSY_RESET); +// _Set_D_SsfdcRdCmd (READ_REDT); +// _Check_D_SsfdcBusy (BUSY_READ); +// _Set_D_SsfdcRdStandby (); +//} +// +////----- Ssfdc_D_ReadID() ----------------------------------------------- +//void Ssfdc_D_ReadID(BYTE *buf, BYTE ReadID) +//{ +// _Set_D_SsfdcRdCmd (ReadID); +// _Set_D_SsfdcRdChip (); +// _Read_D_SsfdcByte (buf++); +// _Read_D_SsfdcByte (buf++); +// _Read_D_SsfdcByte (buf++); +// _Read_D_SsfdcByte (buf); +// _Set_D_SsfdcRdStandby (); +//} +*/ +// 6250 CMD 1 +//----- Ssfdc_D_ReadSect() --------------------------------------------- +int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + WORD addr; + + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Read sect data + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x02; + bcb->CDB[4] = (BYTE)addr; + bcb->CDB[3] = (BYTE)(addr/0x0100); + bcb->CDB[2] = Media.Zone/2; + + result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + // Read redundant + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x10; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + bcb->CDB[4] = (BYTE)addr; + bcb->CDB[3] = (BYTE)(addr/0x0100); + bcb->CDB[2] = Media.Zone/2; + bcb->CDB[8] = 0; + bcb->CDB[9] = 1; + + result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +//----- Ssfdc_D_ReadBlock() --------------------------------------------- +int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + WORD addr; + + //printk("Ssfdc_D_ReadBlock\n"); + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Read sect data + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200*count; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x02; + bcb->CDB[4] = (BYTE)addr; + bcb->CDB[3] = (BYTE)(addr/0x0100); + bcb->CDB[2] = Media.Zone/2; + + result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + // Read redundant + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x10; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + bcb->CDB[4] = (BYTE)addr; + bcb->CDB[3] = (BYTE)(addr/0x0100); + bcb->CDB[2] = Media.Zone/2; + bcb->CDB[8] = 0; + bcb->CDB[9] = 1; + + result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} +/* +////----- Ssfdc_D_ReadSect_DMA() --------------------------------------------- +//int Ssfdc_D_ReadSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +//{ +// WORD SectByteCount, addr; +// DWORD Buffer[4]; +// WORD len; +// +// if (!_Hw_D_ChkCardIn()) +// return(ERROR); +// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; +// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; +// // cycle starting address +// SM_STARTADDR_LSB = 0x00; +// SM_STARTADDR_IISB = (BYTE)addr; +// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100); +// SM_STARTADDR_MSB = Media.Zone/2; +// +// //Sector byte count = 0x200(DMA) +// SectByteCount = 0x20f; +// SM_BYTECNT_LO = (BYTE)SectByteCount; +// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | (BYTE)(SectByteCount/0x0100); +// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) +// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); +// else +// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); +// +// _Hw_D_EccRdReset(); +// _Hw_D_EccRdStart(); +// +// SM_CMD_CTRL1 = (SM_CMD_READ_1); +// SM_CMD_CTRL1 = (SM_CMD_READ_1 | SM_CMD_START_BIT); +// +// SectByteCount = 0x1ff; +// //SM_ReadDataWithDMA(fdoExt, buf, SectByteCount); +// //_ReadRedt_D_SsfdcBuf(redundant); +// len = 0x1000 - ((WORD)(buf) & 0x0FFF); +// if (len < 0x200) +// { +// SM_ReadDataWithDMA(fdoExt, buf, len-1); +// SM_ReadDataWithDMA(fdoExt, buf+len, SectByteCount-len); +// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len); +// } +// else +// SM_ReadDataWithDMA(fdoExt, buf, SectByteCount); +// +// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) +// { +// _ReadRedt_D_SsfdcBuf(redundant); +// } +// else +// { +// Buffer[0] = READ_PORT_DWORD(SM_REG_DATA); +// Buffer[1] = READ_PORT_DWORD(SM_REG_DATA); +// Buffer[2] = READ_PORT_DWORD(SM_REG_DATA); +// Buffer[3] = READ_PORT_DWORD(SM_REG_DATA); +// memcpy(redundant, Buffer, 0x10); +// } +// +// while ( _Hw_D_ChkCardIn() ) +// { +// if((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10)) +// { +// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10); +// break; +// } +// } +// _Hw_D_EccRdStop(); +// _Hw_D_SetRdStandby(); +// _Load_D_SsfdcRdHwECC(EVEN); +// +// _Calc_D_ECCdata(buf); +// _Set_D_SsfdcRdStandby(); +// +// if (!_Hw_D_ChkCardIn()) +// return(ERROR); +// return(SUCCESS); +//} +// +////----- Ssfdc_D_ReadSect_PIO() --------------------------------------------- +//int Ssfdc_D_ReadSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +//{ +// _Set_D_SsfdcRdCmd(READ); +// _Set_D_SsfdcRdAddr(EVEN); +// +// if (_Check_D_SsfdcBusy(BUSY_READ)) +// { _Reset_D_SsfdcErr(); return(ERROR); } +// +// _Start_D_SsfdcRdHwECC(); +// _Read_D_SsfdcBuf(buf); +// _Stop_D_SsfdcRdHwECC(); +// _ReadRedt_D_SsfdcBuf(redundant); +// _Load_D_SsfdcRdHwECC(EVEN); +// +// if (_Check_D_SsfdcBusy(BUSY_READ)) +// { _Reset_D_SsfdcErr(); return(ERROR); } +// +// _Calc_D_ECCdata(buf); +// _Set_D_SsfdcRdStandby(); +// return(SUCCESS); +//} + +// 6250 CMD 3 +//----- Ssfdc_D_WriteSect() -------------------------------------------- +int Ssfdc_D_WriteSect(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +{ + PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + NTSTATUS ntStatus; + WORD addr; + + //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n"); + ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Write sect data + RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); + pBulkCbw->dCBWSignature = CBW_SIGNTURE; + pBulkCbw->bCBWLun = CBW_LUN; + pBulkCbw->dCBWDataTransferLength = 0x200; + pBulkCbw->bmCBWFlags = 0x00; + pBulkCbw->CBWCb[0] = 0xF0; + pBulkCbw->CBWCb[1] = 0x04; + //pBulkCbw->CBWCb[4] = (BYTE)addr; + //pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); + //pBulkCbw->CBWCb[2] = Media.Zone/2; + //pBulkCbw->CBWCb[5] = *(redundant+REDT_ADDR1H); + //pBulkCbw->CBWCb[6] = *(redundant+REDT_ADDR1L); + pBulkCbw->CBWCb[7] = (BYTE)addr; + pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100); + pBulkCbw->CBWCb[5] = Media.Zone/2; + pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H); + pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L); + + ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf); + + if (!NT_SUCCESS(ntStatus)) + return(ERROR); + +// // For Test +// { +// BYTE bf[0x200], rdd[0x10]; +// ULONG i; +// +// RtlZeroMemory(bf, 0x200); +// RtlZeroMemory(rdd, 0x10); +// ntStatus = SM_ReadBlock(fdoExt, bf, rdd); +// for (i=0; i<0x200; i++) +// { +// if (buf[i] != bf[i]) +// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf); +// } +// if (!NT_SUCCESS(ntStatus)) +// ENE_Print("Error\n"); +// } + + return(SUCCESS); +} +*/ +//----- Ssfdc_D_CopyBlock() -------------------------------------------- +int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + //NTSTATUS ntStatus; + WORD ReadAddr, WriteAddr; + + //printk("Ssfdc_D_WriteSect --- ZONE = %x, ReadBlock = %x, WriteBlock = %x\n", Media.Zone, ReadBlock, WriteBlock); + + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+ReadBlock; + ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors; + WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+WriteBlock; + WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors; + + // Write sect data + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200*count; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xF0; + bcb->CDB[1] = 0x08; + bcb->CDB[7] = (BYTE)WriteAddr; + bcb->CDB[6] = (BYTE)(WriteAddr/0x0100); + bcb->CDB[5] = Media.Zone/2; + bcb->CDB[8] = *(redundant+REDT_ADDR1H); + bcb->CDB[9] = *(redundant+REDT_ADDR1L); + bcb->CDB[10] = Media.Sector; + + if (ReadBlock != NO_ASSIGN) + { + bcb->CDB[4] = (BYTE)ReadAddr; + bcb->CDB[3] = (BYTE)(ReadAddr/0x0100); + bcb->CDB[2] = Media.Zone/2; + } + else + bcb->CDB[11] = 1; + + result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} +/* +//----- Ssfdc_D_WriteBlock() -------------------------------------------- +int Ssfdc_D_WriteBlock(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf,BYTE *redundant) +{ + PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + NTSTATUS ntStatus; + WORD addr; + + //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n"); + ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Write sect data + RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); + pBulkCbw->dCBWSignature = CBW_SIGNTURE; + pBulkCbw->bCBWLun = CBW_LUN; + pBulkCbw->dCBWDataTransferLength = 0x200*count; + pBulkCbw->bmCBWFlags = 0x00; + pBulkCbw->CBWCb[0] = 0xF0; + pBulkCbw->CBWCb[1] = 0x04; + pBulkCbw->CBWCb[7] = (BYTE)addr; + pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100); + pBulkCbw->CBWCb[5] = Media.Zone/2; + pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H); + pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L); + + ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf); + + if (!NT_SUCCESS(ntStatus)) + return(ERROR); + +// // For Test +// { +// BYTE bf[0x200], rdd[0x10]; +// ULONG i; +// +// RtlZeroMemory(bf, 0x200); +// RtlZeroMemory(rdd, 0x10); +// ntStatus = SM_ReadBlock(fdoExt, bf, rdd); +// for (i=0; i<0x200; i++) +// { +// if (buf[i] != bf[i]) +// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf); +// } +// if (!NT_SUCCESS(ntStatus)) +// ENE_Print("Error\n"); +// } + + return(SUCCESS); +} +// +////----- Ssfdc_D_WriteSect_DMA() -------------------------------------------- +//int Ssfdc_D_WriteSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +//{ +// WORD SectByteCount, addr; +// DWORD Buffer[4]; +// WORD len; +// +// if (!_Hw_D_ChkCardIn()) +// return(ERROR); +// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; +// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; +// // cycle starting address +// SM_STARTADDR_LSB = 0x00; +// SM_STARTADDR_IISB = (BYTE)addr; +// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100); +// SM_STARTADDR_MSB = Media.Zone/2; +// +// //Sector byte count (DMA) +// SectByteCount = 0x20f; +// SM_BYTECNT_LO = (BYTE)SectByteCount; +// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | 0x20 | (BYTE)(SectByteCount/0x0100); +// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) +// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); +// else +// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); +// +// _Hw_D_EccRdReset(); +// _Hw_D_EccRdStart(); +// +// SM_CMD_CTRL1 = SM_CMD_PAGPRGM_TRUE; +// SM_CMD_CTRL1 = (SM_CMD_PAGPRGM_TRUE | SM_CMD_START_BIT); +// +// SectByteCount = 0x1ff; +// //SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); +// //_WriteRedt_D_SsfdcBuf(redundant); +// len = 0x1000 - ((WORD)(buf) & 0x0FFF); +// if (len < 0x200) +// { +// SM_WriteDataWithDMA(fdoExt, buf, len-1); +// SM_WriteDataWithDMA(fdoExt, buf+len, SectByteCount-len); +// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len); +// } +// else +// SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); +// +// //T1 = (ULONGLONG)buf & 0xFFFFFFFFFFFFF000; +// //T2 = ((ULONGLONG)buf + 0x1FF) & 0xFFFFFFFFFFFFF000; +// //if (T1 != T2) +// // ENE_Print("Ssfdc_D_WriteSect_DMA !!! buf = %p, T1 = %p, T2 = %p\n", buf, T1, T2); +// //if (T2-T1) +// //{ +// // l1 = (WORD)(T2 - (ULONGLONG)buf); +// // SM_WriteDataWithDMA(fdoExt, buf, l1-1); +// // SM_WriteDataWithDMA(fdoExt, (PBYTE)T2, SectByteCount-l1); +// //} +// //else +// // SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); +// +// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) +// { +// _WriteRedt_D_SsfdcBuf(redundant); +// } +// else +// { +// memcpy(Buffer, redundant, 0x10); +// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[0]); +// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[1]); +// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[2]); +// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[3]); +// } +// +// while ( _Hw_D_ChkCardIn() ) +// { +// if ((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10)) +// { +// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10); +// break; +// } +// } +// _Hw_D_EccRdStop(); +// _Hw_D_SetRdStandby(); +// +// _Set_D_SsfdcWrStandby(); +// _Set_D_SsfdcRdStandby(); +// if (!_Hw_D_ChkCardIn()) +// return(ERROR); +// +// return(SUCCESS); +//} +// +////----- Ssfdc_D_WriteSect_PIO() -------------------------------------------- +//int Ssfdc_D_WriteSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +//{ +// _Calc_D_ECCdata(buf); +// _Set_D_SsfdcWrCmd(WRDATA); +// _Set_D_SsfdcWrAddr(EVEN); +// _Start_D_SsfdcWrHwECC(); +// +// _Write_D_SsfdcBuf(buf); +// +// _Load_D_SsfdcWrHwECC(EVEN); +// _Set_D_ECCdata(EVEN,redundant); +// +// _WriteRedt_D_SsfdcBuf(redundant); +// +// _Set_D_SsfdcWrCmd(WRITE); +// +// if (_Check_D_SsfdcBusy(BUSY_PROG)) +// { _Reset_D_SsfdcErr(); return(ERROR); } +// +// _Set_D_SsfdcWrStandby(); +// _Set_D_SsfdcRdStandby(); +// return(SUCCESS); +//} +*/ +//----- Ssfdc_D_WriteSectForCopy() ------------------------------------- +int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + //NTSTATUS ntStatus; + WORD addr; + + //printk("SMILSUB --- Ssfdc_D_WriteSectForCopy\n"); + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Write sect data + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xF0; + bcb->CDB[1] = 0x04; + bcb->CDB[7] = (BYTE)addr; + bcb->CDB[6] = (BYTE)(addr/0x0100); + bcb->CDB[5] = Media.Zone/2; + bcb->CDB[8] = *(redundant+REDT_ADDR1H);; + bcb->CDB[9] = *(redundant+REDT_ADDR1L);; + + result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +// 6250 CMD 5 +//----- Ssfdc_D_EraseBlock() ------------------------------------------- +int Ssfdc_D_EraseBlock(struct us_data *us) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + WORD addr; + + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr=addr*(WORD)Ssfdc.MaxSectors; + + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF2; + bcb->CDB[1] = 0x06; + bcb->CDB[7] = (BYTE)addr; + bcb->CDB[6] = (BYTE)(addr/0x0100); + bcb->CDB[5] = Media.Zone/2; + + result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +// 6250 CMD 2 +//----- Ssfdc_D_ReadRedtData() ----------------------------------------- +int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + WORD addr; + BYTE *buf; + + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x10; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + bcb->CDB[4] = (BYTE)addr; + bcb->CDB[3] = (BYTE)(addr/0x0100); + bcb->CDB[2] = Media.Zone/2; + bcb->CDB[8] = 0; + bcb->CDB[9] = 1; + + buf = kmalloc(0x10, GFP_KERNEL); + //result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0); + result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); + memcpy(redundant, buf, 0x10); + kfree(buf); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +// 6250 CMD 4 +//----- Ssfdc_D_WriteRedtData() ---------------------------------------- +int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + //NTSTATUS ntStatus; + WORD addr; + + result = ENE_LoadBinCode(us, SM_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + { + printk("Load SM RW Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + memset(bcb, 0, sizeof(bcb)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x10; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF2; + bcb->CDB[1] = 0x05; + bcb->CDB[7] = (BYTE)addr; + bcb->CDB[6] = (BYTE)(addr/0x0100); + bcb->CDB[5] = Media.Zone/2; + bcb->CDB[8] = *(redundant+REDT_ADDR1H); + bcb->CDB[9] = *(redundant+REDT_ADDR1L); + + result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +//----- Ssfdc_D_CheckStatus() ------------------------------------------ +int Ssfdc_D_CheckStatus(void) +{ + // Driver 不做 + return(SUCCESS); + //_Set_D_SsfdcRdCmd(RDSTATUS); + // + //if (_Check_D_SsfdcStatus()) + //{ _Set_D_SsfdcRdStandby(); return(ERROR); } + // + //_Set_D_SsfdcRdStandby(); + //return(SUCCESS); +} +/* +////NAND Memory (SmartMedia) Control Subroutine for Read Data +////----- _Set_D_SsfdcRdCmd() -------------------------------------------- +//void _Set_D_SsfdcRdCmd(BYTE cmd) +//{ +// _Hw_D_SetRdCmd(); +// _Hw_D_OutData(cmd); +// _Hw_D_SetRdData(); +//} +// +////----- _Set_D_SsfdcRdAddr() ------------------------------------------- +//void _Set_D_SsfdcRdAddr(BYTE add) +//{ +// WORD addr; +// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; +// ADDRESS_T bb = (ADDRESS_T) &Media; +// +// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; +// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; +// +// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page +// // addr=addr*2+(WORD)add; +// +// _Hw_D_SetRdAddr(); +// _Hw_D_OutData(0x00); +// _Hw_D_OutData((BYTE)addr); +// _Hw_D_OutData((BYTE)(addr/0x0100)); +// +// if ((Ssfdc.Attribute &MADC)==AD4CYC) +// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch +// +// _Hw_D_SetRdData(); +//} +// +////----- _Set_D_SsfdcRdChip() ------------------------------------------- +//void _Set_D_SsfdcRdChip(void) +//{ +// _Hw_D_SetRdAddr(); +// _Hw_D_OutData(0x00); +// _Hw_D_SetRdData(); +//} +// +////----- _Set_D_SsfdcRdStandby() ---------------------------------------- +//void _Set_D_SsfdcRdStandby(void) +//{ +// _Hw_D_SetRdStandby(); +//} +// +////----- _Start_D_SsfdcRdHwECC() ---------------------------------------- +//void _Start_D_SsfdcRdHwECC(void) +//{ +//#ifdef HW_ECC_SUPPORTED +// _Hw_D_EccRdReset(); +// _Hw_D_InData(); +// _Hw_D_EccRdStart(); +//#endif +//} +// +////----- _Stop_D_SsfdcRdHwECC() ----------------------------------------- +//void _Stop_D_SsfdcRdHwECC(void) +//{ +//#ifdef HW_ECC_SUPPORTED +// _Hw_D_EccRdStop(); +//#endif +//} +// +////----- _Load_D_SsfdcRdHwECC() ----------------------------------------- +//void _Load_D_SsfdcRdHwECC(BYTE add) +//{ +//#ifdef HW_ECC_SUPPORTED +// _Hw_D_EccRdRead(); +// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256)) +// { +// EccBuf[0]=_Hw_D_InData(); +// EccBuf[1]=_Hw_D_InData(); +// EccBuf[2]=_Hw_D_InData(); +// } +// +// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256)) +// { +// EccBuf[3]=_Hw_D_InData(); +// EccBuf[4]=_Hw_D_InData(); +// EccBuf[5]=_Hw_D_InData(); +// } +// +// _Hw_D_EccRdStop(); +//#endif +//} +// +////NAND Memory (SmartMedia) Control Subroutine for Write Data +// +////----- _Set_D_SsfdcWrCmd() ----------------------------------------- +//void _Set_D_SsfdcWrCmd(BYTE cmd) +//{ +// _Hw_D_SetWrCmd(); +// _Hw_D_OutData(cmd); +// _Hw_D_SetWrData(); +//} +// +////----- _Set_D_SsfdcWrAddr() ----------------------------------------- +//void _Set_D_SsfdcWrAddr(BYTE add) +//{ +// WORD addr; +// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; +// ADDRESS_T bb = (ADDRESS_T) &Media; +// +// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; +// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; +// +// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page +// // addr=addr*2+(WORD)add; +// +// _Hw_D_SetWrAddr(); +// _Hw_D_OutData(0x00); +// _Hw_D_OutData((BYTE)addr); +// _Hw_D_OutData((BYTE)(addr/0x0100)); +// +// if ((Ssfdc.Attribute &MADC)==AD4CYC) +// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch +// +// _Hw_D_SetWrData(); +//} +// +////----- _Set_D_SsfdcWrBlock() ----------------------------------------- +//void _Set_D_SsfdcWrBlock(void) +//{ +// WORD addr; +// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; +// ADDRESS_T bb = (ADDRESS_T) &Media; +// +// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; +// addr=addr*(WORD)Ssfdc.MaxSectors; +// +// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page +// // addr=addr*2; +// +// _Hw_D_SetWrAddr(); +// _Hw_D_OutData((BYTE)addr); +// _Hw_D_OutData((BYTE)(addr/0x0100)); +// +// if ((Ssfdc.Attribute &MADC)==AD4CYC) +// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch +// +// _Hw_D_SetWrData(); +//} +// +////----- _Set_D_SsfdcWrStandby() ----------------------------------------- +//void _Set_D_SsfdcWrStandby(void) +//{ +// _Hw_D_SetWrStandby(); +//} +// +////----- _Start_D_SsfdcWrHwECC() ----------------------------------------- +//void _Start_D_SsfdcWrHwECC(void) +//{ +//#ifdef HW_ECC_SUPPORTED +// _Hw_D_EccWrReset(); +// _Hw_D_InData(); +// _Hw_D_EccWrStart(); +//#endif +//} +// +////----- _Load_D_SsfdcWrHwECC() ----------------------------------------- +//void _Load_D_SsfdcWrHwECC(BYTE add) +//{ +//#ifdef HW_ECC_SUPPORTED +// _Hw_D_EccWrRead(); +// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256)) +// { +// EccBuf[0]=_Hw_D_InData(); +// EccBuf[1]=_Hw_D_InData(); +// EccBuf[2]=_Hw_D_InData(); +// } +// +// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256)) +// { +// EccBuf[3]=_Hw_D_InData(); +// EccBuf[4]=_Hw_D_InData(); +// EccBuf[5]=_Hw_D_InData(); +// } +// +// _Hw_D_EccWrStop(); +//#endif +//} +// +////NAND Memory (SmartMedia) Control Subroutine +////----- _Check_D_SsfdcBusy() ------------------------------------------- +//int _Check_D_SsfdcBusy(WORD time) +//{ +// WORD count = 0; +// +// do { +// if (!_Hw_D_ChkBusy()) +// return(SUCCESS); +// EDelay(100); +// count++; +// } while (count<=time); +// +// return(ERROR); +//} +// +////----- _Check_D_SsfdcStatus() ----------------------------------------- +//int _Check_D_SsfdcStatus(void) +//{ +// if (_Hw_D_InData() & WR_FAIL) +// return(ERROR); +// +// return(SUCCESS); +//} +// +//// For 712 +////----- _Reset_D_SsfdcErr() ----------------------------------------- +//void _Reset_D_SsfdcErr(void) +//{ +// WORD count = 0; +// +// _Hw_D_SetRdCmd(); +// _Hw_D_OutData(RST_CHIP); +// _Hw_D_SetRdData(); +// +// do { +// if (!_Hw_D_ChkBusy()) +// break; +// EDelay(100); +// count++; +// } while (count<=BUSY_RESET); +// +// _Hw_D_SetRdStandby(); +//} +// +////NAND Memory (SmartMedia) Buffer Data Xfer Subroutine +////----- SM_ReadDataWithDMA() ----------------------------------------- +//void SM_ReadDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount) +//{ +// PHYSICAL_ADDRESS Addr; +// LARGE_INTEGER ptimeout ; +// +// KeClearEvent(&fdoExt->SM_DMADoneEvent); +// +// Addr = MmGetPhysicalAddress(databuf); +// +// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart); +// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0); +// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount); +// +// while ( _Hw_D_ChkCardIn() ) +// { +// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x80)) +// break; +// } +// if (!_Hw_D_ChkCardIn()) return; +// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x01); +// +// ptimeout.QuadPart = 2000 * (-10000); // 2 sec +// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout); +// _Hw_D_SetDMAIntMask(); +//} +// +////----- SM_WriteDataWithDMA() ----------------------------------------- +//void SM_WriteDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount) +//{ +// PHYSICAL_ADDRESS Addr; +// LARGE_INTEGER ptimeout ; +// +// KeClearEvent(&fdoExt->SM_DMADoneEvent); +// +// Addr = MmGetPhysicalAddress(databuf); +// +// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart); +// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 2); +// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount); +// +// while ( _Hw_D_ChkCardIn() ) +// { +// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x40)) +// break; +// } +// if (!_Hw_D_ChkCardIn()) return; +// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x03); +// +// ptimeout.QuadPart = 2000 * (-10000); // 2 sec +// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout); +// _Hw_D_SetDMAIntMask(); +//} +// +////----- _Read_D_SsfdcBuf() ----------------------------------------- +//void _Read_D_SsfdcBuf(BYTE *databuf) +//{ +// int i; +// +// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++) +// for(i=0; i<0x200; i++) +// *databuf++ =_Hw_D_InData(); +//} +// +////----- _Write_D_SsfdcBuf() ----------------------------------------- +//void _Write_D_SsfdcBuf(BYTE *databuf) +//{ +// int i; +// +// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++) +// for(i=0; i<0x200; i++) +// _Hw_D_OutData(*databuf++); +//} +// +////----- _Read_D_SsfdcByte() ----------------------------------------- +//void _Read_D_SsfdcByte(BYTE *databuf) +//{ +// *databuf=(BYTE)_Hw_D_InData(); +//} +// +////----- _ReadRedt_D_SsfdcBuf() ----------------------------------------- +//void _ReadRedt_D_SsfdcBuf(BYTE *redundant) +//{ +// char i; +// +// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++) +// for(i=0; i<0x10; i++) +// redundant[i] =_Hw_D_InData(); +//} +// +////----- _WriteRedt_D_SsfdcBuf() ----------------------------------------- +//void _WriteRedt_D_SsfdcBuf(BYTE *redundant) +//{ +// char i; +// +// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++) +// for(i=0; i<0x10; i++) +// _Hw_D_OutData(*redundant++); +//} +*/ +//SmartMedia ID Code Check & Mode Set Subroutine +//----- Set_D_SsfdcModel() --------------------------------------------- +int Set_D_SsfdcModel(BYTE dcode) +{ + switch (_Check_D_DevCode(dcode)) { + case SSFDC1MB: + Ssfdc.Model = SSFDC1MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 256; + Ssfdc.MaxLogBlocks = 250; + Ssfdc.MaxSectors = 8; + break; + case SSFDC2MB: + Ssfdc.Model = SSFDC2MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 512; + Ssfdc.MaxLogBlocks = 500; + Ssfdc.MaxSectors = 8; + break; + case SSFDC4MB: + Ssfdc.Model = SSFDC4MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 512; + Ssfdc.MaxLogBlocks = 500; + Ssfdc.MaxSectors = 16; + break; + case SSFDC8MB: + Ssfdc.Model = SSFDC8MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 16; + break; + case SSFDC16MB: + Ssfdc.Model = SSFDC16MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC32MB: + Ssfdc.Model = SSFDC32MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; + Ssfdc.MaxZones = 2; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC64MB: + Ssfdc.Model = SSFDC64MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 4; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC128MB: + Ssfdc.Model = SSFDC128MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 8; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC256MB: + Ssfdc.Model = SSFDC256MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 16; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC512MB: + Ssfdc.Model = SSFDC512MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 32; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC1GB: + Ssfdc.Model = SSFDC1GB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 64; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC2GB: + Ssfdc.Model = SSFDC2GB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 128; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + default: + Ssfdc.Model = NOSSFDC; + return(ERROR); + } + + return(SUCCESS); +} + +//----- _Check_D_DevCode() --------------------------------------------- +BYTE _Check_D_DevCode(BYTE dcode) +{ + switch(dcode){ + case 0x6E: + case 0xE8: + case 0xEC: return(SSFDC1MB); // 8Mbit (1M) NAND + case 0x64: + case 0xEA: return(SSFDC2MB); // 16Mbit (2M) NAND + case 0x6B: + case 0xE3: + case 0xE5: return(SSFDC4MB); // 32Mbit (4M) NAND + case 0xE6: return(SSFDC8MB); // 64Mbit (8M) NAND + case 0x73: return(SSFDC16MB); // 128Mbit (16M)NAND + case 0x75: return(SSFDC32MB); // 256Mbit (32M)NAND + case 0x76: return(SSFDC64MB); // 512Mbit (64M)NAND + case 0x79: return(SSFDC128MB); // 1Gbit(128M)NAND + case 0x71: return(SSFDC256MB); + case 0xDC: return(SSFDC512MB); + case 0xD3: return(SSFDC1GB); + case 0xD5: return(SSFDC2GB); + default: return(NOSSFDC); + } +} +/* +////SmartMedia Power Controll Subroutine +////----- Cnt_D_Reset() ---------------------------------------------- +//void Cnt_D_Reset(void) +//{ +// _Hw_D_LedOff(); +// _Hw_D_SetRdStandby(); +// _Hw_D_VccOff(); +//} +// +////----- Cnt_D_PowerOn() ---------------------------------------------- +//int Cnt_D_PowerOn(void) +//{ +// // No support 5V. +// _Hw_D_EnableVcc3VOn(); // Set SM_REG_CTRL_5 Reg. to 3V +// _Hw_D_VccOn(); +// _Hw_D_SetRdStandby(); +// _Wait_D_Timer(TIME_PON); +// +// if (_Hw_D_ChkPower()) +// { +// _Hw_D_EnableOB(); // Set SM_REG_CTRL_5 Reg. to 0x83 +// return(SUCCESS); +// } +// +// _Hw_D_SetVccOff(); +// return(ERROR); +//} +// +////----- Cnt_D_PowerOff() ---------------------------------------------- +//void Cnt_D_PowerOff(void) +//{ +// _Hw_D_SetRdStandby(); +// _Hw_D_SetVccOff(); +// _Hw_D_VccOff(); +//} +// +////----- Cnt_D_LedOn() ---------------------------------------------- +//void Cnt_D_LedOn(void) +//{ +// _Hw_D_LedOn(); +//} +// +////----- Cnt_D_LedOff() ---------------------------------------------- +//void Cnt_D_LedOff(void) +//{ +// _Hw_D_LedOff(); +//} +// +////----- Check_D_CntPower() ---------------------------------------------- +//int Check_D_CntPower(void) +//{ +// if (_Hw_D_ChkPower()) +// return(SUCCESS); // Power On +// +// return(ERROR); // Power Off +//} +// +////----- Check_D_CardExist() ---------------------------------------------- +//int Check_D_CardExist(void) +//{ +// char i,j,k; +// +// if (!_Hw_D_ChkStatus()) // Not Status Change +// if (_Hw_D_ChkCardIn()) +// return(SUCCESS); // Card exist in Slot +// +// for(i=0,j=0,k=0; i<16; i++) { +// if (_Hw_D_ChkCardIn()) // Status Change +// { +// j++; k=0; +// } +// else +// { +// j=0; k++; +// } +// +// if (j>3) +// return(SUCCESS); // Card exist in Slot +// if (k>3) +// return(ERROR); // NO Card exist in Slot +// +// _Wait_D_Timer(TIME_CDCHK); +// } +// +// return(ERROR); +//} +// +////----- Check_D_CardStsChg() ---------------------------------------------- +//int Check_D_CardStsChg(void) +//{ +// if (_Hw_D_ChkStatus()) +// return(ERROR); // Status Change +// +// return(SUCCESS); // Not Status Change +//} +// +////----- Check_D_SsfdcWP() ---------------------------------------------- +//int Check_D_SsfdcWP(void) +//{ // ERROR: WP, SUCCESS: Not WP +// char i; +// +// for(i=0; i<8; i++) { +// if (_Hw_D_ChkWP()) +// return(ERROR); +// _Wait_D_Timer(TIME_WPCHK); +// } +// +// return(SUCCESS); +//} +// +*/ +//SmartMedia ECC Controll Subroutine +//----- Check_D_ReadError() ---------------------------------------------- +int Check_D_ReadError(BYTE *redundant) +{ + // Driver 不做 ECC Check + return(SUCCESS); + if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) + if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) + return(SUCCESS); + + return(ERROR); +} + +//----- Check_D_Correct() ---------------------------------------------- +int Check_D_Correct(BYTE *buf,BYTE *redundant) +{ + // Driver 不做 ECC Check + return(SUCCESS); + if (StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) + if (_Correct_D_SwECC(buf,redundant+0x0D,EccBuf)) + return(ERROR); + + buf+=0x100; + if (StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) + if (_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03)) + return(ERROR); + + return(SUCCESS); +} + +//----- Check_D_CISdata() ---------------------------------------------- +int Check_D_CISdata(BYTE *buf, BYTE *redundant) +{ + BYTE cis[]={0x01,0x03,0xD9,0x01,0xFF,0x18,0x02,0xDF,0x01,0x20}; + + if (!IsSSFDCCompliance && !IsXDCompliance) + return(SUCCESS); // 目前為強制 SUCCESS [Arnold 02-08-23] SSFDC 測試, 不能強制 SUCCESS + + if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) + return(StringCmp((char *)buf,(char *)cis,10)); + + if (!_Correct_D_SwECC(buf,redundant+0x0D,EccBuf)) + return(StringCmp((char *)buf,(char *)cis,10)); + + buf+=0x100; + if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) + return(StringCmp((char *)buf,(char *)cis,10)); + + if (!_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03)) + return(StringCmp((char *)buf,(char *)cis,10)); + + return(ERROR); +} + +//----- Set_D_RightECC() ---------------------------------------------- +void Set_D_RightECC(BYTE *redundant) +{ + // Driver 不做 ECC Check + return; + //StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3); + //StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3); +} +/* +////----- _Calc_D_ECCdata() ---------------------------------------------- +//void _Calc_D_ECCdata(BYTE *buf) +//{ +//#ifdef HW_ECC_SUPPORTED +//#else +// _Calculate_D_SwECC(buf,EccBuf); +// buf+=0x0100; +// _Calculate_D_SwECC(buf,EccBuf+0x03); +//#endif +//} +// +////----- _Set_D_ECCdata() ---------------------------------------------- +//void _Set_D_ECCdata(BYTE add,BYTE *redundant) +//{ +// //if (add==EVEN && (Ssfdc.Attribute &MPS)==PS256) +// // return; +// +// // for 256byte/page +// StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3); +// StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3); +//} +*/ +//Common Subroutine +char Bit_D_Count(BYTE cdata) +{ + WORD bitcount=0; + + while(cdata) { + bitcount+=(WORD)(cdata &0x01); + cdata /=2; + } + + return((char)bitcount); +} + +//----- +char Bit_D_CountWord(WORD cdata) +{ + WORD bitcount=0; + + while(cdata) { + bitcount+=(cdata &0x01); + cdata /=2; + } + + return((char)bitcount); +} + +void StringCopy(char *stringA, char *stringB, int count) +{ + int i; + + for(i=0; i<count; i++) + *stringA++ = *stringB++; +} + +//----- +int StringCmp(char *stringA, char *stringB, int count) +{ + int i; + + for (i=0;i<count;i++) + if (*stringA++ != *stringB++) + return(ERROR); + + return(SUCCESS); +} +/* +//----- SM_ReadBlock() --------------------------------------------- +int SM_ReadBlock(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) +{ + PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; + NTSTATUS ntStatus; + WORD addr; + + ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); + + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + + // Read sect data + RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); + pBulkCbw->dCBWSignature = CBW_SIGNTURE; + pBulkCbw->bCBWLun = CBW_LUN; + pBulkCbw->dCBWDataTransferLength = 0x200; + pBulkCbw->bmCBWFlags = 0x80; + pBulkCbw->CBWCb[0] = 0xF1; + pBulkCbw->CBWCb[1] = 0x02; + pBulkCbw->CBWCb[4] = (BYTE)addr; + pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); + pBulkCbw->CBWCb[2] = Media.Zone/2; + + ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, buf); + + if (!NT_SUCCESS(ntStatus)) + return(ERROR); + + // Read redundant + RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); + pBulkCbw->dCBWSignature = CBW_SIGNTURE; + pBulkCbw->bCBWLun = CBW_LUN; + pBulkCbw->dCBWDataTransferLength = 0x10; + pBulkCbw->bmCBWFlags = 0x80; + pBulkCbw->CBWCb[0] = 0xF1; + pBulkCbw->CBWCb[1] = 0x03; + pBulkCbw->CBWCb[4] = (BYTE)addr; + pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); + pBulkCbw->CBWCb[2] = Media.Zone/2; + pBulkCbw->CBWCb[5] = 0; + pBulkCbw->CBWCb[6] = 1; + + ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, redundant); + + if (!NT_SUCCESS(ntStatus)) + return(ERROR); + + return(SUCCESS); +}*/ |