int ata_sw_reset_dev(ATA_Device_t *ata_dev)
{
	int error;

#ifdef ATA_DEBUG
	Debug_Printf("ATA reset processing...\n");
#endif
	
	ata_write_reg(ATA_DEVICE_CONTROL_REG, ATA_DEV_CTL_nIEN | ATA_DEV_CTL_SRST);
	ata_delay_ms(2);
	ata_write_reg(ATA_DEVICE_CONTROL_REG, ATA_DEV_CTL_nIEN);
	ata_delay_ms(2);
		
	ata_write_reg(ATA_DEVICE_HEAD_REG, ata_dev->current_dev ? ATA_DRIVE1_MASK : ATA_DRIVE0_MASK);
	ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
		
	error = ata_wait_status_bits(ATA_STATUS_BSY|ATA_STATUS_DRDY, ATA_STATUS_DRDY, ATA_CMD_INIT_TIMEOUT);
	if(error)
		return error;
	
	ata_write_reg(ATA_DEVICE_HEAD_REG, ata_dev->current_dev? ATA_DRIVE1_MASK : ATA_DRIVE0_MASK);
	ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
		
	return ATA_NO_ERROR;
}
示例#2
0
void cf_hw_reset()
{
/*	if(ata_cf_info->ata_cf_reset)
//	{
		ata_cf_info->ata_cf_reset(1);
	}
	else
	{
		cf_set_reset_output();
		cf_set_reset_high();
	}
*/
#ifdef CF_POWER_CONTROL
	cf_power_off();
#endif
	ata_delay_ms(200);
#ifdef CF_POWER_CONTROL
	cf_power_on();
	ata_delay_ms(300);
#endif

	if(ata_cf_info->ata_cf_reset)
	{
		ata_cf_info->ata_cf_reset(0);
	}
	else
	{
		cf_set_reset_output();
		cf_set_reset_low();
	}
	ata_delay_ms(100);
	if(ata_cf_info->ata_cf_reset)
	{
		ata_cf_info->ata_cf_reset(1);
	}
	else
	{
		cf_set_reset_output();
		cf_set_reset_high();
	}
	ata_delay_ms(200);
}
int ata_wait_status_bits(unsigned char bits_mask, unsigned char bits_value, unsigned long timeout)
{
	unsigned long cnt = 0;
	unsigned char status;

	while(cnt++ < timeout)
	{
		status = ata_read_reg(ATA_STATUS_REG);
		if((status & bits_mask) == bits_value)
			return ATA_NO_ERROR;
		else
		{
#ifdef CONFIG_CF
		    if(!cf_check_insert())
		        return ATA_ERROR_NO_DEVICE;
#endif
			ata_delay_ms(1);		
		}
	}
	
	return ATA_ERROR_TIMEOUT;
}
示例#4
0
void cf_power_on(void)
{
	ata_delay_ms(cf_power_delay+1);

	if(card_share_ins_pwr_flag[CARD_MODULE_CF])
		card_power_off_flag[CARD_COMPACT_FLASH] = 1;

#ifdef CF_POWER_CONTROL
	if(ata_cf_info->ata_cf_power)
	{
		if(cf_check_insert())
		{
			ata_cf_info->ata_cf_power(1);
		}
	}
	else
	{
		if(cf_check_insert())
		{
			cf_set_enable();
		}
	}
#endif
}
int ata_init_device(ATA_Device_t *ata_dev)
{
    /*_phymem_node_t *memmap = Am_GetSystemMem(MEMMAP_DEFAULT, MEMITEM_DMA_DRAM);
    if(memmap != NULL)
    {
        ata_dma_buf = (void *)(memmap->start);
        ata_dma_buf_size = memmap->end - memmap->start + 1;
    }*/

    //memset(ata_dev, 0, sizeof(ATA_Device_t));
	int error = ATA_NO_ERROR, dev, dev_existed = 0;
	unsigned char reg_data, device_head = 0;

	ata_dev->master_disabled = ATA_MASTER_DISABLED;
	ata_dev->slave_enabled = ATA_SLAVE_ENABLED;
	
#ifdef ATA_DEBUG
	Debug_Printf("Start to poll ATA status, wait BUSY cleared to zero...\n");
#endif
	
	ata_write_reg(ATA_DEVICE_CONTROL_REG, ATA_DEV_CTL_nIEN);
	ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
	
	for(dev=0; dev<2; dev++)
	{
		if(!dev && ata_dev->master_disabled)
			continue;
		else if(dev && !ata_dev->slave_enabled)
			continue;

		if(ata_dev->device_info[dev].device_existed)
		{
			dev_existed = 1;
			continue;
		}
		
		reg_data = dev ? ATA_DRIVE1_MASK : ATA_DRIVE0_MASK;
		ata_write_reg(ATA_DEVICE_HEAD_REG, reg_data);
		ata_delay_ms(2);
		
		error = ata_wait_status_bits(ATA_STATUS_BSY|ATA_STATUS_DRDY, ATA_STATUS_DRDY, ATA_CMD_INIT_TIMEOUT);
		if(error)
		{
			ata_dev->device_info[dev].device_inited = 0;
			continue;
		}
    	
    	ata_write_reg(ATA_SECTOR_COUNT_REG, 0x55);
		ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
		reg_data = ata_read_reg(ATA_SECTOR_COUNT_REG);
		if(reg_data != 0x55)
		{
			ata_dev->device_info[dev].device_inited = 0;
			error = ATA_ERROR_HARDWARE_FAILURE;
			continue;
		}
    	
    	ata_write_reg(ATA_SECTOR_NUMBER_REG, 0xAA);
		ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
		reg_data = ata_read_reg(ATA_SECTOR_NUMBER_REG);
		if(reg_data != 0xAA)
		{
			ata_dev->device_info[dev].device_inited = 0;
			error = ATA_ERROR_HARDWARE_FAILURE;
			continue;
		}

		ata_dev->device_info[dev].device_existed = 1;
		dev_existed = 1;

		if(ATA_EIGHT_BIT_ENABLED)
		{
			device_head = dev ? ATA_DRIVE1_MASK : ATA_DRIVE0_MASK;

			ata_dev->ata_param.Device_Head = device_head;
			ata_dev->ata_param.Features = 0x01;
			ata_dev->ata_param.Command = ATA_SET_FEATURES;
			error = ata_set_features(ata_dev);
			if(error)
				return error;
		}
	}

	if(dev_existed)
	{
#if ((defined CF_USE_PIO_DMA) || (defined HD_USE_DMA))
        atapi_dma_init();
        if (!atapi_dma_done_event) 
            atapi_dma_done_event = AVSemCreate(0);
#endif
        return ATA_NO_ERROR;
    }
    else
		return error;
}
/*This class includes:
-  CFA TRANSLATE SECTOR
-  IDENTIFY DEVICE
-  IDENTIFY PACKET DEVICE
-  READ BUFFER
-  READ MULTIPLE
-  READ SECTOR(S)
-  SMART READ DATA*/
int ata_issue_pio_in_cmd(ATA_Device_t *ata_dev, unsigned long sector_cnt, unsigned char *data_buf)
{
	int error, j;
	unsigned long i;
	unsigned char status, err_reg;
	unsigned short *word_buf;
	unsigned char *byte_buf;
#ifdef CF_USE_PIO_DMA
	INT8U err;
#endif
	
	error = ata_wait_status_bits(ATA_STATUS_BSY|ATA_STATUS_DRQ, 0, ATA_CMD_READY_TIMEOUT);
	if(error)
		return error;
	
	ata_write_reg(ATA_REATURES_REG, ata_dev->ata_param.Features);
	ata_write_reg(ATA_SECTOR_COUNT_REG, ata_dev->ata_param.Sector_Count);
	ata_write_reg(ATA_SECTOR_NUMBER_REG, ata_dev->ata_param.Sector_Number);
	ata_write_reg(ATA_CYLINDER_LOW_REG, ata_dev->ata_param.Cylinder_Low);
	ata_write_reg(ATA_CYLINDER_HIGH_REG, ata_dev->ata_param.Cylinder_High);
	ata_write_reg(ATA_DEVICE_HEAD_REG, ata_dev->ata_param.Device_Head);
	ata_write_reg(ATA_COMMAND_REG, ata_dev->ata_param.Command);

	ata_delay_100ns(ATA_CMD_ISSUE_DELAY);
	
	for(i=0; i<sector_cnt; i++)
	{
		if(ata_dma_buf != NULL && ata_dma_buf_size >= ATA_DRQ_BLK_LENGTH_BYTE)
        {
            word_buf = (void *)(ata_dma_buf);
            byte_buf = ata_dma_buf;
        }
        else
        {
            word_buf = (void *)ata_dev->ata_buf;
            byte_buf = ata_dev->ata_buf;
        }
		
		//This prevents polling host from reading status before it is valid.
		status = ata_read_reg(ATA_ALT_STATUS_REG);

		error = ata_wait_status_bits(ATA_STATUS_BSY|ATA_STATUS_DRQ, ATA_STATUS_DRQ, ATA_CMD_READY_TIMEOUT*3);
		if(error)
		{
		    while(read_status_count--)
		    {
			    status = ata_read_reg(ATA_STATUS_REG);
			    if((status & (ATA_STATUS_BSY|ATA_STATUS_DRQ)) == ATA_STATUS_DRQ)
			    {
			        read_status_count = 1;
			        return error;
			    }
			    else
			        ata_delay_ms(1);
			}
			if(status & ATA_STATUS_ERR)
			{
				err_reg = ata_read_reg(ATA_ERROR_REG);
			}
			return error;
		}

#ifdef CF_USE_PIO_DMA
        atapi_dma_add_work(
            (unsigned)word_buf,       // to/From data location in SDRAM
                0,              // Endian setting: 0,1,2 or 3
                0,              // Level on the Cable select pin during DMA
                0,              // set to 1 if transfering TO the ATAPI device
                0,              // Multi-DMA Mode: 0, 1, 2 or 3 (ignored for UDMA)
                2,              // Type: 0 = Standard DMA, 1 = Ultra DMA, 2 =PIO DMA (new feature)
                0,              // PIO Address: 0,1,..,15.  Used for DMA to PIO address (new feature)
                ATA_DRQ_BLK_LENGTH_BYTE,     // Number of bytes to transfer (must be divisible by 2)
                atapi_dma_done, // callback
                NULL);          // callback arguments  
        AVSemPend(atapi_dma_done_event, 0, &err);
#else
		if (cf_special_flag)
		{
			if(ATA_EIGHT_BIT_ENABLED)
			{
				for(j=0; j<ATA_DRQ_BLK_LENGTH_BYTE; j++)
				{
					*(byte_buf + j) = ata_read_data();
			    	status = ata_read_reg(ATA_STATUS_REG);
				}
			}
			else
			{
				for(j=0; j<ATA_DRQ_BLK_LENGTH_WORD; j++)
				{
					*(word_buf + j) = ata_read_data();
			    	status = ata_read_reg(ATA_STATUS_REG);
				}
			}
		}
		else
		{
			if(ATA_EIGHT_BIT_ENABLED)
			{
				for(j=0; j<ATA_DRQ_BLK_LENGTH_BYTE; j++)
				{
					*(byte_buf + j) = ata_read_data();
				}
			}
			else
			{
				for(j=0; j<ATA_DRQ_BLK_LENGTH_WORD; j++)
				{
					*(word_buf + j) = ata_read_data();
				}
			}
		}
#endif
		
#ifdef AMLOGIC_CHIP_SUPPORT
		if((unsigned long)data_buf == 0x3400000)
		{
			for(j=0; j<ATA_DRQ_BLK_LENGTH_BYTE; j++)
			{
				WRITE_BYTE_TO_FIFO(*byte_buf++);
			}
		}
		else
#endif
		{
			memcpy(data_buf, byte_buf, ATA_DRQ_BLK_LENGTH_BYTE);
			data_buf += ATA_DRQ_BLK_LENGTH_BYTE;
		}
	}

	//This prevents polling host from reading status before it is valid.
	status = ata_read_reg(ATA_ALT_STATUS_REG);
	
	//Status register is read to clear pending interupt.
	status = ata_read_reg(ATA_STATUS_REG);
	
	return ATA_NO_ERROR;
}