📄 scsi.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -