📄 usbmpc5200sffdevlib.c
字号:
/* includes */
#include "vxWorks.h"
#include "string.h"
#include "errno.h"
#include "errnoLib.h"
#include "ioLib.h"
#include "blkIo.h"
#include "stdio.h"
#include "logLib.h"
#include "dosFsLib.h"
#include "usb/usbPlatform.h"
#include "usb/ossLib.h"
#include "usb/usb.h"
#include "usb/usbListLib.h"
#include "usb/usbdLib.h"
#include "usb/usbLib.h"
#include "usbSFFBulkDevLib.h"
/* defines */
#define USB_SFF_DEBUG_MSG 0x01
#define USB_SFF_DEBUG_ERR 0x02
#define USB_SFF_BULK_DEBUG \
if (usbSFFBulkDebug & USB_SFF_DEBUG_MSG) \
logMsg
#define USB_SFF_BULK_ERR \
if (usbSFFBulkDebug & USB_SFF_DEBUG_ERR) \
logMsg
#define USB_SFF_BULK_OFFS 1000
typedef struct usbSFFBulkDev
{
BLK_DEV blkDev; /* Vxworks block device structure */
/* Must be the first one */
USBD_NODE_ID bulkDevId; /* USBD node ID of the device */
UINT16 configuration; /* Configuration value */
UINT16 interface; /* Interface number */
UINT16 altSetting; /* Alternate setting of interface */
UINT16 outEpAddress; /* Bulk out EP address */
UINT16 inEpAddress; /* Bulk in EP address */
USBD_PIPE_HANDLE outPipeHandle; /* Pipe handle for Bulk out EP */
USBD_PIPE_HANDLE inPipeHandle; /* Pipe handle for Bulk in EP */
USB_IRP inIrp; /* IRP used for bulk-in data */
USB_IRP outIrp; /* IRP used for bulk-out data */
USB_IRP statusIrp; /* IRP used for reading status */
UINT8 maxLun; /* Max. number of LUN supported */
USB_SFF_BULK_CBW bulkCbw; /* Structure for Command block */
USB_SFF_BULK_CSW bulkCsw; /* Structure for Command status */
UINT8 * bulkInData; /* Pointer for bulk-in data */
UINT8 * bulkOutData; /* Pointer for bulk-out data */
UINT32 numBlks; /* Number of blocks on device */
UINT32 blkOffset; /* Offset of the starting block */
UINT16 lockCount; /* Count of times structure locked*/
BOOL connected; /* TRUE if USB_SFF_BULK device connected */
LINK bulkDevLink; /* Link to other USB_SFF_BULK devices */
BOOL read10Able; /* Which read/write command the device */
/* supports. If TRUE, the device uses */
/* READ10/WRITE10, if FALSE uses READ12 / */
/* WRITE12 */
} USB_SFF_BULK_DEV, *pUSB_SFF_BULK_DEV;
typedef struct attach_sff_request
{
LINK reqLink; /* linked list of requests */
USB_SFF_BULK_ATTACH_CALLBACK callback; /* client callback routine */
pVOID callbackArg; /* client callback argument*/
} ATTACH_SFF_REQUEST, *pATTACH_SFF_REQUEST;
/* globals */
BOOL usbSFFBulkDebug = 0;
/* locals */
LOCAL UINT16 initSFFCount = 0; /* Count for Bulk device initialisation */
LOCAL USBD_CLIENT_HANDLE usbdSFFHandle; /* Handle for this class driver */
LOCAL LIST_HEAD sffbulkDevList; /* linked list of USB_SFF_BULK_DEV */
LOCAL LIST_HEAD sffreqList; /* Attach callback request list */
MUTEX_HANDLE sffbulkDevMutex; /* mutex used to protect internal structs */
SEM_HANDLE sffbulkIrpSem; /* Semaphore for IRP Synchronisation */
LOCAL UINT32 usbSFFBulkIrpTimeOut = USB_SFF_BULK_IRP_TIME_OUT; /* Time out for IRP */
/* forward declarations */
LOCAL STATUS usbSFFBulkDescShow (USBD_NODE_ID nodeId);
LOCAL STATUS usbSFFBulkConfigDescShow (USBD_NODE_ID nodeId, UINT8 index);
LOCAL STATUS usbSFFBulkPhysDevCreate (USBD_NODE_ID nodeId, UINT16 config,
UINT16 interface);
LOCAL pUSB_SFF_BULK_DEV usbSFFBulkDevFind (USBD_NODE_ID nodeId);
LOCAL STATUS usbSFFBulkDevBlkRd (BLK_DEV *blkDev, int offset, int num,
char * buf);
LOCAL STATUS usbSFFBulkDevBlkWrt (BLK_DEV *blkDev, int offset, int num,
char * buf);
LOCAL STATUS usbSFFBulkDevStatusChk (BLK_DEV *blkDev);
LOCAL STATUS usbSFFBulkDevReset (BLK_DEV *blkDev);
LOCAL void usbSFFBulkIrpCallback (pVOID p);
LOCAL STATUS usbSFFBulkFormSFFCmd (pUSB_SFF_BULK_DEV pBulkDev, UINT SFFCmd,
UINT cmdParam1, UINT cmdParam2);
LOCAL USB_COMMAND_STATUS usbSFFBulkCmdExecute (pUSB_SFF_BULK_DEV pBulkDev);
LOCAL void usbSFFBulkDevDestroy (pUSB_SFF_BULK_DEV pBulkDev);
LOCAL STATUS usbSFFBulkDevResetRecovery (pUSB_SFF_BULK_DEV pBulkDev);
LOCAL VOID notifySFFAttach (USBD_NODE_ID nodeId, UINT16 attachCode);
LOCAL VOID usbSFFBulkDevAttachCallback
(
USBD_NODE_ID nodeId, /* USBD Node ID of the device attached */
UINT16 attachAction, /* Whether device attached / detached */
UINT16 configuration, /* Configur'n value for MSC/SFF/BULK-ONLY */
UINT16 interface, /* Interface number for MSC/SFF/BULK-ONLY */
UINT16 deviceClass, /* Interface class - 0x8 for MSC */
UINT16 deviceSubClass, /* Device sub-class - 0x5 for SFF8070i
* command
*/
UINT16 deviceProtocol /* Interfaceprotocol - 0x50 for Bulk only */
)
{
pUSB_SFF_BULK_DEV pBulkDev; /* Pointer to bulk device,in case of
* removal
*/
USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback: deviceClass = %d, " \
"deviceSubClass = %d, deviceSubClass = %d \n", deviceClass,
deviceSubClass, deviceProtocol, 0, 0, 0);
OSS_MUTEX_TAKE (sffbulkDevMutex, OSS_BLOCK);
switch (attachAction)
{
case USBD_DYNA_ATTACH:
/* MSC/SFF/BULK-ONLY Device attached */
/* Check out whether we already have a structure for this device */
if (usbSFFBulkDevFind (nodeId) != NULL)
break;
USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback : New Bulk-only device "\
"attached\n", 0, 0, 0, 0, 0, 0);
USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback: Configuration = %d, " \
"Interface = %d, Node Id = %d \n", configuration,
interface, (UINT)nodeId, 0, 0, 0);
/* create a USB_SFF_BULK_DEV structure for the device attached */
if ( usbSFFBulkPhysDevCreate (nodeId, configuration,interface) != OK )
{
USB_SFF_BULK_ERR ("usbSFFBulkDevAttachCallback : Error creating Bulk"\
"device\n", 0, 0, 0, 0, 0, 0);
break;
}
/* Notify registered callers that a USB_SFF_BULK_DEV has been added */
notifySFFAttach (nodeId, USB_SFF_BULK_ATTACH);
break;
case USBD_DYNA_REMOVE:
/* MSC/SFF/BULK-ONLY Device detached */
if ((pBulkDev = usbSFFBulkDevFind (nodeId)) == NULL)
break;
/* Check the connected flag */
if (pBulkDev->connected == FALSE)
break;
pBulkDev->connected = FALSE;
/* Notify registered callers that the SFF/BULK-ONLY device has
* been removed
*
* NOTE: We temporarily increment the device's lock count
* to prevent usbSFFBulkDevUnlock() from destroying the
* structure while we're still using it.
*/
pBulkDev->lockCount++;
notifySFFAttach (pBulkDev->bulkDevId, USB_SFF_BULK_REMOVE);
pBulkDev->lockCount--;
if (pBulkDev->lockCount == 0)
usbSFFBulkDevDestroy (pBulkDev);
USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback : Bulk only Mass \
storage device detached\n", 0, 0, 0, 0, 0, 0);
break;
default :
break;
}
OSS_MUTEX_RELEASE (sffbulkDevMutex);
}
STATUS usbSFFBulkDevShutDown
(
int errCode /* Error code - reason for shutdown */
)
{
pUSB_SFF_BULK_DEV pBulkDev; /* Pointer to bulk device */
pATTACH_SFF_REQUEST pRequest;
if (initSFFCount == 0)
return ossStatus (S_usbSFFBulkDevLib_NOT_INITIALIZED);
/* release any bulk devices */
while ((pBulkDev = usbListFirst (&sffbulkDevList)) != NULL)
usbSFFBulkDevDestroy (pBulkDev);
/* Dispose of any outstanding notification requests */
while ((pRequest = usbListFirst (&sffreqList)) != NULL)
{
usbListUnlink (&pRequest->reqLink);
OSS_FREE (pRequest);
}
/*
* Unregister with the USBD. USBD will automatically release any pending
* IRPs or attach requests.
*/
if (usbdSFFHandle != NULL)
{
usbdClientUnregister (usbdSFFHandle);
usbdSFFHandle = NULL;
USB_SFF_BULK_DEBUG ("usbSFFBulkDevShutDown : Bulk Only class driver "\
"unregistered \n", 0, 0, 0, 0, 0, 0);
}
/* release resources */
if (sffbulkDevMutex != NULL)
{
OSS_MUTEX_DESTROY (sffbulkDevMutex);
sffbulkDevMutex = NULL;
}
if (sffbulkIrpSem != NULL)
{
OSS_SEM_DESTROY (sffbulkIrpSem);
sffbulkIrpSem = NULL;
}
initSFFCount--;
return ossStatus (errCode);
}
STATUS usbSFFBulkDevInit (void)
{
/*
* Check whether already initilized. If not, then initialise the required
* structures and register the class driver with USBD.
*/
if (initSFFCount == 0)
{
memset (&sffbulkDevList, 0, sizeof (sffbulkDevList));
memset (&sffreqList, 0, sizeof (sffreqList));
sffbulkDevMutex = NULL;
sffbulkIrpSem = NULL;
usbdSFFHandle = NULL;
if (OSS_MUTEX_CREATE (&sffbulkDevMutex) != OK)
return (usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_OUT_OF_RESOURCES));
if (OSS_SEM_CREATE (1, 1 , &sffbulkIrpSem) != OK)
return (usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_OUT_OF_RESOURCES));
/* Establish connection to USBD and register for attach callback */
if (usbdClientRegister ("BULK_CLASS_SFF", &usbdSFFHandle) != OK ||
usbdDynamicAttachRegister (usbdSFFHandle, USB_CLASS_MASS_STORAGE,
USB_SUBCLASS_SFF_COMMAND_SET,
USB_INTERFACE_PROTOCOL_BULK_ONLY,
usbSFFBulkDevAttachCallback) != OK)
{
USB_SFF_BULK_ERR ("usbSFFBulkDevInit: Client Registration Failed \n",
0, 0, 0, 0, 0, 0);
return usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_USBD_FAULT);
}
}
initSFFCount++;
return (OK);
}
STATUS usbSFFBulkDevIoctl
(
BLK_DEV * pBlkDev, /* pointer to bulk device */
int request, /* request type */
int someArg /* arguments related to request */
)
{
UINT16 actLen= 0xffff;
/* get a pointer to the bulk device */
pUSB_SFF_BULK_DEV pBulkDev = (USB_SFF_BULK_DEV *)pBlkDev;
if ( pBulkDev == (pUSB_SFF_BULK_DEV)NULL )
return (ERROR);
/* Check whether the device exists or not */
if (usbSFFBulkDevFind (pBulkDev->bulkDevId) != pBulkDev)
{
USB_SFF_BULK_ERR ("usbSFFBulkDevIoctl: Bulk Device not found\n",
0, 0, 0, 0, 0, 0);
return (ERROR);
}
switch (request)
{
case FIODISKFORMAT:
/*
* This is the IO control function supported by file system,
* but supplied by the device driver. Other IO control functions
* are directly handled by file system with out the use of this
* routine.
*/
if ( usbSFFBulkFormSFFCmd (pBulkDev,
USB_SFF_FORMAT_UNIT,
NULL,
NULL)
!= OK )
return (ERROR);
if ( usbSFFBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
{
USB_SFF_BULK_ERR ("usbSFFBulkDevIoctl: FORMAT UNIT Command failed\n",
0, 0, 0, 0, 0, 0);
return (ERROR);
}
return (OK);
case USB_SFF_BULK_DESCRIPTOR_GET:
/* invoke routine to display all descriptors */
return (usbSFFBulkDescShow (pBulkDev->bulkDevId));
case USB_SFF_BULK_DEV_RESET:
/* send a class-specific mass storage reset command */
return (usbSFFBulkDevResetRecovery (pBulkDev));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -