Example #1
0
//*****************************************************************************
//
//! This function checks if a drive is ready to be accessed.
//!
//! \param ulInstance is the device instance to use for this read.
//!
//! This function checks if the current device is ready to be accessed.
//! It uses the \e ulInstance parameter to determine which device to check and
//! will return zero when the device is ready.  Any non-zero return code
//! indicates that the device was not ready.
//!
//! \return This function will return zero if the device is ready and it will
//! return a other value if the device is not ready or if an error occurred.
//
//*****************************************************************************
long
USBHMSCDriveReady(unsigned long ulInstance)
{
    unsigned char ucMaxLUN, pBuffer[SCSI_INQUIRY_DATA_SZ];
    unsigned long ulSize;
    tUSBHMSCInstance *pMSCDevice;

    //
    // Get the instance pointer in a more usable form.
    //
    pMSCDevice = (tUSBHMSCInstance *)ulInstance;

    //
    // If there is no device present then return an error.
    //
    if(pMSCDevice->pDevice == 0)
    {
        return(-1);
    }

    //
    // Get the Maximum LUNs on this device.
    //
    USBHMSCGetMaxLUN(g_USBHMSCDevice.pDevice->ulAddress,
                     g_USBHMSCDevice.pDevice->ulInterface, &ucMaxLUN);

    //
    // Save the Maximum number of LUNs on this device.
    //
    g_USBHMSCDevice.ulMaxLUN = ucMaxLUN;

    //
    // Just return if the device is returning not present.
    //
    ulSize = SCSI_REQUEST_SENSE_SZ;
    if(USBHSCSIRequestSense(pMSCDevice->ulBulkInPipe, pMSCDevice->ulBulkOutPipe,
                            pBuffer, &ulSize) != SCSI_CMD_STATUS_PASS)
    {
        return(-1);
    }

    if((pBuffer[SCSI_RS_SKEY] == SCSI_RS_KEY_UNIT_ATTN) &&
       (pBuffer[SCSI_RS_SKEY_AD_SKEY] == SCSI_RS_KEY_NOTPRSNT))
    {
        return(-1);
    }

    //
    // Issue a SCSI Inquiry to get basic information on the device
    //
    ulSize = SCSI_INQUIRY_DATA_SZ;
    if((USBHSCSIInquiry(pMSCDevice->ulBulkInPipe, pMSCDevice->ulBulkOutPipe,
                        pBuffer, &ulSize) != SCSI_CMD_STATUS_PASS))
    {
        return(-1);
    }

    //
    // Get the size of the drive.
    //
    ulSize = SCSI_INQUIRY_DATA_SZ;
    if(USBHSCSIReadCapacity(pMSCDevice->ulBulkInPipe, pMSCDevice->ulBulkOutPipe,
                            pBuffer, &ulSize) != SCSI_CMD_STATUS_PASS)
    {
        //
        // Get the current sense data from the device to see why it failed
        // the Read Capacity command.
        //
        ulSize = SCSI_REQUEST_SENSE_SZ;
        USBHSCSIRequestSense(pMSCDevice->ulBulkInPipe,
                             pMSCDevice->ulBulkOutPipe, pBuffer, &ulSize);

        //
        // If the read capacity failed then check if the drive is ready.
        //
        if(USBHSCSITestUnitReady(pMSCDevice->ulBulkInPipe,
                                 pMSCDevice->ulBulkOutPipe) != SCSI_CMD_STATUS_PASS)
        {
            //
            // Get the current sense data from the device to see why it failed
            // the Test Unit Ready command.
            //
            ulSize = SCSI_REQUEST_SENSE_SZ;
            USBHSCSIRequestSense(pMSCDevice->ulBulkInPipe,
                                 pMSCDevice->ulBulkOutPipe, pBuffer, &ulSize);
        }

        return(-1);
    }
    else
    {
        //
        // Read the block size out, value is stored big endian.
        //
        pMSCDevice->ulBlockSize =
            (pBuffer[7] | (pBuffer[6] << 8) | pBuffer[5] << 16 |
             (pBuffer[4] << 24));

        //
        // Read the block size out.
        //
        pMSCDevice->ulNumBlocks =
            (pBuffer[3] | (pBuffer[2] << 8) | pBuffer[1] << 16 |
             (pBuffer[0] << 24));
    }

    //
    // See if the drive is ready to use.
    //
    if(USBHSCSITestUnitReady(pMSCDevice->ulBulkInPipe,
                             pMSCDevice->ulBulkOutPipe) != SCSI_CMD_STATUS_PASS)
    {
        //
        // Get the current sense data from the device to see why it failed
        // the Test Unit Ready command.
        //
        ulSize = SCSI_REQUEST_SENSE_SZ;
        USBHSCSIRequestSense(pMSCDevice->ulBulkInPipe,
                             pMSCDevice->ulBulkOutPipe, pBuffer, &ulSize);

        return(-1);
    }

    //
    // Success.
    //
    return(0);
}
Example #2
0
//*****************************************************************************
//
//! This function checks if a drive is ready to be accessed.
//!
//! \param psMSCInstance is the device instance to use for this read.
//!
//! This function checks if the current device is ready to be accessed.
//! It uses the \e psMSCInstance parameter to determine which device to check
//! and returns zero when the device is ready.  Any non-zero return code
//! indicates that the device was not ready.
//!
//! \return This function returns zero if the device is ready and it
//! returns a other value if the device is not ready or if an error occurred.
//
//*****************************************************************************
int32_t
USBHMSCDriveReady(tUSBHMSCInstance *psMSCInstance)
{
    uint8_t ui8MaxLUN, pui8Buffer[SCSI_INQUIRY_DATA_SZ];
    uint32_t ui32Size;

    //
    // If there is no device present then return an error.
    //
    if(psMSCInstance->psDevice == 0)
    {
        return(-1);
    }

    //
    // Only request the maximum number of LUNs once.
    //
    if(g_sUSBHMSCDevice.ui32MaxLUN == 0xffffffff)
    {
        //
        // Get the Maximum LUNs on this device.
        //
        USBHMSCGetMaxLUN(g_sUSBHMSCDevice.psDevice,
                         g_sUSBHMSCDevice.psDevice->ui32Interface, &ui8MaxLUN);

        //
        // Save the Maximum number of LUNs on this device.
        //
        g_sUSBHMSCDevice.ui32MaxLUN = ui8MaxLUN;
    }

    //
    // Just return if the device is returning not present.
    //
    ui32Size = SCSI_REQUEST_SENSE_SZ;
    if(USBHSCSIRequestSense(psMSCInstance->ui32BulkInPipe,
                            psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                            &ui32Size) != SCSI_CMD_STATUS_PASS)
    {
        return(-1);
    }

    if((pui8Buffer[SCSI_RS_SKEY] == SCSI_RS_KEY_UNIT_ATTN) &&
       (pui8Buffer[SCSI_RS_SKEY_AD_SKEY] == SCSI_RS_KEY_NOTPRSNT))
    {
        return(-1);
    }

    //
    // Issue a SCSI Inquiry to get basic information on the device
    //
    ui32Size = SCSI_INQUIRY_DATA_SZ;
    if((USBHSCSIInquiry(psMSCInstance->ui32BulkInPipe,
                        psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                        &ui32Size) != SCSI_CMD_STATUS_PASS))
    {
        return(-1);
    }

    //
    // Get the size of the drive.
    //
    ui32Size = SCSI_INQUIRY_DATA_SZ;
    if(USBHSCSIReadCapacity(psMSCInstance->ui32BulkInPipe,
                            psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                            &ui32Size) != SCSI_CMD_STATUS_PASS)
    {
        //
        // Get the current sense data from the device to see why it failed
        // the Read Capacity command.
        //
        ui32Size = SCSI_REQUEST_SENSE_SZ;
        USBHSCSIRequestSense(psMSCInstance->ui32BulkInPipe,
                             psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                             &ui32Size);

        //
        // If the read capacity failed then check if the drive is ready.
        //
        if(USBHSCSITestUnitReady(psMSCInstance->ui32BulkInPipe,
                                 psMSCInstance->ui32BulkOutPipe) !=
           SCSI_CMD_STATUS_PASS)
        {
            //
            // Get the current sense data from the device to see why it failed
            // the Test Unit Ready command.
            //
            ui32Size = SCSI_REQUEST_SENSE_SZ;
            USBHSCSIRequestSense(psMSCInstance->ui32BulkInPipe,
                                 psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                                 &ui32Size);
        }

        return(-1);
    }
    else
    {
        //
        // Read the block size out, value is stored big endian.
        //
        psMSCInstance->ui32BlockSize =
             (pui8Buffer[7] | ((uint32_t)pui8Buffer[6] << 8) | (uint32_t)pui8Buffer[5] << 16 |
              ((uint32_t)pui8Buffer[4] << 24));

        //
        // Read the block size out.
        //
        psMSCInstance->ui32NumBlocks =
            (pui8Buffer[3] | ((uint32_t)pui8Buffer[2] << 8) | (uint32_t)pui8Buffer[1] << 16 |
             ((uint32_t)pui8Buffer[0] << 24));
    }

    //
    // See if the drive is ready to use.
    //
    if(USBHSCSITestUnitReady(psMSCInstance->ui32BulkInPipe,
                             psMSCInstance->ui32BulkOutPipe) !=
       SCSI_CMD_STATUS_PASS)
    {
        //
        // Get the current sense data from the device to see why it failed
        // the Test Unit Ready command.
        //
        ui32Size = SCSI_REQUEST_SENSE_SZ;
        USBHSCSIRequestSense(psMSCInstance->ui32BulkInPipe,
                             psMSCInstance->ui32BulkOutPipe, pui8Buffer,
                             &ui32Size);

        return(-1);
    }

    //
    // Success.
    //
    return(0);
}