static void ufs_test_run_scenario(void *data, async_cookie_t cookie) { struct test_scenario *ts = (struct test_scenario *)data; struct test_iosched *test_iosched = ts->test_iosched; struct ufs_test_data *utd = test_iosched->blk_dev_test_data; int start_sec; int i; int ret = 0; BUG_ON(!ts); start_sec = ts->test_iosched->start_sector; for (i = 0; i < ts->total_req; i++) { int num_bios = DEFAULT_NUM_OF_BIOS; int direction; if (ufs_test_toggle_direction(ts->toggle_direction, i)) direction = (ts->direction == WRITE) ? READ : WRITE; else direction = ts->direction; /* use randomly generated requests */ if (ts->rnd_req && utd->random_test_seed != 0) pseudo_rnd_sector_and_size(&utd->random_test_seed, ts->test_iosched->start_sector, &start_sec, &num_bios); ret = test_iosched_add_wr_rd_test_req(test_iosched, 0, direction, start_sec, num_bios, TEST_PATTERN_5A, scenario_free_end_io_fn); if (ret) { pr_err("%s: failed to create request" , __func__); break; } /* * We want to run the queue every run_q requests, or, * when the requests pool is exhausted */ if (test_iosched->dispatched_count >= QUEUE_MAX_REQUESTS || (ts->run_q && !(i % ts->run_q))) blk_post_runtime_resume(test_iosched->req_q, 0); } blk_post_runtime_resume(test_iosched->req_q, 0); ufs_test_thread_complete(utd, ret); }
static void ufs_test_random_async_query(void *data, async_cookie_t cookie) { int op; struct ufs_hba *hba = (struct ufs_hba *)data; int buff_len = QUERY_DESC_UNIT_MAX_SIZE; u8 desc_buf[QUERY_DESC_UNIT_MAX_SIZE]; bool flag; u32 att; int ret = 0; op = ufs_test_pseudo_random_seed(&utd->random_test_seed, 1, 8); /* * When write data (descriptor/attribute/flag) queries are issued, * regular work and functionality must be kept. The data is read * first to make sure the original state is restored. */ switch (op) { case UPIU_QUERY_OPCODE_READ_DESC: case UPIU_QUERY_OPCODE_WRITE_DESC: ret = ufshcd_query_descriptor(hba, UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_UNIT, 0, 0, desc_buf, &buff_len); if (ret || op == UPIU_QUERY_OPCODE_READ_DESC) break; ret = ufshcd_query_descriptor(hba, UPIU_QUERY_OPCODE_WRITE_DESC, QUERY_DESC_IDN_UNIT, 0, 0, desc_buf, &buff_len); break; case UPIU_QUERY_OPCODE_WRITE_ATTR: case UPIU_QUERY_OPCODE_READ_ATTR: ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &att); if (ret || op == UPIU_QUERY_OPCODE_READ_ATTR) break; ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &att); break; case UPIU_QUERY_OPCODE_READ_FLAG: case UPIU_QUERY_OPCODE_SET_FLAG: case UPIU_QUERY_OPCODE_CLEAR_FLAG: case UPIU_QUERY_OPCODE_TOGGLE_FLAG: /* We read the QUERY_FLAG_IDN_BKOPS_EN and restore it later */ ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, QUERY_FLAG_IDN_BKOPS_EN, &flag); if (ret || op == UPIU_QUERY_OPCODE_READ_FLAG) break; /* After changing the flag we have to change it back */ ret = ufshcd_query_flag(hba, op, QUERY_FLAG_IDN_BKOPS_EN, NULL); if ((op == UPIU_QUERY_OPCODE_SET_FLAG && flag) || (op == UPIU_QUERY_OPCODE_CLEAR_FLAG && !flag)) /* No need to change it back */ break; if (flag) ret |= ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG, QUERY_FLAG_IDN_BKOPS_EN, NULL); else ret |= ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_CLEAR_FLAG, QUERY_FLAG_IDN_BKOPS_EN, NULL); break; default: pr_err("%s: Random error unknown op %d", __func__, op); } if (ret) pr_err("%s: Query thread with op %d, failed with err %d.", __func__, op, ret); ufs_test_thread_complete(ret); }