Logo Search packages:      
Sourcecode: dmraid version File versions

ddf1_cvt.c

/*
 * SNIA DDF1 v1.0 metadata format handler.
 *
 * Copyright (C) 2005-2006 IBM, All rights reserved.
 * Written by Darrick Wong <djwong@us.ibm.com>
 *
 * Copyright (C) 2006 Heinz Mauelshagen, Red Hat GmbH
 *                    All rights reserved.
 *
 * See file LICENSE at the top of this source tree for license information.
 */

#include "internal.h"
#define FORMAT_HANDLER
#include "ddf1.h"
#include "ddf1_lib.h"
#include "ddf1_cvt.h"

#define DM_BYTEORDER_SWAB
#include <datastruct/byteorder.h>

/* Convert a DDF header */
void ddf1_cvt_header(struct ddf1 *ddf1, struct ddf1_header *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT32(hdr->seqnum);
      CVT32(hdr->timestamp);
      CVT64(hdr->primary_table_lba);
      CVT64(hdr->secondary_table_lba);
      CVT32(hdr->workspace_length);
      CVT64(hdr->workspace_lba);
      CVT16(hdr->max_phys_drives);
      CVT16(hdr->max_virt_drives);
      CVT16(hdr->max_partitions);
      CVT16(hdr->vd_config_record_len);
      CVT16(hdr->max_primary_elements);
      CVT32(hdr->adapter_data_offset);
      CVT32(hdr->adapter_data_len);
      CVT32(hdr->phys_drive_offset);
      CVT32(hdr->phys_drive_len);
      CVT32(hdr->virt_drive_offset);
      CVT32(hdr->virt_drive_len);
      CVT32(hdr->config_record_offset);
      CVT32(hdr->config_record_len);
      CVT32(hdr->disk_data_offset);
      CVT32(hdr->disk_data_len);
      CVT32(hdr->badblock_offset);
      CVT32(hdr->badblock_len);
      CVT32(hdr->diag_offset);
      CVT32(hdr->diag_len);
      CVT32(hdr->vendor_offset);
      CVT32(hdr->vendor_len);
}

/* Convert DDF adapter data */
void ddf1_cvt_adapter(struct ddf1 *ddf1, struct ddf1_adapter *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT16(hdr->pci_vendor);
      CVT16(hdr->pci_device);
      CVT16(hdr->pci_subvendor);
      CVT16(hdr->pci_subdevice);
}

/* Convert physical disk data */
void ddf1_cvt_disk_data(struct ddf1 *ddf1, struct ddf1_disk_data *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT32(hdr->reference);
}

/* Convert physical drive header data */
void ddf1_cvt_phys_drive_header(struct ddf1 *ddf1, struct ddf1_phys_drives *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT16(hdr->num_drives);
      CVT16(hdr->max_drives);
}

/* Convert physical drive data */
void ddf1_cvt_phys_drive(struct ddf1 *ddf1, struct ddf1_phys_drive *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->reference);
      CVT16(hdr->type);
      CVT16(hdr->state);
      CVT64(hdr->size);
}

/* Convert virtual drive header data */
void ddf1_cvt_virt_drive_header(struct ddf1 *ddf1, struct ddf1_virt_drives *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT16(hdr->num_drives);
      CVT16(hdr->max_drives);
}

/* Convert virtual drive data */
void ddf1_cvt_virt_drive(struct ddf1 *ddf1, struct ddf1_virt_drive *hdr)
{
      if (BYTE_ORDER == ddf1->disk_format)
            return;

      CVT32(hdr->vd_num);
      CVT32(hdr->type);
}

/* Convert config record data */
int ddf1_cvt_config_record(struct lib_context *lc, struct dev_info *di,
                     struct ddf1 *ddf1, int idx)
{
      unsigned int i;
      uint16_t max_pds;
      uint32_t *ids, x;
      uint64_t *off;
      struct ddf1_config_record *hdr = CR(ddf1, idx);

      if (BYTE_ORDER == ddf1->disk_format)
            return 1;

      max_pds = hdr->primary_element_count;
      ids = CR_IDS(ddf1, hdr);

      /* This chunk is derived from CR_OFF */
      x = ddf1_cr_off_maxpds_helper(ddf1);
      if (ddf1->primary->signature == DDF1_HEADER_BACKWARDS)
            CVT32(x);

      off = ((uint64_t*) (((uint8_t*) hdr) + sizeof(*hdr) + (x * sizeof(x))));

      CVT32(hdr->signature);
      CVT32(hdr->crc);
      CVT32(hdr->timestamp);
      CVT32(hdr->seqnum);
      CVT16(hdr->primary_element_count);
      if (!ddf1->in_cpu_format)
            max_pds = hdr->primary_element_count;

      CVT64(hdr->sectors);
      CVT64(hdr->size);
      for (i = 0; i < 8; i++)
            CVT32(hdr->spares[i]);

      CVT64(hdr->cache_policy);
      for (i = 0; i < max_pds; i++) {
            CVT32(ids[i]);
            CVT64(off[i]);
      }
      return 1;
}

/* Convert spare records */
int ddf1_cvt_spare_record(struct lib_context *lc, struct dev_info *di,
                    struct ddf1 *ddf1, int idx)
{
      uint16_t x, i;
      struct ddf1_spare_header *sh = SR(ddf1, idx);

      if (BYTE_ORDER == ddf1->disk_format)
            return 1;

      CVT32(sh->signature);
      CVT32(sh->crc);
      CVT32(sh->timestamp);
      CVT16(sh->max_spares);
      x = sh->num_spares;
      CVT16(sh->num_spares);
      if (!ddf1->in_cpu_format)
            x = sh->num_spares;

      for (i = 0; i < x; i++)
            CVT16(sh->spares[i].secondary_element);

      return 1;
}

void ddf1_cvt_records(struct lib_context *lc, struct dev_info *di,
             struct ddf1 *ddf1, int in_cpu_format)
{
      static struct ddf1_record_handler handlers = {
            .vd = ddf1_cvt_config_record,
            .spare = ddf1_cvt_spare_record,
      };

      ddf1_process_records(lc, di, &handlers, ddf1, in_cpu_format);
}

/* Convert endianness of all metadata */
void ddf1_cvt_all(struct lib_context *lc, struct ddf1 *ddf1,
              struct dev_info *di)
{
      int i;
      uint16_t pds = 0, vds = 0;

      ddf1_cvt_header(ddf1, &ddf1->anchor);
      if (ddf1->in_cpu_format)
            ddf1_cvt_records(lc, di, ddf1, ddf1->in_cpu_format);

      ddf1_cvt_header(ddf1, ddf1->primary);
      if (!ddf1->in_cpu_format)
            ddf1_cvt_records(lc, di, ddf1, ddf1->in_cpu_format);

      if (ddf1->secondary)
            ddf1_cvt_header(ddf1, ddf1->secondary);

      if (ddf1->adapter)
            ddf1_cvt_adapter(ddf1, ddf1->adapter);

      ddf1_cvt_disk_data(ddf1, ddf1->disk_data);

      if (ddf1->in_cpu_format)
            pds = ddf1->pd_header->num_drives;

      ddf1_cvt_phys_drive_header(ddf1, ddf1->pd_header);
      if (!ddf1->in_cpu_format)
            pds = ddf1->pd_header->num_drives;

      for (i = 0; i < pds; i++)
            ddf1_cvt_phys_drive(ddf1, &ddf1->pds[i]);

      if (ddf1->in_cpu_format)
            vds = ddf1->vd_header->num_drives;

      ddf1_cvt_virt_drive_header(ddf1, ddf1->vd_header);
      if (!ddf1->in_cpu_format)
            vds = ddf1->vd_header->num_drives;

      for (i = 0; i < vds; i++)
            ddf1_cvt_virt_drive(ddf1, &ddf1->vds[i]);

      ddf1->in_cpu_format = !ddf1->in_cpu_format;
}

Generated by  Doxygen 1.6.0   Back to index