Link to home
Start Free TrialLog in
Avatar of raj_ksrt
raj_ksrt

asked on

To know the disks block size, should i use "Read capacity" or "Mode sense" command?

Hi,

The block size of a SCSI disk is stored in one of the Mode pages. Now if i want to know the disk's block size, what is the difference between firing a mode sense command and reading that particular page and issuing a read capacity command? Are they both same?
Avatar of David
David
Flag of United States of America image


The purposes of the READ capacity is to tell you the NUMBER of blocks.  The block headers returned with ANY mode sense command will give you the block size (I.e, # of bytes per block).  So go with READ CAPACITY and get both.

Warning, there is also a READ CAPACITY(16) which is required for HDDs > then 2TB.
Sorry gave you some bad info ... in penance ... here is some code that will work (replace the SCSIME with whatever passthrough mechanism for your O/S.
The X8ToU64 converts a sequence of 8 bytes where byte0 is most significant into 64bit unsigned number.

This shows how to fall back with a 16-byte command if the disk is larger than what can be returned in a 10-byte CDB.  

Note you have to add 1 because the sneaky commands return HIGHEST block #, not total # of blocks.



    CDB_T           CDB;
    Sense_T  Sense;
    int             status;
    U8              CapData[8],CapDataLong[12];
    U64             Total,Work;
    U32             U32BlockCount;
    U32             U32BlockLength;

    memset(CDB,0,sizeof(CDB));
    CDB[0] = READ_CAPACITY10;
    status = SCSIME(Read,CDB,10,CapData,8,&Sense);
    if (status == 0) {  /* This didn't work before 1.24 in LINUX if really big. It works now */
        U32BlockCount =  ((U32)CapData[0] * 0x1000000) + ((U32)CapData[1] * 0x10000) + ((U32)CapData[2] * 0x100) + (U32)CapData[3];
        U32BlockLength = ((U32)CapData[4] * 0x1000000) + ((U32)CapData[5] * 0x10000) + ((U32)CapData[6] * 0x100) + (U32)CapData[7];
        if (U32BlockCount != 0xffffffff) {
            ++U32BlockCount;        /*  This returns highest block number, need to add 1 for # of blocks */
            Total = U32BlockLength;
            Total *= 0x1000000000000LL;
            Total += U32BlockCount;
            return (Total);
        }
        memset(CDB,0,sizeof(CDB));
        memset(CapDataLong,0,sizeof(CapDataLong));
        CDB[0] = 0x9e;              /* SERVICE ACTION IN(16) */
        CDB[1] = 0x10;              /* READ_CAPACITY(16) OPCODE */
        status = SCSIME(Read,CDB,16,CapDataLong,12,&Sense);
        if (status == 0) {
            Work = X8ToU64(CapDataLong,8);
            ++Work;     /*  highest block # needs to change to # of blocks */
            U32BlockLength = ((U32)CapDataLong[8] * 0x1000000) + ((U32)CapDataLong[9] * 0x10000) + ((U32)CapDataLong[10] * 0x100) + (U32)CapDataLong[11];
            Total = U32BlockLength;
            Total *= 0x100000000000LL;
            Total += Work;      /* this is correct, I am not multiplying in what I send back */
            return (Total);
        }
    }   /* This can fail if reservation conflict, or if 16-byte CDB not supported */
    return FALSE;
}
Avatar of raj_ksrt
raj_ksrt

ASKER

Hi dlethe,

THanks for your reply. Although it kind of gave me some info, but didn't exactly answer my question.

I'll rephrase my question to make it more to the point.

The "Read capacity" and "mode sense" commands both can be used to find the block size of a SCSI disk. Now is there any specific situation in which only "Read Capacity"  should be used for knowing the block size? or is there a situation where only "mode sense" command should be used??
What if capacity is greater than 2.09TB and/or you have one of the disks that has 4KB sector size, or are attached to a large virtual drive?  You have to use the Read Capacity(16), then fall back on the Read capacity(10).  No other way to do it.  

     
SO can i conclude that for disks with huge size ( e.g. more than 2.0 TB), i can't use "mode sense" command to find out the block size of the disk?? and that's where i'll need "Read Capacity" comamnd?
ASKER CERTIFIED SOLUTION
Avatar of David
David
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks!!. That answers my question...