Diff for /embedaddon/smartmontools/os_freebsd.cpp between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 16:32:16 version 1.1.1.2, 2012/10/09 09:36:45
Line 194  static const char  smartctl_examples[] = Line 194  static const char  smartctl_examples[] =
   "  smartctl -a --device=cciss,0 /dev/ciss0\n"    "  smartctl -a --device=cciss,0 /dev/ciss0\n"
          "                              (Prints all SMART information for first disk \n"           "                              (Prints all SMART information for first disk \n"
          "                               on Common Interface for SCSI-3 Support driver)\n"           "                               on Common Interface for SCSI-3 Support driver)\n"
  "  smartctl -a --device=areca,1 /dev/arcmsr0\n"  "  smartctl -a --device=areca,3/1 /dev/arcmsr0\n"
         "                              (Prints all SMART information for first disk \n"         "                              (Prints all SMART information for 3rd disk in the 1st enclosure \n"
          "                               on first ARECA RAID controller)\n"           "                               on first ARECA RAID controller)\n"
   
          ;           ;
Line 931  int freebsd_highpoint_device::ata_command_interface(sm Line 931  int freebsd_highpoint_device::ata_command_interface(sm
   
   
 /////////////////////////////////////////////////////////////////////////////  /////////////////////////////////////////////////////////////////////////////
/// Implement standard SCSI support with old functions/// Standard SCSI support
   
 class freebsd_scsi_device  class freebsd_scsi_device
 : public /*implements*/ scsi_device,  : public /*implements*/ scsi_device,
Line 1013  bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_ Line 1013  bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_
     warnx("error allocating ccb");      warnx("error allocating ccb");
     return -ENOMEM;      return -ENOMEM;
   }    }
     // mfi SAT layer is known to be buggy
     if(!strcmp("mfi",m_camdev->sim_name)) {
       if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) { 
         // Controller does not return ATA output registers in SAT sense data
         if (iop->cmnd[2] & (1 << 5)) // chk_cond
           return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
       }
       // SMART WRITE LOG SECTOR causing media errors
       if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16 && iop->cmnd[14] == ATA_SMART_CMD 
           && iop->cmnd[3]==0 && iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) || 
           (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 && iop->cmnd[9] == ATA_SMART_CMD &&
           iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR)) 
         return set_err(ENOSYS, "SMART WRITE LOG SECTOR command is not supported by controller firmware"); 
     }
   
   // clear out structure, except for header that was filled in for us    // clear out structure, except for header that was filled in for us
   bzero(&(&ccb->ccb_h)[1],    bzero(&(&ccb->ccb_h)[1],
Line 1044  bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_ Line 1058  bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_
   }    }
   
   if (iop->sensep) {    if (iop->sensep) {
    memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));    iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
    iop->resp_sense_len = sizeof(struct scsi_sense_data);    memcpy(iop->sensep,&(ccb->csio.sense_data),iop->resp_sense_len);
   }    }
   
   iop->scsi_status = ccb->csio.scsi_status;    iop->scsi_status = ccb->csio.scsi_status;
Line 1075  class freebsd_areca_device Line 1089  class freebsd_areca_device
   public /*extends*/ freebsd_smart_device    public /*extends*/ freebsd_smart_device
 {  {
 public:  public:
  freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum);  freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
   
 protected:  protected:
   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);     virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); 
   
 private:  private:
   int m_disknum; ///< Disk number.    int m_disknum; ///< Disk number.
     int m_encnum;
 };  };
   
   
Line 1299  static int arcmsr_command_handler(int fd, unsigned lon Line 1314  static int arcmsr_command_handler(int fd, unsigned lon
 }  }
   
   
freebsd_areca_device::freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum)freebsd_areca_device::freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 : smart_device(intf, dev_name, "areca", "areca"),  : smart_device(intf, dev_name, "areca", "areca"),
   freebsd_smart_device("ATA"),    freebsd_smart_device("ATA"),
  m_disknum(disknum)  m_disknum(disknum),
   m_encnum(encnum)
 {  {
  set_info().info_name = strprintf("%s [areca_%02d]", dev_name, disknum);  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
 }  }
   
 // Areca RAID Controller  // Areca RAID Controller
