nfit.c (a61fe6f7902ecaa89d5e6c709490fc4324927134) nfit.c (f471f1a7d0aa58c609e665514010650b2afa24b6)
1/*
2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 137 unchanged lines hidden (view full) ---

146 dma_addr_t *label_dma;
147 void **spa_set;
148 dma_addr_t *spa_set_dma;
149 struct nfit_test_dcr **dcr;
150 dma_addr_t *dcr_dma;
151 int (*alloc)(struct nfit_test *t);
152 void (*setup)(struct nfit_test *t);
153 int setup_hotplug;
1/*
2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 137 unchanged lines hidden (view full) ---

146 dma_addr_t *label_dma;
147 void **spa_set;
148 dma_addr_t *spa_set_dma;
149 struct nfit_test_dcr **dcr;
150 dma_addr_t *dcr_dma;
151 int (*alloc)(struct nfit_test *t);
152 void (*setup)(struct nfit_test *t);
153 int setup_hotplug;
154 struct ars_state {
155 struct nd_cmd_ars_status *ars_status;
156 unsigned long deadline;
157 spinlock_t lock;
158 } ars_state;
154};
155
156static struct nfit_test *to_nfit_test(struct device *dev)
157{
158 struct platform_device *pdev = to_platform_device(dev);
159
160 return container_of(pdev, struct nfit_test, pdev);
161}

--- 65 unchanged lines hidden (view full) ---

227
228 nd_cmd->max_ars_out = sizeof(struct nd_cmd_ars_status)
229 + NFIT_TEST_ARS_RECORDS * sizeof(struct nd_ars_record);
230 nd_cmd->status = (ND_ARS_PERSISTENT | ND_ARS_VOLATILE) << 16;
231
232 return 0;
233}
234
159};
160
161static struct nfit_test *to_nfit_test(struct device *dev)
162{
163 struct platform_device *pdev = to_platform_device(dev);
164
165 return container_of(pdev, struct nfit_test, pdev);
166}

--- 65 unchanged lines hidden (view full) ---

232
233 nd_cmd->max_ars_out = sizeof(struct nd_cmd_ars_status)
234 + NFIT_TEST_ARS_RECORDS * sizeof(struct nd_ars_record);
235 nd_cmd->status = (ND_ARS_PERSISTENT | ND_ARS_VOLATILE) << 16;
236
237 return 0;
238}
239
235static int nfit_test_cmd_ars_start(struct nd_cmd_ars_start *nd_cmd,
236 unsigned int buf_len)
240/*
241 * Initialize the ars_state to return an ars_result 1 second in the future with
242 * a 4K error range in the middle of the requested address range.
243 */
244static void post_ars_status(struct ars_state *ars_state, u64 addr, u64 len)
237{
245{
238 if (buf_len < sizeof(*nd_cmd))
246 struct nd_cmd_ars_status *ars_status;
247 struct nd_ars_record *ars_record;
248
249 ars_state->deadline = jiffies + 1*HZ;
250 ars_status = ars_state->ars_status;
251 ars_status->status = 0;
252 ars_status->out_length = sizeof(struct nd_cmd_ars_status)
253 + sizeof(struct nd_ars_record);
254 ars_status->address = addr;
255 ars_status->length = len;
256 ars_status->type = ND_ARS_PERSISTENT;
257 ars_status->num_records = 1;
258 ars_record = &ars_status->records[0];
259 ars_record->handle = 0;
260 ars_record->err_address = addr + len / 2;
261 ars_record->length = SZ_4K;
262}
263
264static int nfit_test_cmd_ars_start(struct ars_state *ars_state,
265 struct nd_cmd_ars_start *ars_start, unsigned int buf_len,
266 int *cmd_rc)
267{
268 if (buf_len < sizeof(*ars_start))
239 return -EINVAL;
240
269 return -EINVAL;
270
241 nd_cmd->status = 0;
271 spin_lock(&ars_state->lock);
272 if (time_before(jiffies, ars_state->deadline)) {
273 ars_start->status = NFIT_ARS_START_BUSY;
274 *cmd_rc = -EBUSY;
275 } else {
276 ars_start->status = 0;
277 ars_start->scrub_time = 1;
278 post_ars_status(ars_state, ars_start->address,
279 ars_start->length);
280 *cmd_rc = 0;
281 }
282 spin_unlock(&ars_state->lock);
242
243 return 0;
244}
245
283
284 return 0;
285}
286
246static int nfit_test_cmd_ars_status(struct nd_cmd_ars_status *nd_cmd,
247 unsigned int buf_len)
287static int nfit_test_cmd_ars_status(struct ars_state *ars_state,
288 struct nd_cmd_ars_status *ars_status, unsigned int buf_len,
289 int *cmd_rc)
248{
290{
249 if (buf_len < sizeof(*nd_cmd))
291 if (buf_len < ars_state->ars_status->out_length)
250 return -EINVAL;
251
292 return -EINVAL;
293
252 nd_cmd->out_length = sizeof(struct nd_cmd_ars_status);
253 /* TODO: emit error records */
254 nd_cmd->num_records = 0;
255 nd_cmd->address = 0;
256 nd_cmd->length = -1ULL;
257 nd_cmd->status = 0;
258
294 spin_lock(&ars_state->lock);
295 if (time_before(jiffies, ars_state->deadline)) {
296 memset(ars_status, 0, buf_len);
297 ars_status->status = NFIT_ARS_STATUS_BUSY;
298 ars_status->out_length = sizeof(*ars_status);
299 *cmd_rc = -EBUSY;
300 } else {
301 memcpy(ars_status, ars_state->ars_status,
302 ars_state->ars_status->out_length);
303 *cmd_rc = 0;
304 }
305 spin_unlock(&ars_state->lock);
259 return 0;
260}
261
262static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
263 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
264 unsigned int buf_len, int *cmd_rc)
265{
266 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
267 struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
306 return 0;
307}
308
309static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
310 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
311 unsigned int buf_len, int *cmd_rc)
312{
313 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
314 struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
268 int i, rc = 0;
315 int i, rc = 0, __cmd_rc;
269
316
317 if (!cmd_rc)
318 cmd_rc = &__cmd_rc;
319 *cmd_rc = 0;
320
270 if (nvdimm) {
271 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
272
273 if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask))
274 return -ENOTTY;
275
276 /* lookup label space for the given dimm */
277 for (i = 0; i < ARRAY_SIZE(handle); i++)

--- 14 unchanged lines hidden (view full) ---

292 case ND_CMD_SET_CONFIG_DATA:
293 rc = nfit_test_cmd_set_config_data(buf, buf_len,
294 t->label[i]);
295 break;
296 default:
297 return -ENOTTY;
298 }
299 } else {
321 if (nvdimm) {
322 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
323
324 if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask))
325 return -ENOTTY;
326
327 /* lookup label space for the given dimm */
328 for (i = 0; i < ARRAY_SIZE(handle); i++)

--- 14 unchanged lines hidden (view full) ---

343 case ND_CMD_SET_CONFIG_DATA:
344 rc = nfit_test_cmd_set_config_data(buf, buf_len,
345 t->label[i]);
346 break;
347 default:
348 return -ENOTTY;
349 }
350 } else {
351 struct ars_state *ars_state = &t->ars_state;
352
300 if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask))
301 return -ENOTTY;
302
303 switch (cmd) {
304 case ND_CMD_ARS_CAP:
305 rc = nfit_test_cmd_ars_cap(buf, buf_len);
306 break;
307 case ND_CMD_ARS_START:
353 if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask))
354 return -ENOTTY;
355
356 switch (cmd) {
357 case ND_CMD_ARS_CAP:
358 rc = nfit_test_cmd_ars_cap(buf, buf_len);
359 break;
360 case ND_CMD_ARS_START:
308 rc = nfit_test_cmd_ars_start(buf, buf_len);
361 rc = nfit_test_cmd_ars_start(ars_state, buf, buf_len,
362 cmd_rc);
309 break;
310 case ND_CMD_ARS_STATUS:
363 break;
364 case ND_CMD_ARS_STATUS:
311 rc = nfit_test_cmd_ars_status(buf, buf_len);
365 rc = nfit_test_cmd_ars_status(ars_state, buf, buf_len,
366 cmd_rc);
312 break;
313 default:
314 return -ENOTTY;
315 }
316 }
317
367 break;
368 default:
369 return -ENOTTY;
370 }
371 }
372
318 /* TODO: error status tests */
319 if (cmd_rc)
320 *cmd_rc = 0;
321 return rc;
322}
323
324static DEFINE_SPINLOCK(nfit_test_lock);
325static struct nfit_test *instances[NUM_NFITS];
326
327static void release_nfit_res(void *data)
328{

--- 93 unchanged lines hidden (view full) ---

422 spin_unlock(&nfit_test_lock);
423 if (nfit_res)
424 return nfit_res;
425 }
426
427 return NULL;
428}
429
373 return rc;
374}
375
376static DEFINE_SPINLOCK(nfit_test_lock);
377static struct nfit_test *instances[NUM_NFITS];
378
379static void release_nfit_res(void *data)
380{

--- 93 unchanged lines hidden (view full) ---

474 spin_unlock(&nfit_test_lock);
475 if (nfit_res)
476 return nfit_res;
477 }
478
479 return NULL;
480}
481
482static int ars_state_init(struct device *dev, struct ars_state *ars_state)
483{
484 ars_state->ars_status = devm_kzalloc(dev,
485 sizeof(struct nd_cmd_ars_status)
486 + sizeof(struct nd_ars_record) * NFIT_TEST_ARS_RECORDS,
487 GFP_KERNEL);
488 if (!ars_state->ars_status)
489 return -ENOMEM;
490 spin_lock_init(&ars_state->lock);
491 return 0;
492}
493
430static int nfit_test0_alloc(struct nfit_test *t)
431{
432 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
433 + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
434 + sizeof(struct acpi_nfit_control_region) * NUM_DCR
435 + offsetof(struct acpi_nfit_control_region,
436 window_size) * NUM_DCR
437 + sizeof(struct acpi_nfit_data_region) * NUM_BDW

--- 33 unchanged lines hidden (view full) ---

471 }
472
473 for (i = 0; i < NUM_DCR; i++) {
474 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
475 if (!t->dcr[i])
476 return -ENOMEM;
477 }
478
494static int nfit_test0_alloc(struct nfit_test *t)
495{
496 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
497 + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
498 + sizeof(struct acpi_nfit_control_region) * NUM_DCR
499 + offsetof(struct acpi_nfit_control_region,
500 window_size) * NUM_DCR
501 + sizeof(struct acpi_nfit_data_region) * NUM_BDW

--- 33 unchanged lines hidden (view full) ---

535 }
536
537 for (i = 0; i < NUM_DCR; i++) {
538 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
539 if (!t->dcr[i])
540 return -ENOMEM;
541 }
542
479 return 0;
543 return ars_state_init(&t->pdev.dev, &t->ars_state);
480}
481
482static int nfit_test1_alloc(struct nfit_test *t)
483{
484 size_t nfit_size = sizeof(struct acpi_nfit_system_address)
485 + sizeof(struct acpi_nfit_memory_map)
486 + offsetof(struct acpi_nfit_control_region, window_size);
487
488 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
489 if (!t->nfit_buf)
490 return -ENOMEM;
491 t->nfit_size = nfit_size;
492
493 t->spa_set[0] = test_alloc_coherent(t, SPA2_SIZE, &t->spa_set_dma[0]);
494 if (!t->spa_set[0])
495 return -ENOMEM;
496
544}
545
546static int nfit_test1_alloc(struct nfit_test *t)
547{
548 size_t nfit_size = sizeof(struct acpi_nfit_system_address)
549 + sizeof(struct acpi_nfit_memory_map)
550 + offsetof(struct acpi_nfit_control_region, window_size);
551
552 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
553 if (!t->nfit_buf)
554 return -ENOMEM;
555 t->nfit_size = nfit_size;
556
557 t->spa_set[0] = test_alloc_coherent(t, SPA2_SIZE, &t->spa_set_dma[0]);
558 if (!t->spa_set[0])
559 return -ENOMEM;
560
497 return 0;
561 return ars_state_init(&t->pdev.dev, &t->ars_state);
498}
499
500static void nfit_test0_setup(struct nfit_test *t)
501{
502 struct acpi_nfit_desc *acpi_desc;
503 struct acpi_nfit_memory_map *memdev;
504 void *nfit_buf = t->nfit_buf;
505 struct acpi_nfit_system_address *spa;

--- 646 unchanged lines hidden (view full) ---

1152 flush = nfit_buf + offset;
1153 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1154 flush->header.length = sizeof(struct acpi_nfit_flush_address);
1155 flush->device_handle = handle[4];
1156 flush->hint_count = 1;
1157 flush->hint_address[0] = t->flush_dma[4];
1158 }
1159
562}
563
564static void nfit_test0_setup(struct nfit_test *t)
565{
566 struct acpi_nfit_desc *acpi_desc;
567 struct acpi_nfit_memory_map *memdev;
568 void *nfit_buf = t->nfit_buf;
569 struct acpi_nfit_system_address *spa;

--- 646 unchanged lines hidden (view full) ---

1216 flush = nfit_buf + offset;
1217 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1218 flush->header.length = sizeof(struct acpi_nfit_flush_address);
1219 flush->device_handle = handle[4];
1220 flush->hint_count = 1;
1221 flush->hint_address[0] = t->flush_dma[4];
1222 }
1223
1224 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
1225
1160 acpi_desc = &t->acpi_desc;
1161 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
1162 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1163 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1164 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1165 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1166 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1167}

--- 45 unchanged lines hidden (view full) ---

1213 dcr->region_index = 0+1;
1214 dcr->vendor_id = 0xabcd;
1215 dcr->device_id = 0;
1216 dcr->revision_id = 1;
1217 dcr->serial_number = ~0;
1218 dcr->code = NFIT_FIC_BYTE;
1219 dcr->windows = 0;
1220
1226 acpi_desc = &t->acpi_desc;
1227 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
1228 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1229 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1230 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1231 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1232 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1233}

--- 45 unchanged lines hidden (view full) ---

1279 dcr->region_index = 0+1;
1280 dcr->vendor_id = 0xabcd;
1281 dcr->device_id = 0;
1282 dcr->revision_id = 1;
1283 dcr->serial_number = ~0;
1284 dcr->code = NFIT_FIC_BYTE;
1285 dcr->windows = 0;
1286
1287 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE);
1288
1221 acpi_desc = &t->acpi_desc;
1222 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1223 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1224 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1225}
1226
1227static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
1228 void *iobuf, u64 len, int rw)

--- 237 unchanged lines hidden ---
1289 acpi_desc = &t->acpi_desc;
1290 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1291 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1292 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1293}
1294
1295static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
1296 void *iobuf, u64 len, int rw)

--- 237 unchanged lines hidden ---