⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbbulkdevlib.c

📁 SL811 USB接口芯片用于VxWorks系统的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

    if ((pInEp = findEndpoint (pBfr, actLength, USB_ENDPOINT_IN)) == NULL)
        goto errorExit;

    pBulkDev->outEpAddress = pOutEp->endpointAddress;
    pBulkDev->inEpAddress  = pInEp->endpointAddress;

    /* Set the device configuration corresponding to MSC/SCSI/BULK-ONLY */

    if ((usbdConfigurationSet (usbdHandle, 
			       pBulkDev->bulkDevId, 
			       pBulkDev->configuration, 
			       pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT)) 
			     != OK )
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to set device "\
                      "configuration \n", 0, 0, 0, 0, 0, 0);
        goto errorExit;
        }
    else
        {
        USB_BULK_DEBUG ("usbBulkPhysDevCreate: Configuration set to 0x%x \n",
                        pBulkDev->configuration, 0, 0, 0, 0, 0);
        }
    
   /* Select interface 
    * 
    * NOTE: Some devices may reject this command, and this does not represent
    * a fatal error.  Therefore, we ignore the return status.
    */

    usbdInterfaceSet (usbdHandle, 
		      pBulkDev->bulkDevId,
		      pBulkDev->interface, 
		      pBulkDev->altSetting);

    maxPacketSize = *((pUINT8) &pOutEp->maxPacketSize) |
                    (*(((pUINT8) &pOutEp->maxPacketSize) + 1) << 8);

    /* Create a Bulk-out pipe for the MSC/SCSI/BULK-ONLY device */

    if (usbdPipeCreate (usbdHandle, 
			pBulkDev->bulkDevId, 
			pOutEp->endpointAddress, 
			pBulkDev->configuration, 
			pBulkDev->interface, 
			USB_XFRTYPE_BULK, 
			USB_DIR_OUT, 
			maxPacketSize, 
			0, 
			0, 
			&(pBulkDev->outPipeHandle)) 
		      != OK)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Error creating bulk out pipe\n",
                        0, 0, 0, 0, 0, 0);
        goto errorExit;
        } 

    maxPacketSize = *((pUINT8) &pInEp->maxPacketSize) |
	    (*(((pUINT8) &pInEp->maxPacketSize) + 1) << 8);

    /* Create a Bulk-in pipe for the MSC/SCSI/BULK-ONLY device */
       
    if (usbdPipeCreate (usbdHandle, 
			pBulkDev->bulkDevId, 
			pInEp->endpointAddress, 
			pBulkDev->configuration, 
			pBulkDev->interface, 
			USB_XFRTYPE_BULK, 
			USB_DIR_IN, 
			maxPacketSize, 
			0, 
			0, 
			&(pBulkDev->inPipeHandle)) 
		      != OK)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Error creating bulk in pipe\n",
                        0, 0, 0, 0, 0, 0);
        goto errorExit;
        } 

    /* Clear HALT feauture on the endpoints */

    if ((usbdFeatureClear (usbdHandle, 
			   pBulkDev->bulkDevId, 
			   USB_RT_ENDPOINT, 
			   USB_FSEL_DEV_ENDPOINT_HALT, 
			   (pOutEp->endpointAddress & 0x0F))) 
			 != OK)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to clear HALT feauture "\
                      "on bulk out Endpoint %x\n", 0, 0, 0, 0, 0, 0);
        }  

    if ((usbdFeatureClear (usbdHandle, 
			   pBulkDev->bulkDevId, 
			   USB_RT_ENDPOINT, 
			   USB_FSEL_DEV_ENDPOINT_HALT, 
			   (pOutEp->endpointAddress & 0x0F))) 
			 != OK)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to clear HALT feauture "\
                      "on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0);
        } 

    /* Link the newly created structure. */

    usbListLink (&bulkDevList, pBulkDev, &pBulkDev->bulkDevLink, LINK_TAIL);
    
    return (OK);

errorExit:

    /* Error in creating a bulk device ..destroy */

    usbBulkDevDestroy (pBulkDev);
    return (ERROR);
    }

/***************************************************************************
*
* usbBulkBlkDevCreate - create a block device.
*
* This routine  initializes a BLK_DEV structure, which describes a 
* logical partition on a USB_BULK_DEV device.  A logical partition is an array 
* of contiguously addressed blocks; it can be completely described by the number
* of blocks and the address of the first block in the partition.  
*
* NOTE:
* If `numBlocks' is 0, the rest of device is used.
* 
* This routine supplies an additional parameter called <flags>.  This bitfield 
* currently only uses bit 1.  This bit determines whether the driver will use a
* SCSI READ6 or SCSI READ10 for read access.
*
* RETURNS: A pointer to the BLK_DEV, or NULL if parameters exceed
* physical device boundaries, or if no bulk device exists.
*/

BLK_DEV * usbBulkBlkDevCreate
    (
    USBD_NODE_ID nodeId,        /* nodeId of the bulk-only device     */ 
    UINT32       numBlks,       /* number of logical blocks on device */
    UINT32       blkOffset,     /* offset of the starting block       */ 
    UINT32       flags		/* optional flags		      */ 
    )
    {
    UINT8   inquiry[36];         /* store for INQUIRY data  */
    DOS_PART_TBL *pPart;
    char    blk0Buffer [512];
    int	    offset=0;
    int ix;

    /* TODO : As of now only the first device is taken care */

    pUSB_BULK_DEV pBulkDev  = usbBulkDevFind (nodeId);
    /*pUSB_BULK_DEV pBulkDev = usbListFirst (&bulkDevList);*/

    if (pBulkDev == NULL)
        {
        USB_BULK_ERR ("usbBulkBlkDevCreate: No MSC/SCSI/BULK-ONLY found\n",
                        0, 0, 0, 0, 0, 0);
        return (NULL);
        }

    OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK); 

    /* Initialise the standard block device structure for use with file systems */

    pBulkDev->blkDev.bd_blkRd        = (FUNCPTR) usbBulkDevBlkRd;
    pBulkDev->blkDev.bd_blkWrt       = (FUNCPTR) usbBulkDevBlkWrt;
    pBulkDev->blkDev.bd_ioctl        = (FUNCPTR) usbBulkDevIoctl;
    pBulkDev->blkDev.bd_reset        = (FUNCPTR) usbBulkDevReset; 
    pBulkDev->blkDev.bd_statusChk    = (FUNCPTR) usbBulkDevStatusChk;
    pBulkDev->blkDev.bd_retry        = 1;
    pBulkDev->blkDev.bd_mode         = O_RDWR;
    pBulkDev->blkDev.bd_readyChanged = TRUE;

    /* 
     * Read out the standard INQUIRY information from the device, mainly to
     * check whether the media is removable or not.
     */

    pBulkDev->bulkInData  = inquiry;
 
    if ( usbBulkFormScsiCmd (pBulkDev, USB_SCSI_INQUIRY, NULL, NULL) != OK )
        {
        USB_BULK_ERR ("usbBulkBlkDevCreate: Error forming command\n",
                        0, 0, 0, 0, 0, 0);
        OSS_MUTEX_RELEASE (bulkDevMutex);
        return (NULL); 
        } 

    if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
        {
        USB_BULK_ERR ("usbBulkBlkDevCreate: Error executing USB_SCSI_INQUIRY "\
                      "command\n", 0, 0, 0, 0, 0, 0);        
        OSS_MUTEX_RELEASE (bulkDevMutex);
        return (NULL);  
        }
 
    /* Check the media type bit  */

    if (inquiry[1] & USB_SCSI_INQUIRY_RMB_BIT)
        {
        pBulkDev->blkDev.bd_removable = TRUE;
        }
    else
        {
        pBulkDev->blkDev.bd_removable = FALSE;      
        }

    /* read the block size and capacity of device (in terms of blocks) */

    if ( usbBulkFormScsiCmd (pBulkDev, 
			     USB_SCSI_READ_CAPACITY, 
			     NULL, 
			     NULL) 
			   != OK )
        {
        OSS_MUTEX_RELEASE (bulkDevMutex); 
        return (NULL); 
        } 

    /* 
     * Read Capacity command will usually return CHECK CONDITION status
     * very first time, just try again.
     */

    if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
        {
        if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )  
            {
            USB_BULK_ERR ("usbBulkBlkDevCreate: Read Capacity command failed\n",
                          0, 0, 0, 0, 0, 0);
            OSS_MUTEX_RELEASE (bulkDevMutex);
            return (NULL);  
            } 
        } 
    
    /* SCSI response is in BIG endian format. Swap it to get correct value */

    pBulkDev->numBlks   = USB_SCSI_SWAP_32(*((UINT32 *)inquiry));
    pBulkDev->blkOffset = blkOffset;

    if ( numBlks == NULL )
        pBulkDev->blkDev.bd_nBlocks = (pBulkDev->numBlks - blkOffset); 
    else 
        pBulkDev->blkDev.bd_nBlocks = numBlks;

    pBulkDev->blkDev.bd_bytesPerBlk = USB_SCSI_SWAP_32(*((UINT32 *)(inquiry+4))); 


    /* determine which type of SCSI read command is implemnted */

    if ( (flags & USB_SCSI_FLAG_READ_WRITE10) == 1 )
	pBulkDev->read10Able = TRUE;
    else
	pBulkDev->read10Able = FALSE;

    if (blkOffset<=0)
        {
        /*  
         * Read the first block off the disk to determine where the logical
         * disk begins.  This code was adapted from usrAta.c.  It  trys
         * to determine if the first block is a partition table.  If so, it
         * pulls the offset into the logical disk and stores it in the BLK_DEVs
         * offset paramter.  If not it assumes the first block (LBA = 0) is the
         * beginning of the logical disk.
         */
        
        usbBulkDevBlkRd ((BLK_DEV *) pBulkDev, 
                         0,				/* read LBA #0 */
                         1,				/* read only this block */
                         blk0Buffer);
        
        /* get the offset into the partition table */
        
        pPart	= (DOS_PART_TBL *)&blk0Buffer[DOS_BOOT_PART_TBL];
        
        for (ix = 0; ix < 4; ix++)		/* active primary DOS partition */
            {
            if (pPart->dospt_status == 0x80)
                if ((pPart->dospt_type == 0x01) ||
                    (pPart->dospt_type == 0x04) ||
                    (pPart->dospt_type == 0x06))
                    {
                    offset = pPart->dospt_absSec;
                    break;
                    }
            pPart++;
            }
        
        
        pBulkDev->blkOffset = offset;
        
        if ( numBlks == NULL )
            pBulkDev->blkDev.bd_nBlocks = (pBulkDev->numBlks - offset); 
        else 
            pBulkDev->blkDev.bd_nBlocks = numBlks;
        
        pBulkDev->blkDev.bd_bytesPerBlk = USB_SCSI_SWAP_32(*((UINT32 *)(inquiry+4))); 
        }
        
    OSS_MUTEX_RELEASE (bulkDevMutex);

    return (&pBulkDev->blkDev);
       
    }        

/***************************************************************************
*
* usbBulkDevBlkRd - routine to read one or more blocks from the device.
*
* This routine reads the specified physical sector(s) from a specified
* physical device.  Typically called by file system when data is to be
* read from a particular device.
*
* RETURNS: OK on success, or ERROR if failed to read from device
*/

LOCAL STATUS usbBulkDevBlkRd
    (
    BLK_DEV * pBlkDev,           /* pointer to bulk device   */ 
    int       blkNum,            /* logical block number     */
    int       numBlks,           /* number of blocks to read */
    char *    pBuf               /* store for data           */ 
    )
    {

    pUSB_BULK_DEV  pBulkDev = (USB_BULK_DEV *)pBlkDev;   
    UINT readType;

    /*  Ensure that the device has not been removed during a transfer */

    if ( pBulkDev->connected == FALSE ) 
	return ERROR;

    USB_BULK_DEBUG ("usbBulkDevBlkRd: Number of blocks = %d, Starting blk = %d\n",
                    numBlks, blkNum, 0, 0, 0, 0); 

    OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK);

    /* intialise the pointer to store bulk in data */ 

    pBulkDev->bulkInData = (UINT8 *)pBuf ; 

    if (pBulkDev->read10Able)
	readType = USB_SCSI_READ10;
    else 
	readType = USB_SCSI_READ6;

    if ( usbBulkFormScsiCmd (pBulkDev, 
			     readType, 
			     blkNum, 
			     numBlks) 
			   != OK )
        {
        OSS_MUTEX_RELEASE (bulkDevMutex);
        return (ERROR);  
        }

    if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
        {
        OSS_MUTEX_RELEASE (bulkDevMutex);
        return (ERROR); 
        }

    OSS_MUTEX_RELEASE (bulkDevMutex);
    return (OK);
  
    }

/***************************************************************************
*
* usbBulkDevBlkWrt - routine to write one or more blocks to the device.
*
* This routine write

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -