[BACK]Return to atactl.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / atactl

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sbin/atactl/atactl.c between version 1.14 and 1.15

version 1.14, 2001/09/07 16:33:50 version 1.15, 2002/08/05 23:29:29
Line 52 
Line 52 
 #include <util.h>  #include <util.h>
   
 #include <dev/ata/atareg.h>  #include <dev/ata/atareg.h>
   #include <dev/ata/atavar.h>
 #include <dev/ic/wdcreg.h>  #include <dev/ic/wdcreg.h>
 #include <sys/ataio.h>  #include <sys/ataio.h>
   
Line 70  int main(int, char *[]);
Line 71  int main(int, char *[]);
 void    usage(void);  void    usage(void);
 void    ata_command(struct atareq *);  void    ata_command(struct atareq *);
 void    print_bitinfo(const char *, const char *, u_int, struct bitinfo *);  void    print_bitinfo(const char *, const char *, u_int, struct bitinfo *);
   void    print_smart_status(void *vbuf, void *tbuf);
   int     is_smart(int silent);
   
 int     fd;                             /* file descriptor for device */  int     fd;                             /* file descriptor for device */
 const   char *dvname;                   /* device name */  const   char *dvname;                   /* device name */
Line 81  void device_identify(int, char *[]);
Line 84  void device_identify(int, char *[]);
 void    device_setidle(int, char *[]);  void    device_setidle(int, char *[]);
 void    device_idle(int, char *[]);  void    device_idle(int, char *[]);
 void    device_checkpower(int, char *[]);  void    device_checkpower(int, char *[]);
   void    device_smart(int, char *[]);
   
 struct command commands[] = {  struct command commands[] = {
         { "identify",   "",                     device_identify },          { "identify",   "",                     device_identify },
Line 90  struct command commands[] = {
Line 94  struct command commands[] = {
         { "standby",    "",                     device_idle },          { "standby",    "",                     device_idle },
         { "sleep",      "",                     device_idle },          { "sleep",      "",                     device_idle },
         { "checkpower", "",                     device_checkpower },          { "checkpower", "",                     device_checkpower },
           { "smart",      "enable|disable|info",  device_smart },
         { NULL,         NULL,                   NULL },          { NULL,         NULL,                   NULL },
 };  };
   
Line 263  print_bitinfo(const char *bf, const char
Line 268  print_bitinfo(const char *bf, const char
 }  }
   
 /*  /*
    * Print out SMART attribute thresholds and values
    */
   
   void
   print_smart_status(void *vbuf, void *tbuf)
   {
           struct ata_smart_attributes *value_buf = vbuf;
           struct ata_smart_thresholds *threshold_buf = tbuf;
           int values[256];
           int thresholds[256];
           int flags[256];
           int i;
           int id;
           int8_t checksum;
   
           for (i = checksum = 0; i < 511; i++)
                   checksum += ((int8_t *) value_buf)[i];
           checksum *= -1;
           if (checksum != value_buf->checksum) {
                   fprintf(stderr, "SMART attribute values checksum error\n");
                   return;
           }
   
           for (i = checksum = 0; i < 511; i++)
                   checksum += ((int8_t *) threshold_buf)[i];
           checksum *= -1;
           if (checksum != threshold_buf->checksum) {
                   fprintf(stderr, "SMART attribute thresholds checksum error\n");
                   return;
           }
   
           memset(values, 0, sizeof(values));
           memset(thresholds, 0, sizeof(thresholds));
           memset(flags, 0, sizeof(flags));
   
           for (i = 0; i < 30; i++) {
                   id = value_buf->attributes[i].id;
                   values[id] = value_buf->attributes[i].value;
                   flags[id] = value_buf->attributes[i].flags;
                   id = threshold_buf->thresholds[i].id;
                   thresholds[id] = threshold_buf->thresholds[i].value;
           }
   
           printf("id\tvalue\tthresh\tcrit\tcollect\treliability\n");
           for (i = 0; i < 256; i++) {
                   if (values[i] != 00 && values[i] != 0xFE && values[i] != 0xFF) {
                           printf("%2d\t%3d\t%3d\t%s\t%sline\t%stive\n",
                                  i, values[i], thresholds[i],
                                  flags[i] & WDSM_ATTR_ADVISORY ? "yes" : "no",
                                  flags[i] & WDSM_ATTR_COLLECTIVE ? "on" : "off",
                                  values[i] > thresholds[i] ? "posi" : "nega");
                   }
           }
   }
   
   /*
    * is_smart:
    *
    *      Detect whether device supports SMART and SMART is enabled.
    */
   
   int
   is_smart(int silent)
   {
           int retval = 0;
           struct atareq req;
           unsigned char inbuf[DEV_BSIZE];
           struct ataparams *inqbuf;
           char *status;
   
           memset(&inbuf, 0, sizeof(inbuf));
           memset(&req, 0, sizeof(req));
   
           inqbuf = (struct ataparams *) inbuf;
   
           req.flags = ATACMD_READ;
           req.command = WDCC_IDENTIFY;
           req.databuf = (caddr_t) inbuf;
           req.datalen = sizeof(inbuf);
           req.timeout = 1000;
   
           ata_command(&req);
   
           if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) {
                   if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) {
                           fprintf(stderr, "SMART unsupported\n");
                   } else {
                           if (inqbuf->atap_ata_major <= WDC_VER_ATA5 ||
                               inqbuf->atap_cmd_set2 == 0xffff ||
                               inqbuf->atap_cmd_set2 == 0x0000) {
                                   status = "status unknown";
                                   retval = 2;
                           } else {
                                   if (inqbuf->atap_cmd_set2 & ATA_CMD2_SMART) {
                                           status = "enabled";
                                           retval = 1;
                                   } else {
                                           status = "disabled";
                                   }
                           }
                           if (!silent || retval == 0) {
                                   printf("SMART supported, SMART %s\n", status);
                           }
                   }
           }
           return retval;
   }
   
   /*
  * DEVICE COMMANDS   * DEVICE COMMANDS
  */   */
   
Line 517  device_checkpower(int argc, char *argv[]
Line 631  device_checkpower(int argc, char *argv[]
   
         return;          return;
 }  }
   
   /*
    * device_smart:
    *
    *      Display SMART status
    */
   void
   device_smart(int argc, char *argv[])
   {
           struct atareq req;
           unsigned char inbuf[DEV_BSIZE];
           unsigned char inbuf2[DEV_BSIZE];
   
           /* Only one argument */
           if (argc != 1)
                   usage();
   
           if (strcmp(argv[0], "enable") == 0) {
                   if (is_smart(1)) {
                           memset(&req, 0, sizeof(req));
   
                           req.features = WDSM_ENABLE_OPS;
                           req.command = WDCC_SMART;
                           req.cylinder = htole16(WDSMART_CYL);
                           req.timeout = 1000;
   
                           ata_command(&req);
   
                           is_smart(0);
                   }
           } else if (strcmp(argv[0], "disable") == 0) {
                   if (is_smart(1)) {
                           memset(&req, 0, sizeof(req));
   
                           req.features = WDSM_DISABLE_OPS;
                           req.command = WDCC_SMART;
                           req.cylinder = htole16(WDSMART_CYL);
                           req.timeout = 1000;
   
                           ata_command(&req);
   
                           is_smart(0);
                   }
           } else if (strcmp(argv[0], "info") == 0) {
                   if (is_smart(0)) {
                           memset(&inbuf, 0, sizeof(inbuf));
                           memset(&req, 0, sizeof(req));
   
                           req.features = WDSM_STATUS;
                           req.command = WDCC_SMART;
                           req.cylinder = htole16(WDSMART_CYL);
                           req.timeout = 1000;
   
                           ata_command(&req);
   
                           if (req.cylinder != htole16(WDSMART_CYL)) {
                                   fprintf(stderr, "Threshold exceeds condition\n");
                           }
   
                           /* WDSM_RD_DATA and WDSM_RD_THRESHOLDS are optional
                            * features, the following ata_command()'s may error
                            * and exit().
                            */
   
                           memset(&inbuf, 0, sizeof(inbuf));
                           memset(&req, 0, sizeof(req));
   
                           req.flags = ATACMD_READ;
                           req.features = WDSM_RD_DATA;
                           req.command = WDCC_SMART;
                           req.databuf = (caddr_t) inbuf;
                           req.datalen = sizeof(inbuf);
                           req.cylinder = htole16(WDSMART_CYL);
                           req.timeout = 1000;
   
                           ata_command(&req);
   
                           memset(&inbuf2, 0, sizeof(inbuf2));
                           memset(&req, 0, sizeof(req));
   
                           req.flags = ATACMD_READ;
                           req.features = WDSM_RD_THRESHOLDS;
                           req.command = WDCC_SMART;
                           req.databuf = (caddr_t) inbuf2;
                           req.datalen = sizeof(inbuf2);
                           req.cylinder = htole16(WDSMART_CYL);
                           req.timeout = 1000;
   
                           ata_command(&req);
   
                           print_smart_status(inbuf, inbuf2);
                   } else {
                           fprintf(stderr, "SMART not supported\n");
                   }
           } else {
                   usage();
           }
           return;
   }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

CVSweb <webmaster@jp.NetBSD.org>