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

📄 scsi.c

📁 FIC8120方案的 StartCell_Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//	File name: SCSI.C
//	Version: 1.0
//	Date: 2003/7/13
//  Description: 
//
//
//	Author: 
//	Email: 
//	Phone: (03) 578-7888
//	Company: Faraday Tech. Corp.
///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "chipset.h"  
#include "flib.h" 
#include "Lib_Host20.h" 
#include "Host20_AP.H"
#include "scsi.h"
#include "MassStorage.h"


static void vScsi_SendCmd_Done(struct scsi_cmnd *srb);
struct us_data *Mass_stor_us;
struct us_data us_data_Signal;
struct LUN_Device Mass_stor_device_1;
struct LUN_Device Mass_stor_device_2;
struct LUN_Device Mass_stor_device_3;

UINT8 u8Drive = 0;


//***************************************************************************************
// Function Name: vSCSICmd_READ_10
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
void vSCSICmd_READ_10(struct us_data *us, Scsi_Cmnd *srb, INT8U u8LunNum,
							  INT32U u32BlockAddr, INT16U u16BlockNum, INT8U *u8Buffer)
{


	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = READ_10;

	srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
	srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
	srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
	srb->cmnd[5] = (INT8U)(u32BlockAddr);
	
	srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
	srb->cmnd[8] = (INT8U)(u16BlockNum );


	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_READ_10;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
	srb->request_buffer = u8Buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = (us->Mass_stor_device[u8LunNum].u32BlockSize)*u16BlockNum;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8LunNum;
	
	srb->scsi_done = vScsi_SendCmd_Done;


	
}

//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
void vSCSICmd_WRITE_10(struct us_data *us, Scsi_Cmnd *srb,  INT8U u8LunNum,
							  INT32U u32BlockAddr, INT16U u16BlockNum, INT8U *u8Buffer)
{


	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = WRITE_10;

	srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
	srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
	srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
	srb->cmnd[5] = (INT8U)(u32BlockAddr);
	
	srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
	srb->cmnd[8] = (INT8U)(u16BlockNum );


	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_WRITE_10;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_WRITE;

	/* use the new buffer we have */
	srb->request_buffer = u8Buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = us->Mass_stor_device[u8LunNum].u32BlockSize*u16BlockNum;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8LunNum;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}

//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
void vSCSICmd_INQUIRY(struct us_data *us,  Scsi_Cmnd *srb, INT8U *u8Buffer)
{

	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = INQUIRY;
	srb->cmnd[4] = DATA_LENGTH_INQUIRY;

	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_INQUIRY;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
	srb->request_buffer = u8Buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = DATA_LENGTH_INQUIRY;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8Drive;//0;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}
//***************************************************************************************
// Function Name:
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
void vSCSICmd_READ_CAPACITY(struct us_data *us,  Scsi_Cmnd *srb, INT8U *u8Buffer)
{

	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = READ_CAPACITY;

	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_READ_CAPACITY;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
	srb->request_buffer = u8Buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = DATA_LENGTH_READ_CAPACITY;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8Drive;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}
//***************************************************************************************
// Function Name:vSCSICmd_MODE_SENSE
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************
void vSCSICmd_MODE_SENSE(struct us_data *us,  Scsi_Cmnd *srb,INT8U u8PageCode,INT8U *u8Buffer)
{

	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = MODE_SENSE;
	srb->cmnd[2] = u8PageCode;
	srb->cmnd[4] = DATA_LENGTH_MODE_SENSE;

	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_MODE_SENSE;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
	srb->request_buffer = u8Buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = DATA_LENGTH_MODE_SENSE;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8Drive;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}
//***************************************************************************************
// Function Name:vSCSICmd_REQUEST_SENSE
// Description:
// Input:
// Output:
// Status:
//***************************************************************************************
void vSCSICmd_REQUEST_SENSE(struct us_data *us,  Scsi_Cmnd *srb)
{


	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = REQUEST_SENSE;
//	srb->cmnd[1] = old_cmnd[1] & 0xE0;
	srb->cmnd[4] = 18;

	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_REQUEST_SENSE;

	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
	srb->request_buffer = srb->sense_buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = 18;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8Drive;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}
//***************************************************************************************
// Function Name:vSCSICmd_TEST_UNIT_READY
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
void vSCSICmd_TEST_UNIT_READY(struct us_data *us,  Scsi_Cmnd *srb)
{



	/* set the command and the LUN */
	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
	srb->cmnd[0] = TEST_UNIT_READY;

	/* FIXME: we must do the protocol translation here */
/*	
	if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
		srb->cmd_len = 6;
	else
		srb->cmd_len = 12;
*/
	srb->cmd_len = CB_LENGTH_TEST_UNIT_READY;


	/* set the transfer direction */
	srb->sc_data_direction = SCSI_DATA_READ;

	/* use the new buffer we have */
//	srb->request_buffer = srb->sense_buffer;

	/* set the buffer length for transfer */
	srb->request_bufflen = 0;

	/* set up for no scatter-gather use */
	srb->use_sg = 0;

	/* change the serial number -- toggle the high bit*/
	srb->serial_number ^= 0x80000000;

	/* set Lun number*/
	srb->lun= u8Drive;
	
	srb->scsi_done = vScsi_SendCmd_Done;


}













//=======================================================================================
//=======================================================================================
//=======================================================================================
//=======================================================================================
//***************************************************************************************
// Function Name:vSCSI_REQUEST_SENSE
// Description: Reserved.
//              If Device do not support the command-A
//              ,Host should issue command "vSCSI_REQUEST_SENSE" to ask "why not support".
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
void vSCSI_REQUEST_SENSE(void)
{
	INT8U *u8RequestSenseData;	
	u8RequestSenseData = (INT8U*)malloc(DATA_LENGTH_REQUEST_SENSE);
	
	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_REQUEST_SENSE(Mass_stor_us, Mass_stor_us->srb);

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


	free(u8RequestSenseData);
	if(Mass_stor_us->srb != NULL)
		free(Mass_stor_us->srb);	
}

//***************************************************************************************
// Function Name:bSCSI_INQUIRY
// Description:To ask the device u8DeviceType/u8ProductID/u8ProductVer... information
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
///////////////////////////////////////////////////////////////////////////////
//		bSCSI_INQUIRY()
//		Description:
//			1. scsi inquiry command.
//		input: none
//		output: TRUE or FALSE (BOOLEAN)
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bSCSI_INQUIRY(void)
{
	INT8U u8i, u8j;
	INT8U *u8InquiryData;	

	for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
	{
		u8InquiryData = (INT8U*)malloc(DATA_LENGTH_INQUIRY);
		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_INQUIRY(Mass_stor_us, Mass_stor_us->srb, u8InquiryData);

		// call mass storage function to send CBW
		// and get INQUIRY 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 INQUIRY data 
			Mass_stor_us->device.u8DeviceType = (u8InquiryData[0] & 0x1F);
			for(u8i =0; u8i <8; u8i++)
				Mass_stor_us->device.u8VendorID[u8i] = u8InquiryData[u8i+8];
			for(u8i =0; u8i <16; u8i++)
				Mass_stor_us->device.u8ProductID[u8i] = u8InquiryData[u8i+16];
			for(u8i =0; u8i <4; u8i++)
				Mass_stor_us->device.u8ProductVer[u8i] = u8InquiryData[u8i+32];

			if(Mass_stor_us->device.u8DeviceType != TYPE_DISK)
			{
				SCSI_DbgPrint("Device type unsuport, it's not a scsi disk%s","\n");		
				free(u8InquiryData);
				if(Mass_stor_us->srb != NULL)
					free(Mass_stor_us->srb);

				return FALSE;
			}
			else
			{
				SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&Mass_stor_us->device.u8VendorID);
				SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&Mass_stor_us->device.u8ProductID);
				SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&Mass_stor_us->device.u8ProductVer);
			}
			
			free(u8InquiryData);
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
			return TRUE;
		}	
		else
		{
			free(u8InquiryData);
			if(Mass_stor_us->srb != NULL)
				free(Mass_stor_us->srb);	
		}
	}
	return FALSE;
}
//***************************************************************************************
// Function Name:bSCSI_MODE_SENSE
// Description:To know the mode of device <1>.Write Protect => Y/N
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
///////////////////////////////////////////////////////////////////////////////
//		bSCSI_MODE_SENSE()
//		Description:
//			1. scsi mode sense command.
//		input: none
//		output: TRUE or FALSE (BOOLEAN)
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bSCSI_MODE_SENSE(void)
{
	INT8U  u8j;

⌨️ 快捷键说明

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