Line 1423  if (!ata_cmd_is_ok(in,  Line 1439  if (!ata_cmd_is_ok(in, 
             return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");              return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");
         }          }
   
        areca_packet[11] = m_disknum - 1;                  // drive number        areca_packet[11] = m_disknum - 1;               // disk #
         areca_packet[19] = m_encnum - 1;                // enc#
   
         // ----- BEGIN TO SETUP CHECKSUM -----          // ----- BEGIN TO SETUP CHECKSUM -----
         for ( int loop = 3; loop < areca_packet_len - 1; loop++ )          for ( int loop = 3; loop < areca_packet_len - 1; loop++ )
Line 1590  smart_device * freebsd_scsi_device::autodetect_open() Line 1607  smart_device * freebsd_scsi_device::autodetect_open()
     return this;      return this;
   }    }
   
  // SAT or USB ?  // SAT or USB, skip MFI controllers because of bugs
   {    {
     smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);      smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
    if (newdev)    if (newdev) {
       // NOTE: 'this' is now owned by '*newdev'        // NOTE: 'this' is now owned by '*newdev'
         if(!strcmp("mfi",m_camdev->sim_name)) {
           newdev->close();
           newdev->set_err(ENOSYS, "SATA device detected,\n"
             "MegaRAID SAT layer is reportedly buggy, use '-d sat' to try anyhow");
         }
       return newdev;        return newdev;
       }
   }    }
   
   // Nothing special found    // Nothing special found
Line 1749  bool get_dev_names_cam(std::vector<std::string> & name Line 1772  bool get_dev_names_cam(std::vector<std::string> & name
       if (ccb.cdm.matches[i].type == DEV_MATCH_BUS) {        if (ccb.cdm.matches[i].type == DEV_MATCH_BUS) {
         bus_result = &ccb.cdm.matches[i].result.bus_result;          bus_result = &ccb.cdm.matches[i].result.bus_result;
   
        if (strcmp(bus_result->dev_name,"ata") == 0 /* ATAPICAM devices will be probed as ATA devices, skip'em there */        if (strcmp(bus_result->dev_name,"xpt") == 0) /* skip XPT bus at all */
          || strcmp(bus_result->dev_name,"xpt") == 0) /* skip XPT bus at all */ 
         skip_bus = 1;          skip_bus = 1;
         else          else
           skip_bus = 0;            skip_bus = 0;
Line 2079  smart_device * freebsd_smart_interface::autodetect_sma Line 2101  smart_device * freebsd_smart_interface::autodetect_sma
   int bus=-1;    int bus=-1;
   int i,c;    int i,c;
   int len;    int len;
     const char * test_name = name;
   
   // if dev_name null, or string length zero    // if dev_name null, or string length zero
   if (!name || !(len = strlen(name)))    if (!name || !(len = strlen(name)))
     return 0;      return 0;
   
     // Dereference symlinks
     struct stat st;
     std::string pathbuf;
     if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
       char * p = realpath(name, (char *)0);
       if (p) {
         pathbuf = p;
         free(p);
         test_name = pathbuf.c_str();
       }
     }
   
   // check ATA bus    // check ATA bus
   char * * atanames = 0; int numata = 0;    char * * atanames = 0; int numata = 0;
   numata = get_dev_names_ata(&atanames);    numata = get_dev_names_ata(&atanames);
   if (numata > 0) {    if (numata > 0) {
     // check ATA/ATAPI devices      // check ATA/ATAPI devices
     for (i = 0; i < numata; i++) {      for (i = 0; i < numata; i++) {
      if(!strcmp(atanames[i],name)) {      if(!strcmp(atanames[i],test_name)) {
         for (c = i; c < numata; c++) free(atanames[c]);          for (c = i; c < numata; c++) free(atanames[c]);
         free(atanames);          free(atanames);
        return new freebsd_ata_device(this, name, "");        return new freebsd_ata_device(this, test_name, "");
       }        }
       else free(atanames[i]);        else free(atanames[i]);
     }      }
Line 2111  smart_device * freebsd_smart_interface::autodetect_sma Line 2146  smart_device * freebsd_smart_interface::autodetect_sma
   else if (!scsinames.empty()) {    else if (!scsinames.empty()) {
     // check all devices on CAM bus      // check all devices on CAM bus
     for (i = 0; i < (int)scsinames.size(); i++) {      for (i = 0; i < (int)scsinames.size(); i++) {
      if(strcmp(scsinames[i].c_str(), name)==0)      if(strcmp(scsinames[i].c_str(), test_name)==0)
       { // our disk device is CAM        { // our disk device is CAM
        if ((cam_dev = cam_open_device(name, O_RDWR)) == NULL) {        if ((cam_dev = cam_open_device(test_name, O_RDWR)) == NULL) {
           // open failure            // open failure
           set_err(errno);            set_err(errno);
           return 0;            return 0;
         }          }
           
         // zero the payload          // zero the payload
         bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE);          bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE);
         ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device          ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device
Line 2136  smart_device * freebsd_smart_interface::autodetect_sma Line 2170  smart_device * freebsd_smart_interface::autodetect_sma
           if(usbdevlist(bus,vendor_id, product_id, version)){            if(usbdevlist(bus,vendor_id, product_id, version)){
             const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);              const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
             if (usbtype)              if (usbtype)
              return get_sat_device(usbtype, new freebsd_scsi_device(this, name, ""));              return get_sat_device(usbtype, new freebsd_scsi_device(this, test_name, ""));
           }            }
           return 0;            return 0;
         }          }
Line 2144  smart_device * freebsd_smart_interface::autodetect_sma Line 2178  smart_device * freebsd_smart_interface::autodetect_sma
         // check if we have ATA device connected to CAM (ada)          // check if we have ATA device connected to CAM (ada)
         if(ccb.cpi.protocol == PROTO_ATA){          if(ccb.cpi.protocol == PROTO_ATA){
           cam_close_device(cam_dev);            cam_close_device(cam_dev);
          return new freebsd_atacam_device(this, name, "");          return new freebsd_atacam_device(this, test_name, "");
         }          }
 #endif  #endif
         // close cam device, we don`t need it anymore          // close cam device, we don`t need it anymore
         cam_close_device(cam_dev);          cam_close_device(cam_dev);
         // handle as usual scsi          // handle as usual scsi
        return new freebsd_scsi_device(this, name, "");              return new freebsd_scsi_device(this, test_name, "");      
       }        }
     }      }
   }    }
   // device is LSI raid supported by mfi driver    // device is LSI raid supported by mfi driver
  if(!strncmp("/dev/mfid", name, strlen("/dev/mfid")))  if(!strncmp("/dev/mfid", test_name, strlen("/dev/mfid")))
     set_err(EINVAL, "To monitor disks on LSI RAID load mfip.ko module and run 'smartctl -a /dev/passX' to show SMART information");      set_err(EINVAL, "To monitor disks on LSI RAID load mfip.ko module and run 'smartctl -a /dev/passX' to show SMART information");
   // device type unknown    // device type unknown
   return 0;    return 0;
Line 2230  smart_device * freebsd_smart_interface::get_custom_sma Line 2264  smart_device * freebsd_smart_interface::get_custom_sma
       set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);        set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
       return 0;        return 0;
     }      }
    return new freebsd_cciss_device(this, name, disknum);    return get_sat_device("sat,auto", new freebsd_cciss_device(this, name, disknum));
   }    }
 #if FREEBSDVER > 800100  #if FREEBSDVER > 800100
   // adaX devices ?    // adaX devices ?
Line 2239  smart_device * freebsd_smart_interface::get_custom_sma Line 2273  smart_device * freebsd_smart_interface::get_custom_sma
 #endif  #endif
   // Areca?    // Areca?
   disknum = n1 = n2 = -1;    disknum = n1 = n2 = -1;
  if (sscanf(type, "areca,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {  int encnum = 1;
    if (n2 != (int)strlen(type)) {  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
      set_err(EINVAL, "Option -d areca,N requires N to be a non-negative integer");    if (!(1 <= disknum && disknum <= 128)) {
       set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
       return 0;        return 0;
     }      }
    if (!(1 <= disknum && disknum <= 24)) {    if (!(1 <= encnum && encnum <= 8)) {
      set_err(EINVAL, "Option -d areca,N (N=%d) must have 1 <= N <= 24", disknum);      set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
       return 0;        return 0;
     }      }
     return new freebsd_areca_device(this, name, disknum);      return new freebsd_areca_device(this, name, disknum);
Line 2256  smart_device * freebsd_smart_interface::get_custom_sma Line 2291  smart_device * freebsd_smart_interface::get_custom_sma
   
 std::string freebsd_smart_interface::get_valid_custom_dev_types_str()  std::string freebsd_smart_interface::get_valid_custom_dev_types_str()
 {  {
  return "3ware,N, hpt,L/M/N, cciss,N, areca,N"  return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
 #if FREEBSDVER > 800100  #if FREEBSDVER > 800100
   ", atacam"    ", atacam"
 #endif  #endif

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>