#include #include "usb.h" #include "scsiglue.h" #include "smcommon.h" #include "smil.h" int Check_D_LogCHS (WORD *,BYTE *,BYTE *); void Initialize_D_Media (void); void PowerOff_D_Media (void); int Check_D_MediaPower (void); int Check_D_MediaExist (void); int Check_D_MediaWP (void); int Check_D_MediaFmt (struct us_data *); int Check_D_MediaFmtForEraseAll (struct us_data *); int Conv_D_MediaAddr (struct us_data *, DWORD); int Inc_D_MediaAddr (struct us_data *); int Check_D_FirstSect (void); int Check_D_LastSect (void); int Media_D_ReadOneSect (struct us_data *, WORD, BYTE *); int Media_D_WriteOneSect (struct us_data *, WORD, BYTE *); int Media_D_CopyBlockHead (struct us_data *); int Media_D_CopyBlockTail (struct us_data *); int Media_D_EraseOneBlock (void); int Media_D_EraseAllBlock (void); int Copy_D_BlockAll (struct us_data *, DWORD); int Copy_D_BlockHead (struct us_data *); int Copy_D_BlockTail (struct us_data *); int Reassign_D_BlockHead (struct us_data *); int Assign_D_WriteBlock (void); int Release_D_ReadBlock (struct us_data *); int Release_D_WriteBlock (struct us_data *); int Release_D_CopySector (struct us_data *); int Copy_D_PhyOneSect (struct us_data *); int Read_D_PhyOneSect (struct us_data *, WORD, BYTE *); int Write_D_PhyOneSect (struct us_data *, WORD, BYTE *); int Erase_D_PhyOneBlock (struct us_data *); int Set_D_PhyFmtValue (struct us_data *); int Search_D_CIS (struct us_data *); int Make_D_LogTable (struct us_data *); void Check_D_BlockIsFull (void); int MarkFail_D_PhyOneBlock (struct us_data *); DWORD ErrXDCode; DWORD ErrCode; //BYTE SectBuf[SECTSIZE]; static BYTE WorkBuf[SECTSIZE]; static BYTE Redundant[REDTSIZE]; static BYTE WorkRedund[REDTSIZE]; //WORD Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; static WORD *Log2Phy[MAX_ZONENUM]; // 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; static BYTE Assign[MAX_ZONENUM][MAX_BLOCKNUM/8]; static WORD AssignStart[MAX_ZONENUM]; WORD ReadBlock; WORD WriteBlock; DWORD MediaChange; static DWORD SectCopyMode; //BIT Control Macro static BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ; #define Set_D_Bit(a,b) (a[(BYTE)((b)/8)]|= BitData[(b)%8]) #define Clr_D_Bit(a,b) (a[(BYTE)((b)/8)]&=~BitData[(b)%8]) #define Chk_D_Bit(a,b) (a[(BYTE)((b)/8)] & BitData[(b)%8]) //extern PBYTE SMHostAddr; BYTE IsSSFDCCompliance; BYTE IsXDCompliance; // ////Power Control & Media Exist Check Function ////----- Init_D_SmartMedia() -------------------------------------------- //int Init_D_SmartMedia(void) //{ // int i; // // EMCR_Print("Init_D_SmartMedia start\n"); // for (i=0; i len) bn = len; else bn = count; //if (Media_D_ReadOneSect(fdoExt, SectBuf)) //if (Media_D_ReadOneSect(fdoExt, count, buf)) if (Media_D_ReadOneSect(us, bn, buf)) { ErrCode = ERR_EccReadErr; return(ErrCode); } Media.Sector += bn; count -= bn; if (count<=0) break; buf += bn * SECTSIZE; if (Inc_D_MediaAddr(us)) return(ErrCode); } return(NO_ERROR); } // here //----- Media_D_CopySector() ------------------------------------------ int Media_D_CopySector(struct us_data *us, DWORD start,WORD count,BYTE *buf) { //DWORD mode; //int i; WORD len, bn; //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; //ADDRESS_T bb = (ADDRESS_T) &Media; /* pr_info("Media_D_CopySector !!!\n"); */ if (Conv_D_MediaAddr(us, start)) return(ErrCode); while(1) { if (Assign_D_WriteBlock()) return(ERROR); len = Ssfdc.MaxSectors - Media.Sector; if (count > len) bn = len; else bn = count; //if (Ssfdc_D_CopyBlock(fdoExt,count,buf,Redundant)) if (Ssfdc_D_CopyBlock(us,bn,buf,Redundant)) { ErrCode = ERR_WriteFault; return(ErrCode); } Media.Sector = 0x1F; //if (Release_D_ReadBlock(fdoExt)) if (Release_D_CopySector(us)) { if (ErrCode==ERR_HwError) { ErrCode = ERR_WriteFault; return(ErrCode); } } count -= bn; if (count<=0) break; buf += bn * SECTSIZE; if (Inc_D_MediaAddr(us)) return(ErrCode); } return(NO_ERROR); } //----- Release_D_CopySector() ------------------------------------------ int Release_D_CopySector(struct us_data *us) { //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; //ADDRESS_T bb = (ADDRESS_T) &Media; 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); } /* //----- Media_D_WriteSector() ------------------------------------------ int Media_D_WriteSector(PFDO_DEVICE_EXTENSION fdoExt, DWORD start,WORD count,BYTE *buf) { int i; WORD len, bn; SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; ADDRESS_T bb = (ADDRESS_T) &Media; //if (Check_D_MediaPower()) // return(ErrCode); // //if (Check_D_MediaFmt(fdoExt)) // return(ErrCode); // //if (Check_D_MediaWP()) // return(ErrCode); if (Conv_D_MediaAddr(fdoExt, start)) return(ErrCode); //ENE_Print("Media_D_WriteSector --- Sector = %x\n", Media.Sector); if (Check_D_FirstSect()) { if (Media_D_CopyBlockHead(fdoExt)) { ErrCode = ERR_WriteFault; return(ErrCode); } } while(1) { if (!Check_D_FirstSect()) { if (Assign_D_WriteBlock()) return(ErrCode); } len = Ssfdc.MaxSectors - Media.Sector; if (count > len) bn = len; else bn = count; //for(i=0;iDrive_IsSWLED) // { // if (enable) // Led_D_TernOn(); // else // Led_D_TernOff(); // } //} // ////----- Led_D_TernOn() ------------------------------------------------- //void Led_D_TernOn(void) //{ // if (Check_D_CardStsChg()) // MediaChange=ERROR; // // Cnt_D_LedOn(); //} // ////----- Led_D_TernOff() ------------------------------------------------ //void Led_D_TernOff(void) //{ // if (Check_D_CardStsChg()) // MediaChange=ERROR; // // Cnt_D_LedOff(); //} // ////SmartMedia Logical Format Subroutine ////----- Check_D_LogCHS() ----------------------------------------------- //int Check_D_LogCHS(WORD *c,BYTE *h,BYTE *s) //{ // switch(Ssfdc.Model) { // case SSFDC1MB: *c=125; *h= 4; *s= 4; break; // case SSFDC2MB: *c=125; *h= 4; *s= 8; break; // case SSFDC4MB: *c=250; *h= 4; *s= 8; break; // case SSFDC8MB: *c=250; *h= 4; *s=16; break; // case SSFDC16MB: *c=500; *h= 4; *s=16; break; // case SSFDC32MB: *c=500; *h= 8; *s=16; break; // case SSFDC64MB: *c=500; *h= 8; *s=32; break; // case SSFDC128MB: *c=500; *h=16; *s=32; break; // default: *c= 0; *h= 0; *s= 0; ErrCode = ERR_NoSmartMedia; return(ERROR); // } // // return(SMSUCCESS); //} // ////Power Control & Media Exist Check Subroutine ////----- Initialize_D_Media() ------------------------------------------- //void Initialize_D_Media(void) //{ // ErrCode = NO_ERROR; // MediaChange = ERROR; // SectCopyMode = COMPLETED; // Cnt_D_Reset(); //} // ////----- PowerOff_D_Media() --------------------------------------------- //void PowerOff_D_Media(void) //{ // Cnt_D_PowerOff(); //} // ////----- Check_D_MediaPower() ------------------------------------------- //int Check_D_MediaPower(void) //{ // //usleep(56*1024); // if (Check_D_CardStsChg()) // MediaChange = ERROR; // //usleep(56*1024); // if ((!Check_D_CntPower())&&(!MediaChange)) // ¦³ power & Media ¨S³Q change, «h return success // return(SMSUCCESS); // //usleep(56*1024); // // if (Check_D_CardExist()) // Check if card is not exist, return err // { // ErrCode = ERR_NoSmartMedia; // MediaChange = ERROR; // return(ERROR); // } // //usleep(56*1024); // if (Cnt_D_PowerOn()) // { // ErrCode = ERR_NoSmartMedia; // MediaChange = ERROR; // return(ERROR); // } // //usleep(56*1024); // Ssfdc_D_Reset(fdoExt); // //usleep(56*1024); // return(SMSUCCESS); //} // ////-----Check_D_MediaExist() -------------------------------------------- //int Check_D_MediaExist(void) //{ // if (Check_D_CardStsChg()) // MediaChange = ERROR; // // if (!Check_D_CardExist()) // { // if (!MediaChange) // return(SMSUCCESS); // // ErrCode = ERR_ChangedMedia; // return(ERROR); // } // // ErrCode = ERR_NoSmartMedia; // // return(ERROR); //} // ////----- Check_D_MediaWP() ---------------------------------------------- //int Check_D_MediaWP(void) //{ // if (Ssfdc.Attribute &MWP) // { // ErrCode = ERR_WrtProtect; // return(ERROR); // } // // return(SMSUCCESS); //} */ //SmartMedia Physical Format Test Subroutine //----- Check_D_MediaFmt() --------------------------------------------- int Check_D_MediaFmt(struct us_data *us) { pr_info("Check_D_MediaFmt\n"); //ULONG i,j, result=FALSE, zone,block; //usleep(56*1024); if (!MediaChange) return(SMSUCCESS); MediaChange = ERROR; SectCopyMode = COMPLETED; //usleep(56*1024); if (Set_D_PhyFmtValue(us)) { ErrCode = ERR_UnknownMedia; return(ERROR); } //usleep(56*1024); if (Search_D_CIS(us)) { ErrCode = ERR_IllegalFmt; return(ERROR); } MediaChange = SMSUCCESS; return(SMSUCCESS); } /* ////----- Check_D_BlockIsFull() ---------------------------------- //void Check_D_BlockIsFull() //{ // ULONG i, block; // // if (IsXDCompliance || IsSSFDCCompliance) // { // // If the blocks are full then return write-protect. // block = Ssfdc.MaxBlocks/8; // for (Media.Zone=0; Media.ZoneChildDeviceObject) return(ERROR); // //pdoExt = fdoExt->ChildDeviceObject->DeviceExtension; // // Ssfdc_D_ReadID(idcode, READ_ID_1); // //if (Set_D_SsfdcModel(idcode[1])) if (Set_D_SsfdcModel(us->SM_DeviceID)) return(ERROR); // //Use Multi-function pin to differentiate SM and xD. // UserDefData_1 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) & 0x80; // if (UserDefData_1) // { // if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x80 ) fdoExt->DiskType = DISKTYPE_XD; // if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x40 ) fdoExt->DiskType = DISKTYPE_SM; // // if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) ) // { // Ssfdc_D_ReadID(idcode, READ_ID_3); // if (idcode[2] != 0xB5) // return(ERROR); // } // } // // //Use GPIO to differentiate SM and xD. // UserDefData_2 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) >> 8; // if ( UserDefData_2 ) // { // Data = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, 0, 0xAC); // // mask = 1 << (UserDefData_2-1); // // 1 : xD , 0 : SM // if ( Data & mask) // fdoExt->DiskType = DISKTYPE_XD; // else // fdoExt->DiskType = DISKTYPE_SM; // // if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) ) // { // Ssfdc_D_ReadID(idcode, READ_ID_3); // if (idcode[2] != 0xB5) // return(ERROR); // } // } // // if ( !(UserDefData_1 | UserDefData_2) ) // { // // Use UserDefine Register to differentiate SM and xD. // Ssfdc_D_ReadID(idcode, READ_ID_3); // // if (idcode[2] == 0xB5) // fdoExt->DiskType = DISKTYPE_XD; // else // { // if (!IsXDCompliance) // fdoExt->DiskType = DISKTYPE_SM; // else // return(ERROR); // } // // if (fdoExt->UserDef_DiskType == 0x04) fdoExt->DiskType = DISKTYPE_XD; // if (fdoExt->UserDef_DiskType == 0x08) fdoExt->DiskType = DISKTYPE_SM; // } // // if (!fdoExt->UserDef_DisableWP) // { // if (fdoExt->DiskType == DISKTYPE_SM) // { // if (Check_D_SsfdcWP()) // Ssfdc.Attribute|=WP; // } // } return(SMSUCCESS); } //----- Search_D_CIS() ------------------------------------------------- int Search_D_CIS(struct us_data *us) { //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; //ADDRESS_T bb = (ADDRESS_T) &Media; Media.Zone=0; Media.Sector=0; for (Media.PhyBlock=0; Media.PhyBlock<(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1); Media.PhyBlock++) { if (Ssfdc_D_ReadRedtData(us, Redundant)) { Ssfdc_D_Reset(us); return(ERROR); } if (!Check_D_FailBlock(Redundant)) break; } if (Media.PhyBlock==(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1)) { Ssfdc_D_Reset(us); return(ERROR); } while (Media.Sector=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; Media.Sector = (BYTE)(Ssfdc.MaxSectors-1); if (Ssfdc_D_ReadRedtData(us, Redundant)) { Ssfdc_D_Reset(us); return(ERROR); } if (!Load_D_LogBlockAddr(Redundant)) { if (Media.LogBlock==logblock) { Media.PhyBlock=Log2Phy[Media.Zone][logblock]; if (Ssfdc_D_ReadRedtData(us, Redundant)) { Ssfdc_D_Reset(us); return(ERROR); } Media.PhyBlock=phyblock; if (!Load_D_LogBlockAddr(Redundant)) { if (Media.LogBlock!=logblock) { Media.PhyBlock=Log2Phy[Media.Zone][logblock]; Log2Phy[Media.Zone][logblock]=phyblock; } } else { Media.PhyBlock=Log2Phy[Media.Zone][logblock]; Log2Phy[Media.Zone][logblock]=phyblock; } } } Media.Sector=0; // here Not yet //#ifdef L2P_ERR_ERASE // if (!(Ssfdc.Attribute &MWP)) // { // Ssfdc_D_Reset(fdoExt); // if (Ssfdc_D_EraseBlock(fdoExt)) // return(ERROR); // // if (Ssfdc_D_CheckStatus()) // { // if (MarkFail_D_PhyOneBlock()) // return(ERROR); // } // else // Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock); // } //#else // Ssfdc.Attribute|=MWP; //#endif Media.PhyBlock=phyblock; } // End for (Media.PhyBlockErrCode = STATUS_CMD_FAIL; // // Init_D_SmartMedia(); // // if (Check_D_MediaPower()) // return (ErrCode==ERR_NoSmartMedia) ? STATUS_CMD_NO_MEDIA : STATUS_CMD_FAIL; // // if (Set_D_PhyFmtValue(fdoExt)) // return STATUS_CMD_FAIL; // // //usleep(56*1024); // if (Search_D_CIS(fdoExt)) // return STATUS_CMD_FAIL; // // if (Check_D_MediaWP()) // return STATUS_CMD_MEDIA_WP; // // pParamOut->PageSize = Ssfdc.MaxSectors; // pParamOut->BlockSize = Ssfdc.MaxBlocks; // pParamOut->ZoneSize = Ssfdc.MaxZones; // // return STATUS_CMD_SUCCESS; //}*/