⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tffs2lnx.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 4 页
字号:
                flashFormatInput.fpPtr->binaryPartitionInfo = bin_fp;#  else                return -EINVAL;#  endif            }            /* set to NULL not mapped pointers */            flashFormatInput.fpPtr->progressCallback  = NULL;            flashFormatInput.fpPtr->embeddedCIS       = NULL;            flashFormatInput.fpPtr->embeddedCISlength = 0;            ioreq.irHandle = (bdtlVolume & 0x0f);            flIOctl (&ioreq);            if( copy_to_user(user_outputStatusRecord, &outputStatusRecord, sizeof(outputStatusRecord)))                return -EFAULT;            return 0;	}# endif /* FL_FORMAT_VOLUME */	case FL_IOCTL_ERASE_BD:# ifdef FL_FORMAT_VOLUME		PrintkDebug("TffsIoctl:FL_IOCTL_ERASE_BD");		USR2KRN11(bdtlVolume,flEraseBDInput,flOutputStatusRecord,pSoc);# else /* FL_FORMAT_VOLUME */		return -EINVAL;# endif /* FL_FORMAT_VOLUME */	case FL_IOCTL_FLASH_UNFORMAT:# ifdef FL_FORMAT_VOLUME		USR2KRN11(bdtlVolume,flFlashUnformatInput,flOutputStatusRecord,pSoc);# else /* FL_FORMAT_VOLUME */		return -EINVAL;# endif /* FL_FORMAT_VOLUME */#if defined(TFFS_USE_G4) && defined(HW_OTP)	case FL_IOCTL_MCOTP:	{		flMCOtpInput mcotpInput;		flOutputStatusRecord outputStatusRecord;		void*outputStatusRecordSave,*bufferSave=NULL,*mcotpInputSave;		if(!access_ok(VERIFY_READ|VERIFY_WRITE,ioctlRecord.inputRecord,sizeof(flMCOtpInput)))			return -EFAULT;		if(copy_from_user(&mcotpInput,ioctlRecord.inputRecord,sizeof(flMCOtpInput)))			return -EFAULT;		if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord)))			return -EFAULT;		outputStatusRecordSave=ioctlRecord.outputRecord;		mcotpInputSave=ioctlRecord.inputRecord;		ioctlRecord.inputRecord=&mcotpInput;		ioctlRecord.outputRecord=&outputStatusRecord;		if(mcotpInput.length!=0)		{			bufferSave=mcotpInput.buffer;			mcotpInput.buffer=VMalloc(mcotpInput.length);			if(mcotpInput.buffer==NULL)				return -ENOMEM;			if(!access_ok(VERIFY_READ|VERIFY_WRITE,mcotpInput.buffer,mcotpInput.length))				return -EFAULT;			if(copy_from_user(mcotpInput.buffer,bufferSave,sizeof(mcotpInput.length)))				return -EFAULT;		}		ioreq.irHandle = bdtlVolume&0x0f;		flIOctl (&ioreq);		if(mcotpInput.length!=0)		{			if(copy_to_user(bufferSave,mcotpInput.buffer,sizeof(mcotpInput.length)))				return -EFAULT;			vfree(mcotpInput.buffer);			mcotpInput.buffer=bufferSave;		}		if(copy_to_user(mcotpInputSave,&mcotpInput,sizeof(flMCOtpInput)))			return -EFAULT;		if(copy_to_user(outputStatusRecordSave,&outputStatusRecord,sizeof(flMCOtpInput)))			return -EFAULT;	}#endif /* defined(TFFS_USE_G4) && defined(HW_OTP) */	case FL_IOCTL_LNX:		{			flInputLnxRecord  inRec;			flOutputLnxRecord outRec;			if(!access_ok(VERIFY_READ,ioctlRecord.inputRecord,sizeof(flInputLnxRecord)))				return -EFAULT;			if(copy_from_user(&inRec,ioctlRecord.inputRecord,sizeof(flInputLnxRecord)))				return -EFAULT;			if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputLnxRecord)))				return -EFAULT;			switch(inRec.command)			{			case 0:	/* set TrueFFS handle for future IOCTLs */			        {				    handle_for_ioctls = inRec.data;				    outRec.status = flOK;				    if(copy_to_user(ioctlRecord.outputRecord, &outRec, sizeof(flOutputLnxRecord)))					return -EFAULT;				    return 0;				}#if defined(TFFS_DEBUG_DRIVER) && !defined(TFFS_RO)			case 3: /* print no of used sectors on device */				{					ioreq.irHandle=pDevice->bHandle;					ioreq.irLength=0;					outRec.status =flDefragmentVolume (&ioreq);					outRec.data=ioreq.irLength;					if(copy_to_user(ioctlRecord.outputRecord,&outRec,sizeof(flOutputLnxRecord)))						return -EFAULT;					return 0;				}#endif /* TFFS_DEBUG_DRIVER */                        case 5:  /* ATA pass-through command */			    return ata_passthrough (pDevice, &ioctlRecord, &inRec);			}		}	default:		PrintkDebug("TffsIoctl: no Tffs ioctl");		return -EINVAL;	}	/* do not check error code - it sended by outRec->status */	flIOctl (&ioreq);	return 0;#else /* FL_IOCTL_INTERFACE */	return 1;#endif /* FL_IOCTL_INTERFACE */}/******************************************************************************* *                                                                             * *                         T f f s E n a b l e I R Q                           * *                                                                             * *  This routine enables DiskOnChip interrupt generation upon completion of    * *  flash erase/write operation. Works with all types of DiskOnChip devices.   * *                                                                             * *  Parameters:                                                                * *                                                                             * *         psoc     socket pointer                                             * *                                                                             * *  Returns:                                                                   * *                                                                             * *         always zero (success)                                               * *                                                                             * *******************************************************************************/int TffsEnableIRQ (SocketInfo * psoc){    IOreq ioreq;    ioreq.irHandle = psoc->bHandle;    ioreq.irFlags  = FL_IRQ_RB_TYPE;    ioreq.irLength = (FL_INT_RB_ENABLED | /* FL_IRQ_EDGE_TYPE */ FL_IRQ_LEVEL_TYPE);    flHwConfig (&ioreq);    return 0;}/******************************************************************************* *                                                                             * *                           T f f s S e t P I O                               * *                                                                             * *  If requested, this routine sets multi-sector polled I/O mode in DiskOnChip * *  H3 devices. It has no effect on H1/G4/G3 DiskOnChip devices.               * *                                                                             * *  Parameters:                                                                * *                                                                             * *         psoc     socket pointer                                             * *                                                                             * *  Returns:                                                                   * *                                                                             * *         zero if success otherwise respective error code                     * *                                                                             * *******************************************************************************/int TffsSetPIO (SocketInfo * psoc){    IOreq       ioreq;    DOCH_Error  rc = DOCH_OK;    if (tffs_pio > 0) /* multi-sector polled I/O mode requested */    {        /* If we are going to use intermediate DMA buffer (which is one MMU page         * in size), we must make sure that multi-sector PIO won't overrun it.         */        if( (tffs_dma_mode > 0)  &&  !(tffs_dma_mode & 0x4)  &&                              ((tffs_pio * FL_SECTOR_SIZE) > PAGE_SIZE) )        {             PrintkError ("Multi-sector polled I/O overruns DMA buffer, disabled");            tffs_pio = 0;            return -1;        }        /* Set multi-sector polled I/O mode to transfer up to         * 'tffs_pio_mode' (but no more then 256) sectors at once.         */        ioreq.irHandle = psoc->bHandle;        ioreq.irCount  = DOCH_DATA_XFER_MODE_MULT;        ioreq.irLength = ((tffs_pio <= 255) ? tffs_pio : 0);        if ((rc = flDOCHSetDataTransferMode(&ioreq)) != DOCH_OK)        {            PrintkError ("Can't set multi-sector polled I/O, error %d", rc);            tffs_pio = 0;            return -1;        }    }    else               /* single-sector polled I/O mode requested */    {      /* DiskOnChip H3 devices default to single-sector polled I/O mode       * upon reset, so we don't have to do anything here.       */    }    return (int)rc;}#if 0 /* andrayk June 23 2006: added for H3 burst *//*  * Check various burst-related parameters for sanity.  * This routine is specific to DiskOnChip H3 devices. */staticint set_burst (SocketInfo * psoc){    /* check DiskOnChip H3 burst settings for sanity */    if (tffs_burst == TRUE)    {        switch (tffs_burst_length)        {            case  4: tffs_burst_length = 0x0000; break; /* DOCH_BURST_LEN_4_CYC  */            case  8: tffs_burst_length = 0x0800; break; /* DOCH_BURST_LEN_8_CYC  */            case 16: tffs_burst_length = 0x1000; break; /* DOCH_BURST_LEN_16_CYC */            case 32: tffs_burst_length = 0x1800; break; /* DOCH_BURST_LEN_32_CYC */            default:                PrintkError ("Bad burst length (%d), burst disabled", tffs_burst_length);                tffs_burst = 0;                return -1;        }        switch (tffs_burst_hold)        {            case  1: tffs_burst_hold = 0x0000; break; /* DOCH_BURST_HOLD_1_CLK  */            case  2: tffs_burst_hold = 0x2000; break; /* DOCH_BURST_HOLD_2_CYC  */            default:                PrintkError ("Bad burst hold (%d), burst disabled", tffs_burst_hold);                tffs_burst = 0;                return -1;        }    }    return 0;}#endif /* 1 *//******************************************************************************* *                                                                             * *                           T f f s S u s p e n d                             * *                                                                             * *  Power down DiskOnChip socket.                                              * *                                                                             * *  Parameters:                                                                * *                                                                             * *         psoc     socket pointer                                             * *                                                                             * *  Returns:                                                                   * *                                                                             * *         always zero (success)                                               * *                                                                             * *******************************************************************************/int TffsSuspend (SocketInfo * psoc){    IOreq ioreq;    ioreq.irHandle = psoc->bHandle;    ioreq.irFlags  = DEEP_POWER_DOWN;    flDeepPowerDownMode (&ioreq);    return 0;}/******************************************************************************* *                                                                             * *                           T f f s R e s u m e                               * *                                                                             * *  Power up (previously powered down) DiskOnChip socket.                      * *                                                                             * *  Parameters:                                                                * *                                                                             * *         psoc     socket pointer                                             * *                                                                             * *  Returns:                                                                   * *                                                                             * *         always zero (success)                                               * *                                                                             * *******************************************************************************/int TffsResume (SocketInfo * psoc){    IOreq ioreq;    ioreq.irHandle = psoc->bHandle;    ioreq.irFlags  = EXIT_DEEP_POWER_DOWN;    flDeepPowerDownMode (&ioreq);    return 0;}staticvoid set_disk_geometry (DeviceInfo *pDevice){	/* Limitations for old BIOSes:		no. of heads : 8 bits - max 255		no. of cylinders: 10 bits - max 1023		no. of sectors per track: 6 bits - max 63 */	unsigned long dwSectors,dwRest;	unsigned long dwMinSec,dwMaxSec,dwSec;	unsigned long dwMinCyl,dwCyl;	if(pDevice->dwSize==0)	{		pDevice->wCyl=1;		pDevice->bHead=1;		pDevice->bSect=1;		return;	}	dwRest=dwSectors = (pDevice->dwSize >> pDevice->wTffsHWSectorSizeShift); /* use shared sector size instead kernel HW sector size - the same geometry for any harsect */	dwMinSec=dwSectors/(1023*255);	if(dwSectors!=dwMinSec*1023*255)		dwMinSec++;	dwMaxSec=63>>pDevice->wTffsHWSectorSizeShift;	dwMinCyl=dwSectors/(dwMaxSec*255);	if(dwSectors!=dwMinCyl*dwMaxSec*255)		dwMinCyl++;	for(dwSec=dwMaxSec;dwSec>=dwMinSec;dwSec--)	{		unsigned long dwMinHead,dwMaxHead,dwHead;		dwMinHead=dwSectors/(dwSec*1023);		if(dwSectors!=dwMinHead*dwSec*1023)			dwMinHead++;		/* if(dwMinHead%16) dwMinHead=((dwMinHead>>4)+1)<<4; */		dwMaxHead=dwSectors/(dwSec*dwMinCyl);		if(dwMaxHead>255)			dwMaxHead=255;		for(dwHead=dwMinHead;dwHead<=dwMaxHead;dwHead++ /*=16*/ )		{			unsigned long tmp;			dwCyl=dwSectors/(dwSec*dwHead);			tmp=dwSectors-dwCyl*dwSec*dwHead;			if(dwRest>tmp)			{				pDevice->wCyl=dwCyl;				pDevice->bHead=dwHead;				pDevice->bSect=dwSec<<pDevice->wTffsHWSectorSizeShift;				if(tmp==0)				{					PrintkDebug("C/H/S (0) %u %u %u",pDevice->wCyl,pDevice->bHead,pDevice->bSect);					return;				}				dwRest=tmp;			}		}	}	PrintkError("C/H/S %u %u %u",pDevice->wCyl,pDevice->bHead,pDevice->bSect);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -