Ejemplo n.º 1
0
smart_device * smart_interface::get_smart_device(const char * name, const char * type)
{
  clear_err();

  // Call platform specific autodetection if no device type specified
  smart_device * dev;
  if (!type || !*type) {
    dev = autodetect_smart_device(name);
    if (!dev && !get_errno())
      set_err(EINVAL, "Unable to detect device type");
    return dev;
  }

  // First check for platform specific device types
  dev = get_custom_smart_device(name, type);
  if (dev || get_errno())
    return dev;

  if (!strcmp(type, "ata"))
    dev = get_ata_device(name, type);
  else if (!strcmp(type, "scsi"))
    dev = get_scsi_device(name, type);

  else if (  ((!strncmp(type, "sat", 3) && (!type[3] || strchr(",+", type[3])))
           || (!strncmp(type, "usb", 3)))) {
    // Split "sat...+base..." -> ("sat...", "base...")
    unsigned satlen = strcspn(type, "+");
    std::string sattype(type, satlen);
    const char * basetype = (type[satlen] ? type+satlen+1 : "");
    // Recurse to allocate base device, default is standard SCSI
    if (!*basetype)
      basetype = "scsi";
    smart_device_auto_ptr basedev( get_smart_device(name, basetype) );
    if (!basedev) {
      set_err(EINVAL, "Type '%s+...': %s", sattype.c_str(), get_errmsg());
      return 0;
    }
    // Result must be SCSI
    if (!basedev->is_scsi()) {
      set_err(EINVAL, "Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
      return 0;
    }
    // Attach SAT tunnel
    ata_device * satdev = get_sat_device(sattype.c_str(), basedev->to_scsi());
    if (!satdev)
      return 0;
    basedev.release();
    return satdev;
  }

  else {
    set_err(EINVAL, "Unknown device type '%s'", type);
    return 0;
  }
  if (!dev && !get_errno())
    set_err(EINVAL, "Not a device of type '%s'", type);
  return dev;
}
Ejemplo n.º 2
0
int add_entry_label(struct data_entry *entry, int label)
{
  int *atable = NULL;

  clear_err();

  /* adding an empty label does nothing */
  if (label == LABEL_EMPTY)
    return 0;
  
  /* add first label to entry */
  if (entry->num_labs == 0)
    {
      entry->num_labs = 1;
      entry->lab.label = label;
      return 0;
    }

  /* if there is already one label, we need to allocate a table for the 
     labels */

  if (entry->num_labs == 1)
    {
      atable = malloc(sizeof(int) * ATABLE_INCREMENT);
      if (atable == NULL)
	return ERR_NOMEM;
      
      /* move old entry to table and add the new label */
      entry->num_labs++;
      atable[0] = entry->lab.label;
      atable[1] = label;
      entry->lab.label_array = atable;
      return 0;
    }

  atable = entry->lab.label_array;

  /* enlarge label array if needed */
  if ((entry->num_labs % ATABLE_INCREMENT) == 0)
    {
      /* need more space */
      atable = realloc(atable,
		       sizeof(int) * (entry->num_labs + ATABLE_INCREMENT));
      if (atable == NULL)
	return ERR_NOMEM;
      entry->lab.label_array = atable;
    }

  atable[entry->num_labs++] = label;
      
  return 0;
}
Ejemplo n.º 3
0
struct hitlist *new_hitlist(void)
{
  struct hitlist *hl;

  clear_err();

  hl = malloc(sizeof(struct hitlist));
  if (hl == NULL)
    {
      ERROR(ERR_NOMEM);
      return NULL;
    }

  hl->head = hl->tail = NULL;
  hl->entries = 0;
  
  return hl;
}
Ejemplo n.º 4
0
    /**
     * \brief Calls the qualified compressor (inflate)
     *
     * \param[in] cdata pointer to compressed data
     * \param[in] cdata_size length of compressed data in bytes
     * \param[in,out] rdata pointer to memory for decompressed data
     * \param[out] rdata_size available space ar \p rdata in bytes
     * \param[in] rdata_element_size size of one element in decompressed vector
     * \returns true on success
     */
    bool unpack( void* cdata, size_t cdata_size, void* rdata, size_t rdata_size, size_t rdata_element_size )
    {
        bool status = false;

        assert( rdata && rdata_size > 0 );
        
        free_result();
        clear_data();
        clear_err();
        
        /// acquire compressed data
        m_cdata               = cdata;
        m_cdata_size          = cdata_size;
        m_rdata               = rdata;
        m_rdata_size          = rdata_size;
        m_rdata_element_size  = rdata_element_size;
        
        /// dispatch
        switch( m_eCompressorType )
        {
          case CT_BLOSC:
            status = bloscDecompress();
            break;
            
          case CT_QLIN16:
            status = linlogQuantizerDecompress( /* bDoLog*/ false );
            break;
            
          case CT_QLOG16:
            status = linlogQuantizerDecompress( /* bDoLog*/ true );
            break;
            
          default:
            break;
        }
        
        /// deplay result (uncompressed/raw data)
        m_result_is_const   = true;
        m_result            = m_rdata;
        m_result_size       = m_rdata_size;
        
        return status;        
    }
Ejemplo n.º 5
0
 /**
  * \brief Calls the qualified compressor (deflate) which always allocates sufficient memory (m_cdata)
  *
  * \param[in] rdata pointer to raw data (byte stream)
  * \param[in] rdata_size length of raw data in bytes
  * \param[in] rdata_element_size size of one element in bytes
  * \param[in] isDoubleClass true, if elements represent double types
  * \returns true on success
  */
 bool pack( void* rdata, size_t rdata_size, size_t rdata_element_size, bool isDoubleClass )
 {
     bool status = false;
     
     free_result();
     clear_data();
     clear_err();
     
     // acquire raw data
     m_rdata                 = rdata;
     m_rdata_size            = rdata_size;
     m_rdata_element_size    = rdata_element_size;
     m_rdata_is_double_type  = isDoubleClass;
     
     // dispatch
     switch( m_eCompressorType )
     {
       case CT_BLOSC:
         status = bloscCompress();
         break;
         
       case CT_QLIN16:
         status = linlogQuantizerCompress( /* bDoLog*/ false );
         break;
         
       case CT_QLOG16:
         status = linlogQuantizerCompress( /* bDoLog*/ true );
         break;
         
       default:
         break;
     }
     
     /// deploy result (compressed data)
     m_result_is_const   = false;
     m_result            = m_cdata;
     m_result_size       = m_cdata_size;
     
     return status;
 }
Ejemplo n.º 6
0
int copy_entry_labels(struct data_entry *dest, struct data_entry *source)
{
  int blocks, size, *atable;
  
  clear_err();

  clear_entry_labels(dest); /* remove old labels first */

  if (source->num_labs <= 1)
    dest->lab.label = source->lab.label;
  else
    {
      blocks = (source->num_labs + ATABLE_INCREMENT - 1) / ATABLE_INCREMENT;
      size = sizeof(int) * blocks * ATABLE_INCREMENT;
      atable = malloc(size);
      if (atable == NULL)
	return ERR_NOMEM;
      memcpy(atable, source->lab.label_array, size);
      dest->lab.label_array = atable;
    }
  dest->num_labs = source->num_labs;

  return 0;
}
Ejemplo n.º 7
0
bool ata_device_with_command_set::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
{
  if (!ata_cmd_is_ok(in, true)) // data_out_support
    return false;

  smart_command_set command = (smart_command_set)-1;
  int select = 0;
  char * data = (char *)in.buffer;
  char buffer[512];
  switch (in.in_regs.command) {
    case ATA_IDENTIFY_DEVICE:
      command = IDENTIFY;
      break;
    case ATA_IDENTIFY_PACKET_DEVICE:
      command = PIDENTIFY;
      break;
    case ATA_CHECK_POWER_MODE:
      command = CHECK_POWER_MODE;
      data = buffer; data[0] = 0;
      break;
    case ATA_SMART_CMD:
      switch (in.in_regs.features) {
        case ATA_SMART_ENABLE:
          command = ENABLE;
          break;
        case ATA_SMART_READ_VALUES:
          command = READ_VALUES;
          break;
        case ATA_SMART_READ_THRESHOLDS:
          command = READ_THRESHOLDS;
          break;
        case ATA_SMART_READ_LOG_SECTOR:
          command = READ_LOG;
          select = in.in_regs.lba_low;
          break;
        case ATA_SMART_WRITE_LOG_SECTOR:
          command = WRITE_LOG;
          select = in.in_regs.lba_low;
          break;
        case ATA_SMART_DISABLE:
          command = DISABLE;
          break;
        case ATA_SMART_STATUS:
          command = (in.out_needed.lba_high ? STATUS_CHECK : STATUS);
          break;
        case ATA_SMART_AUTO_OFFLINE:
          command = AUTO_OFFLINE;
          select = in.in_regs.sector_count;
          break;
        case ATA_SMART_AUTOSAVE:
          command = AUTOSAVE;
          select = in.in_regs.sector_count;
          break;
        case ATA_SMART_IMMEDIATE_OFFLINE:
          command = IMMEDIATE_OFFLINE;
          select = in.in_regs.lba_low;
          break;
        default:
          return set_err(ENOSYS, "Unknown SMART command");
      }
      break;
    default:
      return set_err(ENOSYS, "Non-SMART commands not implemented");
  }

  clear_err(); errno = 0;
  int rc = ata_command_interface(command, select, data);
  if (rc < 0) {
    if (!get_errno())
      set_err(errno);
    return false;
  }

  switch (command) {
    case CHECK_POWER_MODE:
      out.out_regs.sector_count = data[0];
      break;
    case STATUS_CHECK:
      switch (rc) {
        case 0: // Good SMART status
          out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
          break;
        case 1: // Bad SMART status
          out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
          break;
      }
      break;
    default:
      break;
  }
  return true;
}