Beispiel #1
0
//*****************************************************************************
//
//! This function issues a SCSI Read(10) command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param ulLBA is the logical block address to read.
//! \param pucData is the data buffer to return the data.
//! \param pulSize is the size of the buffer on entry and number of bytes read
//! on exit.
//! \param ulNumBlocks is the number of contiguous blocks to read from the
//! device.
//!
//! This function is used to issue a SCSI Read(10) command to a device.  The
//! \e ulLBA parameter specifies the logical block address to read from the
//! device.  The data from this block will be returned in the buffer pointed to
//! by \e pucData.  The parameter \e pulSize should indicate enough space to
//! hold a full block size, or only the first pulSize bytes of the LBA will
//! be returned.
//!
//! \return This function returns the results of the SCSI Read(10) command.
//! The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIRead10(unsigned long ulInPipe, unsigned long ulOutPipe,
               unsigned long ulLBA, unsigned char *pucData,
               unsigned long *pulSize, unsigned long ulNumBlocks)
{
    tMSCCBW SCSICmd;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    SCSICmd.bCBWCBLength = 10;

    //
    // Set the parameter options.
    //
    SCSICmd.CBWCB[0] = SCSI_READ_10;

    //
    // Clear the reserved field.
    //
    SCSICmd.CBWCB[1] = 0;

    //
    // LBA starts at offset 2.
    //
    SCSICmd.CBWCB[2] = (unsigned char)(ulLBA >> 24);
    SCSICmd.CBWCB[3] = (unsigned char)(ulLBA >> 16);
    SCSICmd.CBWCB[4] = (unsigned char)(ulLBA >> 8);
    SCSICmd.CBWCB[5] = (unsigned char)ulLBA;

    //
    // Clear the reserved field.
    //
    SCSICmd.CBWCB[6] = 0;

    //
    // Transfer length in blocks starts at offset 2.
    // This also sets the Control value to 0 at offset 9.
    //
    SCSICmd.CBWCB[7] = (ulNumBlocks & 0xFF00) >> 8;
    *((unsigned long *)&SCSICmd.CBWCB[8]) = (ulNumBlocks & 0xFF);
    *((unsigned long *)&SCSICmd.CBWCB[12]) = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
//*****************************************************************************
//
//! This function issues a SCSI Read(10) command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param ui32LBA is the logical block address to read.
//! \param pui8Data is the data buffer to return the data.
//! \param pui32Size is the size of the buffer on entry and number of bytes
//! read on exit.
//! \param ui32NumBlocks is the number of contiguous blocks to read from the
//! device.
//!
//! This function is used to issue a SCSI Read(10) command to a device.  The
//! \e ui32LBA parameter specifies the logical block address to read from the
//! device.  The data from this block will be returned in the buffer pointed to
//! by \e pui8Data.  The parameter \e pui32Size should indicate enough space to
//! hold a full block size, or only the first \e pui32Size bytes of the LBA are
//! returned.
//!
//! \return This function returns the results of the SCSI Read(10) command.
//! The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIRead10(uint32_t ui32InPipe, uint32_t ui32OutPipe,
               uint32_t ui32LBA, uint8_t *pui8Data,
               uint32_t *pui32Size, uint32_t ui32NumBlocks)
{
    tMSCCBW sSCSICmd;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 10;

    //
    // Set the parameter options.
    //
    sSCSICmd.CBWCB[0] = SCSI_READ_10;

    //
    // Clear the reserved field.
    //
    sSCSICmd.CBWCB[1] = 0;

    //
    // LBA starts at offset 2.
    //
    sSCSICmd.CBWCB[2] = (uint8_t)(ui32LBA >> 24);
    sSCSICmd.CBWCB[3] = (uint8_t)(ui32LBA >> 16);
    sSCSICmd.CBWCB[4] = (uint8_t)(ui32LBA >> 8);
    sSCSICmd.CBWCB[5] = (uint8_t)ui32LBA;

    //
    // Clear the reserved field.
    //
    sSCSICmd.CBWCB[6] = 0;

    //
    // Transfer length in blocks starts at offset 2.
    // This also sets the Control value to 0 at offset 9.
    //
    sSCSICmd.CBWCB[7] = (ui32NumBlocks & 0xFF00) >> 8;
    *((uint32_t *)&sSCSICmd.CBWCB[8]) = (ui32NumBlocks & 0xFF);
    *((uint32_t *)&sSCSICmd.CBWCB[12]) = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
Beispiel #3
0
//*****************************************************************************
//
//! This function issues a SCSI Read(10) command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param ui32LBA is the logical block address to read.
//! \param pui8Data is the data buffer to return the data.
//! \param pui32Size is the size of the buffer on entry and number of bytes
//! read on exit.
//! \param ui32NumBlocks is the number of contiguous blocks to read from the
//! device.
//!
//! This function is used to issue a SCSI Read(10) command to a device.  The
//! \e ui32LBA parameter specifies the logical block address to read from the
//! device.  The data from this block will be returned in the buffer pointed to
//! by \e pui8Data.  The parameter \e pui32Size should indicate enough space to
//! hold a full block size, or only the first \e pui32Size bytes of the LBA are
//! returned.
//!
//! \return This function returns the results of the SCSI Read(10) command.
//! The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIRead10(uint32_t ui32InPipe, uint32_t ui32OutPipe,
               uint32_t ui32LBA, uint8_t *pui8Data,
               uint32_t *pui32Size, uint32_t ui32NumBlocks)
{
    tMSCCBW sSCSICmd;
    int32_t i32Idx;

    //
    // Zero out the response data.
    //
    for(i32Idx = 0; i32Idx < sizeof(sSCSICmd.CBWCB); i32Idx++)
    {
        sSCSICmd.CBWCB[i32Idx] = 0;
    }

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 10;

    //
    // Set the parameter options.
    //
    sSCSICmd.CBWCB[0] = SCSI_READ_10;

    //
    // LBA starts at offset 2.
    //
    sSCSICmd.CBWCB[2] = (uint8_t)(ui32LBA >> 24);
    sSCSICmd.CBWCB[3] = (uint8_t)(ui32LBA >> 16);
    sSCSICmd.CBWCB[4] = (uint8_t)(ui32LBA >> 8);
    sSCSICmd.CBWCB[5] = (uint8_t)ui32LBA;

    //
    // Transfer length in blocks starts at offset 7.
    //
    sSCSICmd.CBWCB[7] = (uint8_t)(ui32NumBlocks >> 8);
    sSCSICmd.CBWCB[8] = (uint8_t)ui32NumBlocks;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
Beispiel #4
0
//*****************************************************************************
//
//! This will issue the SCSI inquiry command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param pucData is the data buffer to return the results into.
//! \param pulSize is the size of buffer that was passed in on entry and the
//! number of bytes returned.
//!
//! This function should be used to issue a SCSI Inquiry command to a mass
//! storage device.  To allow for multiple devices, the \e ulInPipe and
//! \e ulOutPipe parameters indicate which USB pipes to use for this call.
//!
//! \note The \e pucData buffer pointer should have at least
//! \b SCSI_INQUIRY_DATA_SZ bytes of data or this function will overflow the
//! buffer.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIInquiry(unsigned long ulInPipe, unsigned long ulOutPipe,
                unsigned char *pucData, unsigned long *pulSize)
{
    tMSCCBW SCSICmd;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // The number of bytes of data that the host expects to transfer on the
    // Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during
    // the execution of this command.  If this field is zero, the device and
    // the host shall transfer no data between the CBW and the associated CSW,
    // and the device shall ignore the value of the Direction bit in
    // bmCBWFlags.
    //
    *pulSize = SCSI_INQUIRY_DATA_SZ;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // This is the length of the command itself.
    //
    SCSICmd.bCBWCBLength = 6;

    //
    // Send Inquiry command with no request for vital product data.
    //
    pulData[0] = SCSI_INQUIRY_CMD;

    //
    // Allocation length.
    //
    pulData[1] = SCSI_INQUIRY_DATA_SZ;
    pulData[2] = 0;
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
//*****************************************************************************
//
//! This will issue the SCSI inquiry command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param pui8Data is the data buffer to return the results into.
//! \param pui32Size is the size of buffer that was passed in on entry and the
//! number of bytes returned.
//!
//! This function should be used to issue a SCSI Inquiry command to a mass
//! storage device.  To allow for multiple devices, the \e ui32InPipe and
//! \e ui32OutPipe parameters indicate which USB pipes to use for this call.
//!
//! \note The \e pui8Data buffer pointer should have at least
//! \b SCSI_INQUIRY_DATA_SZ bytes of data or this function will overflow the
//! buffer.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIInquiry(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                uint8_t *pui8Data, uint32_t *pui32Size)
{
    tMSCCBW sSCSICmd;
    usb32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (usb32_t *)sSCSICmd.CBWCB;

    //
    // The number of bytes of data that the host expects to transfer on the
    // Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during
    // the execution of this command.  If this field is zero, the device and
    // the host shall transfer no data between the CBW and the associated CSW,
    // and the device shall ignore the value of the Direction bit in
    // bmCBWFlags.
    //
    *pui32Size = SCSI_INQUIRY_DATA_SZ;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // This is the length of the command itself.
    //
    sSCSICmd.bCBWCBLength = 6;

    //
    // Send Inquiry command with no request for vital product data.
    //
    writeusb32_t(&(pui32Data[0]), SCSI_INQUIRY_CMD);

    //
    // Allocation length.
    //
    writeusb32_t(&(pui32Data[1]), SCSI_INQUIRY_DATA_SZ);
    writeusb32_t(&(pui32Data[2]), 0);
    writeusb32_t(&(pui32Data[3]), 0);

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
Beispiel #6
0
//*****************************************************************************
//
//! This will issue the SCSI read capacity command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param pucData is the data buffer to return the results into.
//! \param pulSize is the size of buffer that was passed in on entry and the
//! number of bytes returned.
//!
//! This function should be used to issue a SCSI Read Capacity command
//! to a mass storage device that is connected.  To allow for multiple devices,
//! the \e ulInPipe and \e ulOutPipe parameters indicate which USB pipes to
//! use for this call.
//!
//! \note The \e pucData buffer pointer should have at least
//! \b SCSI_READ_CAPACITY_SZ bytes of data or this function will overflow the
//! buffer.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIReadCapacity(unsigned long ulInPipe, unsigned long ulOutPipe,
                     unsigned char *pucData, unsigned long *pulSize)
{
    tMSCCBW SCSICmd;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // Set the size of the command data.
    //
    *pulSize = SCSI_READ_CAPACITY_SZ;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the length of the command itself.
    //
    SCSICmd.bCBWCBLength = 12;

    //
    // Only use the first byte and set it to the Read Capacity command.  The
    // rest are set to 0.
    //
    pulData[0] = SCSI_READ_CAPACITY;
    pulData[1] = 0;
    pulData[2] = 0;
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
Beispiel #7
0
//*****************************************************************************
//
//! This will issue the SCSI read capacity command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param pui8Data is the data buffer to return the results into.
//! \param pui32Size is the size of buffer that was passed in on entry and the
//! number of bytes returned.
//!
//! This function should be used to issue a SCSI Read Capacity command
//! to a mass storage device that is connected.  To allow for multiple devices,
//! the \e ui32InPipe and \e ui32OutPipe parameters indicate which USB pipes to
//! use for this call.
//!
//! \note The \e pui8Data buffer pointer should have at least
//! \b SCSI_READ_CAPACITY_SZ bytes of data or this function will overflow the
//! buffer.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIReadCapacity(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                     uint8_t *pui8Data, uint32_t *pui32Size)
{
    tMSCCBW sSCSICmd;
    uint32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (uint32_t *)sSCSICmd.CBWCB;

    //
    // Set the size of the command data.
    //
    *pui32Size = SCSI_READ_CAPACITY_SZ;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the length of the command itself.
    //
    sSCSICmd.bCBWCBLength = 12;

    //
    // Only use the first byte and set it to the Read Capacity command.  The
    // rest are set to 0.
    //
    pui32Data[0] = SCSI_READ_CAPACITY;
    pui32Data[1] = 0;
    pui32Data[2] = 0;
    pui32Data[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
Beispiel #8
0
//*****************************************************************************
//
//! This function issues a SCSI Test Unit Ready command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//!
//! This function is used to issue a SCSI Test Unit Ready command to a device.
//! This call will simply return the results of issuing this command.
//!
//! \return This function returns the results of the SCSI Test Unit Ready
//! command.  The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSITestUnitReady(uint32_t ui32InPipe, uint32_t ui32OutPipe)
{
    tMSCCBW sSCSICmd;
    uint32_t ui32Size;
    uint32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (uint32_t *)sSCSICmd.CBWCB;

    //
    // No data in this command.
    //
    ui32Size = 0;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 6;

    //
    // Set the parameter options.
    //
    pui32Data[0] = SCSI_TEST_UNIT_READY;
    pui32Data[1] = 0;
    pui32Data[2] = 0;
    pui32Data[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, 0,
                               &ui32Size));
}
Beispiel #9
0
//*****************************************************************************
//
//! This function issues a SCSI Test Unit Ready command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//!
//! This function is used to issue a SCSI Test Unit Ready command to a device.
//! This call will simply return the results of issuing this command.
//!
//! \return This function returns the results of the SCSI Test Unit Ready
//! command.  The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSITestUnitReady(unsigned long ulInPipe, unsigned long ulOutPipe)
{
    tMSCCBW SCSICmd;
    unsigned long ulSize;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // No data in this command.
    //
    ulSize = 0;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    SCSICmd.bCBWCBLength = 6;

    //
    // Set the parameter options.
    //
    pulData[0] = SCSI_TEST_UNIT_READY;
    pulData[1] = 0;
    pulData[2] = 0;
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, 0, &ulSize));
}
Beispiel #10
0
//*****************************************************************************
//
//! This will issue the SCSI Mode Sense(6) command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param ulFlags is a combination of flags defining the exact query that is
//! to be made.
//! \param pucData is the data buffer to return the results into.
//! \param pulSize is the size of the buffer on entry and number of bytes read
//! on exit.
//!
//! This function should be used to issue a SCSI Mode Sense(6) command
//! to a mass storage device.  To allow for multiple devices,the \e ulInPipe
//! and \e ulOutPipe parameters indicate which USB pipes to use for this call.
//! The call will return at most the number of bytes in the \e pulSize
//! parameter, however it can return less and change the \e pulSize parameter
//! to the number of valid bytes in the \e *pulSize buffer.
//!
//! The \e ulFlags parameter is a combination of the following three sets of
//! definitions:
//!
//! One of the following values must be specified:
//!
//! - \b SCSI_MS_PC_CURRENT request for current settings.
//! - \b SCSI_MS_PC_CHANGEABLE request for changeable settings.
//! - \b SCSI_MS_PC_DEFAULT request for default settings.
//! - \b SCSI_MS_PC_SAVED request for the saved values.
//!
//! One of these following values must also be specified to determine the page
//! code for the request:
//!
//! - \b SCSI_MS_PC_VENDOR is the vendor specific page code.
//! - \b SCSI_MS_PC_DISCO is the disconnect/reconnect page code.
//! - \b SCSI_MS_PC_CONTROL is the control page code.
//! - \b SCSI_MS_PC_LUN is the protocol specific LUN page code.
//! - \b SCSI_MS_PC_PORT is the protocol specific port page code.
//! - \b SCSI_MS_PC_POWER is the power condition page code.
//! - \b SCSI_MS_PC_INFORM is the informational exceptions page code.
//! - \b SCSI_MS_PC_ALL will request all pages codes supported by the device.
//!
//! The last value is optional and supports the following global flag:
//! - \b SCSI_MS_DBD disables returning block descriptors.
//!
//! Example: Request for all current settings.
//!
//! \verbatim
//! SCSIModeSense6(ulInPipe, ulOutPipe,
//!                SCSI_MS_PC_CURRENT | SCSI_MS_PC_ALL,
//!                pucData, pulSize);
//! \endverbatim
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIModeSense6(unsigned long ulInPipe, unsigned long ulOutPipe,
                   unsigned long ulFlags, unsigned char *pucData,
                   unsigned long *pulSize)
{
    tMSCCBW SCSICmd;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    SCSICmd.bCBWCBLength = 6;

    //
    // Set the options for the Mode Sense Command (6).
    //
    pulData[0] = (SCSI_MODE_SENSE_6 | ulFlags);
    pulData[1] = (unsigned char)*pulSize;
    pulData[2] = 0;
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
Beispiel #11
0
//*****************************************************************************
//
//! This will issue the SCSI Mode Sense(6) command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param ui32Flags is a combination of flags defining the exact query that is
//! to be made.
//! \param pui8Data is the data buffer to return the results into.
//! \param pui32Size is the size of the buffer on entry and number of bytes
//! read on exit.
//!
//! This function should be used to issue a SCSI Mode Sense(6) command
//! to a mass storage device.  To allow for multiple devices,the \e ui32InPipe
//! and \e ui32OutPipe parameters indicate which USB pipes to use for this
//! call. The call will return at most the number of bytes in the \e pui32Size
//! parameter, however it can return less and change the \e pui32Size parameter
//! to the number of valid bytes in the \e *pui32Size buffer.
//!
//! The \e ui32Flags parameter is a combination of the following three sets of
//! definitions:
//!
//! One of the following values must be specified:
//!
//! - \b SCSI_MS_PC_CURRENT request for current settings.
//! - \b SCSI_MS_PC_CHANGEABLE request for changeable settings.
//! - \b SCSI_MS_PC_DEFAULT request for default settings.
//! - \b SCSI_MS_PC_SAVED request for the saved values.
//!
//! One of these following values must also be specified to determine the page
//! code for the request:
//!
//! - \b SCSI_MS_PC_VENDOR is the vendor specific page code.
//! - \b SCSI_MS_PC_DISCO is the disconnect/reconnect page code.
//! - \b SCSI_MS_PC_CONTROL is the control page code.
//! - \b SCSI_MS_PC_LUN is the protocol specific LUN page code.
//! - \b SCSI_MS_PC_PORT is the protocol specific port page code.
//! - \b SCSI_MS_PC_POWER is the power condition page code.
//! - \b SCSI_MS_PC_INFORM is the informational exceptions page code.
//! - \b SCSI_MS_PC_ALL will request all pages codes supported by the device.
//!
//! The last value is optional and supports the following global flag:
//! - \b SCSI_MS_DBD disables returning block descriptors.
//!
//! Example: Request for all current settings.
//!
//! \verbatim
//! SCSIModeSense6(ui32InPipe, ui32OutPipe,
//!                SCSI_MS_PC_CURRENT | SCSI_MS_PC_ALL,
//!                pui8Data, pui32Size);
//! \endverbatim
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIModeSense6(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                   uint32_t ui32Flags, uint8_t *pui8Data,
                   uint32_t *pui32Size)
{
    tMSCCBW sSCSICmd;
    uint32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (uint32_t *)sSCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 6;

    //
    // Set the options for the Mode Sense Command (6).
    //
    pui32Data[0] = (SCSI_MODE_SENSE_6 | ui32Flags);
    pui32Data[1] = (uint8_t)*pui32Size;
    pui32Data[2] = 0;
    pui32Data[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
//*****************************************************************************
//
//! This function issues a SCSI Request Sense command to a device.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param pui8Data is the data buffer to return the results into.
//! \param pui32Size is the size of the buffer on entry and number of bytes
//! read on exit.
//!
//! This function is used to issue a SCSI Request Sense command to a device.
//! It will return the data in the buffer pointed to by \e pui8Data.  The
//! parameter \e pui32Size should have the allocation size in bytes of the
//! buffer pointed to by \e pui8Data.
//!
//! \return This function returns the results of the SCSI Request Sense
//! command.  The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIRequestSense(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                     uint8_t *pui8Data, uint32_t *pui32Size)
{
    tMSCCBW sSCSICmd;
    usb32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (usb32_t *)sSCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 12;

    //
    // Set the parameter options.
    //
    writeusb32_t(&(pui32Data[0]), SCSI_REQUEST_SENSE);
    writeusb32_t(&(pui32Data[1]), 18);
    writeusb32_t(&(pui32Data[2]), 0);
    writeusb32_t(&(pui32Data[3]), 0);


    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}
Beispiel #13
0
//*****************************************************************************
//
//! This function issues a SCSI Request Sense command to a device.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param pucData is the data buffer to return the results into.
//! \param pulSize is the size of the buffer on entry and number of bytes read
//! on exit.
//!
//! This function is used to issue a SCSI Request Sense command to a device.
//! It will return the data in the buffer pointed to by \e pucData.  The
//! parameter \e pulSize should have the allocation size in bytes of the buffer
//! pointed to by pucData.
//!
//! \return This function returns the results of the SCSI Request Sense
//! command.  The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIRequestSense(unsigned long ulInPipe, unsigned long ulOutPipe,
                     unsigned char *pucData, unsigned long *pulSize)
{
    tMSCCBW SCSICmd;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_IN;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    SCSICmd.bCBWCBLength = 12;

    //
    // Set the parameter options.
    //
    pulData[0] = SCSI_REQUEST_SENSE;
    pulData[1] = 18;
    pulData[2] = 0;
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
Beispiel #14
0
//*****************************************************************************
//
//! This function issues a SCSI Write(10) command to a device.
//!
//! This function is used to issue a SCSI Write(10) command to a device.  The
//! \e ulLBA parameter specifies the logical block address on the device.  The
//! data to write to this block should be in the buffer pointed to by
//! \e pucData parameter.  The parameter \e pulSize should indicate the amount
//! of data to write to the specified LBA.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param ulLBA is the logical block address to read.
//! \param pucData is the data buffer to write out.
//! \param pulSize is the size of the buffer.
//! \param ulNumBlocks is the number of contiguous blocks to write to the
//! device.
//!
//! \return This function returns the results of the SCSI Write(10) command.
//! The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
unsigned long
USBHSCSIWrite10(unsigned long ulInPipe, unsigned long ulOutPipe,
                unsigned long ulLBA, unsigned char *pucData,
                unsigned long *pulSize, unsigned long ulNumBlocks)
{
    tMSCCBW SCSICmd;
    unsigned long *pulData;

    //
    // Create a local unsigned long pointer to the command.
    //
    pulData = (unsigned long *)SCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    SCSICmd.bmCBWFlags = CBWFLAGS_DIR_OUT;

    //
    // Only handle LUN 0.
    //
    SCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    SCSICmd.bCBWCBLength = 10;

    //
    // Set the parameter options.
    //
    SCSICmd.CBWCB[0] = SCSI_WRITE_10;

    //
    // Clear the reserved field.
    //
    SCSICmd.CBWCB[1] = 0;

    //
    // LBA starts at offset 2.
    //
    SCSICmd.CBWCB[2] = (unsigned char)(ulLBA >> 24);
    SCSICmd.CBWCB[3] = (unsigned char)(ulLBA >> 16);
    SCSICmd.CBWCB[4] = (unsigned char)(ulLBA >> 8);
    SCSICmd.CBWCB[5] = (unsigned char)ulLBA;

    //
    // Clear the reserved field.
    //
    SCSICmd.CBWCB[6] = 0;

    //
    // Set the transfer length in blocks.
    // This also sets the Control value to 0 at offset 9.
    //
    SCSICmd.CBWCB[7] = (ulNumBlocks & 0xFF00) >> 8;

    //
    // The blocks go into is byte offset 8 or word address 2.
    //
    pulData[2] = (ulNumBlocks & 0xFF);

    //
    // The blocks go into is byte offset 12 or word address 3.
    //
    pulData[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ulInPipe, ulOutPipe, &SCSICmd, pucData,
                               pulSize));
}
Beispiel #15
0
//*****************************************************************************
//
//! This function issues a SCSI Write(10) command to a device.
//!
//! This function is used to issue a SCSI Write(10) command to a device.  The
//! \e ui32LBA parameter specifies the logical block address on the device.
//! The data to write to this block should be in the buffer pointed to by
//! \e pui8Data parameter.  The parameter \e pui32Size should indicate the
//! amount of data to write to the specified LBA.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param ui32LBA is the logical block address to read.
//! \param pui8Data is the data buffer to write out.
//! \param pui32Size is the size of the buffer.
//! \param ui32NumBlocks is the number of contiguous blocks to write to the
//! device.
//!
//! \return This function returns the results of the SCSI Write(10) command.
//! The value will be either \b SCSI_CMD_STATUS_PASS or
//! \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
uint32_t
USBHSCSIWrite10(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                uint32_t ui32LBA, uint8_t *pui8Data,
                uint32_t *pui32Size, uint32_t ui32NumBlocks)
{
    tMSCCBW sSCSICmd;
    uint32_t *pui32Data;

    //
    // Create a local 32-bit pointer to the command.
    //
    pui32Data = (uint32_t *)sSCSICmd.CBWCB;

    //
    // This is an IN request.
    //
    sSCSICmd.bmCBWFlags = CBWFLAGS_DIR_OUT;

    //
    // Only handle LUN 0.
    //
    sSCSICmd.bCBWLUN = 0;

    //
    // Set the size of the command data.
    //
    sSCSICmd.bCBWCBLength = 10;

    //
    // Set the parameter options.
    //
    sSCSICmd.CBWCB[0] = SCSI_WRITE_10;

    //
    // Clear the reserved field.
    //
    sSCSICmd.CBWCB[1] = 0;

    //
    // LBA starts at offset 2.
    //
    sSCSICmd.CBWCB[2] = (uint8_t)(ui32LBA >> 24);
    sSCSICmd.CBWCB[3] = (uint8_t)(ui32LBA >> 16);
    sSCSICmd.CBWCB[4] = (uint8_t)(ui32LBA >> 8);
    sSCSICmd.CBWCB[5] = (uint8_t)ui32LBA;

    //
    // Clear the reserved field.
    //
    sSCSICmd.CBWCB[6] = 0;

    //
    // Set the transfer length in blocks.
    // This also sets the Control value to 0 at offset 9.
    //
    sSCSICmd.CBWCB[7] = (ui32NumBlocks & 0xFF00) >> 8;

    //
    // The blocks go into is byte offset 8 or word address 2.
    //
    pui32Data[2] = (ui32NumBlocks & 0xFF);

    //
    // The blocks go into is byte offset 12 or word address 3.
    //
    pui32Data[3] = 0;

    //
    // Send the command and get the results.
    //
    return(USBHSCSISendCommand(ui32InPipe, ui32OutPipe, &sSCSICmd, pui8Data,
                               pui32Size));
}