Logo Search packages:      
Sourcecode: u3-tool version File versions

int u3_send_cmd ( u3_handle_t device,
uint8_t  cmd[U3_CMD_LEN],
int  dxfer_direction,
int  dxfer_length,
uint8_t *  dxfer_data,
uint8_t *  status 

Execute a scsi command at device

This send the given SCSI CDB in 'cmd' to the device given by 'device'. Optional data is transfered from or to the device. The SCSI status as returned by the device is placed in 'status'.

device U3 handle
dxfer_direction Direction of extra data, given by on of the U3_DATA_* enum values
dxfer_len Length of extra data
dxfer_data Buffer with extra data
status Pointer to variable to return SCSI status in
U3_SUCCESS if successful, else U3_FAILURE and an error string can be obtained using u3_error()

Definition at line 94 of file u3_scsi_sg.c.

References u3_handle::dev, and u3_send_cmd().

Referenced by u3_cd_write(), u3_change_password(), u3_chip_info(), u3_data_partition_info(), u3_disable_security(), u3_enable_security(), u3_partition(), u3_partition_info(), u3_partition_sector_round(), u3_read_device_property(), u3_reset(), u3_security_sector_round(), u3_send_cmd(), and u3_unlock().

      sg_io_hdr_t io_hdr;
      unsigned char sense_buf[32];
      int *sg_fd = (int *)device->dev;

      // translate dxfer_direction
      switch (dxfer_direction) {
            case U3_DATA_NONE:
                  dxfer_direction = SG_DXFER_NONE;
            case U3_DATA_TO_DEV:
                  dxfer_direction = SG_DXFER_TO_DEV;
            case U3_DATA_FROM_DEV:
                  dxfer_direction = SG_DXFER_FROM_DEV;

      // Prepare command
      memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
      io_hdr.interface_id = 'S';                // fixed
      io_hdr.cmd_len = U3_CMD_LEN;              // length of command in bytes
      // io_hdr.iovec_count = 0;                // don't use iovector stuff
      io_hdr.mx_sb_len = sizeof(sense_buf);           // sense buffer size. do we use this???
      io_hdr.dxfer_direction = dxfer_direction; // send data to device
      io_hdr.dxfer_len = dxfer_length;          // Size of data transfered
      io_hdr.dxferp = dxfer_data;               // Data buffer to transfer
      io_hdr.cmdp = cmd;                        // Command buffer to execute
      io_hdr.sbp = sense_buf;                   // Sense buffer
      io_hdr.timeout = U3_TIMEOUT;              // timeout
      // io_hdr.flags = 0;                      // take defaults: indirect IO, etc 
      // io_hdr.pack_id = 0;                    // internal packet. used by te program to recognize packets
      // io_hdr.usr_ptr = NULL;                 // user data

      // preform ioctl on device
      if (ioctl(*sg_fd, SG_IO, &io_hdr) < 0) {
            u3_set_error(device, "Failed executing scsi command: "
                        "SG_IO ioctl Failed");
            return U3_FAILURE;

      // evaluate result
      if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
            if (io_hdr.host_status == SG_ERR_DID_OK &&
                (io_hdr.driver_status & SG_ERR_DRIVER_SENSE))
                  // The usb-storage driver automatically request sense
                  // data if a command fails. So this state isn't really
                  // a error but only indicates that the sense data in
                  // the buffer is fresh. Currently we aren't don't use
                  // this sense data, we only wanna know if a command
                  // failed or not. so ignore this...

            } else {
                  u3_set_error(device, "Failed executing scsi command: "
                        "Status (S:0x%x,H:0x%x,D:0x%x)", io_hdr.status,
                        io_hdr.host_status, io_hdr.driver_status);
                  return U3_FAILURE;

      *status = io_hdr.masked_status;

      return U3_SUCCESS;

Generated by  Doxygen 1.6.0   Back to index