예제 #1
0
/*************************************************************************
	BOTStall
	========
		Local function to stall ongoing transfer
		
	Which endpoint to stall is determined by looking at the transfer
	direction intended by the host.

**************************************************************************/
static void BOTStall(void)
{
	if ((CBW.bmCBWFlags & 0x80) || (CBW.dwCBWDataTransferLength == 0)) {
		// stall data-in or CSW
		USBHwEPStall(MSC_BULK_IN_EP, TRUE);
	}
	else {
		// stall data-out
		USBHwEPStall(MSC_BULK_OUT_EP, TRUE);
	}
}
예제 #2
0
/**
	Handles the BOT bulk IN endpoint
		
	@param [in]	bEP			Endpoint number
	@param [in]	bEPStatus	Endpoint status (indicates NAK, STALL, etc)
		
 */
void MSCBotBulkIn(U8 bEP, U8 bEPStatus)
{
	// ignore events on stalled EP
	if (bEPStatus & EP_STATUS_STALLED) {
		return;
	}

	switch (eState) {
	
	case eCBW:
	case eDataOut:
		// ignore possibly old ACKs
		break;
	
	case eDataIn:
		HandleDataIn();
		break;
	
	case eCSW:
		// wait for an IN token, then send the CSW
		USBHwEPWrite(MSC_BULK_IN_EP, (U8 *)&CSW, 13);
		eState = eCBW;
		break;
		
	case eStalled:
		// keep stalling
		USBHwEPStall(MSC_BULK_IN_EP, TRUE);
		break;
		
	default:
		DBG("Invalid state %d\n", eState);
		ASSERT(FALSE);
		break;
	}
}
예제 #3
0
/**
	Local function to handle a standard endpoint request
		
	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in]		ppbData		Data buffer.

	@return TRUE if the request was handled successfully
 */
static int HandleStdEndPointReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
{
	unsigned char	*pbData = *ppbData;

	switch (pSetup->bRequest) {
	case REQ_GET_STATUS:
		// bit 0 = endpointed halted or not
		pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
		pbData[1] = 0;
		*piLen = 2;
		break;
		
	case REQ_CLEAR_FEATURE:
		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
			// clear HALT by unstalling
			USBHwEPStall(pSetup->wIndex, FALSE);
			break;
		}
		// only ENDPOINT_HALT defined for endpoints
		return FALSE;
	
	case REQ_SET_FEATURE:
		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
			// set HALT by stalling
			USBHwEPStall(pSetup->wIndex, TRUE);
			break;
		}
		// only ENDPOINT_HALT defined for endpoints
		return FALSE;

	case REQ_SYNCH_FRAME:
		DBG("EP req %d not implemented\n", pSetup->bRequest);
		return FALSE;

	default:
		DBG("Illegal EP req %d\n", pSetup->bRequest);
		return FALSE;
	}
	
	return TRUE;
}
예제 #4
0
파일: usbcontrol.c 프로젝트: OpenUAS/wasp
/*************************************************************************
	StallControlPipe
	================
		Local function to stall the control endpoint

**************************************************************************/
static void StallControlPipe(U8 bEPStat)
{
	U8	*pb;
	int	i;

	DBG("STALL on [");
// dump setup packet
	pb = (U8 *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(" %02x", *pb++);
	}
	DBG("] stat=%x\n", bEPStat);
	USBHwEPStall(0x80, TRUE);
}
예제 #5
0
/**
	Local function to stall the control endpoint

	@param [in]	bEPStat	Endpoint status
 */
static void StallControlPipe(U8 bEPStat __attribute__ ((unused)))
{
	U8	*pb __attribute__((unused));
	int	i;

	USBHwEPStall(0x80, TRUE);

// dump setup packet
	DBG("STALL on [");
	pb = (U8 *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(" %02x", *pb++);
	}
	DBG("] stat=%x\n", bEPStat);
}
예제 #6
0
/**
	Local function to stall the control endpoint

	@param [in]	bEPStat	Endpoint status
 */
