Exemplo n.º 1
0
Arquivo: ftl.c Projeto: ESOS-Lab/VSSIM
int _FTL_READ(int32_t sector_nb, unsigned int length)
{
#ifdef FTL_DEBUG
	printf("[%s] Start\n",__FUNCTION__);
#endif
	if(sector_nb + length > SECTOR_NB){
		printf("Error[FTL_READ] Exceed Sector number\n"); 
		return FAIL;	
	}

	unsigned int remain = length;
	unsigned int lba = sector_nb;
	unsigned int left_skip = sector_nb % SECTORS_PER_PAGE;
	unsigned int right_skip;
	unsigned int read_sects;

	unsigned int phy_flash_nb;
	unsigned int phy_block_nb;
	unsigned int phy_page_nb;

	unsigned int ret = SUCCESS;
	unsigned int ret_seq, ret_ran_hot, ret_ran_cold, ret_data;

	int read_page_offset = 0;
	int io_page_nb;

#ifdef FIRM_IO_BUFFER
	INCREASE_RB_FTL_POINTER(length);
#endif

	while(remain > 0){

		if(remain > SECTORS_PER_PAGE - left_skip){
			right_skip = 0;
		}
		else{
			right_skip = SECTORS_PER_PAGE - left_skip - remain;
		}
		read_sects = SECTORS_PER_PAGE - left_skip - right_skip;

		ret_seq = FIND_PAGE_IN_SEQ_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);

		if(ret_seq != SUCCESS){
			ret_ran_hot = FIND_PAGE_IN_RAN_HOT_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}

		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS){
			ret_ran_cold = FIND_PAGE_IN_RAN_COLD_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}

		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS){
			ret_data = FIND_PAGE_IN_DATA_BLOCK(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}
		
		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS && ret_data != SUCCESS){
#ifdef FTL_DEBUG
			printf("Error[FTL_READ] No Mapping info\n");
#endif
#ifdef FIRM_IO_BUFFER
			INCREASE_RB_LIMIT_POINTER();
#endif
			return FAIL;
		}

		lba += read_sects;
		remain -= read_sects;
		left_skip = 0;
	}

	io_alloc_overhead = ALLOC_IO_REQUEST(sector_nb, length, READ, &io_page_nb);

	remain = length;
	lba = sector_nb;
	left_skip = sector_nb % SECTORS_PER_PAGE;

	while(remain > 0){
	
		if(remain > SECTORS_PER_PAGE - left_skip){
			right_skip = 0;
		}
		else{
			right_skip = SECTORS_PER_PAGE - left_skip - remain;
		}
		read_sects = SECTORS_PER_PAGE - left_skip - right_skip;

		ret_seq = FIND_PAGE_IN_SEQ_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);

		if(ret_seq != SUCCESS){
			ret_ran_hot = FIND_PAGE_IN_RAN_HOT_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}

		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS){
			ret_ran_cold = FIND_PAGE_IN_RAN_COLD_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}

		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS){
			ret_data = FIND_PAGE_IN_DATA_BLOCK(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb);
		}
		

		if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS && ret_data != SUCCESS){
#ifdef FTL_DEBUG
			printf("Error[FTL_READ] No Mapping info\n");
#endif
		}
		else{
			ret = SSD_PAGE_READ(phy_flash_nb, phy_block_nb, phy_page_nb, read_page_offset, READ, io_page_nb);
		}

		if(ret == SUCCESS){
#ifdef FTL_DEBUG
			printf("[FTL_READ] Complete [%d, %d, %d] from ",phy_flash_nb, phy_block_nb, phy_page_nb);

			if(ret_seq == SUCCESS){
				printf("SEQ Block\n");
			}
			else if(ret_ran_hot == SUCCESS){
				printf("RAN HOT Block\n");
			}
			else if(ret_ran_cold == SUCCESS){
				printf("RAN COLD Block\n");
			}
			else if(ret_data == SUCCESS){
				printf("DATA Block\n");
			}
			else{
				printf("No Map\n");
			}
#endif
		}
		else if(ret == FAIL){
			printf("Error[FTL_READ] %d page read fail \n", phy_page_nb);
		}

		read_page_offset++;

		lba += read_sects;
		remain -= read_sects;
		left_skip = 0;

	}

	INCREASE_IO_REQUEST_SEQ_NB();

#ifdef FIRM_IO_BUFFER
	INCREASE_RB_LIMIT_POINTER();
#endif

#ifdef MONITOR_ON
	char szTemp[1024];
	sprintf(szTemp, "READ PAGE %d ", length);
	WRITE_LOG(szTemp);
#endif

#ifdef FTL_DEBUG
	printf("[%s] End\n",__FUNCTION__);
#endif

	return ret;
}
Exemplo n.º 2
0
void COPY_DATA_TO_READ_BUFFER(event_queue_entry* dst_entry, event_queue_entry* src_entry)
{
#ifdef FIRM_IO_BUF_DEBUG
	printf("[%s] Start.\n",__FUNCTION__);
#endif
	if(dst_entry == NULL || src_entry == NULL){
		printf("[%s] Null pointer error.\n",__FUNCTION__);
		return;
	}

	int count = 0;
	int offset;
	void* dst_buf;	// new read entry
	void* src_buf;  // write entry

	int32_t dst_sector_nb = dst_entry->sector_nb;
	int32_t src_sector_nb = src_entry->sector_nb;
	unsigned int dst_length = dst_entry->length;

	/* Update read entry buffer pointer */	
	dst_buf = dst_entry->buf; 

	/* Calculate write buffer frame address */
	src_buf = src_entry->buf;
	offset = dst_sector_nb - src_sector_nb;


	while(count != offset){

		if(GET_WB_VALID_ARRAY_ENTRY(src_buf)!='I'){
			count++;
		}

		src_buf = src_buf + SECTOR_SIZE;
		if(src_buf == write_buffer_end){
			src_buf = write_buffer;
		}
	}

	count = 0;
	while(count != dst_length){
		if(GET_WB_VALID_ARRAY_ENTRY(src_buf)=='I'){
			src_buf = src_buf + SECTOR_SIZE;
			if(src_buf == write_buffer_end){
				src_buf = write_buffer;
			}
			continue;
		}

		/* Copy Write Buffer Data to Read Buffer */
		memcpy(dst_buf, src_buf, SECTOR_SIZE);

		/* Increase offset */
		dst_buf = dst_buf + SECTOR_SIZE;
		src_buf = src_buf + SECTOR_SIZE;

		ftl_read_ptr = ftl_read_ptr + SECTOR_SIZE;

		if(dst_buf == read_buffer_end){
			dst_buf = read_buffer;
			ftl_read_ptr = read_buffer;
		}
		if(src_buf == write_buffer_end){
			src_buf = write_buffer;
		}
		count++;
	}

	INCREASE_RB_LIMIT_POINTER();

#ifdef FIRM_IO_BUF_DEBUG
	printf("[%s] End.\n",__FUNCTION__);
#endif
}