⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi.c

📁 FIC8120方案的 StartCell_Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
	INT8U *u8ModeSenseData;	

	u8ModeSenseData = (INT8U*)malloc(DATA_LENGTH_MODE_SENSE);
	Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
	
	for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
	{
		memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));
		// Build SCSI command.		
		vSCSICmd_MODE_SENSE(Mass_stor_us, Mass_stor_us->srb,0x3F, u8ModeSenseData);

		// call mass storage function to send CBW
		// and get Mode Sense Data. Return CSW to check status.
		Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

		if(Mass_stor_us->srb->result == SAM_STAT_GOOD)
		{
			// save all Mode Sense(page code=0x3F) data 
			// Now we only use u8ModeSenseData[2], this byte save device
			// write protection information
			Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect = (u8ModeSenseData[2]==0x80)?
												TRUE:FALSE;
			
			free(u8ModeSenseData);
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
			return TRUE;
		}	
	}
	free(u8ModeSenseData);
	if(Mass_stor_us->srb != NULL)
		free(Mass_stor_us->srb);	
	return FALSE;
}

//***************************************************************************************
// Function Name:bSCSI_READ_CAPACITY
// Description:To get the CAPACITY
// Input:
// Output:
// Status:S
//***************************************************************************************
///////////////////////////////////////////////////////////////////////////////
//		bSCSI_READ_CAPACITY()
//		Description:
//			1. scsi READ_CAPACITY command.
//		input: none
//		output: TRUE or FALSE (BOOLEAN)
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bSCSI_READ_CAPACITY(void)
{
	INT8U u8j;
	INT8U *u8ReadCapacityData;	

	for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
	{		
		u8ReadCapacityData = (INT8U*)malloc(DATA_LENGTH_READ_CAPACITY);		
		Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
		memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));
		
		// Build SCSI command.	
		vSCSICmd_READ_CAPACITY(Mass_stor_us, Mass_stor_us->srb, u8ReadCapacityData);

		// call mass storage function to send CBW
		// and get CAPACITY Data. Return CSW to check status.
		Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

		if(Mass_stor_us->srb->result == SAM_STAT_GOOD)
		{
			// save all CAPACITY data 
			Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[0] << 24) |
										   ((INT32U)u8ReadCapacityData[1] << 16) |
										   ((INT32U)u8ReadCapacityData[2] << 8) |
										   ((INT32U)u8ReadCapacityData[3] ) ;

			Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize = ((INT32U)u8ReadCapacityData[4] << 24) |
									   ((INT32U)u8ReadCapacityData[5] << 16) |
									   ((INT32U)u8ReadCapacityData[6] << 8) |
									   ((INT32U)u8ReadCapacityData[7] ) ;
      if ( Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize > 1024)
      {
        printk("Block size over 1024, is %X\n",Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize);
        while(1);
      }
			
			SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
					(INT16U)(Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum >> 16),
					(INT16U)Mass_stor_us->Mass_stor_device[u8Drive].u32BlockTotalNum);
			SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us->Mass_stor_device[u8Drive].u32BlockSize);
			
			free(u8ReadCapacityData);
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
			return TRUE;
		}
		else
		{
			free(u8ReadCapacityData);
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
		}
	}
	return FALSE;

}



//***************************************************************************************
// Function Name:bSCSI_TEST_UNIT_READY
// Description: To know that "device is ready ?"
// Input:
// Output:
// Status:
//***************************************************************************************
///////////////////////////////////////////////////////////////////////////////
//		bSCSI_TEST_UNIT_READY()
//		Description:
//			1. scsi TEST_UNIT_READY command.
//		input: none
//		output: TRUE or FALSE (BOOLEAN)
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bSCSI_TEST_UNIT_READY(void)
{
	INT8U u8j;

  

	for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
	{		
		Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
		memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));
		
		// Build SCSI command.	
		vSCSICmd_TEST_UNIT_READY(Mass_stor_us, Mass_stor_us->srb);

		// call mass storage function to send CBW
		// and get CAPACITY Data. Return CSW to check status.
		Host20_MSCD_usb_stor_control_thread(Mass_stor_us);


		if(Mass_stor_us->srb->result == SAM_STAT_GOOD)
		{
			Mass_stor_us->Mass_stor_device[u8Drive].bDeviceReady = TRUE;
			SCSI_DbgPrint("SCSI TEST UNIT READY (Lun=%d): Succeed\n",u8Drive);
			
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
			return TRUE;
		}
		else
		{
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
		}
//Bruce  #if 0	
//Bruce  		if(iCardSuddenlyRemove == TRUE)
//Bruce  		{
//Bruce  			fLib_RemoveFileSystem((u8Drive+'A'));
//Bruce  			Mass_stor_us->Mass_stor_device[u8Drive].bDeviceReady = FALSE;
//Bruce  			iCardSuddenlyRemove = FALSE;
//Bruce  			SCSI_DbgPrint("**Media already be removed.%s","\n");
//Bruce  		}
//Bruce  		if(iCardReplace == TRUE)
//Bruce  		{
//Bruce  			SCSI_DbgPrint("**Media has been replaced.%s","\n");
//Bruce  			fLib_RemoveFileSystem((u8Drive+'A'));
//Bruce  
//Bruce  			Drive = 'A'+u8Drive;		
//Bruce  			fLib_InsertFileSystem(Drive, &(Mass_stor_us->Mass_stor_device[u8Drive].FileSys));
//Bruce  			fLib_InitFATFileSystemRoutines(&(Mass_stor_us->Mass_stor_device[u8Drive].FileSys), 
//Bruce  										&(Mass_stor_us->Mass_stor_device[u8Drive]), 
//Bruce  										(INIT_CARD)bSCSI_Initial, 
//Bruce  										(READ_SECTOR)bSCSI_READ_10, 
//Bruce  										(WRITE_SECTOR)bSCSI_Write_10, 
//Bruce  										(ERASE_SECTOR)bSCSI_ERASE);
//Bruce  			// Get FAT, John add
//Bruce  		  	SplitDrivePath(&Drive, &DriveName, Path);
//Bruce  			GetFileSystem(DriveName);
//Bruce  			iCardReplace = FALSE;
//Bruce  		}
//Bruce  #endif			
	}	
	SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n");
	return FALSE;
}
//***************************************************************************************
// Function Name:bSCSI_Initial
// Description:
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
BOOLEAN bSCSI_Initial(struct LUN_Device* LunDevice)
{
	//INT8U i=0;
	//iCardSuddenlyRemove = FALSE;
	//iCardReplace = FALSE;
	
	if(!bSCSI_TEST_UNIT_READY())
	{
		SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive);
		return FALSE;
	}
	bSCSI_INQUIRY();
	
	if(!bSCSI_READ_CAPACITY())
	{
		SCSI_DbgPrint("Read CAPACITY failed.%s","\n");
		return FALSE;
	}
	
	if(!bSCSI_TEST_UNIT_READY())
	{
		SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive);
		return FALSE;
	}
		
	return TRUE;
	
}
//***************************************************************************************
// Function Name:bUSBDisk_FileSystem_Initial
// Description:
// Input:
// Output:
// Status:P-OK
//***************************************************************************************

BOOLEAN bUSBDisk_FileSystem_Initial(void)
{
	UINT32 DriveName;
	INT8 Path[MAX_DIRECTORY_PATH_SIZE];
	INT8U Drive,i,DriveTmp[2];

//	fLib_InitFileSystem();
	/* register a file system to file system control */
	for(i=0; i<=Mass_stor_us->max_lun; i++)
	{
		if(!Mass_stor_us->Mass_stor_device[i].bDeviceReady)
		{
			Mass_stor_us->Mass_stor_device[i].u8LunNum = i;
			u8Drive = i;
			Drive = 'A'+i;//'C'+
			
			fLib_InsertFileSystem(Drive, &(Mass_stor_us->Mass_stor_device[i].FileSys));

			fLib_InitFATFileSystemRoutines(&(Mass_stor_us->Mass_stor_device[i].FileSys), 
										&(Mass_stor_us->Mass_stor_device[i]), 
										(INIT_CARD)bSCSI_Initial, 
										(READ_SECTOR)bSCSI_READ_10, 
										(WRITE_SECTOR)bSCSI_Write_10, 
										(ERASE_SECTOR)bSCSI_ERASE);

			// Get FAT, John add
		  	SplitDrivePath(&Drive, &DriveName, Path);
			GetFileSystem(DriveName);

			// Show Drive status..
			DriveTmp[0] = Drive; 
			DriveTmp[1] = 0;
			if(Mass_stor_us->Mass_stor_device[i].bDeviceReady == TRUE)
			{
				printk("Drive '%01s' ready to wrok..\n",DriveTmp);
			}
			else
			{
				printk("Drive '%01s' already registered, but can't work now..\n",DriveTmp);				
			}
		}
	}
	u8Drive = Mass_stor_us->max_lun;
	return TRUE;
}
//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************

void vUSBDisk_FileSystem_Remove(void)
{
	INT8U Drive ,i;
	
	for(i=0; i<=Mass_stor_us->max_lun; i++)
	{
		Drive = 'A'+i;
		fLib_RemoveFileSystem(Drive);
	}
}
//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************

BOOLEAN bSCSI_ERASE( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum,
							INT32U u32SectorSize)
{
	return TRUE;
}
//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************

