📄 usb_tpbulk.c
字号:
/*********************************************************************
** Module Name: USB_TPBulk.c **
** Author: ZhangQuan **
** Version: 1.0 **
** CreateDate: 2001-05-18 **
** Description: Declarations for Supports the USB Mass **
** Storage Class Rev. 1.0 **
** Remark: **
** Revision History: **
**********************************************************************/
//#include <linux/interrupt.h>
#include "DataType.h"
#include "MC68VZ328.h"
//#define BULK_DEBUG 0
void TPBulk_Reset(void);
void TPBulk_WrongCommand(void);
void TPBulk_StallMainRxEP(void);
void TPBulk_StallMainTxEP(void);
void TPBulk_StallMainEP(void);
void TPBulk_GetMaxLUN(void);
void TPBulk_StallEP0(void);
//*******************************************************************
//**** Following are the funs for Mass storage special function ****
//**** Bulk-Only Transport Description P7/22 ****
//**** Two special functions: ****
//**** (1)Bulk_Only Mass Storage Reset: void TPBulk_Reset() ****
//**** (2)Get Max LUN command:UCHAR TPBulk_GetMaxLUN(void) ****
//**** And a wrong command processing function ****
//**** void TPBulk_WrongCommand(void) ****
//*******************************************************************
// **************** Bulk-Only TP- Bulk Hanlder **********************
void TPBulk_ClassRequestHandler(void)
{
switch(ControlData.DeviceRequest.bRequest)
{
case 0xff: //It is a Bulk-only Mass storage reset command
TPBulk_Reset();
break;
case 0xfe: //It is Get Max LUN command
TPBulk_GetMaxLUN();
break;
default: //Invalid Bulk_Only storage command
TPBulk_WrongCommand();
break;
}
}
// **************** Bulk-Only RESET command *************************
void TPBulk_Reset()
{
// Check it is a valid command or not? In Bulk-Only Transport P7/22;
if( ControlData.DeviceRequest.wIndex == 0 &&
ControlData.DeviceRequest.wLength == 0 &&
ControlData.DeviceRequest.wValue == 0 &&
ControlData.DeviceRequest.bmRequestType == 0x21)
{
//Endpoint 2 Enter "IDLE" phase
bD12flags.bits.BOT_state = USBFSM4BOT_IDLE;
//Tell Host this command is processed by send a zero package;
//Endpoint 0 Enter "Handshake" phase
TPBulk_SingleTransmitEP0(0,0);
}
else
{
printk(" Invalid Mass reset command;\n");
//Default pipe enters STALL phase ,Host will terminate the transfer
TPBulk_StallEP0();
}
}
// **************** Bulk-Only GET MAX LUN Command *******************
//UCHAR TPBulk_GetMaxLUN(void)
void TPBulk_GetMaxLUN(void)
{
UCHAR c;
// Check it is a valid command or not? In Bulk-Only Transport P7/22;
if( ControlData.DeviceRequest.wValue == 0 &&
ControlData.DeviceRequest.wIndex == 0 &&
ControlData.DeviceRequest.wLength == 1 &&
ControlData.DeviceRequest.bmRequestType == 0xa1)
{
//There is only one LUN in all, so MaxLUN==0;
c = 0;
//Tell Host this command is processed and has one LUN number ;
//Endpoint 0 Enter "Handshake" phase
TPBulk_SingleTransmitEP0(&c,1);
}
else
{
printk(" Invalid Get Max LUN command ;\n");
//Default pipe enters STALL phase ,Host will terminate the transfer
TPBulk_StallEP0();
}
}
// **************** Bulk-Only Wrong Command *************************
void TPBulk_WrongCommand(void)
{
TPBulk_StallEP0();
}
//*******************************************************************
//**** About are the functions for Mass storage special function ****
//*******************************************************************
//*******************************************************************
//**** Following is the function for CBW processing ****
//**** Bulk-Only Transport Description P13/22 ****
//*******************************************************************
void TPBulk_CBWHandler(void)
{
UCHAR CBWsize;
ULONG i;
// Get CBW package including CBW and atapi command package.
//CBWsize = D12_ReadMainEndpoint((UCHAR *)&TPBulk_CommandBlock);
cli();
CBWsize = D12_ReadMainEndpoint(CBWBuf);
sti();
TPBulk_CommandBlock_dCBW_Signature=((TPBulk_CommandBlock_dCBW_Signature>>24) & 0xff) |
((TPBulk_CommandBlock_dCBW_Signature>>8) & 0xff00) |
((TPBulk_CommandBlock_dCBW_Signature<<8) & 0xff0000) |
((TPBulk_CommandBlock_dCBW_Signature<<24) & 0xff000000);
TPBulk_CommandBlock_dCBW_DataXferLen=((TPBulk_CommandBlock_dCBW_DataXferLen>>24) & 0xff) |
((TPBulk_CommandBlock_dCBW_DataXferLen>>8) & 0xff00) |
((TPBulk_CommandBlock_dCBW_DataXferLen<<8) & 0xff0000) |
((TPBulk_CommandBlock_dCBW_DataXferLen<<24) & 0xff000000);
//-------------------------------------------------------------------
//Judge CBW is valid or not;
//Four conditions:
//(1): size is equal to 31 bytes or not?
//(2): signature is equal to 0x43425355 or not;
//(3): logic unit is less than 2 or not?
//(4): atapi command length should be equal to 12 bytes;
//If four conditions are all true, it is a valid CBW;
//else it is a invalid CBW.
//-------------------------------------------------------------------
if(31/*sizeof(CBW)*/==CBWsize &&
TPBulk_CommandBlock_dCBW_Signature == CBW_SIGNATURE &&
TPBulk_CommandBlock_bCBW_LUN < 2 &&
TPBulk_CommandBlock_bCBW_CDBLen == 12)
{
IOZip_AtapiHandle();
}
else
{
printk("InValid CBW\n");
// for Invalid CBW, Stall Both Bulk Endpoints Let host issue reset recovery
cli();
TPBulk_StallMainEP();
sti();
}
}
//*******************************************************************
//**** Following is the function for CSW processing ****
//**** Bulk-Only Transport Description P14/22 ****
//**** Tell the Host the result of the command's execution ****
//**** statues 1: Good: execution successfully ****
//**** statues 2: Fail: command failed ****
//**** statues 3: Bad: execution badly(Wrong command or others)
//**** And need Host to reset the device ****
//**** These statues are gotten from TPBulk_ErrorHandler() ****
//*******************************************************************
void TPBulk_CSWHandler(void)
{
cli();
bD12flags.bits.BOT_state = USBFSM4BOT_CSW;
D12_WriteEndpoint(5, CSWBuf, 13);
sti();
}
//*******************************************************************
//**** Following is the function for ERROR processing ****
//**** Bulk-Only Transport Description P19/22 ****
//**** Tell the Host the result of the command's execution ****
//**** statues 1: Good: execution successfully ****
//**** statues 2: Fail: execution failed ****
//**** statues 3: Bad: execution badly(Wrong command or others)
//*******************************************************************
//**** Hn: Host expects no data transfers
//**** Hi: Host expects to receive data from device
//**** Ho: Host expects to send data to device
//**** Dn: Device intends to transfer no data
//**** Di: Device intends to send data to host
//**** Do: Device intends to receive data from host
//*******************************************************************
void TPBulk_ErrorHandler(UCHAR HostDevCase, ULONG DevXferCount)
{
switch(HostDevCase)
{
case CASEOK:
TPBulk_CommandStatus_dCSW_DataResidue = 0;
TPBulk_CommandStatus_bCSW_Status = CSW_GOOD;
break;
case CASE1: // Hn=Dn
case CASE6: // Hi=Di
case CASE12: // Ho=Do
TPBulk_CommandStatus_dCSW_DataResidue = 0;
// TPBulk_CommandStatus.bCSW_Status = CSW_GOOD;
break;
case CASE4: // Hi>Dn
case CASE5: // Hi>Di
TPBulk_StallMainTxEP();
TPBulk_CommandStatus_dCSW_DataResidue = TPBulk_CommandBlock_dCBW_DataXferLen - DevXferCount;
TPBulk_CommandStatus_bCSW_Status = CSW_FAIL;
break;
case CASE9: // Ho>Dn
case CASE11: // Ho>Do
TPBulk_StallMainRxEP();
TPBulk_CommandStatus_dCSW_DataResidue = TPBulk_CommandBlock_dCBW_DataXferLen - DevXferCount;
TPBulk_CommandStatus_bCSW_Status = CSW_FAIL;
break;
case CASE2: // Hn<Di
case CASE3: // Hn<Do
TPBulk_StallMainTxEP();
TPBulk_CommandStatus_dCSW_DataResidue = 0;
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE8: // Hi<>Do
TPBulk_StallMainTxEP();
TPBulk_CommandStatus_dCSW_DataResidue = TPBulk_CommandBlock_dCBW_DataXferLen;
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE10: // Ho<>Di
TPBulk_StallMainRxEP();
TPBulk_CommandStatus_dCSW_DataResidue = TPBulk_CommandBlock_dCBW_DataXferLen;
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE7: // Hi<Di
TPBulk_StallMainTxEP();
TPBulk_CommandStatus_dCSW_DataResidue = -1; /* return non-zero value*/
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
case CASE13: // Ho<Do
TPBulk_StallMainRxEP();
TPBulk_CommandStatus_dCSW_DataResidue = -1; /* return non-zero value*/
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
case CASECBW: // invalid CBW
TPBulk_StallMainEP();
TPBulk_CommandStatus_bCSW_Status = CSW_PHASE_ERROR;
break;
default:
printk("Fatal error !\n");
break;
}
TPBulk_CommandStatus_dCSW_Signature = CSW_SIGNATURE;
TPBulk_CommandStatus_dCSW_Tag = TPBulk_CommandBlock_dCBW_Tag;
}
//*******************************************************************
//****Following are the PRIVATE subfunctions used for above function
//*******************************************************************
//**** Host will terminate the transfer in PIPE 0,1
void TPBulk_StallEP0(void)
{
bD12flags.bits.DCP_state = USBFSM4DCP_STALL;
stall_ep0();
}
//**** Device thansfers the data to Host
void TPBulk_SingleTransmitEP0(UCHAR *buf, UCHAR len)
{
single_transmit(buf, len);
bD12flags.bits.DCP_state = USBFSM4DCP_HANDSHAKE;
}
//**** Host will terminate the transfer in PIPE 4
void TPBulk_StallMainRxEP(void)
{
D12_SetEndpointStatus(4, 1);
}
//**** Host will terminate the transfer in PIPE 5
void TPBulk_StallMainTxEP(void)
{
D12_SetEndpointStatus(5, 1);
}
//**** Host will terminate the transfer in PIPE 4,5
void TPBulk_StallMainEP(void)
{
D12_SetEndpointStatus(4, 1);
D12_SetEndpointStatus(5, 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -