home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 November / PCONLINE_11_99.ISO / filesbbs / OS2 / DANIS506.ZIP / source / DiskInfo.c
Encoding:
C/C++ Source or Header  |  1999-07-28  |  11.9 KB  |  318 lines

  1. #define INCL_DOS
  2. #include <OS2.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6. #pragma pack(1)
  7.  
  8. #define DSKSP_CAT_SMART         0x80  /* SMART IOCTL category */
  9.  
  10. #define DSKSP_SMART_ONOFF        0x20  /* turn SMART on or off */
  11. #define DSKSP_SMART_AUTOSAVE_ONOFF  0x21  /* turn SMART autosave on or off */
  12. #define DSKSP_SMART_SAVE        0x22  /* force save of SMART data */
  13. #define DSKSP_SMART_GETSTATUS        0x23  /* get SMART status (pass/fail) */
  14. #define DSKSP_SMART_GET_ATTRIBUTES  0x24  /* get SMART attributes table */
  15. #define DSKSP_SMART_GET_THRESHOLDS  0x25  /* get SMART thresholds table */
  16.  
  17. #define SMART_CMD_ON      1          /* on value for related SMART functions */
  18. #define SMART_CMD_OFF      0          /* off value for related SMART functions */
  19.  
  20. #define DSKSP_CAT_GENERIC        0x90  /* generic IOCTL category */
  21. #define DSKSP_GEN_GET_COUNTERS        0x40  /* get general counter values table */
  22. #define DSKSP_GET_UNIT_INFORMATION  0x41  /* get unit configuration and BM DMA c*/
  23. #define DSKSP_GET_INQUIRY_DATA        0x42  /* get ATA/ATAPI inquiry data */
  24.  
  25. typedef struct _DSKSP_CommandParameters {
  26.   BYTE byPhysicalUnit;           /* physical unit number 0-n */
  27.                    /* 0 = Pri/Mas, 1=Pri/Sla, 2=Sec/Mas,*/
  28. } DSKSP_CommandParameters, *PDSKSP_CommandParameters;
  29.  
  30. /*
  31.  * Parameters for SMART and generic commands
  32.  */
  33.  
  34. /*
  35.  * SMART Attribute table item
  36.  */
  37.  
  38. typedef struct _S_Attribute
  39. {
  40.   BYTE          byAttribID;          /* attribute ID number */
  41.   USHORT      wFlags;              /* flags */
  42.   BYTE          byValue;              /* attribute value */
  43.   BYTE          byVendorSpecific[8];      /* vendor specific data */
  44. } S_Attribute;
  45.  
  46. /*
  47.  * SMART Attribute table structure
  48.  */
  49.  
  50. typedef struct _DeviceAttributesData
  51. {
  52.   USHORT      wRevisionNumber;          /* revision number of attribute table */
  53.   S_Attribute Attribute[30];          /* attribute table */
  54.   BYTE          byReserved[6];          /* reserved bytes */
  55.   USHORT      wSMART_Capability;      /* capabilities word */
  56.   BYTE          byReserved2[16];          /* reserved bytes */
  57.   BYTE          byVendorSpecific[125];      /* vendor specific data */
  58.   BYTE          byCheckSum;          /* checksum of data in this structure */
  59. } DeviceAttributesData, NEAR *NPDeviceAttributesData, FAR *PDeviceAttributesData;
  60.  
  61. /*
  62.  * SMART Device Threshold table item
  63.  */
  64.  
  65. typedef struct _S_Threshold
  66. {
  67.   BYTE          byAttributeID;          /* attribute ID number */
  68.   BYTE          byValue;              /* threshold value */
  69.   BYTE          byReserved[10];          /* reserved bytes */
  70. } S_Threshold;
  71.  
  72. /*
  73.  * SMART Device Threshold table
  74.  */
  75.  
  76. typedef struct _DeviceThresholdsData
  77. {
  78.   USHORT      wRevisionNumber;          /* table revision number */
  79.   S_Threshold Threshold[30];          /* threshold table */
  80.   BYTE          byReserved[18];          /* reserved bytes */
  81.   BYTE          VendorSpecific[131];      /* vendor specific data */
  82.   BYTE          byCheckSum;          /* checksum of data in this structure */
  83. } DeviceThresholdsData, NEAR *NPDeviceThresholdsData, FAR *PDeviceThresholdsData;
  84.  
  85. /*
  86.  * Unit Configuration and Counters
  87.  */
  88.  
  89. typedef struct _UnitInformationData
  90. {
  91.   USHORT    wRevisionNumber;        /* structure revision number */
  92.   USHORT    wTaskFileBase;            /* task file register base addr */
  93.   USHORT    wAlternateStatusAddress;    /* alternate status register addr */
  94.   USHORT    wIRQ;                /* interrupt request level */
  95.   USHORT    wFlags;             /* flags */
  96.   BYTE          byPIO_Mode;          /* PIO transfer mode programmed */
  97.   BYTE          byDMA_Mode;          /* DMA transfer mode programmed */
  98.  
  99. } UnitInformationData, *PUnitInformationData;
  100.  
  101. /*
  102.  * Unit Information Flags Definitions
  103.  */
  104.  
  105. #define UIF_VALID        0x8000      /* unit information valid */
  106. #define UIF_TIMINGS_VALID   0x4000      /* timing information valid */
  107. #define UIF_RUNNING_BMDMA   0x2000      /* running Bus Master DMA on unit */
  108. #define UIF_RUNNING_DMA     0x1000      /* running slave DMA on unit */
  109. #define UIF_SLAVE        0x0002      /* slave on channel */
  110. #define UIF_ATAPI        0x0001      /* ATAPI device if 1, ATA otherwise */
  111.  
  112. typedef struct _DeviceCountersData
  113. {
  114.   USHORT      wRevisionNumber;          /* counter structure revision */
  115.   ULONG       TotalReadOperations;      /* total read operations performed */
  116.   ULONG       TotalWriteOperations;      /* total write operations performed */
  117.   ULONG       TotalWriteErrors;       /* total write errors encountered */
  118.   ULONG       TotalReadErrors;          /* total read errors encountered */
  119.   ULONG       TotalSeekErrors;          /* total seek errors encountered */
  120.   ULONG       TotalSectorsRead;       /* total number of sectors read */
  121.   ULONG       TotalSectorsWritten;      /* total number of sectors written */
  122.  
  123.   ULONG       TotalBMReadOperations;      /* [003] total bus master DMA read operations */
  124.   ULONG       TotalBMWriteOperations;      /* [003] total bus master DMA write operations */
  125.   ULONG       ByteMisalignedBuffers;      /* [003] total buffers on odd byte boundary */
  126.   ULONG       TransfersAcross64K;      /* [003] total buffers crossing a 64K page boundary */
  127.   ULONG       Reserved[4];          /* [003] */
  128. } DeviceCountersData, *PDeviceCountersData;
  129.  
  130. /* Identify Data */
  131.  
  132. typedef struct _IDENTIFYDATA  *PIDENTIFYDATA;
  133.  
  134. typedef struct _IDENTIFYDATA
  135. {
  136.   USHORT    GeneralConfig;        /*  0 General configuration bits      */
  137.   USHORT    TotalCylinders;     /*  1 Default Translation - Num cyl   */
  138.   USHORT    Reserved;        /*  2 Reserved                  */
  139.   USHORT    NumHeads;        /*  3              - Num heads */
  140.   USHORT    NumUnformattedbpt;    /*  4 Unformatted Bytes   - Per track */
  141.   USHORT    NumUnformattedbps;    /*  5              - Per sector*/
  142.   USHORT    SectorsPerTrack;    /*  6 Default Translation - Sec/Trk   */
  143.   USHORT    NumBytesISG;        /*  7 Byte Len - inter-sector gap     */
  144.   USHORT    NumBytesSync;        /*  8           - sync field          */
  145.   USHORT    NumWordsVUS;        /*  9 Len - Vendor Unique Info          */
  146.   CHAR        SerialNum[20];        /* 10 Serial number              */
  147.   USHORT    CtrlType;        /* 20 Controller Type              */
  148.   USHORT    CtrlBufferSize;     /* 21 Ctrl buffer size - Sectors      */
  149.   USHORT    NumECCBytes;        /* 21 ECC bytes -  read/write long    */
  150.   CHAR        FirmwareRN[8];        /* 23 Firmware Revision           */
  151.   CHAR        ModelNum[40];        /* 27 Model number              */
  152.   USHORT    NumSectorsPerInt;    /* 47 Multiple Mode - Sec/Blk          */
  153.   USHORT    DoubleWordIO;        /* 48 [001] Double Word IO Flag       */
  154.   USHORT    IDECapabilities;    /* 49 [001] Capability Flags Word     */
  155.   USHORT    Reserved2;        /* 50 [001]                  */
  156.   USHORT    PIOCycleTime;        /* 51 Transfer Cycle Timing - PIO     */
  157.   USHORT    DMACycleTime;        /* 52                - DMA     */
  158.   USHORT    AdditionalWordsValid;    /* 53 [002] Additional Words valid    */
  159.   USHORT    LogNumCyl;        /* 54 Current Translation - Num Cyl   */
  160.   USHORT    LogNumHeads;        /* 55                Num Heads */
  161.   USHORT    LogSectorsPerTrack;    /* 56                Sec/Trk   */
  162.   ULONG     LogTotalSectors;    /* 57                Total Sec */
  163.   USHORT    LogNumSectorsPerInt;    /* 59                      */
  164.   ULONG     LBATotalSectors;    /* 60 LBA Mode - Sectors          */
  165.   USHORT    DMASWordFlags;        /* 62                      */
  166.   USHORT    DMAMWordFlags;        /* 63                      */
  167.   USHORT    AdvancedPIOModes;    /* 64 [002] Advanced PIO modes supported */
  168.   USHORT    MinMWDMACycleTime;    /* 65 [002] Minimum multiWord DMA cycle time */
  169.   USHORT    RecMWDMACycleTime;    /* 66 [002] Recommended MW DMA cycle time */
  170.   USHORT    MinPIOCycleTimeWOFC;    /* 67 [002] Minimum PIO cycle time without IORDY */
  171.   USHORT    MinPIOCycleTime;    /* 68 [002] Minimum PIO cycle time    */
  172.   USHORT    Reserved3[82-69];    /* 69             @V179942 @DANI1    */
  173.   USHORT    CommandSetSupported[3]; /* 82             @DANI1*/
  174.   USHORT    CommandSetEnabled[3];    /* 85             @DANI1*/
  175.   USHORT    UltraDMAModes;        /* 88 Ultra DMA Modes     @V179942     */
  176.   USHORT    Reserved4[93-89];    /* 89             @V179942     *//*@DANI12*/
  177.   USHORT    HardwareTestResult;    /* 93 hardware test result    @DANI12 */
  178.   USHORT    Reserved5[127-94];    /* 94             @DANI12      */
  179.   USHORT    MediaStatusWord;    /* 127 media status Word @V151345 SRD */
  180.   USHORT    Reserved6[256-128];    /*             @V151345     *//*@DANI12*/
  181. }IDENTIFYDATA;
  182.  
  183.  
  184. int main (int argc, char *argv[]) {
  185.   APIRET rc;
  186.   HFILE hDevice;
  187.   ULONG ActionTaken;
  188.   UCHAR Options = 0;
  189.   int i, j;
  190.   DSKSP_CommandParameters Parms;
  191.   ULONG PLen = 1;
  192.   ULONG IDLen = 512;
  193.   IDENTIFYDATA Id;
  194.   ULONG UnitInfoLen = sizeof (UnitInformationData);
  195.   UnitInformationData UnitInfo;
  196.   char Model[41];
  197.  
  198.   {
  199.     PCHAR p;
  200.  
  201.     if ((p = strrchr (argv[0], '.')) != NULL)
  202.       *p = '\0';
  203.     if ((p = strrchr (argv[0], '\\')) != NULL)
  204.       p++;
  205.     else
  206.       if ((p = strrchr (argv[0], ':')) != NULL)
  207.     p++;
  208.     argv[0] = p;
  209.   }
  210.  
  211.   if (argc > 1) {
  212.     for (i = 1; i < argc; i++) {
  213.       if (strchr (argv[i], 'i')) Options |= 4;
  214.       if (strchr (argv[i], 'c')) Options |= 2;
  215.       if (strchr (argv[i], 'v')) Options |= 1;
  216.       if (strchr (argv[i], 's')) Options |= 8;
  217.     }
  218.     if (Options == 0) {
  219.       printf ("Usage: %s {i}{c}{v}{s}\n", argv[0]);
  220.       exit (1);
  221.     }
  222.   }
  223.  
  224.   rc = DosOpen ("\\DEV\\IBMS506$", &hDevice, &ActionTaken, 0,  FILE_SYSTEM,
  225.          OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
  226.          OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
  227.   if (rc) exit (rc);
  228.  
  229.   for (i = 0; i < 8; i++) {
  230.     printf ("%d/%c: ", i / 2, i % 2 ? 's' : 'm');
  231.     Parms.byPhysicalUnit = i;
  232.     memset (&Id, 0, 512);
  233.     rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
  234.               (PVOID)&Parms, PLen, &PLen, (PVOID)&Id, IDLen, &IDLen);
  235.     if (rc == 0xFF02) {
  236.       printf ("(not present)\n");
  237.       continue;
  238.     }
  239.  
  240.     for (j = 0; j < 40; j++)
  241.       Model[j] = Id.ModelNum[j ^ 1];
  242.     Model[40] = '\0';
  243.     printf ("%s \n", Model);
  244.  
  245.     rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GET_UNIT_INFORMATION,
  246.               (PVOID)&Parms, PLen, &PLen, (PVOID)&UnitInfo, UnitInfoLen, &UnitInfoLen);
  247.  
  248.     if (Options & 1) {
  249.       printf ("Port %4X/%4X, Irq %d",
  250.           UnitInfo.wTaskFileBase, UnitInfo.wAlternateStatusAddress, UnitInfo.wIRQ);
  251.       if (UnitInfo.wFlags & UIF_ATAPI) printf (", ATAPI");
  252.       if (UnitInfo.wFlags & UIF_RUNNING_BMDMA) printf (", DMA busmaster");
  253.       printf (", PIO%d", UnitInfo.byPIO_Mode);
  254.       if (UnitInfo.wFlags & UIF_RUNNING_BMDMA)
  255.     if (UnitInfo.byDMA_Mode > 2)
  256.       printf (", UltraDMA%d", UnitInfo.byDMA_Mode - 3);
  257.     else
  258.       printf (", DMA%d", UnitInfo.byDMA_Mode);
  259.       printf ("\n\n");
  260.     }
  261.  
  262.     if ((Options & 8) && !(UnitInfo.wFlags & UIF_ATAPI)) {
  263.       ULONG value;
  264.       ULONG DataLen = sizeof (value);
  265.  
  266.       rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GETSTATUS,
  267.             (PVOID)&Parms, PLen, &PLen, (PVOID)&value, DataLen, &DataLen);
  268.       printf ("SMART: ");
  269.       if (rc == 0xFF03)
  270.     printf ("not supported or disabled\n\n");
  271.       else
  272.     printf ("device is%s reliable\n\n", value ? " NOT" : "");
  273.     }
  274.  
  275.     if ((Options & 2) && !(UnitInfo.wFlags & UIF_ATAPI)) {
  276.       ULONG CountersLen = sizeof (DeviceCountersData);
  277.       DeviceCountersData Counters;
  278.  
  279.       rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GEN_GET_COUNTERS,
  280.             (PVOID)&Parms, PLen, &PLen, (PVOID)&Counters, CountersLen, &CountersLen);
  281.  
  282.       printf ("Device counters\n");
  283.       printf ("Total operations    : %8d reads, %8d writes\n", Counters.TotalReadOperations, Counters.TotalWriteOperations);
  284.       printf ("Total sectors       : %8d reads, %8d writes\n", Counters.TotalSectorsRead, Counters.TotalSectorsWritten);
  285.       printf ("Busmaster operations: %8d reads, %8d writes, %8d misaligned\n",
  286.     Counters.TotalBMReadOperations, Counters.TotalBMWriteOperations, Counters.ByteMisalignedBuffers);
  287.       printf ("Total errors        : %8d reads, %8d writes, %8d seeks \n", Counters.TotalReadErrors, Counters.TotalWriteErrors, Counters.TotalSeekErrors);
  288.       printf ("\n");
  289.     }
  290.  
  291.     if (Options & 4) {
  292.       int k;
  293.       USHORT *p;
  294.  
  295.       printf ("%sIDENTIFY response\n", (UnitInfo.wFlags & UIF_ATAPI) ? "ATAPI " : "");
  296.  
  297.       p = (USHORT *)&Id;
  298.       for (j = 0; j < 256; j += 8) {
  299.     printf ("% 4d/%03X: ", j, j);
  300.     for (k = 0; k < 8; k++) {
  301.       printf ("%04X ", *(p++));
  302.       if (k == 3)
  303.         printf (" ");
  304.     }
  305.     printf ("\n");
  306.       }
  307.       printf ("\n");
  308.     }
  309.   }
  310.  
  311.   DosClose (hDevice);
  312.  
  313.   if (Options == 0)
  314.     printf ("\nmore info with %s {i}{c}{v}{s}\n", argv[0]);
  315.  
  316.   return (rc);
  317. }
  318.