static void StallControlPipe(uint8_t bEPStat)
{
	uint8_t	*pb;
	int	i;

	USBHwEPStall(0x80, true);

// dump setup packet
	DBG(UART0,"STALL on [");
	pb = (uint8_t *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(UART0," %02x", *pb++);
	}
	DBG(UART0,"] stat=%x\n", bEPStat);
}
/**
	Local function to stall the control endpoint
	
	@param [in]	bEPStat	Endpoint status
 */
static void StallControlPipe(unsigned char bEPStat)
{
	unsigned char	*pb;
	int	i;

	USBHwEPStall(0x80, TRUE);

// dump setup packet
	DBG("STALL on [");
	pb = (unsigned char *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(" %02x", *pb++);
	}
	DBG("] stat=%x\n", bEPStat);
}
예제 #8
0
/**
	Local function to stall the control endpoint
	
	@param [in]	bEPStat	Endpoint status
 */
static void StallControlPipe(unsigned char bEPStat)
{
	unsigned char	*pb;
	int	i;
	
	// Just for removing the unused variable warning
	(void) bEPStat;

	USBHwEPStall(0x80, TRUE);

// dump setup packet
	DBG("STALL on [");
	pb = (unsigned char *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(" %02x", *pb++);
	}
	DBG("] stat=%x\n", bEPStat);
}
예제 #9
0
/**
	Handles the BOT bulk OUT endpoint
		
	@param [in]	bEP			Endpoint number
	@param [in]	bEPStatus	Endpoint status (indicates NAK, STALL, etc)
		
 */
void MSCBotBulkOut(U8 bEP, U8 bEPStatus)
{
	int 	iLen, iChunk;
	BOOL	fHostIn, fDevIn;
	
	// ignore events on stalled EP
	if (bEPStatus & EP_STATUS_STALLED) {
		return;
	}

	switch (eState) {

	case eCBW:
		iLen = USBHwEPRead(bEP, (U8 *)&CBW, sizeof(CBW));

		// check if we got a good CBW
		if (!CheckCBW(&CBW, iLen)) {
			// see 6.6.1
			USBHwEPStall(MSC_BULK_IN_EP, TRUE);
			USBHwEPStall(MSC_BULK_OUT_EP, TRUE);
			eState = eStalled;
			break;
		}
		
		DBG("CBW: len=%d, flags=%x, cmd=%x, cmdlen=%d\n",
			CBW.dwCBWDataTransferLength, CBW.bmCBWFlags, CBW.CBWCB[0], CBW.bCBWCBLength);
		
		dwOffset = 0;
		dwTransferSize = 0;
		fHostIn = ((CBW.bmCBWFlags & 0x80) != 0);
		
		// verify request
		pbData = SCSIHandleCmd(CBW.CBWCB, CBW.bCBWCBLength, &iLen, &fDevIn);
		if (pbData == NULL) {
			// unknown command
			BOTStall();
			SendCSW(STATUS_FAILED);
			break;			
		}

		// rule: if device and host disagree on direction, send CSW with status 2
		if ((iLen > 0) &&
			((fHostIn && !fDevIn) ||
			(!fHostIn && fDevIn))) {
			DBG("Host and device disagree on direction\n");
			BOTStall();
			SendCSW(STATUS_PHASE_ERR);
			break;
		}

		// rule: if D > H, send CSW with status 2
		if (iLen > CBW.dwCBWDataTransferLength) {
			DBG("Negative residue\n");
			BOTStall();
			SendCSW(STATUS_PHASE_ERR);
			break;
		}

		dwTransferSize = iLen;
		if ((dwTransferSize == 0) || fDevIn) {
			// data from device-to-host
			eState = eDataIn;
			HandleDataIn();
		}
		else {
			// data from host-to-device
			eState = eDataOut;
		}
		break;
		
	case eDataOut:
		HandleDataOut();
		break;
		
	case eDataIn:
	case eCSW:
		iChunk = USBHwEPRead(bEP, NULL, 0);
		DBG("Phase error in state %d, %d bytes\n", eState, iChunk);
		eState = eCBW;
		break;
	
	case eStalled:
		// keep stalling
		USBHwEPStall(MSC_BULK_OUT_EP, TRUE);
		break;
		
	default:
		DBG("Invalid state %d\n", eState);
		ASSERT(FALSE);
		break;
	}
}