?? usbtargrbccmd.c
字號:
/* usbTargRbcCmd.c - Reduced Block Command set routine library *//* Copyright 2004 Wind River Systems, Inc. *//*DESCRIPTIONThis module implements a framework based on the RBC (Reduced Block Command)set. These routines are invoked by the USB 2.0 mass storage driver basedon the contents of the USB CBW (command block wrapper).INCLUDES: vxWorks.h, disFsLib.h, dcacheCbio.h, ramDrv.h, usrFdiskPartLib.h, usb/usbPlatform.h, usb/usb.h, usb/target/usbTargLib.h, drv/usb/target/usbTargMsLib.h, drv/usb/target/usbTargRbcCmd.h*//*modification history--------------------01g,02aug04,mta Merge from Integration Branch to development branch01f,29jul04,pdg Diab warnings fixed01e,23jul04,hch change vxworks.h to vxWorks.h01d,23jul04,ami Coding Convention Changes01c,21jul04,pdg Changes for windows host01b,19jul04,hch created the file element01a,12mar04,jac written.*//* includes */#include "vxWorks.h"#include "dosFsLib.h"#include "dcacheCbio.h"#include "ramDrv.h"#include "ramDiskCbio.h"#include "usrFdiskPartLib.h"#include "usb/usbPlatform.h"#include "usb/usb.h"#include "usb/usbLib.h"#include "usb/target/usbTargLib.h"#include "drv/usb/usbBulkDevLib.h"#include "drv/usb/target/usbTargMsLib.h"#include "drv/usb/target/usbTargRbcCmd.h"/* defines */#define DATA_BUFFER_LEN BYTES_PER_BLOCK * NUM_BLOCKS /* data buffer */#define RBC_MODE_PARAMETER_PAGE 0x06 /* RBC Mode Page */ #define BLK_DEV_NAME "/bd/0" /* bulk device name */#ifdef USE_RBC_SUBCLASS #define PERIPHERAL_DEVICE_TYPE 0xe /* Simplified direct-access */ /* device (RBC) */#elif defined(USE_SCSI_SUBCLASS) #define PERIPHERAL_DEVICE_TYPE 0x0 /* Direct-access device */#else #error PERIPHERAL_DEVICE_TYPE undefined#endif#define PERIPHERAL_DEVICE_QUAL 0x0 /* device qualifier */ #define MIN_STD_INQUIRY_LGTH 36 /* inquiry length */#define VPD_SUPPORTED_PAGE_CODE 0x0 /* VPD page code */#define VPD_UNIT_SERIAL_NUM_PAGE_CODE 0x80 /* VPD serial page number */#define VPD_DEVICE_ID_PAGE_CODE 0x83 /* VPD device id page code */#define VENDOR_SPECIFIC_23_LENGTH 12 /* vendor specific length *//* locals */LOCAL VPD_SUPPORTED_PAGE g_vpdSupportedPage = { ((PERIPHERAL_DEVICE_QUAL & 0x7) << 5) | PERIPHERAL_DEVICE_TYPE, /* device qualifier and device type */ 0x0, /* this page has page code = 0 */ 0x0, /* reserved */ 0x3, /* page length is three */ VPD_SUPPORTED_PAGE_CODE, /* page zero is supported */ VPD_UNIT_SERIAL_NUM_PAGE_CODE, /* serial num page */ VPD_DEVICE_ID_PAGE_CODE /* device ID page */ };LOCAL VPD_DEVICE_ID_PAGE g_vpdDevIdPage = { ((PERIPHERAL_DEVICE_QUAL & 0x7) << 5) | PERIPHERAL_DEVICE_TYPE, /* device qualifier and device type */ VPD_DEVICE_ID_PAGE_CODE, /* this page code */ 0x0, /* reserved */ 0x1, /* page length is one */ { 0x2, /* code set is ASCI */ 0x1, /* association is zero, ID type is Vendor ID */ 0x0, /* reserved */ DEVICE_ID_LGTH, /* device ID length */ {DEVICE_ID} /* the ASCI device ID */ } };LOCAL VPD_UNIT_SERIAL_NUM_PAGE g_vpdSerialNumPage = { ((PERIPHERAL_DEVICE_QUAL & 0x7) << 5) | PERIPHERAL_DEVICE_TYPE, /* device qualifier and device type */ VPD_UNIT_SERIAL_NUM_PAGE_CODE, /* this page code */ 0x0, /* reserved */ 24, /* this page length (n - 3) */ { '0',0, /* SerialNumber */ '0',0, '0',0, '0',0, '0',0, '0',0, '0',0, '0',0, '0',0, '0',0, '0',0, '0',0 } };LOCAL COMMAND_DATA g_cmdData = { ((PERIPHERAL_DEVICE_QUAL & 0x7) << 5) | PERIPHERAL_DEVICE_TYPE, /* device qualifier and device type */ 0x1, /* The device server does not support the tested SCSI */ /* operation code. All data after byte 1 is undefined */ { 0x0, /* reserved fields */ 0x0 }, 0x2, /* cdbSize */ 0x0, /* cdbOpCode */ 0x0 /* cdbUsageMap */ };LOCAL STD_INQUIRY_DATA g_stdInquiryData = { ((PERIPHERAL_DEVICE_QUAL & 0x7) << 5) | PERIPHERAL_DEVICE_TYPE, /* device qualifier and device type */ 0x80, /* media is removable */ 0x0, /* The device does not claim conformance to any standard. */ 0x2, /* data format corresponds to this standard */ 91, /* n - 4 (95-4) */ 0x0, /* sccs = 0, no embedded storage ctrl */ 0x0, /* BQUE ENCSERV VS MULTIP MCHNGR Obsolete Obsolete ADDR16 */ 0x0, /* RELADR Obsolete WBUS16 SYNC LINKED Obsolete CMDQUE VS */ { 'W','R','S',' ', /* vendorId[8] */ ' ',' ',' ',' ' }, { 'U','S','B',' ', /* productId[16] */ 'M','a','s','s', ' ','S','t','o', 'r','a','g','e' }, { '1','.','0','0' /* productRevisionLevel[4] */ }, { 0, 0, 0, 0, /* vendorSpecific[20] */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0x0, /* Reserved CLOCKING QAS IUS */ 0x0, { /* UINT16 VersionDescriptor[8] */ 0x023C, /* RBC ANSI NCITS.330:2000 */ 0x0260, /* SPC-2 (no version claimed) */ 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, /* UINT8 Reserved3[22] */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };LOCAL MODE_PARAMETER_HEADER g_deviceHdr = { sizeof(MODE_PARAMETER_LIST)-1, /* data len */ 0x0, /* reqd. by RBC */ 0x0, /* reqd. by RBC */ 0x0 /* reqd. by RBC */ };LOCAL MODE_PARAMETER_LIST g_deviceParamList = { /* g_deviceHdr */ { sizeof (MODE_PARAMETER_LIST)-1, /* data len */ 0x0, /* reqd. by RBC */ 0x0, /* reqd. by RBC */ 0x0 /* reqd. by RBC */ }, /* g_deviceParams */ { 0x80 | RBC_MODE_PARAMETER_PAGE, /* bit 7 is page save (always 1), */ /* page code is RBC (0x6) */ 0xb, /* page length */ 0x1, /* writeCacheDisable: return status */ /*after a WRITE */ { /*Logical block Size = 512 Bytes (0x200) */ (BYTES_PER_BLOCK & 0xff00) >> 8, BYTES_PER_BLOCK & 0xff }, { /*Number of logical blocks = 400 (0x190) */ (NUM_BLOCKS & 0xff000000) >> 24, (NUM_BLOCKS & 0x00ff0000) >> 16, (NUM_BLOCKS & 0x0000ff00) >> 8, (NUM_BLOCKS & 0x000000ff), }, 0xFF, /* highest possible Power/Peformance */ 0x3, /* read and write access, media cannot */ /*be formatted or locked */ 0x0 /* reserved */ } };LOCAL MODE_PARAMETER_LIST g_deviceParamListMask = { /* g_deviceHdr */ { sizeof (MODE_PARAMETER_LIST)-1, /* data len */ 0x0, /* reqd. by RBC */ 0x0, /* reqd. by RBC */ 0x0 /* reqd. by RBC */ }, /* g_deviceParamsMask */ { 0x80 | RBC_MODE_PARAMETER_PAGE, /* bit 7 is page save (always 1), */ /* page code is RBC (0x6) */ 0x0, /* page length */ 0x0, /* write cached disabled bit */ { /* Logical block Size */ 0x00, 0x00 }, { /* Number of logical blocks */ 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x0, /* highest possible Power/Peformance */ 0x0, /* READD WRITED FORMATD LOCKD */ 0x0 /* reserved */ }};LOCAL SENSE_DATA g_senseData = { 0x70, /* VALID = 0, responseCode = current */ /*sense data */ 0x0, /* obsolete */ SCSI_SENSE_NO_SENSE, /* senseKey = NO SENSE */ { 0x0, /* info fields all zero */ 0x0, 0x0, 0x0 }, 0xa, /* additionalSenseLgth always 0xa */ { 0x0, /* cmdSpecificInfo[4] depends on command */ 0x0, 0x0, 0x0 }, SCSI_ADSENSE_NO_SENSE, /* ASC = NO ADDITIONAL SENSE INFORMATION */ 0x0, /* ASCQ = NO ADDITIONAL SENSE INFORMATION */ 0x0, /* fieldReplaceableUnitCode: 0 = no failures */ /* or no data avail */ { 0x0, /* bit 7 = 0 (invalid) => sense key specific */ /* data not defined */ 0x0, 0x0 } };LOCAL CAPACITY_DATA g_capacityData = { /* capacity data for the blocks */ ((NUM_BLOCKS - 1) & 0xff000000) >> 24, ((NUM_BLOCKS - 1) & 0x00ff0000) >> 16, ((NUM_BLOCKS - 1) & 0x0000ff00) >> 8, (NUM_BLOCKS - 1) & 0x000000ff, (BYTES_PER_BLOCK & 0xff000000) >> 24, (BYTES_PER_BLOCK & 0x00ff0000) >> 16, (BYTES_PER_BLOCK & 0x0000ff00) >> 8, BYTES_PER_BLOCK & 0x000000ff };LOCAL UINT8 g_VendorSpecificData[VENDOR_SPECIFIC_23_LENGTH] = { 0, 0, 0, 0x08, 0x02, 0x54, 0x29, 0x7f, 0, 0, 0x02, 0 };LOCAL UINT8 g_dataInBfr[DATA_BUFFER_LEN]; /* Bulk In buffer */LOCAL UINT8 g_dataOutBfr[DATA_BUFFER_LEN]; /* Bulk Out buffer */LOCAL BOOL g_mediaRemoved = FALSE; /* TRUE - if media removed */LOCAL BOOL g_mediaReady = TRUE; /* TRUE - if media ready */LOCAL BOOL g_mediaPrevent = FALSE; LOCAL UINT8 g_pwrConditions = 0; /* power conditions */pVOID g_rbcBlkDev = NULL;/********************************************************************************* usbTargRbcSenseDataSet - set sense data** This routine is used locally to set the sense key, additional sense code, * and additional sense code qualifier of the current sense data.** RETURNS: OK* * ERRNO:* none.** \NOMANUAL*/LOCAL STATUS usbTargRbcSenseDataSet ( UINT8 senseKey, /* the SCSI sense key */ UINT8 asc, /* additional sense code */ UINT8 ascq /* additional sense code qualifier */ ) { g_senseData.senseKey = senseKey; g_senseData.asc = asc; g_senseData.ascq = ascq; return(OK); }/********************************************************************************** usbTargRbcRead - read data from the RBC device** This routine reads data from the RBC block I/O device.** RETURNS: OK or ERROR* * ERRNO: none* none*/STATUS usbTargRbcRead ( UINT8 arg[10], /* the RBC command */ UINT8 ** ppData, /* pointer to where data will be read by host */ UINT32 * pSize /* size of data to be read */ ) { UINT32 startBlk = 0; /* start block */ UINT16 numBlks = 0; /* number of blocks */ CBIO_DEV_ID cbio; /* CBIO_DEV_ID */ STATUS retVal; /* status */ cookie_t cookie; /* cookie_t */ cbio = (CBIO_DEV_ID)usbTargRbcBlockDevGet (); /* get starting blk number */ startBlk = (arg[2] << 24) | (arg[3] << 16)| (arg[4] << 8) | arg[5]; /* get number of blks */ numBlks = (arg[7] << 8) | arg[8]; /* perform blk read */ retVal = cbioBlkRW (cbio, startBlk, numBlks, (addr_t)&g_dataInBfr[0], CBIO_READ, &cookie); *ppData = &g_dataInBfr[0]; *pSize = BYTES_PER_BLOCK * numBlks; if (retVal == ERROR) { usbDbgPrint ("usbTargRbcRead: cbioBlkRW returned ERROR\n"); return(ERROR); } /* set sense data to no sense */ usbTargRbcSenseDataSet(SCSI_SENSE_NO_SENSE,SCSI_ADSENSE_NO_SENSE,0x0); return(OK); }/******************************************************************************** usbTargRbcCapacityRead - read the capacity of the RBC device** This routine reads the capacity of the RBC block I/O device.** RETURNS: OK or ERROR* * ERRNO: * none.*/STATUS usbTargRbcCapacityRead ( UINT8 arg[10], /* RBC command */ UINT8 **ppData, /* point to capacity data */ UINT32 *pSize /* size of capacity */ ) { if (!g_mediaRemoved) { *ppData = (UINT8 *)&g_capacityData; *pSize = sizeof(CAPACITY_DATA); /* set sense data to no sense */ usbTargRbcSenseDataSet(SCSI_SENSE_NO_SENSE,SCSI_ADSENSE_NO_SENSE,0x0); } else { *ppData = NULL; *pSize = 0; /* * set sense key to NOT READY (02h), and an ASC of LOGICAL UNIT * NOT READY (04h). set ASCQ to cause not reportable (0x0) */ usbTargRbcSenseDataSet (SCSI_SENSE_NOT_READY, SCSI_ADSENSE_LUN_NOT_READY, 0x0); return(ERROR); } return(OK); }/********************************************************************************* usbTargRbcStartStop - start or stop the RBC device** This routine starts or stops the RBC block I/O device.** RETURNS: OK or ERROR* * ERRNO:* none*/STATUS usbTargRbcStartStop ( UINT8 arg[6] /* the RBC command */ ) { UINT8 pwrConditions = arg[4] & 0xf0; /* power conditions */ UINT8 loEj = arg[4] & 0x2; /* load eject */ UINT8 start = arg[4] & 0x1; /* enable or disable media */ /* access operations */ if (pwrConditions != 0) { switch (pwrConditions) { case 1: /* Place device in Active condition */ break; case 2: /* Place device in Idle condition */ break;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -