XilinxProcessorIPLib/drivers/usbpsu/examples/xusb_class_composite.c
void ParseCBW(struct Usb_DevData *InstancePtr, struct storage_if *f)
{
	u32	Offset;
	u8	Array[50];
	u8	Index;

	switch (f->cbw.CBWCB[0]) {
	case USB_RBC_INQUIRY:
		f->phase = USB_EP_STATE_DATA_IN;
		Index = (IsSuperSpeed(InstancePtr) != XST_SUCCESS) ? 0 : 1;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				(void *) &scsiInquiry[Index],
				sizeof(scsiInquiry[Index]));
		break;

	case USB_UFI_GET_CAP_LIST: {
		SCSI_CAP_LIST	*CapList;

		CapList = (SCSI_CAP_LIST *) txBuffer;
		CapList->listLength	= 8;
		CapList->descCode	= 3;
		CapList->numBlocks	= htonl(STORAGE_NUM_BLOCKS);
		CapList->blockLength = htons(STORAGE_BLOCK_SIZE);
		f->phase = USB_EP_STATE_DATA_IN;

		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				txBuffer, sizeof(SCSI_CAP_LIST));
	}
		break;

	case USB_RBC_READ_CAP: {
		SCSI_READ_CAPACITY	*Cap;

		Cap = (SCSI_READ_CAPACITY *) txBuffer;
		Cap->numBlocks = htonl(STORAGE_NUM_BLOCKS - 1);
		Cap->blockSize = htonl(STORAGE_BLOCK_SIZE);
		f->phase = USB_EP_STATE_DATA_IN;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP, txBuffer,
				sizeof(SCSI_READ_CAPACITY));
	}
		break;

	case USB_RBC_READ:
		Offset = htonl(((SCSI_READ_WRITE *) &f->cbw.CBWCB)-> block) *
			STORAGE_BLOCK_SIZE;
		f->phase = USB_EP_STATE_DATA_IN;
		u32 RetVal = EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				f->disk + Offset,
				htons(((SCSI_READ_WRITE *) &f->cbw.CBWCB)->
					length) * STORAGE_BLOCK_SIZE);
		if (RetVal != XST_SUCCESS) {
			xil_printf("Failed: READ Offset 0x%08x\n", Offset);
			return;
		}
		break;

	case USB_RBC_MODE_SENSE:
		f->phase = USB_EP_STATE_DATA_IN;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				(u8 *) "\003\000\000\000", 4);
		break;

	case USB_RBC_MODE_SELECT:
		f->phase = USB_EP_STATE_DATA_OUT;
		EpBufferRecv(InstancePtr->PrivateData, STORAGE_EP,
				(u8 *)Array, 24);
		break;

	case USB_RBC_TEST_UNIT_READY:
		SendCSW(InstancePtr, f, 0);
		break;

	case USB_RBC_MEDIUM_REMOVAL:
		SendCSW(InstancePtr, f, 0);
		break;

	case USB_RBC_VERIFY:
		SendCSW(InstancePtr, f, 0);
		break;

	case USB_RBC_WRITE:
		Offset = htonl(((SCSI_READ_WRITE *) &f->cbw.CBWCB)-> block) *
			STORAGE_BLOCK_SIZE;
		f->diskptr = f->disk + Offset;
		f->bytesleft = htons(((SCSI_READ_WRITE *) &f->cbw.CBWCB)->length) *
			STORAGE_BLOCK_SIZE;
		f->phase = USB_EP_STATE_DATA_OUT;

		EpBufferRecv(InstancePtr->PrivateData, STORAGE_EP,
				f->disk + Offset, f->bytesleft);
		break;

	case USB_RBC_STARTSTOP_UNIT: {
		u8 immed;

		immed = ((SCSI_START_STOP *) &f->cbw.CBWCB)->immed;
		/* If the immediate bit is 0 we are supposed to send
		 * a success status.
		 */
		if (0 == (immed & 0x01)) {
			SendCSW(InstancePtr, f, 0);
		}
		break;
	}

	case USB_RBC_REQUEST_SENSE:
		break;

	case USB_SYNC_SCSI:
		SendCSW(InstancePtr, f, 0);
		break;
	}
}
/*****************************************************************************/
/**
* This function handles Reduced Block Command (RBC) requests from the host.
*
* @param	InstancePtr is a pointer to Usb_DevData instance of the controller.
* @param	f is a pointer to storage interface
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
This function handles Reduced Block Command (RBC) requests from the host.
This function handles Reduced Block Command ( RBC ) requests from the host .
void ParseCBW(struct Usb_DevData *InstancePtr, struct storage_if *f)
{
	u32	Offset;
	u8	Array[50];
	u8	Index;
	switch (f->cbw.CBWCB[0]) {
	case USB_RBC_INQUIRY:
		f->phase = USB_EP_STATE_DATA_IN;
		Index = (IsSuperSpeed(InstancePtr) != XST_SUCCESS) ? 0 : 1;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				(void *) &scsiInquiry[Index],
				sizeof(scsiInquiry[Index]));
		break;
	case USB_UFI_GET_CAP_LIST: {
		SCSI_CAP_LIST	*CapList;
		CapList = (SCSI_CAP_LIST *) txBuffer;
		CapList->listLength	= 8;
		CapList->descCode	= 3;
		CapList->numBlocks	= htonl(STORAGE_NUM_BLOCKS);
		CapList->blockLength = htons(STORAGE_BLOCK_SIZE);
		f->phase = USB_EP_STATE_DATA_IN;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				txBuffer, sizeof(SCSI_CAP_LIST));
	}
		break;
	case USB_RBC_READ_CAP: {
		SCSI_READ_CAPACITY	*Cap;
		Cap = (SCSI_READ_CAPACITY *) txBuffer;
		Cap->numBlocks = htonl(STORAGE_NUM_BLOCKS - 1);
		Cap->blockSize = htonl(STORAGE_BLOCK_SIZE);
		f->phase = USB_EP_STATE_DATA_IN;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP, txBuffer,
				sizeof(SCSI_READ_CAPACITY));
	}
		break;
	case USB_RBC_READ:
		Offset = htonl(((SCSI_READ_WRITE *) &f->cbw.CBWCB)-> block) *
			STORAGE_BLOCK_SIZE;
		f->phase = USB_EP_STATE_DATA_IN;
		u32 RetVal = EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				f->disk + Offset,
				htons(((SCSI_READ_WRITE *) &f->cbw.CBWCB)->
					length) * STORAGE_BLOCK_SIZE);
		if (RetVal != XST_SUCCESS) {
			xil_printf("Failed: READ Offset 0x%08x\n", Offset);
			return;
		}
		break;
	case USB_RBC_MODE_SENSE:
		f->phase = USB_EP_STATE_DATA_IN;
		EpBufferSend(InstancePtr->PrivateData, STORAGE_EP,
				(u8 *) "\003\000\000\000", 4);
		break;
	case USB_RBC_MODE_SELECT:
		f->phase = USB_EP_STATE_DATA_OUT;
		EpBufferRecv(InstancePtr->PrivateData, STORAGE_EP,
				(u8 *)Array, 24);
		break;
	case USB_RBC_TEST_UNIT_READY:
		SendCSW(InstancePtr, f, 0);
		break;
	case USB_RBC_MEDIUM_REMOVAL:
		SendCSW(InstancePtr, f, 0);
		break;
	case USB_RBC_VERIFY:
		SendCSW(InstancePtr, f, 0);
		break;
	case USB_RBC_WRITE:
		Offset = htonl(((SCSI_READ_WRITE *) &f->cbw.CBWCB)-> block) *
			STORAGE_BLOCK_SIZE;
		f->diskptr = f->disk + Offset;
		f->bytesleft = htons(((SCSI_READ_WRITE *) &f->cbw.CBWCB)->length) *
			STORAGE_BLOCK_SIZE;
		f->phase = USB_EP_STATE_DATA_OUT;
		EpBufferRecv(InstancePtr->PrivateData, STORAGE_EP,
				f->disk + Offset, f->bytesleft);
		break;
	case USB_RBC_STARTSTOP_UNIT: {
		u8 immed;
		immed = ((SCSI_START_STOP *) &f->cbw.CBWCB)->immed;
		if (0 == (immed & 0x01)) {
			SendCSW(InstancePtr, f, 0);
		}
		break;
	}
	case USB_RBC_REQUEST_SENSE:
		break;
	case USB_SYNC_SCSI:
		SendCSW(InstancePtr, f, 0);
		break;
	}
}
void ParseCBW ( struct Usb_DevData * InstancePtr , struct storage_if * f ) { u32 Offset ; u8 Array [ 50 ] ; u8 Index ; switch ( f -> cbw . CBWCB [ 0 ] ) { case USB_RBC_INQUIRY : f -> phase = USB_EP_STATE_DATA_IN ; Index = ( IsSuperSpeed ( InstancePtr ) != XST_SUCCESS ) ? 0 : 1 ; EpBufferSend ( InstancePtr -> PrivateData , STORAGE_EP , ( void * ) & scsiInquiry [ Index ] , sizeof ( scsiInquiry [ Index ] ) ) ; break ; case USB_UFI_GET_CAP_LIST : { SCSI_CAP_LIST * CapList ; CapList = ( SCSI_CAP_LIST * ) txBuffer ; CapList -> listLength = 8 ; CapList -> descCode = 3 ; CapList -> numBlocks = htonl ( STORAGE_NUM_BLOCKS ) ; CapList -> blockLength = htons ( STORAGE_BLOCK_SIZE ) ; f -> phase = USB_EP_STATE_DATA_IN ; EpBufferSend ( InstancePtr -> PrivateData , STORAGE_EP , txBuffer , sizeof ( SCSI_CAP_LIST ) ) ; } break ; case USB_RBC_READ_CAP : { SCSI_READ_CAPACITY * Cap ; Cap = ( SCSI_READ_CAPACITY * ) txBuffer ; Cap -> numBlocks = htonl ( STORAGE_NUM_BLOCKS - 1 ) ; Cap -> blockSize = htonl ( STORAGE_BLOCK_SIZE ) ; f -> phase = USB_EP_STATE_DATA_IN ; EpBufferSend ( InstancePtr -> PrivateData , STORAGE_EP , txBuffer , sizeof ( SCSI_READ_CAPACITY ) ) ; } break ; case USB_RBC_READ : Offset = htonl ( ( ( SCSI_READ_WRITE * ) & f -> cbw . CBWCB ) -> block ) * STORAGE_BLOCK_SIZE ; f -> phase = USB_EP_STATE_DATA_IN ; u32 RetVal = EpBufferSend ( InstancePtr -> PrivateData , STORAGE_EP , f -> disk + Offset , htons ( ( ( SCSI_READ_WRITE * ) & f -> cbw . CBWCB ) -> length ) * STORAGE_BLOCK_SIZE ) ; if ( RetVal != XST_SUCCESS ) { xil_printf ( " \n " , Offset ) ; return ; } break ; case USB_RBC_MODE_SENSE : f -> phase = USB_EP_STATE_DATA_IN ; EpBufferSend ( InstancePtr -> PrivateData , STORAGE_EP , ( u8 * ) " \003 \000 \000 \000 " , 4 ) ; break ; case USB_RBC_MODE_SELECT : f -> phase = USB_EP_STATE_DATA_OUT ; EpBufferRecv ( InstancePtr -> PrivateData , STORAGE_EP , ( u8 * ) Array , 24 ) ; break ; case USB_RBC_TEST_UNIT_READY : SendCSW ( InstancePtr , f , 0 ) ; break ; case USB_RBC_MEDIUM_REMOVAL : SendCSW ( InstancePtr , f , 0 ) ; break ; case USB_RBC_VERIFY : SendCSW ( InstancePtr , f , 0 ) ; break ; case USB_RBC_WRITE : Offset = htonl ( ( ( SCSI_READ_WRITE * ) & f -> cbw . CBWCB ) -> block ) * STORAGE_BLOCK_SIZE ; f -> diskptr = f -> disk + Offset ; f -> bytesleft = htons ( ( ( SCSI_READ_WRITE * ) & f -> cbw . CBWCB ) -> length ) * STORAGE_BLOCK_SIZE ; f -> phase = USB_EP_STATE_DATA_OUT ; EpBufferRecv ( InstancePtr -> PrivateData , STORAGE_EP , f -> disk + Offset , f -> bytesleft ) ; break ; case USB_RBC_STARTSTOP_UNIT : { u8 immed ; immed = ( ( SCSI_START_STOP * ) & f -> cbw . CBWCB ) -> immed ; if ( 0 == ( immed & 0x01 ) ) { SendCSW ( InstancePtr , f , 0 ) ; } break ; } case USB_RBC_REQUEST_SENSE : break ; case USB_SYNC_SCSI : SendCSW ( InstancePtr , f , 0 ) ; break ; } }
This function handles Reduced Block Command (RBC) requests from the host.
This function handles Reduced Block Command ( RBC ) requests from the host .
/* If the immediate bit is 0 we are supposed to send
		 * a success status.
		 */