split dev_queue
[cor.git] / drivers / block / rsxx / config.c
blob11ed1d9646b9c0cbd63b8850985d7f4b73f7eb07
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Filename: config.c
5 * Authors: Joshua Morris <josh.h.morris@us.ibm.com>
6 * Philip Kelleher <pjk1939@linux.vnet.ibm.com>
8 * (C) Copyright 2013 IBM Corporation
9 */
11 #include <linux/types.h>
12 #include <linux/crc32.h>
13 #include <linux/swab.h>
15 #include "rsxx_priv.h"
16 #include "rsxx_cfg.h"
18 static void initialize_config(struct rsxx_card_cfg *cfg)
20 cfg->hdr.version = RSXX_CFG_VERSION;
22 cfg->data.block_size = RSXX_HW_BLK_SIZE;
23 cfg->data.stripe_size = RSXX_HW_BLK_SIZE;
24 cfg->data.vendor_id = RSXX_VENDOR_ID_IBM;
25 cfg->data.cache_order = (-1);
26 cfg->data.intr_coal.mode = RSXX_INTR_COAL_DISABLED;
27 cfg->data.intr_coal.count = 0;
28 cfg->data.intr_coal.latency = 0;
31 static u32 config_data_crc32(struct rsxx_card_cfg *cfg)
34 * Return the compliment of the CRC to ensure compatibility
35 * (i.e. this is how early rsxx drivers did it.)
38 return ~crc32(~0, &cfg->data, sizeof(cfg->data));
42 /*----------------- Config Byte Swap Functions -------------------*/
43 static void config_hdr_be_to_cpu(struct card_cfg_hdr *hdr)
45 hdr->version = be32_to_cpu((__force __be32) hdr->version);
46 hdr->crc = be32_to_cpu((__force __be32) hdr->crc);
49 static void config_hdr_cpu_to_be(struct card_cfg_hdr *hdr)
51 hdr->version = (__force u32) cpu_to_be32(hdr->version);
52 hdr->crc = (__force u32) cpu_to_be32(hdr->crc);
55 static void config_data_swab(struct rsxx_card_cfg *cfg)
57 u32 *data = (u32 *) &cfg->data;
58 int i;
60 for (i = 0; i < (sizeof(cfg->data) / 4); i++)
61 data[i] = swab32(data[i]);
64 static void config_data_le_to_cpu(struct rsxx_card_cfg *cfg)
66 u32 *data = (u32 *) &cfg->data;
67 int i;
69 for (i = 0; i < (sizeof(cfg->data) / 4); i++)
70 data[i] = le32_to_cpu((__force __le32) data[i]);
73 static void config_data_cpu_to_le(struct rsxx_card_cfg *cfg)
75 u32 *data = (u32 *) &cfg->data;
76 int i;
78 for (i = 0; i < (sizeof(cfg->data) / 4); i++)
79 data[i] = (__force u32) cpu_to_le32(data[i]);
83 /*----------------- Config Operations ------------------*/
84 static int rsxx_save_config(struct rsxx_cardinfo *card)
86 struct rsxx_card_cfg cfg;
87 int st;
89 memcpy(&cfg, &card->config, sizeof(cfg));
91 if (unlikely(cfg.hdr.version != RSXX_CFG_VERSION)) {
92 dev_err(CARD_TO_DEV(card),
93 "Cannot save config with invalid version %d\n",
94 cfg.hdr.version);
95 return -EINVAL;
98 /* Convert data to little endian for the CRC calculation. */
99 config_data_cpu_to_le(&cfg);
101 cfg.hdr.crc = config_data_crc32(&cfg);
104 * Swap the data from little endian to big endian so it can be
105 * stored.
107 config_data_swab(&cfg);
108 config_hdr_cpu_to_be(&cfg.hdr);
110 st = rsxx_creg_write(card, CREG_ADD_CONFIG, sizeof(cfg), &cfg, 1);
111 if (st)
112 return st;
114 return 0;
117 int rsxx_load_config(struct rsxx_cardinfo *card)
119 int st;
120 u32 crc;
122 st = rsxx_creg_read(card, CREG_ADD_CONFIG, sizeof(card->config),
123 &card->config, 1);
124 if (st) {
125 dev_err(CARD_TO_DEV(card),
126 "Failed reading card config.\n");
127 return st;
130 config_hdr_be_to_cpu(&card->config.hdr);
132 if (card->config.hdr.version == RSXX_CFG_VERSION) {
134 * We calculate the CRC with the data in little endian, because
135 * early drivers did not take big endian CPUs into account.
136 * The data is always stored in big endian, so we need to byte
137 * swap it before calculating the CRC.
140 config_data_swab(&card->config);
142 /* Check the CRC */
143 crc = config_data_crc32(&card->config);
144 if (crc != card->config.hdr.crc) {
145 dev_err(CARD_TO_DEV(card),
146 "Config corruption detected!\n");
147 dev_info(CARD_TO_DEV(card),
148 "CRC (sb x%08x is x%08x)\n",
149 card->config.hdr.crc, crc);
150 return -EIO;
153 /* Convert the data to CPU byteorder */
154 config_data_le_to_cpu(&card->config);
156 } else if (card->config.hdr.version != 0) {
157 dev_err(CARD_TO_DEV(card),
158 "Invalid config version %d.\n",
159 card->config.hdr.version);
161 * Config version changes require special handling from the
162 * user
164 return -EINVAL;
165 } else {
166 dev_info(CARD_TO_DEV(card),
167 "Initializing card configuration.\n");
168 initialize_config(&card->config);
169 st = rsxx_save_config(card);
170 if (st)
171 return st;
174 card->config_valid = 1;
176 dev_dbg(CARD_TO_DEV(card), "version: x%08x\n",
177 card->config.hdr.version);
178 dev_dbg(CARD_TO_DEV(card), "crc: x%08x\n",
179 card->config.hdr.crc);
180 dev_dbg(CARD_TO_DEV(card), "block_size: x%08x\n",
181 card->config.data.block_size);
182 dev_dbg(CARD_TO_DEV(card), "stripe_size: x%08x\n",
183 card->config.data.stripe_size);
184 dev_dbg(CARD_TO_DEV(card), "vendor_id: x%08x\n",
185 card->config.data.vendor_id);
186 dev_dbg(CARD_TO_DEV(card), "cache_order: x%08x\n",
187 card->config.data.cache_order);
188 dev_dbg(CARD_TO_DEV(card), "mode: x%08x\n",
189 card->config.data.intr_coal.mode);
190 dev_dbg(CARD_TO_DEV(card), "count: x%08x\n",
191 card->config.data.intr_coal.count);
192 dev_dbg(CARD_TO_DEV(card), "latency: x%08x\n",
193 card->config.data.intr_coal.latency);
195 return 0;