📄 doch_api.c
字号:
/****************************************************************************** * * * Project: DOC Driver for Linux 2.4 Block device driver for mDOC H3 family * * of devices under Linux kernel 2.4. * * * * Version: 1.0 * * Email questions to: oemsupport@sandisk.com * * Copyright (C) SanDisk IL Ltd. 1995 - 2007 * * SanDisk IL Ltd., 7 Atir Yeda Street, Kfar Saba 44425, Israel * * * ****************************************************************************** * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation; either version 2 of the License, or any later version.* * This program is distributed in the hope that it will be useful, but WITHOUT* * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details, which is set forth in the readme.txt file. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., 51 * * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * * * This License does not grant you any right to use the trademarks, service * * marks or logos of SanDisk IL Ltd. or SanDisk Corporation. * * Subject to the foregoing, SanDisk IL Ltd., for itself and on behalf of its * * licensors, hereby reserves all intellectual property rights in the program,* * except for the rights expressly granted in this License. * * * ******************************************************************************//*
* $Log: V:/PVCSDB/DiskOnChip/archives/Test for 7.x/src/H3/doch_api.c-arc $
*
* Rev 1.64 Dec 03 2006 15:38:56 Yaniv.Iarovici
* Fixed compilation warning
*
* Rev 1.63 Dec 03 2006 13:31:24 Yaniv.Iarovici
* Encapsulate auto wipe-sector operation for Dev1 under '#ifndef DOCH_NO_AUTO_WIPE_SECTORS_DEV1'
*
* Rev 1.62 Nov 30 2006 10:23:36 Yaniv.Iarovici
* 1. Fixed compilation warnings.
* 2. Added SDK level secure-wipe power-failure immunity.
* 3. Fixed flDOCHAtaReset in case of cascaded configuration.
*
* Rev 1.61 Nov 21 2006 14:26:14 Yaniv.Iarovici
* 1. Fixed IRQ handling in case of cascaded configuration.
* 2. Fixed OTW setting of a partition residing on Dev1 (cascaded configuration).
*
* Rev 1.60 Nov 12 2006 09:46:42 Yaniv.Iarovici
* Modify parameter list of doch_reset().
*
* Rev 1.59 Oct 31 2006 12:23:22 yaniv.iarovici
* Search for the current window after resetting Dev0 in flDOCHAtaReset().
*
* Rev 1.58 Oct 30 2006 15:50:24 yaniv.iarovici
* Add call to DOCHAddPartition() after creating spanned partition
* for updating actual number of partitions.
*
* Rev 1.57 Oct 25 2006 09:10:26 Yaniv.Iarovici
* Fix for cascaded scenario in which last partition on dev0 is NOT spanned, and is RW protected.
*
* Rev 1.56 Oct 05 2006 11:00:28 yaniv.iarovici
* 1. Retrieve MAX DRQ supported by the device.
* 2. Check that requested DRQ size is supported by the device.
* 3. Remove verify write option from DOCHWriteIPLSingleFloor().
*
* Rev 1.55 Sep 14 2006 09:56:30 yaniv.iarovici
* DOCHSetCustomParameterSingleFloor() to return DOCH_ProtectionFault in case of protection violation.
*
* Rev 1.54 Sep 13 2006 10:30:46 yaniv.iarovici
* Fix compilation warnings
*
* Rev 1.53 Sep 11 2006 13:45:14 yaniv.iarovici
* Legal header added
*
* Rev 1.52 Sep 10 2006 10:03:14 Yaniv.Iarovici
* 1. Bug Fix: Calculation of total number of partitions in DOCHIdentifyDiskOnChipDevice() in cascaded configuration, when last partition on Dev0 fills the first floor entirely.
*
* 2. Bug Fix: Support creation of Read protected partition which is spanned on both devices in cascaded configuration.
*
* 3. Bug Fix: Setting configuration register values to Dev1 in cascaded configuration (DOCHConfigHW()).
*
* Rev 1.51 Sep 03 2006 14:44:22 Yaniv.Iarovici
* 1. Fixed logic of setting bLastDev0PartSpanned in case last partition on Dev0 fills entire Dev0. (Cascaded configuration)
* 2. Preserve current OTW setting when changing protection type. (Can only be set by AddPartition)
*
* Rev 1.50 Aug 24 2006 11:40:46 Yaniv.Iarovici
* API Change to following protection related routines:
* - DOCHAccessPartWithPwdSingleFloor
* - DOCHDisablePartAccessSingleFloor
* - DOCHSendHostPublicKey
* - DOCHReceiveDochPublicKey
* - DOCHVerifyHostKey
* (The change differs DOCH_ACCESS_ALL_PARTITIONS flag from partition number field
* in ioreq)
*
* Rev 1.49 Aug 22 2006 13:23:36 Yaniv.Iarovici
* 1) Bug fix: 'pdev->bAtaDevNum' was not recovered correctly to 'origDevNum' (multiple places)
* 2) In DOCHWriteIPLSingleFloor(), set rc = DOCH_OK at decleration, to prevent compilation warning
* 3) Bug fix: flDOCHAddPartition - Cascaded configuration
*
* Rev 1.48 Aug 16 2006 08:44:18 Yaniv.Iarovici
* 1) Fix bdCallDOCH() Description
* 2) Check if ETFFS was identified on the device - if not, return 'DOCH_FeatureNotSupported'
* 2) Free MUTEX before returning error when (gDochAccessNanosec == 0) is detected
* 3) Check that Multi-sector transfer mode does not exceed max allowed in DOCHSetDataTransferModeSingleFloor()
* 4) Set pdev->device[devNum].ETFFS_Identified = TRUE adfter a SUCCESSFULL completion of DOCHIdentifyDiskOnChipDeviceSingleFloor()
* 5) Remove unneccesary code from DOCHGetResetStatus()
* 6) Reset pdev->bAtaDevNum to original value upon failure (various places in the code)
* 7) Check that pdev is valid in the various routines
* 8) Change description of DOCHGetPowerMode() and DOCHSetPowerMode() to fit SW Spec 0.84
*
* Rev 1.47 Aug 09 2006 17:26:50 Polina.Marimont
* initial for DOC Driver 1.0
*
*/
#include "flchkdef.h"
#include "flsystyp.h"
#include "flcommon.h"
#include "flsysfun.h"
#include "doch_func.h"
#include "doch_ata.h"
#include "flstdcmp.h"
#include "hib.h"
#include "part_inf.h"
#include "dochtl.h"
#ifdef FL_MIGRATION_VERSION
#include "docsys.h"
#endif /* FL_MIGRATION_VERSION */
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************/
/*
* Global variables
*/
/******************************************************************************/
/* NOTE: Global variables with "boolean like" behavior are set to a unique pattern (DOCH_GLOBAL_BOOL_PATTERN)
to indicate them as "TRUE" */
FLDword gDochVerifyWrite[DOCH_MAX_SOCKETS]; /*Indicates to perform verify operation on every written sector to the specified socket*/
FLDword gDochAtaDebug = 0; /*Indicates to retrieve ATA debug buffer upon completion of ATA command */
FLDword gSdkInitDone = 0; /*Indicates that DochSDKInit() was completed */
FLDword gSdkDOCAddressObtained = 0; /*Indicates that DOC address was obtained (used by DOCHConfigHW) */
FLDword gConfigHWDefaults[DOCH_NUM_OF_DCONFIGHW_ITEMS];
FLDword gConfigHWInitDone = 0; /*Indicates that gConfigHWDefaults[] was set to defaults */
FLDword gIPLChunkOffsetInSectors = 0; /*Offset of current IPL chunk to write*/
FLDword gSDKUpdatesDiskAttributes = 0; /*Indication that first 0x40 bytes of disk user attributes should be written as well*/
FLDword gIsDMAEnabled = 0; /*DMA is Enabled/Disabled*/
FLDword gAutoDPDByHost = 0; /*Host enters device to DPD automatically after every command*/
FLBoolean gDochIrqEnabled[DOCH_MAX_SOCKETS]; /* holds TRUE, when interrupt enable for socket, FALSE otherwise */
extern FLDword gAccessLayerType;
extern FLDword gATANoTimeout;
#ifdef DOCH_DMA_CONFIG
extern FLDword gDMAChannelOpen;
#endif /*DOCH_DMA_CONFIG*/
extern DOCH_DpdSettings gDpdSettings;
extern DOCH_Socket sockets [DOCH_MAX_SOCKETS];
#ifdef CHECK_POWER_ON_EVERY_COMMAND
extern FLBoolean gDeviceTurnedOff;
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
extern FLDword gUseShortWaitOnBusy;
/******************************************************************************/
/*
* Extern routines
*/
/******************************************************************************/
extern DOCH_Error io_input(DOCH_Socket *pdev, FLSNative devNum, DOCH_Registers* regs, void *buf, FLNative secNum);
extern DOCH_Error io_output(DOCH_Socket *pdev, FLSNative devNum, DOCH_Registers* regs, void *buf, FLNative secNum);
extern DOCH_Error get_out_registers(DOCH_Socket* pdev, FLSNative devNum, DOCH_Registers* out_regs);
void DOCH_SetBits(FLDword* var, FLDword mask, FLByte offset, FLDword val)
{
FLDword temp = *var;
temp &= ~(mask);
temp |= (val << offset);
*var = temp;
}
extern DOCH_Error dochSetMutex(FLByte socketNum,
FLBoolean state,
FLByte partition);
/******************************************************************************/
/*
* Static routines
*/
/******************************************************************************/
static DOCH_Error performSectorsOperation(DOCH_Command cmd,
FLByte devHeadOptions,
DOCH_Socket* pdev,
IOreq* ioreq,
DOCH_Registers* out_regs,
FLSNative sectorsToPerfrom,
FLSNative * sectorNumber,
FLSNative * totalNumOfSectors,
FLSNative * sectorsPerformed,
FLSNative * buf_offset,
FLByte* buf_ptr);
#ifdef DOCH_BIG_ENDIAN
static FLWord be_FLWord (FLByte * v);
static FLDword be_FLDword (FLByte * v);
#endif /*DOCH_BIG_ENDIAN*/
DOCH_Error DOCHGetParitionUserAttributesSingleFloor(IOreq* ioreq);
DOCH_Error DOCHAccessPartWithPwdSingleFloor(IOreq* ioreq);
DOCH_Error DOCHSetParitionProtectionSingleFloor(IOreq* ioreq);
/******************************************************************************/
/*
* Static Buffers
*/
/******************************************************************************/
static DOCH_PartitionFormatInfo partFormatInfo;
static DOCH_DeviceInfo diskOnChipDeviceInfo;
static DOCH_DeviceInfo diskOnChipDeviceInfo2;
static DOCH_DeviceUserAttr devUserAttr;
static DOCH_PartitionInfo partitionInfoTemp;
static DOCH_PartitionFormatInfoAPI partInfoTemp;
static DOCH_PartitionProtectionAPI protAPI;
static DOCH_PartitionAcessPassword partAccessTemp;
static FLByte currentAttributes[DOCH_SECTOR_SIZE];
static FLByte verifyBuf[DOCH_SECTOR_SIZE];
static FLDword wipeSectorsDev0[((2*DOCH_SECTOR_SIZE) / sizeof(FLDword))];
static FLDword wipeSectorsDev1[((2*DOCH_SECTOR_SIZE) / sizeof(FLDword))];
/******************************************************************************/
/*
* Local MACROs
*/
/******************************************************************************/
#ifdef DOCH_DMA_CONFIG
#define DOCH_OPEN_DMA_CHANNEL \
{ \
DMA_Params_S dmaParams; \
\
if(pdev->bUseDMA && (gDMAChannelOpen == 0)) \
{ \
dmaParams.bOpType = DOCH_DMA_OPEN_CHANNEL; \
DOCH_DMA_CONFIG(&dmaParams); \
if(dmaParams.fDmaStatus != 0) \
{ \
DBG_PRINT_ERR(FLZONE_API, "DOCHReadPartitionSectors(): DOCH_DMA_OPEN_CHANNEL Failed\r\n"); \
return DOCH_GeneralFailure; \
} \
\
gDMAChannelOpen = DOCH_GLOBAL_BOOL_PATTERN; \
\
DBG_PRINT_FLOW(FLZONE_ATA, "\r\nDMA Channel opened\r\n"); \
} \
}
#endif /*DOCH_DMA_CONFIG*/
#define DOCH_SET_ATA_ADDRESS_VALUES(addr_vals, sectorNumber, deviceNum) \
addr_vals.bSecNum = (FLByte) sectorNumber; \
addr_vals.bCylLow = (FLByte) (sectorNumber >> 8); \
addr_vals.bCylHi = (FLByte) (sectorNumber >> 16); \
addr_vals.bDevHead = (FLByte) (((sectorNumber >> 24) & 0x0f) | DOCH_LBA | (deviceNum<<4));
#define DOCH_PARTITION_ON_DEV0 \
((!pdev->sSpanData.secondFloorActive) || (partNum < pdev->sSpanData.bLastPartitionOnDev0) || \
((partNum == pdev->sSpanData.bLastPartitionOnDev0) && (!pdev->sSpanData.bLastDev0PartSpanned)))
#define DOCH_PARTITION_ON_DEV1 \
(((pdev->sSpanData.secondFloorActive) && (partNum > pdev->sSpanData.bLastPartitionOnDev0)) \
&& (pdev->wNumOfDevices > 1))
#define DOCH_PARTITION_IS_SPANNED \
(((pdev->sSpanData.bLastDev0PartSpanned) && (partNum == pdev->sSpanData.numOfSpannedPartitionOnDev0)) \
&& (pdev->wNumOfDevices > 1))
/*----------------------------------------------------------------------*/
/* p e r f o r m S e c t o r O p e r a t i o n */
/* */
/* Performs sector(s) operation */
/* */
/* Parameters: */
/* cmd : ATA command to perform */
/* pdev : Socket to perform on */
/* ioreq : IOreq */
/* totalNumOfSectors : Total num of sectors to perform */
/* sectorsPerformed : Num of sectors actually performed */
/* */
/* Returns: */
/* device head with proper bit */
/*----------------------------------------------------------------------*/
static
DOCH_Error performSectorsOperation(DOCH_Command cmd,
FLByte devHeadOptions,
DOCH_Socket* pdev,
IOreq* ioreq,
DOCH_Registers* out_regs,
FLSNative sectorsToPerfrom,
FLSNative * sectorNumber,
FLSNative * totalNumOfSectors,
FLSNative * sectorsPerformed,
FLSNative * buf_offset,
FLByte* buf_ptr)
{
DOCH_Error rc;
DOCH_Registers in_regs;
Addressing_Values_s addr_vals;
/*Perform 1 operation cycle*/
/*=========================*/
/*Set ATA addressing registers*/
/*---------------------------*/
DOCH_SET_ATA_ADDRESS_VALUES(addr_vals, (*sectorNumber), (pdev->bAtaDevNum));
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_GET_PARTITION_FROM_IOREQ_HANDLE(ioreq);
if(sectorsToPerfrom < DOCH_MAX_SECTORS)
in_regs.bSectorCount = sectorsToPerfrom;
else
in_regs.bSectorCount = 0; /*DOCH_MAX_SECTORS*/
in_regs.bSectorNumber = addr_vals.bSecNum;
in_regs.bCylLow = addr_vals.bCylLow;
in_regs.bCylHigh = addr_vals.bCylHi;
in_regs.bDriveHead = addr_vals.bDevHead | devHeadOptions;
in_regs.bCommandStatus = cmd;
/*Activate ATA command*/
/*--------------------*/
rc = doch_command ( DOCH_GET_SOCKET_FROM_IOREQ_HANDLE(ioreq),
pdev->bAtaDevNum,
&in_regs,
out_regs,
(void*)(&buf_ptr[*buf_offset]),
sectorsToPerfrom);
if(rc != DOCH_OK)
{
DBG_PRINT_ERR(FLZONE_API, "performSectorsOperation(): ATA Error: ");
DBG_PRINT_ERR_PRM(FLZONE_API, (FLTXT("0x%x "), rc));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -