예제 #1
0
파일: ndshared.c 프로젝트: NemProjects/WLAN
void
shared_lb_put(
	IN shared_info_t *shared,
	IN struct lbfree *l,
	IN struct lbuf *lb
)
{
	NdisAcquireSpinLock(&l->queue_lock);
	ASSERT(l->count <= l->total);
	ASSERT(lb->p == NULL);
	ASSERT(lb->link == NULL);
	ASSERT(lb->next == NULL);
	ASSERT(lb->l == l);

	lb->data = lb->tail = (uchar*)(uintptr)0xdeadbeef;
	lb->len = 0;
	lb->link = l->free;
	l->free = lb;
	l->count++;
	if ((uint)shared_lb_freecount(&shared->rxfree) > shared->rxflowHi) {
		if (shared->rxflowMode == RX_FLOW_CONTROL_WATERMARK && shared->rxflow == TRUE) {
			shared->rxflow = FALSE;
			ND_TRACE(("%s: rx flow OFF, free count = %d\n", __FUNCTION__,
				shared_lb_freecount(&shared->rxfree)));
			dhd_rx_flow(shared->dhd, FALSE);
		}
	}
	NdisReleaseSpinLock(&l->queue_lock);
}
예제 #2
0
파일: ndshared.c 프로젝트: NemProjects/WLAN
struct lbuf *
shared_lb_get(
	IN shared_info_t *shared,
	IN struct lbfree *l
)
{
	struct lbuf	*lb;

	NdisAcquireSpinLock(&l->queue_lock);
	ASSERT(l->count <= l->total);

	if (lb = l->free) {
		l->free = lb->link;
		lb->link = lb->next = NULL;
		lb->data = lb->tail = lb->head;
		lb->priority = 0;
		lb->len = 0;
		l->count--;
		bzero(lb->pkttag, OSL_PKTTAG_SZ);
	}
	if ((uint)shared_lb_freecount(&shared->rxfree) < shared->rxflowLow) {
		if (shared->rxflowMode ==  RX_FLOW_CONTROL_WATERMARK && shared->rxflow == FALSE) {
			shared->rxflow = TRUE;
			ND_TRACE(("%s: rx flow ON, free count = %d\n", __FUNCTION__,
				shared_lb_freecount(&shared->rxfree)));
			dhd_rx_flow(shared->dhd, TRUE);
		}
	}
	NdisReleaseSpinLock(&l->queue_lock);
	return (lb);
}
예제 #3
0
파일: ndshared.c 프로젝트: NemProjects/WLAN
void
shared_lb_free(
	IN shared_info_t *shared,
	IN struct lbfree *l,
	IN BOOLEAN shared_mem,
	IN BOOLEAN cached
)
{
	uint i;
	int maxpages;

	ND_TRACE(("%s%d: shared_lb_free\n", shared->id, shared->unit));

	ASSERT(l->count <= l->total);
	/* uncached not supported */
	ASSERT(cached);

	/* free all buffer memory pages */
	for (i = 0; i < l->npages; i++) {
		if (!shared_mem)
			MFREE(shared->osh, l->pages[i].va, PAGE_SIZE);
		else {
				NdisMFreeSharedMemory(shared->adapterhandle, PAGE_SIZE, cached,
				                      (PVOID)l->pages[i].va, l->pages[i].pa);
		}
	}
	/* free the page list */
	if (l->pages) {
		maxpages = (l->total * l->size) / PAGE_SIZE;
		MFREE(shared->osh, (uchar *) l->pages, maxpages * sizeof(page_t));
	}
	l->free = NULL;
	l->total = 0;
	l->count = 0;
	l->pages = NULL;
	l->npages = 0;
	NdisFreeSpinLock(&l->queue_lock);
}
예제 #4
0
void target_init(void)
{
#if defined(NAND_BOOT_INCLUDE)
	ASSERT(NAND_MTD_PARTITION_NUM == num_parts);
		
	unsigned	offset;	
	unsigned	total_num_of_blocks;
	unsigned	blocks_per_megabytes;
	unsigned	next_ptr_start_adr = 0;
	int		 	ret, i;

	struct 		flash_info *flash_info;
	bool  		start_addr_changed = false;
	
	unsigned long long			nMTDReserved_Num=0;			// total number of MTD Reserved Area
	TNFTL_MTDBadBlkInfo			MTDBadBlkInfo[num_parts];

	/////////////////////////////////////////////////////////////////////////////////////////////	
	unsigned long long	nROAreaSize, nPartitionSize = 0;
	unsigned long int	nBlockSize, nBlockSize_MB;
	unsigned int		nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate;
	unsigned int		j, nUserDataArea = 0;
	struct ptable 		sPartition_List;
			

	memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts );

	edi_init();
#endif
	dprintf(ALWAYS, "target_init()\n");

	keys_init();
	keypad_init();

#if defined(BOOTSD_INCLUDE)

	if (target_is_emmc_boot())
	{
		emmc_boot_main();
		return ;

	}
#endif

#if defined(NAND_BOOT_INCLUDE)
#if defined(TNFTL_V8_INCLUDE)
	if (check_fwdn_mode()) {
		fwdn_start();
		return;
	}

	flash_boot_main();

#else
	if ( ( flash_get_ptable() == NULL ) ) {

		ptable_init(&flash_ptable);
		
		flash_set_partnum( num_parts );
		flash_init();
		flash_info = flash_get_info();
		ASSERT(flash_info);

		if ( (flash_info->num_blocks) && (!flash_check_table()) ) 
		{

			memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts );

			flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num );

			nROAreaSize		= (unsigned long long)( nMTDReserved_Num << 20 );		
			nBlockSize		= flash_info->page_size << flash_info->ShiftPpB;			// Set Block Size ( Byte Size ) 
			//nROAreaSize		=	flash_info->num_blocks * nBlockSize;					// Set Total ROArea Size ( Byte Size )
			nBlockSize_MB	=	nBlockSize / ( 1 << 20 );								
			if( nBlockSize_MB > 1 )					// If Block is over the 1MB. Block must aligned. 
			{										// ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1.
			
				if( nBlockSize_MB == 2 )			// If Block Size 2MB.
				{
					for( i = 0; i < num_parts; i++ )
					{
						if( sPartition_List.parts[i].length & 0x01 )
							sPartition_List.parts[i].length++;
					}
				}
				else if ( nBlockSize_MB == 4 )		// If Block Size 4MB 
				{
					unsigned int nDiff_Val;
						
					for( i = 0; i < num_parts; i++ )
					{
						nDiff_Val = sPartition_List.parts[i].length & 0x03;
						if( nDiff_Val )
							sPartition_List.parts[i].length += ( 4 - nDiff_Val );
					}
				}
				
			}			

			nMTDReserved_Num 	= 	( nMTDReserved_Num << 20 ) / nBlockSize;

			nDevBBpV			=	( nDevPBpV / 1024 ) * nDevBBpZ;
			nRervRate			=	( nMTDReserved_Num * 100 ) / nDevPBpV;
			nDevBBpV			=	( nDevBBpV * nRervRate ) / 100;

			if( nRervRate != 0 )
				nRervRate			= 	( 100 / nRervRate );

			nMTDReserved_Num	=	nRervRate + nDevBBpV;								// Setup ROArea Reserved Block 

			if(nMTDReserved_Num == 0) 
				nMTDReserved_Num = 2;
			else if ( nMTDReserved_Num & 0x01 )
				nMTDReserved_Num++;

			if( flash_info->ExtInterrupt == TRUE )
				nMTDReserved_Num = nMTDReserved_Num << 1;

			for( i = 0; i < num_parts; i++ )
			{
				if( sPartition_List.parts[i].length != VARIABLE_LENGTH )
				{
					sPartition_List.parts[i].length  = (unsigned long long)(sPartition_List.parts[i].length << 20); 	// Convert Length Unit. MByte -> Byte	
					nPartitionSize					+= sPartition_List.parts[i].length;

					//ND_TRACE("sPartition_List.parts[%d].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[i].length, nPartitionSize);
				}
				else
				{
					nUserDataArea	=	i;
				}
			}

			if( nUserDataArea != 0 )
			{
				sPartition_List.parts[nUserDataArea].length	= nROAreaSize - nPartitionSize;			// Calculate UserDataArea Size ( include Rerv Block )
				//ND_TRACE("sPartition_List.parts[5].length:%lld [nPartitionSize:%d]\n", i, sPartition_List.parts[5].length, nPartitionSize);
				//sPartition_List.parts[nUserDataArea].length	-= (nMTDReserved_Num * nBlockSize ); 	// UserDataArea Size. Reverved Block Removed
			}	

			i = 1;
			sPartition_List.parts[0].length		/= nBlockSize;									// Partition 0 Length ( Block Unit )
			MTDBadBlkInfo[0].PartBlkNum			 =	sPartition_List.parts[0].length;			// Set Block Number Each Partition
			
			do
			{
				sPartition_List.parts[i].length /= nBlockSize;									// Partition i Length ( Block Unit )
				sPartition_List.parts[i].start	 = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length;

				MTDBadBlkInfo[i].PartBlkNum		 = sPartition_List.parts[i].length;				// Set Block Number Each Partition

				++i;
				
			} while( i < num_parts );

			flash_set_rervnum( nMTDReserved_Num );				// Set Reserved Block Number
			flash_set_badblkinfo( MTDBadBlkInfo );				// Set Bad Block Table Info. About Block Number Each Partition
			

			for( i = 0; i < num_parts; i++ )
			{
				ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start,
						   				  sPartition_List.parts[i].length, sPartition_List.parts[i].flags);
			}

			ND_TRACE("\n-------------- [ Partition Table ] --------------\n");		          
			for( i = 0; i < num_parts; i++ )
			{
			ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length );	
			}
			ND_TRACE("-------------------------------------------------\n");
			
			dprintf(INFO, "[NAND        ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n",
				flash_info->vendor, flash_info->device, flash_info->page_size);
			dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_TotalBlock:%d]\n",
				flash_info->spare_size, flash_info->block_size, flash_info->num_blocks);
			//dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n",
			//	flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num);
		
			//ptable_dump(&flash_ptable);
			flash_set_ptable(&flash_ptable);

			ret = flash_set_badblktable();

			if( ret != SUCCESS )
			{
				dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ );
				ASSERT(-1);
			}
			
			flash_set_tablestatus(TRUE);
			
		}
	}
