📄 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",(char *)&Mass_stor_us->device.u8VendorID); SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",(char *)&Mass_stor_us->device.u8ProductID); SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",(char *)&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 + -