Files
ubports_kernel_google_msm/include/linux/test-iosched.h
Maya Erez 5ff3f387d7 mmc: card: Add Sanitize unit test
This test write data to the card, then send DISCARD on random
addresses on the card, send SANITIZE to the card to erase all
the unmapped areas.

Change-Id: I2904023ccd258e64b99b004bacfbe576b0ead59a
Signed-off-by: Maya Erez <merez@codeaurora.org>
2013-02-27 18:16:43 -08:00

235 lines
7.1 KiB
C

/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*
* The test scheduler allows to test the block device by dispatching
* specific requests according to the test case and declare PASS/FAIL
* according to the requests completion error code.
* Each test is exposed via debugfs and can be triggered by writing to
* the debugfs file.
*
*/
#ifndef _LINUX_TEST_IOSCHED_H
#define _LINUX_TEST_IOSCHED_H
/*
* Patterns definitions for read/write requests data
*/
#define TEST_PATTERN_SEQUENTIAL -1
#define TEST_PATTERN_5A 0x5A5A5A5A
#define TEST_PATTERN_FF 0xFFFFFFFF
#define TEST_NO_PATTERN 0xDEADBEEF
#define BIO_U32_SIZE 1024
struct test_data;
typedef int (prepare_test_fn) (struct test_data *);
typedef int (run_test_fn) (struct test_data *);
typedef int (check_test_result_fn) (struct test_data *);
typedef int (post_test_fn) (struct test_data *);
typedef char* (get_test_case_str_fn) (struct test_data *);
typedef void (blk_dev_test_init_fn) (void);
typedef void (blk_dev_test_exit_fn) (void);
/**
* enum test_state - defines the state of the test
*/
enum test_state {
TEST_IDLE,
TEST_RUNNING,
TEST_COMPLETED,
};
/**
* enum test_results - defines the success orfailure of the test
*/
enum test_results {
TEST_NO_RESULT,
TEST_FAILED,
TEST_PASSED,
TEST_NOT_SUPPORTED,
};
/**
* enum req_unique_type - defines a unique request type
*/
enum req_unique_type {
REQ_UNIQUE_NONE,
REQ_UNIQUE_DISCARD,
REQ_UNIQUE_FLUSH,
REQ_UNIQUE_SANITIZE,
};
/**
* struct test_debug - debugfs directories
* @debug_root: The test-iosched debugfs root directory
* @debug_utils_root: test-iosched debugfs utils root
* directory
* @debug_tests_root: test-iosched debugfs tests root
* directory
* @debug_test_result: Exposes the test result to the user
* space
* @start_sector: The start sector for read/write requests
*/
struct test_debug {
struct dentry *debug_root;
struct dentry *debug_utils_root;
struct dentry *debug_tests_root;
struct dentry *debug_test_result;
struct dentry *start_sector;
};
/**
* struct test_request - defines a test request
* @queuelist: The test requests list
* @bios_buffer: Write/read requests data buffer
* @buf_size: Write/read requests data buffer size (in
* bytes)
* @rq: A block request, to be dispatched
* @req_completed: A flag to indicate if the request was
* completed
* @req_result: Keeps the error code received in the
* request completion callback
* @is_err_expected: A flag to indicate if the request should
* fail
* @wr_rd_data_pattern: A pattern written to the write data
* buffer. Can be used in read requests to
* verify the data
* @req_id: A unique ID to identify a test request
* to ease the debugging of the test cases
*/
struct test_request {
struct list_head queuelist;
unsigned int *bios_buffer;
int buf_size;
struct request *rq;
bool req_completed;
int req_result;
int is_err_expected;
int wr_rd_data_pattern;
int req_id;
};
/**
* struct test_info - specific test information
* @testcase: The current running test case
* @timeout_msec: Test specific test timeout
* @buf_size: Write/read requests data buffer size (in
* bytes)
* @prepare_test_fn: Test specific test preparation callback
* @run_test_fn: Test specific test running callback
* @check_test_result_fn: Test specific test result checking
* callback
* @get_test_case_str_fn: Test specific function to get the test name
* @data: Test specific private data
*/
struct test_info {
int testcase;
unsigned timeout_msec;
prepare_test_fn *prepare_test_fn;
run_test_fn *run_test_fn;
check_test_result_fn *check_test_result_fn;
post_test_fn *post_test_fn;
get_test_case_str_fn *get_test_case_str_fn;
void *data;
};
/**
* struct blk_dev_test_type - identifies block device test
* @list: list head pointer
* @init_fn: block device test init callback
* @exit_fn: block device test exit callback
*/
struct blk_dev_test_type {
struct list_head list;
blk_dev_test_init_fn *init_fn;
blk_dev_test_exit_fn *exit_fn;
};
/**
* struct test_data - global test iosched data
* @queue: The test IO scheduler requests list
* @test_queue: The test requests list
* @next_req: Points to the next request to be
* dispatched from the test requests list
* @wait_q: A wait queue for waiting for the test
* requests completion
* @test_state: Indicates if there is a running test.
* Used for dispatch function
* @test_result: Indicates if the test passed or failed
* @debug: The test debugfs entries
* @req_q: The block layer request queue
* @num_of_write_bios: The number of write BIOs added to the test requests.
* Used to calcualte the sector number of
* new BIOs.
* @start_sector: The address of the first sector that can
* be accessed by the test
* @timeout_timer: A timer to verify test completion in
* case of non-completed requests
* @wr_rd_next_req_id: A unique ID to identify WRITE/READ
* request to ease the debugging of the
* test cases
* @unique_next_req_id: A unique ID to identify
* FLUSH/DISCARD/SANITIZE request to ease
* the debugging of the test cases
* @lock: A lock to verify running a single test
* at a time
* @test_info: A specific test data to be set by the
* test invokation function
* @ignore_round: A boolean variable indicating that a
* test round was disturbed by an external
* flush request, therefore disqualifying
* the results
*/
struct test_data {
struct list_head queue;
struct list_head test_queue;
struct test_request *next_req;
wait_queue_head_t wait_q;
enum test_state test_state;
enum test_results test_result;
struct test_debug debug;
struct request_queue *req_q;
int num_of_write_bios;
u32 start_sector;
struct timer_list timeout_timer;
int wr_rd_next_req_id;
int unique_next_req_id;
spinlock_t lock;
struct test_info test_info;
bool fs_wr_reqs_during_test;
bool ignore_round;
};
extern int test_iosched_start_test(struct test_info *t_info);
extern void test_iosched_mark_test_completion(void);
extern int test_iosched_add_unique_test_req(int is_err_expcted,
enum req_unique_type req_unique,
int start_sec, int nr_sects, rq_end_io_fn *end_req_io);
extern int test_iosched_add_wr_rd_test_req(int is_err_expcted,
int direction, int start_sec,
int num_bios, int pattern, rq_end_io_fn *end_req_io);
extern struct dentry *test_iosched_get_debugfs_tests_root(void);
extern struct dentry *test_iosched_get_debugfs_utils_root(void);
extern struct request_queue *test_iosched_get_req_queue(void);
extern void test_iosched_set_test_result(int);
void test_iosched_set_ignore_round(bool ignore_round);
void test_iosched_register(struct blk_dev_test_type *bdt);
void test_iosched_unregister(struct blk_dev_test_type *bdt);
#endif /* _LINUX_TEST_IOSCHED_H */