#endif
#endif
}
예제 #5
0
void target_init(void)
{

	ASSERT(NAND_MTD_PARTITION_NUM == num_parts);

		
	unsigned	offset;	
	unsigned	total_num_of_blocks;
	unsigned	blocks_per_megabytes;
	unsigned	next_ptr_start_adr = 0;
	int		 	ret, i;

	struct 		flash_info *flash_info;
	bool  		start_addr_changed = false;
	
	unsigned int				nMTDReserved_Num=0;			// total number of MTD Reserved Area
	TNFTL_MTDBadBlkInfo			MTDBadBlkInfo[num_parts];

	/////////////////////////////////////////////////////////////////////////////////////////////	
	unsigned int  		nROAreaSize, nPartitionSize = 0;
	unsigned int		nBlockSize, nBlockSize_MB;
	unsigned int		nDevPBpV, nDevBBpZ, nDevBBpV, nRervRate;
	unsigned int		j, nUserDataArea = 0;
	struct ptable 		sPartition_List;
			

	memset( MTDBadBlkInfo, 0, sizeof(TNFTL_MTDBadBlkInfo) * num_parts );
	dprintf(ALWAYS, "target_init()\n");
	
#if _EMMC_BOOT_TCC	
	PARTITION PartitionArr[50]; 	 
	unsigned int nPartitionCnt = 0; 
#endif		

#ifdef TRIFLASH_INCLUDE
		ioctl_diskinfo_t	disk_info;
#endif	


#if (!ENABLE_NANDWRITE)
#ifdef BOARD_TCC930X_STB_DEMO

#else
	keys_init();
	keypad_init();
#endif
#endif

	if (target_is_emmc_boot())
	{
#if _EMMC_BOOT_TCC	
		dprintf(INFO, "target_init() emmc_boot\n");
 
		ptable_init(&flash_ptable);

		//SDMMC init  //MCC
		DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_INITIALIZE, NULL );

		//get flash info?   //MCC
		DISK_Ioctl(DISK_DEVICE_TRIFLASH, DEV_GET_DISKINFO, (void *)&disk_info);

		dprintf(INFO, "disk info: head: %d cylinder: %d sector : %d  sector size: %d Total_sectors: %d \n",disk_info.head,disk_info.cylinder,disk_info.sector,disk_info.sector_size,disk_info.Total_sectors);

		//ptabel init			//MCC
//		offset = flash_info->offset;	
		offset = 0;     //fixme

//		total_num_of_blocks = flash_info->num_blocks;
		total_num_of_blocks=10000000;    // fixme
																					 
		memset(&PartitionArr, 0, sizeof(PARTITION) * 50);												 
		nPartitionCnt = GetLocalPartition(0, PartitionArr); 											 
																								   
		for(i=0; i<nPartitionCnt; i++)																	 
			PrintPartitionInfo(&PartitionArr[i], i);		


		/* convert partition size to block unit */  //512byte ?
		blocks_per_megabytes = 1024*1024 / (disk_info.sector_size);		
		ASSERT(blocks_per_megabytes);
		
		for (i = 0; i < num_parts; i++) {
			struct ptentry *ptn = &board_part_list[i];
			if (ptn->length != VARIABLE_LENGTH)
				ptn->length *= blocks_per_megabytes;
		}
		
		for (i = 0; i < num_parts; i++) {
			struct ptentry *ptn = &board_part_list[i];
			unsigned len = ptn->length;
	
			if (ptn->start != DIFF_START_ADDR)
			{			
				if(i==2)
				{
					ptn->start = PartitionArr[1].start;
				}
				else
				{
					ptn->start *= blocks_per_megabytes;
				}
			}	
			
			if (len == VARIABLE_LENGTH) {
				start_addr_changed = true;
				unsigned length_for_prt = ptn->start;
				unsigned j;
				for (j = i+1; j < num_parts; j++)
				{
						struct ptentry *temp_ptn = &board_part_list[j];
						ASSERT(temp_ptn->length != VARIABLE_LENGTH);
						length_for_prt += temp_ptn->length;
				}
				len = total_num_of_blocks - length_for_prt;
				ASSERT(len >= 0);
				next_ptr_start_adr = ptn->start + len;
			}
			if((ptn->start == DIFF_START_ADDR) && (start_addr_changed)) {
				ASSERT(next_ptr_start_adr);
				ptn->start = next_ptr_start_adr;
				next_ptr_start_adr = ptn->start + ptn->length;
			}
			ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
				   len, ptn->flags);
		}
		ptable_dump(&flash_ptable);
		flash_set_ptable(&flash_ptable);		