BOOLEAN bSCSI_READ_10( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum,
							INT32U u32SectorSize, INT8U *u8Buffer)
{
#if 1
	INT32U u32DataLeft = (Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize)*u32BlockNum;
	INT32U u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
	
	Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
	memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));

	while(u32DataLeft > 0)
	{

		if(u32DataLeft > Scsi_Max_Transfer_Len)
		{
			u32TransBlockTmp = Scsi_Max_Transfer_Len / Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
			u32TransSizeTmp = u32TransBlockTmp * Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
			u32DataLeft -= u32TransSizeTmp;
		}
		else
		{
			u32TransBlockTmp = u32DataLeft/Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
			u32TransSizeTmp = u32DataLeft;
			u32DataLeft = 0;
		}
			
		// Build SCSI command.	
		vSCSICmd_READ_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum,
							u32BlockAddr + u32BlockOfSet, (INT16U)u32TransBlockTmp, u8Buffer + u32TransOfSet);

		// call mass storage function to send scsi command
		Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

		if(Mass_stor_us->srb->result != SAM_STAT_GOOD)
		{
			SCSI_DbgPrint("Scsi READ_10 command failed.%s","\n");
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);
			return FALSE;
		}
		u32BlockOfSet += u32TransBlockTmp;
		u32TransOfSet += u32TransSizeTmp;
	}
	
	if(Mass_stor_us->srb != NULL)
		free(Mass_stor_us->srb);
	printk("#");
	return TRUE;

#else
	
	Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
	memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));

	// Build SCSI command.	
	vSCSICmd_READ_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum,
						u32BlockAddr, (INT16U)u32BlockNum, u8Buffer);

	// call mass storage function to send scsi command
	Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

	if(Mass_stor_us->srb->result != SAM_STAT_GOOD)
	{
		SCSI_DbgPrint("Scsi READ_10 command failed.%s","\n");
		if(Mass_stor_us->srb != NULL)
			free(Mass_stor_us->srb);
		return FALSE;
	}
	if(Mass_stor_us->srb != NULL)
		free(Mass_stor_us->srb);

	printk("#");
	return TRUE;

#endif
	
}
//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************

BOOLEAN bSCSI_Write_10( struct LUN_Device* LunDevice, INT32U u32BlockAddr, INT32U u32BlockNum,
							INT32U u32SectorSize, INT8U *u8Buffer)
{
#if 1
	INT32U u32DataLeft = (Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize)*u32BlockNum;
	INT32U u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;

	if(!Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect)
	{
		Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
		memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));
		
		while(u32DataLeft > 0)
		{

			if(u32DataLeft > Scsi_Max_Transfer_Len)
			{
				u32TransBlockTmp = Scsi_Max_Transfer_Len / Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
				u32TransSizeTmp = u32TransBlockTmp * Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
				u32DataLeft -= u32TransSizeTmp;
			}
			else
			{
				u32TransBlockTmp = u32DataLeft/Mass_stor_us->Mass_stor_device[LunDevice->u8LunNum].u32BlockSize;
				u32TransSizeTmp = u32DataLeft;
				u32DataLeft = 0;
			}
				

			// Build SCSI command.	
			vSCSICmd_WRITE_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum,
								u32BlockAddr + u32BlockOfSet, (INT16U)u32TransBlockTmp, u8Buffer + u32TransOfSet);

			// call mass storage function to send scsi command
			Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

			if(Mass_stor_us->srb->result != SAM_STAT_GOOD)
			{
				SCSI_DbgPrint("Scsi WRITE_10 command failed.%s","\n");
				if(Mass_stor_us->srb != NULL)
					free(Mass_stor_us->srb);
				return FALSE;
			}
			
			u32BlockOfSet += u32TransBlockTmp;
			u32TransOfSet += u32TransSizeTmp;
			
		}	
		
		if(Mass_stor_us->srb != NULL)
			free(Mass_stor_us->srb);
		printk("*");
		return TRUE;
	}
	else
	{
		printk("This device is write protect now\n");
		return FALSE;
	}

#else

	if(!Mass_stor_us->Mass_stor_device[u8Drive].bWriteProtect)
	{
		Mass_stor_us->srb = (struct scsi_cmnd *)malloc(sizeof(struct scsi_cmnd ));
		memset(Mass_stor_us->srb, 0, sizeof(struct scsi_cmnd ));

		// Build SCSI command.	
		vSCSICmd_WRITE_10(Mass_stor_us, Mass_stor_us->srb, LunDevice->u8LunNum,
							u32BlockAddr, (INT16U)u32BlockNum, u8Buffer);

		// call mass storage function to send scsi command
		Host20_MSCD_usb_stor_control_thread(Mass_stor_us);

		if(Mass_stor_us->srb->result != SAM_STAT_GOOD)
		{
			SCSI_DbgPrint("Scsi WRITE_10 command failed.%s","\n");
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);
			return FALSE;
		}
		if(Mass_stor_us->srb != NULL)
			free(Mass_stor_us->srb);
		printk("*");
		return TRUE;
	}
	else
	{
		printk("This device is write protect now\n");
		return FALSE;
	}
#endif	
}
//***************************************************************************************
// Function Name:vScsi_SendCmd_Done
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************
static void vScsi_SendCmd_Done(struct scsi_cmnd *srb)
{

	SCSI_DbgPrint("Send SCSI command (0x%x) Done (LUN=%d), result = 0x%x\n", srb->cmnd[0],u8Drive, srb->result);

}
















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -