Release 4.7 drivers/block/rsxx/config.c
  
  
/*
* Filename: config.c
*
*
* Authors: Joshua Morris <josh.h.morris@us.ibm.com>
*       Philip Kelleher <pjk1939@linux.vnet.ibm.com>
*
* (C) Copyright 2013 IBM Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
#include <linux/crc32.h>
#include <linux/swab.h>
#include "rsxx_priv.h"
#include "rsxx_cfg.h"
static void initialize_config(struct rsxx_card_cfg *cfg)
{
	cfg->hdr.version = RSXX_CFG_VERSION;
	cfg->data.block_size        = RSXX_HW_BLK_SIZE;
	cfg->data.stripe_size       = RSXX_HW_BLK_SIZE;
	cfg->data.vendor_id         = RSXX_VENDOR_ID_IBM;
	cfg->data.cache_order       = (-1);
	cfg->data.intr_coal.mode    = RSXX_INTR_COAL_DISABLED;
	cfg->data.intr_coal.count   = 0;
	cfg->data.intr_coal.latency = 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 81 | 96.43% | 1 | 33.33% | 
| philip j kelleher | philip j kelleher | 3 | 3.57% | 2 | 66.67% | 
 | Total | 84 | 100.00% | 3 | 100.00% | 
static u32 config_data_crc32(struct rsxx_card_cfg *cfg)
{
	/*
         * Return the compliment of the CRC to ensure compatibility
         * (i.e. this is how early rsxx drivers did it.)
         */
	return ~crc32(~0, &cfg->data, sizeof(cfg->data));
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 32 | 100.00% | 1 | 100.00% | 
 | Total | 32 | 100.00% | 1 | 100.00% | 
/*----------------- Config Byte Swap Functions -------------------*/
static void config_hdr_be_to_cpu(struct card_cfg_hdr *hdr)
{
	hdr->version = be32_to_cpu((__force __be32) hdr->version);
	hdr->crc     = be32_to_cpu((__force __be32) hdr->crc);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 41 | 100.00% | 1 | 100.00% | 
 | Total | 41 | 100.00% | 1 | 100.00% | 
static void config_hdr_cpu_to_be(struct card_cfg_hdr *hdr)
{
	hdr->version = (__force u32) cpu_to_be32(hdr->version);
	hdr->crc     = (__force u32) cpu_to_be32(hdr->crc);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 41 | 100.00% | 1 | 100.00% | 
 | Total | 41 | 100.00% | 1 | 100.00% | 
static void config_data_swab(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;
	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = swab32(data[i]);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 62 | 100.00% | 1 | 100.00% | 
 | Total | 62 | 100.00% | 1 | 100.00% | 
static void config_data_le_to_cpu(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;
	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = le32_to_cpu((__force __le32) data[i]);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 66 | 100.00% | 1 | 100.00% | 
 | Total | 66 | 100.00% | 1 | 100.00% | 
static void config_data_cpu_to_le(struct rsxx_card_cfg *cfg)
{
	u32 *data = (u32 *) &cfg->data;
	int i;
	for (i = 0; i < (sizeof(cfg->data) / 4); i++)
		data[i] = (__force u32) cpu_to_le32(data[i]);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 66 | 100.00% | 1 | 100.00% | 
 | Total | 66 | 100.00% | 1 | 100.00% | 
/*----------------- Config Operations ------------------*/
static int rsxx_save_config(struct rsxx_cardinfo *card)
{
	struct rsxx_card_cfg cfg;
	int st;
	memcpy(&cfg, &card->config, sizeof(cfg));
	if (unlikely(cfg.hdr.version != RSXX_CFG_VERSION)) {
		dev_err(CARD_TO_DEV(card),
			"Cannot save config with invalid version %d\n",
			cfg.hdr.version);
		return -EINVAL;
	}
	/* Convert data to little endian for the CRC calculation. */
	config_data_cpu_to_le(&cfg);
	cfg.hdr.crc = config_data_crc32(&cfg);
	/*
         * Swap the data from little endian to big endian so it can be
         * stored.
         */
	config_data_swab(&cfg);
	config_hdr_cpu_to_be(&cfg.hdr);
	st = rsxx_creg_write(card, CREG_ADD_CONFIG, sizeof(cfg), &cfg, 1);
	if (st)
		return st;
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 131 | 99.24% | 1 | 50.00% | 
| philip j kelleher | philip j kelleher | 1 | 0.76% | 1 | 50.00% | 
 | Total | 132 | 100.00% | 2 | 100.00% | 
int rsxx_load_config(struct rsxx_cardinfo *card)
{
	int st;
	u32 crc;
	st = rsxx_creg_read(card, CREG_ADD_CONFIG, sizeof(card->config),
				&card->config, 1);
	if (st) {
		dev_err(CARD_TO_DEV(card),
			"Failed reading card config.\n");
		return st;
	}
	config_hdr_be_to_cpu(&card->config.hdr);
	if (card->config.hdr.version == RSXX_CFG_VERSION) {
		/*
                 * We calculate the CRC with the data in little endian, because
                 * early drivers did not take big endian CPUs into account.
                 * The data is always stored in big endian, so we need to byte
                 * swap it before calculating the CRC.
                 */
		config_data_swab(&card->config);
		/* Check the CRC */
		crc = config_data_crc32(&card->config);
		if (crc != card->config.hdr.crc) {
			dev_err(CARD_TO_DEV(card),
				"Config corruption detected!\n");
			dev_info(CARD_TO_DEV(card),
				"CRC (sb x%08x is x%08x)\n",
				card->config.hdr.crc, crc);
			return -EIO;
		}
		/* Convert the data to CPU byteorder */
		config_data_le_to_cpu(&card->config);
	} else if (card->config.hdr.version != 0) {
		dev_err(CARD_TO_DEV(card),
			"Invalid config version %d.\n",
			card->config.hdr.version);
		/*
                 * Config version changes require special handling from the
                 * user
                 */
		return -EINVAL;
	} else {
		dev_info(CARD_TO_DEV(card),
			"Initializing card configuration.\n");
		initialize_config(&card->config);
		st = rsxx_save_config(card);
		if (st)
			return st;
	}
	card->config_valid = 1;
	dev_dbg(CARD_TO_DEV(card), "version:     x%08x\n",
		card->config.hdr.version);
	dev_dbg(CARD_TO_DEV(card), "crc:         x%08x\n",
		card->config.hdr.crc);
	dev_dbg(CARD_TO_DEV(card), "block_size:  x%08x\n",
		card->config.data.block_size);
	dev_dbg(CARD_TO_DEV(card), "stripe_size: x%08x\n",
		card->config.data.stripe_size);
	dev_dbg(CARD_TO_DEV(card), "vendor_id:   x%08x\n",
		card->config.data.vendor_id);
	dev_dbg(CARD_TO_DEV(card), "cache_order: x%08x\n",
		card->config.data.cache_order);
	dev_dbg(CARD_TO_DEV(card), "mode:        x%08x\n",
		card->config.data.intr_coal.mode);
	dev_dbg(CARD_TO_DEV(card), "count:       x%08x\n",
		card->config.data.intr_coal.count);
	dev_dbg(CARD_TO_DEV(card), "latency:     x%08x\n",
		 card->config.data.intr_coal.latency);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 406 | 99.27% | 1 | 50.00% | 
| philip j kelleher | philip j kelleher | 3 | 0.73% | 1 | 50.00% | 
 | Total | 409 | 100.00% | 2 | 100.00% | 
Overall Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| josh h. morris | josh h. morris | 944 | 99.26% | 1 | 25.00% | 
| philip j kelleher | philip j kelleher | 7 | 0.74% | 3 | 75.00% | 
 | Total | 951 | 100.00% | 4 | 100.00% | 
  
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.