📄 scsi.c
字号:
/*++
Copyright (c) 2001 Sunplus Technology Co., Ltd.
Module Name:
scsi.c
Abstract:
Module related to SCSI command
Environment:
Keil C51 Compiler
Revision History:
08/28/2001 Chi-Yeh Tsai created
--*/
//=============================================================================
//Header file
//=============================================================================
#include "general.h"
#if ((USBMSDC_OPTION == 1) || (USBMSDC_OPTION == 2))
#include "scsi.h"
#include "sense.h"
#include "main.h"
#include "usbmsdc2.h"
#include "doslink.h"
//richie
#include "bulkout.h"
#include "ctlsetup.h"
#include "initio.h"
#include "setmode.h"
#include "cardlink.h" // WWW1
extern code UCHAR K_ScsiVendorInformation[];
extern code UCHAR K_ScsiProductIdentification[];
extern code UCHAR K_ScsiProductRevisionLevel[];
//=============================================================================
//Symbol
//=============================================================================
//-----------------------------------------------------------------------------
//Constant
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Variable
//-----------------------------------------------------------------------------
//=============================================================================
//Program
//=============================================================================
//-----------------------------------------------------------------------------
//SCSICMD_TestUnitReady
//-----------------------------------------------------------------------------
UCHAR SCSICMD_TestUnitReady(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Inquiry command (0x00)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
PSCSICMD_06BYTE pSCSI06;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
//richie@1203 if no medium then set sensekey = 02
if (G_ucStorageType != G_Card_Type)
{
G_USBMSDC_ucCSWStatus = K_USBMSDC_NoMedium;
*pSize = 0;
return (FALSE);
}
*pSize = 0;
return(TRUE);
}
//Chamber@031103
#if 0
//-----------------------------------------------------------------------------
//SCSICMD_RezeroUnit
//-----------------------------------------------------------------------------
UCHAR SCSICMD_RezeroUnit(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Rezero command (0x01)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
PSCSICMD_06BYTE pSCSI06;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
*pSize = 0;
return(TRUE);
}
#endif
//-----------------------------------------------------------------------------
//SCSICMD_RequestSense
//-----------------------------------------------------------------------------
UCHAR SCSICMD_RequestSense(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Request Sense command (0x03)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
PSCSICMD_06BYTE pSCSI06;
PSCSIDATA_REQUEST_SENSE pRequestSense;
UCHAR i;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
pRequestSense = (PSCSIDATA_REQUEST_SENSE) G_pucStorDataPointer;
pRequestSense->BYTE0.valid = 0;
pRequestSense->BYTE0.errorCode = 0x70;
pRequestSense->reserved0 = 0;
pRequestSense->BYTE2.reserved = 0;
pRequestSense->BYTE2.senseKey = K_SCSISENSE[G_USBMSDC_ucSenseCodeIdx].senseKey;
pRequestSense->information = 0;
//richie
//pRequestSense->additionalSenseLength = 0x0a;
pRequestSense->additionalSenseLength = 0x12;
for (i = 0; i < 4; i++)
pRequestSense->reserved1[i] = 0x00;
pRequestSense->additionalSenseCode = K_SCSISENSE[G_USBMSDC_ucSenseCodeIdx].additionalSenseCode;
pRequestSense->additionalSenseCodeQualifier = K_SCSISENSE[G_USBMSDC_ucSenseCodeIdx].additionalSenseCodeQualifier;
for (i = 0; i < 4; i++)
pRequestSense->reserved2[i] = 0x00;
*pSize = SCSIDATA_REQUEST_SENSE_SIZE;
return(TRUE);
}
//Chamber@031103
#if 0
//-----------------------------------------------------------------------------
//SCSICMD_FormatUnit
//-----------------------------------------------------------------------------
UCHAR SCSICMD_FormatUnit(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Rezero command (0x04)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
PSCSICMD_06BYTE pSCSI06;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
*pSize = 0;
return(TRUE);
}
#endif
//-----------------------------------------------------------------------------
//SCSICMD_Inquiry
//-----------------------------------------------------------------------------
UCHAR SCSICMD_Inquiry(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Inquiry command (0x12)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
PSCSICMD_06BYTE pSCSI06;
PSCSIDATA_INQUIRY pInquiry;
UCHAR i;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
pInquiry = (PSCSIDATA_INQUIRY) G_pucStorDataPointer;
pInquiry->BYTE0.reserved = 0;
pInquiry->BYTE0.peripheralDeviceType = 0;
pInquiry->BYTE1.RMB = 1;
pInquiry->BYTE1.reserved = 0;
pInquiry->BYTE2.isoVersion = 0;
pInquiry->BYTE2.emcaVersion = 0;
pInquiry->BYTE2.ansiVersion = 0;
pInquiry->BYTE3.reserved = 0;
//richie
pInquiry->BYTE3.responseDataFormat = 1;
//pInquiry->BYTE3.responseDataFormat = 0;
pInquiry->additionalLength = 0x1f;
for (i = 0; i < 3; i++)
pInquiry->reserved0[i] = 0x00;
//patch4.5@richie@vender info begin
for (i = 0; i < 8; i++)
#if (USBVendorConfiguration_OPTION == 1)
// Get the Vendor Information from NAND Flash
pInquiry->vendorInformation[i] = G_ucStorData[i+384];;
#else
// Get the Vendor Information from ROM Table
pInquiry->vendorInformation[i] = K_ScsiVendorInformation[i];
#endif
for (i = 0; i < 16; i++)
#if (USBVendorConfiguration_OPTION == 1)
// Get the Product Identification from NAND Flash
pInquiry->productIdentification[i] = G_ucStorData[i+392];
#else
// Get the Product Identification from ROM Table
pInquiry->productIdentification[i] = K_ScsiProductIdentification[i];
#endif
for (i = 0; i < 4; i++)
#if (USBVendorConfiguration_OPTION == 1)
// Get the Product Revision from NAND Flash
pInquiry->productRevisionLevel[i] = G_ucStorData[i+408];
#else
// Get the Product Revision from ROM Table
pInquiry->productRevisionLevel[i] = K_ScsiProductRevisionLevel[i];
#endif
//patch4.5@richie@vender info end
//richie@1129
*pSize = SCSIDATA_INQUIRY_SIZE;
return(SCSIDATA_INQUIRY_SIZE);
}
//Chamber@031103
#if 0
//-----------------------------------------------------------------------------
//SCSICMD_ModeSelect06
//-----------------------------------------------------------------------------
UCHAR SCSICMD_ModeSelect06(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Mode Select 06 command (0x15)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
UCHAR status = TRUE;
PSCSICMD_06BYTE pSCSI06;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
*pSize = (ULONG) pSCSI06->dataLength;
return(status);
}
#endif
//patch4.5@richie@wp xp begin
//-----------------------------------------------------------------------------
//SCSICMD_ModeSense06
//-----------------------------------------------------------------------------
UCHAR SCSICMD_ModeSense06(PUCHAR pSCSI, PULONG pSize) USING_1
/*++
Routine Description:
process Mode Sense 06 command (0x1a)
Arguments:
pSCSI - pointer to SCSI command
pSize - data size processed
Return Value:
valid command or not
--*/
{
UCHAR status = TRUE;
PSCSICMD_06BYTE pSCSI06;
ULONG size = SCSIDATA_MODE06_PARAMETER_HEADER_SIZE;
pSCSI06 = (PSCSICMD_06BYTE) pSCSI;
/*
if ((pSCSI06->logicalBlockAddress & 0x3f00) == 0x3f00)
{
}
else
{
status = FALSE;
}
*/
//patch4.5@richie@wp xp begin
switch (pSCSI06->logicalBlockAddress & 0x3f00)
{
case 0x0100: //Media Type and Write Protect Page
size += SCSICMD_ModePage01(G_pucStorDataPointer + size);
break;
case 0x1b00: //Removable Block Access Capacities Page
size += SCSICMD_ModePage1b(G_pucStorDataPointer + size);
break;
case 0x1c00: //Timer and Protect Page
size += SCSICMD_ModePage1c(G_pucStorDataPointer + size);
break;
case 0x3f00: //Return All Pages
size += SCSICMD_ModePage01(G_pucStorDataPointer + size);
size += SCSICMD_ModePage1b(G_pucStorDataPointer + size);
size += SCSICMD_ModePage1c(G_pucStorDataPointer + size);
break;
default:
status = FALSE;
break;
}
//patch4.5@richie@wp xp end
if (status)
{
SCSICMD_Mode06ParameterHeader(G_pucStorDataPointer, size);
*pSize = size;
}
return(status);
}
//patch4.5@richie@wp xp end
//-----------------------------------------------------------------------------
//SCSICMD_ModePage01
//-----------------------------------------------------------------------------
ULONG SCSICMD_ModePage01(PUCHAR pPage) USING_1
/*++
Routine Description:
process Mode Page 01
Arguments:
pSCSI - pointer to SCSI command
Return Value:
size of data processed
--*/
{
PSCSIDATA_MODE_RW_ERR_RECOVERY_PAGE pPage01;
pPage01 = (PSCSIDATA_MODE_RW_ERR_RECOVERY_PAGE) pPage;
pPage01->BYTE0.PS = 0;
pPage01->BYTE0.reserved = 0;
pPage01->BYTE0.pageCode = 0x01;
pPage01->pageLength = SCSIDATA_MODE_RW_ERR_RECOVERY_PAGE_SIZE - 2;
pPage01->BYTE2.AWRE = 0;
pPage01->BYTE2.reserved0 = 0;
pPage01->BYTE2.RC = 0;
pPage01->BYTE2.reserved1 = 0;
pPage01->BYTE2.PER = 0;
pPage01->BYTE2.reserved2 = 0;
pPage01->BYTE2.DCR = 0;
pPage01->readRetryCount = 3;
pPage01->reserved0 = 0;
pPage01->writeRetryCount = 3;
pPage01->reserved1 = 0;
return(SCSIDATA_MODE_RW_ERR_RECOVERY_PAGE_SIZE);
}
//-----------------------------------------------------------------------------
//SCSICMD_ModePage1b
//-----------------------------------------------------------------------------
ULONG SCSICMD_ModePage1b(PUCHAR pPage) USING_1
/*++
Routine Description:
process Mode Page 1b
Arguments:
pSCSI - pointer to SCSI command
Return Value:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -