Unable to send SCSI commands to USB Drive

I am connecting a USB mass storage removeable drive to Solaris 10 x86 machine.

The device is detected and i am able to perform standard read and write functions.
But i want to use a code to send IOCTL based SCSI commands to the same device to read and write the data. Which i am unable to do so. I have learned from internet that this is not possible due to MPXI/O can anyone tell me a way out.

USB is not SCSI.

Take note of Corona688's reply and do some research...

Small Computer System(s) Interface - a parallel interface.

Universal Serial Bus - a serial interface, usually P-n-P but may require specific drivers.

Actually USB does have a well-specified SCSI command set. Look up the UAS (USB Attached SCSI - T10/2095-D) and the UASP (Universal Serial Bus Mass Storage Class - USB Attached SCSI Protocol) specifications.

I do not know if Solaris has IOCTLs or a library that support either specification.

I use SCSI.dll on Windows OS based PC and SCSI.h and SG.h on Linux OS based PC to do SCSI command set communication with USB Mass Storage devices. Typically READ10 and WRITE10 SCSI commands are excuted with ease using IOCTL on both OS's. I want to do the same on Solaris x86 please guide me

anybody here to give his/her opinion guidline to me on the issue?

Does it show up as a disk or not? What does "rmformat" show?

yes the device does show mounted. I can send files to/from the device i.e. read/write to device with standard copy/paste/cut opreations on JDE on solaris 10 but if i compile the code on gcc and run it on terminal for scsi communication using ioctl with the device the open command works but the ioctl command returns negative value.
Also the rmformat command shows the device detected and displays all the parameters

---------- Post updated at 11:40 PM ---------- Previous update was at 11:18 PM ----------

Volmgt Node: /vol/dev/aliases/rmdisk0
        Logical Node: /dev/rdsk/c2t0d0p0
        Physical Node: /pci@0,0/pci1028,211@1a,7/storage@3/disk@0,0
        Connected Device: NS                 1.00
        Device Type: Removable

this information is displayed when rmformat command is executed

---------- Post updated 02-25-15 at 02:59 AM ---------- Previous update was 02-24-15 at 11:40 PM ----------

Below is my code

________________________________________________________

int fd, res, i;

    const int t_length = 512; // 512 bytes transferred
    const unsigned char blocks = 1; // Blocks transferred
    unsigned char rdCmdBlk[SCSI_CDB_LEN] = { 0x28, // Command
    0, 0, 0, 0, 0, 0, 0, 0, 0 };
    unsigned char sense_b[SENSE_BUFF_LEN];
    sg_io_hdr_t io_hdr;

    // Open device
    fd = open(deviceName , O_RDWR|O_SYNC);
    
    printf("fd in write is : %d\n" , fd);
    
    // Prepare SCSI READ (10) command
    rdCmdBlk[2] = 0x00; // LBA
    rdCmdBlk[3] = 0x00; // LBA
    rdCmdBlk[4] = 0x00; // LBA
    rdCmdBlk[5] = 0x66; // LBA
    rdCmdBlk[8] = blocks; // transfer length

    // Prepare the sg_io_hdr_t structure
    memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
    io_hdr.interface_id = 'S';
    io_hdr.cmd_len = sizeof(rdCmdBlk);
    io_hdr.mx_sb_len = sizeof(sense_b);
    io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
    io_hdr.dxfer_len = t_length;
    io_hdr.dxferp = dataTxChallenge;
    io_hdr.cmdp = rdCmdBlk;
    io_hdr.sbp = sense_b;
    io_hdr.timeout = 5000;

    // Sends the command to device
    if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) 
    {
        
        close(fd);
}




printf("IOCTL RESULT :    %d",res);

printf("ERROR NO :    %d",errno);

_______________________________________________________
The return value of ioctl is -1 and errno is 25 which is

#define    ENOTTY    25    /* Inappropriate ioctl for device */

What's the value of errno before you make your call? Often things like printf() will make ioctl() calls which fail with ENOTTY.

If you want to be sure you get a clean errno value, you have to set it to zero yourself before you make your call.

the value of errno before the call is 0. i also manually cleared it before making the ioctl call. please consider that the primary problem is working of ioctl to pass scsi command of read write to a USB mass storage device which is successfully opened by open() call.
I hope so you will be able to help me better with this reply

The exact values of errno are important because it's an indicator of why something failed.

If you've set the value to errno to zero, and you know the value of errno is zero before you make your ioctl call, the code you posted does not represent the code you're running.

Also, you need to be aware that "errno" is defined by the C/C++ standard to be a macro. As such, if you use a debugger to examine the value of the "errno" symbol, you likely will not be seeing or setting the actual value used by your process. On Solaris, the value of errno actually used by your code is quite likely the dereferenced integer pointer returned by the libc function "___errno()", and not the global "errno" symbol.

It's kind of hard to help you when you're not precisely representing nor understanding what you're doing.

You are using Linux (or at list GLIBC) specific ioctls with Solaris. This can't work. Your code shouldn't even compile under Solaris so I guest you naively copied include files from a Linux machine to the Solaris one. You should have stated that in the first place to get a quicker answer.

Use the proper Solaris API, uscsi. Start with:

man uscsi

Thanks for your reply yes i am truly new to it. And yes i applogize for giving less information.

I did what u asked me to. used USCSI Solaris API but it gives Segmetation Fault - core dumped here is the new code

#include <fcntl.h>
#include </usr/include/sys/scsi/impl/uscsi.h>

#define deviceName "/vol/dev/aliases/rmdisk0"
#define SCSI_CDB_LEN 10
#define SENSE_BUFF_LEN 18

int main()
{
    int fd, res, i;
    unsigned char data[512]={0xe1,0xe2,0xe3,0xe4};
    const int t_length = 512; // 512 bytes transferred
    const unsigned char blocks = 1; // Blocks transferred
    unsigned char rdCmdBlk[SCSI_CDB_LEN] = { 0x2a, // Command
    0, 0, 0, 0, 0, 0, 0, 0, 0 };
    unsigned char sense_b[SENSE_BUFF_LEN];
    struct uscsi_cmd    *cmd1;
    
    // Open device
    fd = open(deviceName , O_RDWR);
    
    printf("fd in write is : %d\n" , fd);
    
    // Prepare SCSI  (10) command
    rdCmdBlk[2] = 0x00; // LBA
    rdCmdBlk[3] = 0x00; // LBA
    rdCmdBlk[4] = 0x00; // LBA
    rdCmdBlk[5] = 0x42; // LBA
    rdCmdBlk[8] = blocks; // transfer length
  
    
    cmd1->uscsi_flags= USCSI_WRITE;
    cmd1->uscsi_buflen =t_length;
    cmd1->uscsi_bufaddr =  data;
    cmd1->uscsi_timeout = 5000;
    cmd1->uscsi_cdb = (caddr_t) &rdCmdBlk;
    cmd1->uscsi_cdblen = SCSI_CDB_LEN;




    

    // Sends the command to device
    if ((res = ioctl(fd,USCSICMD,&cmd1)) < 0) 
    {
        
        close(fd);

printf("IOCTL FAILS:    %d",res);
        return -1;
    }
printf("IOCTL SUCCESS :     %d",res);
    
    
         close(fd);
        return 0;


}


That's no surprise. You do not allocate space for cmd1.

i tried doing that but failed same result can u help me?

(void) memset((char *)&cmd1, 0, sizeof(cmd1));

You are still missing to allocate space. This should be done with the malloc or the calloc command.

i did as u said the Segmentation Error is gone now. ioctl still returns -1

cmd1 =  malloc(550);

A similar post was found on this forum on which u replied but the post thread was short. just posting the link so that it may ring any bells in your mind?

i also have the same number 3 as return result of open() command and ioctl returns -1

I ran a SCSI Inquiry based command with the same USCSI header files and was able to communicate and get VID and PID of the USB but SCSI read and write IOCTL fails can u hint a possible reason?