示例#1
0
uint8_t sdmmc_readSector(uint32_t pSectorNum, char* pOutput) {
    SET_CS();

    // Send command 17 (READ_SINGLE_BLOCK)
    if (sdmmc_writeCommand(SDMMC_READ_SINGLE_BLOCK, SECTOR_TO_BYTE(pSectorNum), SDMMC_DEFAULT_CRC) != 0) {
        CLEAR_CS();
        return FALSE;
    }

    uint8_t response = 0;
    uint8_t retry = 0;

    // Wait for start-byte
    while(response != 0xFE) {
        response = spi_readByte();
        if (retry++ == 0xFF) {
            CLEAR_CS();
            return FALSE;
        }
    }

    // Read the block
    for (uint16_t i = 0; i < fBlockLength; i++) {
        pOutput[i] = spi_readByte();
    }

    // Ignore the CRC checksum
    spi_readByte();
    spi_readByte();

    CLEAR_CS();
    return TRUE;
}
示例#2
0
uint8_t sdmmc_writeSector(uint32_t pSectorNum, char* pInput) {
    SET_CS();

    // Send command 24 (WRITE_BLOCK)
    if (sdmmc_writeCommand(SDMMC_WRITE_BLOCK, SECTOR_TO_BYTE(pSectorNum), SDMMC_DEFAULT_CRC) != 0) {
        CLEAR_CS();
        return FALSE;
    }

    // Send some dummy clocks
    for(uint8_t i = 0; i < 100; i++) {
        spi_readByte();
    }

    // Send start-byte
    spi_writeByte(0xFE);

    // Send data
    for(uint16_t i = 0; i < fBlockLength; i++) {
        spi_writeByte(pInput[i]);
    }

    // Send dummy CRC checksum (won't be checked in SPI mode)
    spi_writeByte(0xFF);
    spi_writeByte(0xFF);

    // Get response
    if ((spi_readByte() & 0x1F) != 0x05) {
        CLEAR_CS();
        return FALSE;
    }

    // Wait until memory card is ready for new commands
    while (spi_readByte() != 0xFF) {
        // burn energy
    }

    CLEAR_CS();
    return TRUE;
}
示例#3
0
void
hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
{
    ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
    PCommand pCmd;
	UINT result;
	int needsync=0, retry=0, needdelete=0;
	void *buffer = NULL;

	_VBUS_INST(&pAdapter->VBus)

	if (pArray->u.array.rf_broken==1 ||
    	pArray->u.array.RebuildSectors>=capacity)
		return;

	mtx_lock(&pAdapter->lock);
	
	switch(flags)
	{
		case DUPLICATE:
		case REBUILD_PARITY:
			if(pArray->u.array.rf_rebuilding == 0)
			{
				pArray->u.array.rf_rebuilding = 1;
				hpt_printk(("Rebuilding started.\n"));
				ioctl_ReportEvent(ET_REBUILD_STARTED, pArray);
			}
			break;

		case INITIALIZE:
			if(pArray->u.array.rf_initializing == 0)
			{
				pArray->u.array.rf_initializing = 1;
				hpt_printk(("Initializing started.\n"));
				ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray);
			}
			break;

		case VERIFY:
			if(pArray->u.array.rf_verifying == 0)
			{
				pArray->u.array.rf_verifying = 1;
				hpt_printk(("Verifying started.\n"));
				ioctl_ReportEvent(ET_VERIFY_STARTED, pArray);
			}
			break;
	}
	
retry_cmd:
	pCmd = AllocateCommand(_VBUS_P0);
	HPT_ASSERT(pCmd);
	pCmd->cf_control = 1;
	End_Job = 0;

	if (pArray->VDeviceType==VD_RAID_1) 
	{
		#define MAX_REBUILD_SECTORS 0x40

		/* take care for discontinuous buffer in R1ControlSgl */
		buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
		if(!buffer) {
			FreeCommand(_VBUS_P pCmd);
			hpt_printk(("can't allocate rebuild buffer\n"));
			goto fail;
		}
		switch(flags) 
		{
			case DUPLICATE:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
				break;

			case VERIFY:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY;
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2;
				break;

			case INITIALIZE:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; 
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
				break;
		}

		pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors;

		if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors)
			pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors;

		pCmd->uCmd.R1Control.Buffer = buffer;
		pCmd->pfnBuildSgl = R1ControlSgl;
	}
	else if (pArray->VDeviceType==VD_RAID_5)
	{
		switch(flags)
		{
			case DUPLICATE:
			case REBUILD_PARITY:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break;
			case VERIFY:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break;
			case INITIALIZE:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break;
		}
		pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift;
	}
	else
示例#4
0
int HPTLIBAPI
R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical)
{
	ULONG bufferSize = SECTOR_TO_BYTE(pCmd->uCmd.R1Control.nSectors);
	if (pCmd->uCmd.R1Control.Command==CTRL_CMD_VERIFY)
		bufferSize<<=1;
	if (logical) {
		pSgTable->dSgAddress = (ULONG_PTR)pCmd->uCmd.R1Control.Buffer;
		pSgTable->wSgSize = (USHORT)bufferSize;
		pSgTable->wSgFlag = SG_FLAG_EOT;
	}
	else {
		/* build physical SG table for pCmd->uCmd.R1Control.Buffer */
		ADDRESS dataPointer, v, nextpage, currvaddr, nextvaddr, currphypage, nextphypage;
		ULONG length;
		int idx = 0;

		v = pCmd->uCmd.R1Control.Buffer;
		dataPointer = (ADDRESS)fOsPhysicalAddress(v);

		if ((ULONG_PTR)dataPointer & 0x1)
			return FALSE;

		#define ON64KBOUNDARY(x) (((ULONG_PTR)(x) & 0xFFFF) == 0)
		#define NOTNEIGHBORPAGE(highvaddr, lowvaddr) ((ULONG_PTR)(highvaddr) - (ULONG_PTR)(lowvaddr) != PAGE_SIZE)

		do {
			if (idx >= MAX_SG_DESCRIPTORS)  return FALSE;

			pSgTable[idx].dSgAddress = fOsPhysicalAddress(v);
			currvaddr = v;
			currphypage = (ADDRESS)fOsPhysicalAddress((void*)trunc_page((ULONG_PTR)currvaddr));


			do {
				nextpage = (ADDRESS)trunc_page(((ULONG_PTR)currvaddr + PAGE_SIZE));
				nextvaddr = (ADDRESS)MIN(((ULONG_PTR)v + bufferSize), (ULONG_PTR)(nextpage));

				if (nextvaddr == (ADDRESS)((ULONG_PTR)v + bufferSize)) break;
				nextphypage = (ADDRESS)fOsPhysicalAddress(nextpage);

				if (NOTNEIGHBORPAGE(nextphypage, currphypage) || ON64KBOUNDARY(nextphypage)) {
					nextvaddr = nextpage;
					break;
				}

				currvaddr = nextvaddr;
				currphypage = nextphypage;
			}while (1);

			length = (ULONG_PTR)nextvaddr - (ULONG_PTR)v;
			v = nextvaddr;
			bufferSize -= length;

			pSgTable[idx].wSgSize = (USHORT)length;
			pSgTable[idx].wSgFlag = (bufferSize)? 0 : SG_FLAG_EOT;
			idx++;

		}while (bufferSize);
	}
	return 1;
}