usbmpc5200devlib.c
来自「MPC5200 BSP 支持ATA,USB, I2C,扩展网口」· C语言 代码 · 共 1,989 行 · 第 1/5 页
C
1,989 行
/* 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 "usbMpc5200DevLib.h"
/* defines */
#define USB_DEBUG_MSG 0x01
#define USB_DEBUG_ERR 0x02
#define USB_BULK_DEBUG \
if (usbBulkDebug & USB_DEBUG_MSG) \
logMsg
#define USB_BULK_ERR \
if (usbBulkDebug & USB_DEBUG_ERR) \
logMsg
#define USB_BULK_OFFS 1000
typedef struct usbBulkDev
{
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_BULK_CBW bulkCbw; /* Structure for Command block */
USB_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_BULK device connected */
LINK bulkDevLink; /* Link to other USB_BULK devices */
BOOL read10Able; /* Which read/write command the device */
/* supports. If TRUE, the device uses */
/* READ10/WRITE10, if FALSE uses READ6 / */
/* WRITE6 */
} USB_BULK_DEV, *pUSB_BULK_DEV;
typedef struct attach_request
{
LINK reqLink; /* linked list of requests */
USB_BULK_ATTACH_CALLBACK callback; /* client callback routine */
pVOID callbackArg; /* client callback argument*/
} ATTACH_REQUEST, *pATTACH_REQUEST;
/* globals */
BOOL usbBulkDebug = 0;
/* locals */
LOCAL UINT16 initCount = 0; /* Count for Bulk device initialisation */
LOCAL USBD_CLIENT_HANDLE usbdHandle; /* Handle for this class driver */
LOCAL LIST_HEAD bulkDevList; /* linked list of USB_BULK_DEV */
LOCAL LIST_HEAD reqList; /* Attach callback request list */
MUTEX_HANDLE bulkDevMutex; /* mutex used to protect internal structs */
SEM_HANDLE bulkIrpSem; /* Semaphore for IRP Synchronisation */
LOCAL UINT32 usbBulkIrpTimeOut = USB_BULK_IRP_TIME_OUT; /* Time out for IRP */
/* forward declarations */
LOCAL STATUS usbBulkDescShow (USBD_NODE_ID nodeId);
LOCAL STATUS usbBulkConfigDescShow (USBD_NODE_ID nodeId, UINT8 index);
LOCAL STATUS usbBulkPhysDevCreate (USBD_NODE_ID nodeId, UINT16 config,
UINT16 interface);
LOCAL pUSB_BULK_DEV usbBulkDevFind (USBD_NODE_ID nodeId);
LOCAL STATUS usbBulkDevBlkRd (BLK_DEV *blkDev, int offset, int num,
char * buf);
LOCAL STATUS usbBulkDevBlkWrt (BLK_DEV *blkDev, int offset, int num,
char * buf);
LOCAL STATUS usbBulkDevStatusChk (BLK_DEV *blkDev);
LOCAL STATUS usbBulkDevReset (BLK_DEV *blkDev);
LOCAL void usbBulkIrpCallback (pVOID p);
LOCAL STATUS usbBulkFormScsiCmd (pUSB_BULK_DEV pBulkDev, UINT scsiCmd,
UINT cmdParam1, UINT cmdParam2);
LOCAL USB_COMMAND_STATUS usbBulkCmdExecute (pUSB_BULK_DEV pBulkDev);
LOCAL void usbBulkDevDestroy (pUSB_BULK_DEV pBulkDev);
LOCAL STATUS usbBulkDevResetRecovery (pUSB_BULK_DEV pBulkDev);
LOCAL VOID notifyAttach (USBD_NODE_ID nodeId, UINT16 attachCode);
LOCAL VOID usbBulkDevAttachCallback
(
USBD_NODE_ID nodeId, /* USBD Node ID of the device attached */
UINT16 attachAction, /* Whether device attached / detached */
UINT16 configuration, /* Configur'n value for MSC/SCSI/BULK-ONLY */
UINT16 interface, /* Interface number for MSC/SCSI/BULK-ONLY */
UINT16 deviceClass, /* Interface class - 0x8 for MSC */
UINT16 deviceSubClass, /* Device sub-class - 0x6 for SCSI
* command
*/
UINT16 deviceProtocol /* Interfaceprotocol - 0x50 for Bulk only */
)
{
pUSB_BULK_DEV pBulkDev; /* Pointer to bulk device,in case of
* removal
*/
USB_BULK_DEBUG ("usbBulkDevAttachCallback: deviceClass = %d, " \
"deviceSubClass = %d, deviceSubClass = %d \n", deviceClass,
deviceSubClass, deviceProtocol, 0, 0, 0);
OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK);
switch (attachAction)
{
case USBD_DYNA_ATTACH:
/* MSC/SCSI/BULK-ONLY Device attached */
/* Check out whether we already have a structure for this device */
if (usbBulkDevFind (nodeId) != NULL)
break;
USB_BULK_DEBUG ("usbBulkDevAttachCallback : New Bulk-only device "\
"attached\n", 0, 0, 0, 0, 0, 0);
USB_BULK_DEBUG ("usbBulkDevAttachCallback: Configuration = %d, " \
"Interface = %d, Node Id = %d \n", configuration,
interface, (UINT)nodeId, 0, 0, 0);
/* create a USB_BULK_DEV structure for the device attached */
if ( usbBulkPhysDevCreate (nodeId, configuration,interface) != OK )
{
USB_BULK_ERR ("usbBulkDevAttachCallback : Error creating Bulk"\
"device\n", 0, 0, 0, 0, 0, 0);
break;
}
/* Notify registered callers that a USB_BULK_DEV has been added */
notifyAttach (nodeId, USB_BULK_ATTACH);
break;
case USBD_DYNA_REMOVE:
/* MSC/SCSI/BULK-ONLY Device detached */
if ((pBulkDev = usbBulkDevFind (nodeId)) == NULL)
break;
/* Check the connected flag */
if (pBulkDev->connected == FALSE)
break;
pBulkDev->connected = FALSE;
/* Notify registered callers that the SCSI/BULK-ONLY device has
* been removed
*
* NOTE: We temporarily increment the device's lock count
* to prevent usbBulkDevUnlock() from destroying the
* structure while we're still using it.
*/
pBulkDev->lockCount++;
notifyAttach (pBulkDev->bulkDevId, USB_BULK_REMOVE);
pBulkDev->lockCount--;
if (pBulkDev->lockCount == 0)
usbBulkDevDestroy (pBulkDev);
USB_BULK_DEBUG ("usbBulkDevAttachCallback : Bulk only Mass \
storage device detached\n", 0, 0, 0, 0, 0, 0);
break;
default :
break;
}
OSS_MUTEX_RELEASE (bulkDevMutex);
}
STATUS usbBulkDevShutDown
(
int errCode /* Error code - reason for shutdown */
)
{
pUSB_BULK_DEV pBulkDev; /* Pointer to bulk device */
pATTACH_REQUEST pRequest;
if (initCount == 0)
return ossStatus (S_usbBulkDevLib_NOT_INITIALIZED);
/* release any bulk devices */
while ((pBulkDev = usbListFirst (&bulkDevList)) != NULL)
usbBulkDevDestroy (pBulkDev);
/* Dispose of any outstanding notification requests */
while ((pRequest = usbListFirst (&reqList)) != NULL)
{
usbListUnlink (&pRequest->reqLink);
OSS_FREE (pRequest);
}
/*
* Unregister with the USBD. USBD will automatically release any pending
* IRPs or attach requests.
*/
if (usbdHandle != NULL)
{
usbdClientUnregister (usbdHandle);
usbdHandle = NULL;
USB_BULK_DEBUG ("usbBulkDevShutDown : Bulk Only class driver "\
"unregistered \n", 0, 0, 0, 0, 0, 0);
}
/* release resources */
if (bulkDevMutex != NULL)
{
OSS_MUTEX_DESTROY (bulkDevMutex);
bulkDevMutex = NULL;
}
if (bulkIrpSem != NULL)
{
OSS_SEM_DESTROY (bulkIrpSem);
bulkIrpSem = NULL;
}
initCount--;
return ossStatus (errCode);
}
STATUS usbBulkDevInit (void)
{
/*
* Check whether already initilized. If not, then initialise the required
* structures and register the class driver with USBD.
*/
if (initCount == 0)
{
memset (&bulkDevList, 0, sizeof (bulkDevList));
memset (&reqList, 0, sizeof (reqList));
bulkDevMutex = NULL;
bulkIrpSem = NULL;
usbdHandle = NULL;
if (OSS_MUTEX_CREATE (&bulkDevMutex) != OK)
return (usbBulkDevShutDown (S_usbBulkDevLib_OUT_OF_RESOURCES));
if (OSS_SEM_CREATE (1, 1 , &bulkIrpSem) != OK)
return (usbBulkDevShutDown (S_usbBulkDevLib_OUT_OF_RESOURCES));
/* Establish connection to USBD and register for attach callback */
if (usbdClientRegister ("BULK_CLASS", &usbdHandle) != OK ||
usbdDynamicAttachRegister (usbdHandle, USB_CLASS_MASS_STORAGE,
USB_SUBCLASS_SCSI_COMMAND_SET,
USB_INTERFACE_PROTOCOL_BULK_ONLY,
usbBulkDevAttachCallback) != OK)
{
USB_BULK_ERR ("usbBulkDevInit: Client Registration Failed \n",
0, 0, 0, 0, 0, 0);
return usbBulkDevShutDown (S_usbBulkDevLib_USBD_FAULT);
}
}
initCount++;
return (OK);
}
STATUS usbBulkDevIoctl
(
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_BULK_DEV pBulkDev = (USB_BULK_DEV *)pBlkDev;
if ( pBulkDev == (pUSB_BULK_DEV)NULL )
return (ERROR);
/* Check whether the device exists or not */
if (usbBulkDevFind (pBulkDev->bulkDevId) != pBulkDev)
{
USB_BULK_ERR ("usbBulkDevIoctl: 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 ( usbBulkFormScsiCmd (pBulkDev,
USB_SCSI_FORMAT_UNIT,
0,
0)
!= OK )
return (ERROR);
if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
{
USB_BULK_ERR ("usbBulkDevIoctl: FORMAT UNIT Command failed\n",
0, 0, 0, 0, 0, 0);
return (ERROR);
}
return (OK);
case USB_BULK_DESCRIPTOR_GET:
/* invoke routine to display all descriptors */
return (usbBulkDescShow (pBulkDev->bulkDevId));
case USB_BULK_DEV_RESET:
/* send a class-specific mass storage reset command */
return (usbBulkDevResetRecovery (pBulkDev));
case USB_BULK_EJECT_MEDIA:
/* Only applicable if media is removable */
if ( pBulkDev->blkDev.bd_removable != TRUE )
return (ERROR);
else
{
if ( usbBulkFormScsiCmd (pBulkDev,
USB_SCSI_START_STOP_UNIT,
USB_SCSI_START_STOP_LOEJ,
0)
!= OK )
return (ERROR);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?