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 --- |