#endif
		return;
	}

	if (flash_get_ptable() == NULL) {

		ptable_init(&flash_ptable);
		
		flash_set_partnum( num_parts );
		flash_init();
		flash_info = flash_get_info();
		ASSERT(flash_info);

		if ( (flash_info->num_blocks) && (!flash_check_table()) ) 
		{
			

			memcpy( sPartition_List.parts, board_part_list, sizeof( struct ptentry ) * num_parts );

			nBlockSize		=	flash_info->page_size << flash_info->ShiftPpB;			// Set Block Size ( Byte Size ) 
			nROAreaSize		=	flash_info->num_blocks * nBlockSize;					// Set Total ROArea Size ( Byte Size )
			nBlockSize_MB	=	nBlockSize / ( 1 << 20 );								
			
			if( nBlockSize_MB > 1 )					// If Block is over the 1MB. Block must aligned. 
			{										// ex) Block Size 2MB, If Partition Size is 3MB. Partition Block Number must be 2. not 1.
			
				if( nBlockSize_MB == 2 )			// If Block Size 2MB.
				{
					for( i = 0; i < num_parts; i++ )
					{
						if( sPartition_List.parts[i].length & 0x01 )
							sPartition_List.parts[i].length++;
					}
				}
				else if ( nBlockSize_MB == 4 )		// If Block Size 4MB 
				{
					unsigned int nDiff_Val;
						
					for( i = 0; i < num_parts; i++ )
					{
						nDiff_Val = sPartition_List.parts[i].length & 0x03;
						if( nDiff_Val )
							sPartition_List.parts[i].length += ( 4 - nDiff_Val );
					}
				}
				
			}
				
			flash_get_DevPBpV( &nDevPBpV, &nDevBBpZ, &nMTDReserved_Num );

			nMTDReserved_Num 	= 	( nMTDReserved_Num << 20 ) / nBlockSize;

			nDevBBpV			=	( nDevPBpV / 1024 ) * nDevBBpZ;
			nRervRate			=	( nMTDReserved_Num * 100 ) / nDevPBpV;
			nDevBBpV			=	( nDevBBpV * nRervRate ) / 100;
			nRervRate			= 	( 100 / nRervRate );

			nMTDReserved_Num	=	nRervRate + nDevBBpV;								// Setup ROArea Reserved Block 

			if( nMTDReserved_Num & 0x01 )
				nMTDReserved_Num++;

			if( flash_info->ExtInterrupt == TRUE )
				nMTDReserved_Num = nMTDReserved_Num << 1;

			for( i = 0; i < num_parts; i++ )
			{
				if( sPartition_List.parts[i].length != VARIABLE_LENGTH )
				{
					sPartition_List.parts[i].length  = sPartition_List.parts[i].length << 20; 	// Convert Length Unit. MByte -> Byte	
					nPartitionSize					+= sPartition_List.parts[i].length;
				}
				else
				{
					nUserDataArea	=	i;
				}
			}
		
			sPartition_List.parts[nUserDataArea].length	= nROAreaSize - nPartitionSize;			// Calculate UserDataArea Size ( include Rerv Block )
			sPartition_List.parts[nUserDataArea].length	-= (nMTDReserved_Num * nBlockSize ); 	// UserDataArea Size. Reverved Block Removed

			i = 1;
			sPartition_List.parts[0].length		/= nBlockSize;									// Partition 0 Length ( Block Unit )
			MTDBadBlkInfo[0].PartBlkNum			 =	sPartition_List.parts[0].length;			// Set Block Number Each Partition
			
			do
			{
				sPartition_List.parts[i].length /= nBlockSize;									// Partition i Length ( Block Unit )
				sPartition_List.parts[i].start	 = sPartition_List.parts[i-1].start + sPartition_List.parts[i-1].length;

				MTDBadBlkInfo[i].PartBlkNum		 = sPartition_List.parts[i].length;				// Set Block Number Each Partition

				++i;
				
			} while( i < num_parts );

			flash_set_rervnum( nMTDReserved_Num );				// Set Reserved Block Number
			flash_set_badblkinfo( MTDBadBlkInfo );				// Set Bad Block Table Info. About Block Number Each Partition
			

			for( i = 0; i < num_parts; i++ )
			{
				ptable_add(&flash_ptable, sPartition_List.parts[i].name, flash_info->offset + sPartition_List.parts[i].start,
						   				  sPartition_List.parts[i].length, sPartition_List.parts[i].flags);
			}

			ND_TRACE("\n-------------- [ Partition Table ] --------------\n");		          
			for( i = 0; i < num_parts; i++ )
			{
			ND_TRACE(" [Part %2d.%9s] [Start:%4d] [Length:%4d]\n", i, sPartition_List.parts[i].name ,sPartition_List.parts[i].start + flash_info->offset, sPartition_List.parts[i].length );	
			}
			ND_TRACE("-------------------------------------------------\n");
			
			dprintf(INFO, "[NAND        ] [Maker:0x%02x ][Device:0x%02x][Page_size:%d]\n",
				flash_info->vendor, flash_info->device, flash_info->page_size);
			dprintf(INFO, "               [Spare_Size:%d][Block_Size:%d][MTD_Block:%d][Rerv_Block:%d]\n",
				flash_info->spare_size, flash_info->block_size, flash_info->num_blocks - (U32)nMTDReserved_Num, (U32)nMTDReserved_Num);
		
			//ptable_dump(&flash_ptable);
			flash_set_ptable(&flash_ptable);

			ret = flash_set_badblktable();

			if( ret != SUCCESS )
			{
				dprintf(INFO, " !!! Fail Create Bad Block Table. [func:%s] [line:%d] !!! \n", __func__, __LINE__ );
				ASSERT(-1);
			}
			
			flash_set_tablestatus(TRUE);
			
		}
	}

}
예제 #6
0
파일: ndshared.c 프로젝트: NemProjects/WLAN
NDIS_STATUS
shared_lb_alloc(
	IN shared_info_t *shared,
	IN struct lbfree *l,
	IN uint total,
	IN BOOLEAN shared_mem,
	IN BOOLEAN cached,
	IN BOOLEAN piomode,
	IN BOOLEAN data_buf
)
{
	NDIS_STATUS status;
	page_t page;
	int maxpages;
	int i;
	uint ipp, lbdatasz;

	/* uncached not supported */
	ASSERT(cached);

	if (data_buf)
		total = ROUNDUP(total, BPP);
	else
		/* add one if LBPP is not page aligned */
		total = ROUNDUP(total, (LBPP + ((PAGE_SIZE % sizeof(struct lbuf)) ? 1 : 0)));

	ND_TRACE(("%s%d: shared_lb_alloc: total %d\n", shared->id, shared->unit, total));

	l->free = NULL;
	l->total = total;
	l->count = 0;
	l->size = data_buf ? LBUFSZ : sizeof(struct lbuf);
	l->pages = NULL;
	l->npages = 0;
	l->headroom = 0;
	NdisAllocateSpinLock(&l->queue_lock);

	maxpages = (l->total * l->size) / PAGE_SIZE;

	/* allocate page list memory */
	if ((l->pages = (page_t*) MALLOC(shared->osh, maxpages * sizeof(page_t))) == NULL)
		goto enomem;
	bzero(l->pages, maxpages * sizeof(page_t));

	/* set item per page number and data size */
	if (data_buf) {
		ipp = BPP;
		lbdatasz = LBDATASZ;
	} else {
		ipp = LBPP;
		lbdatasz = 0;
	}

	/* fill the freelist */
	for (i = 0; i < maxpages; i++) {
		status = shared_allocpage(shared, shared_mem, cached, &page);
		if (NDIS_ERROR(status))
			goto enomem;
		status = shared_lb_addpage(shared, l, piomode, &page, ipp, lbdatasz);
		if (NDIS_ERROR(status))
			goto enomem;
	}

	return (NDIS_STATUS_SUCCESS);

enomem:
	ND_ERROR(("%s%d: shared_lb_alloc: out of memory, malloced %d bytes\n", shared->id,
	          shared->unit, MALLOCED(shared->osh)));
	shared_lb_free(shared, l, shared_mem, TRUE);
	return (NDIS_STATUS_RESOURCES);
}