drm/tests: hdmi: Fix memory leaks in drm_display_mode_from_cea_vic()
[drm/drm-misc.git] / drivers / scsi / scsi_lib_test.c
blob99834426a100a7548c913682049a280e2bd512ff
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * KUnit tests for scsi_lib.c.
5 * Copyright (C) 2023, Oracle Corporation
6 */
7 #include <kunit/test.h>
9 #include <scsi/scsi_proto.h>
10 #include <scsi/scsi_cmnd.h>
11 #include <scsi/scsi_device.h>
13 #define SCSI_LIB_TEST_MAX_ALLOWED 3
14 #define SCSI_LIB_TEST_TOTAL_MAX_ALLOWED 5
16 static void scsi_lib_test_multiple_sense(struct kunit *test)
18 struct scsi_failure multiple_sense_failure_defs[] = {
20 .sense = DATA_PROTECT,
21 .asc = 0x1,
22 .ascq = 0x1,
23 .result = SAM_STAT_CHECK_CONDITION,
26 .sense = UNIT_ATTENTION,
27 .asc = 0x11,
28 .ascq = 0x0,
29 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
30 .result = SAM_STAT_CHECK_CONDITION,
33 .sense = NOT_READY,
34 .asc = 0x11,
35 .ascq = 0x22,
36 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
37 .result = SAM_STAT_CHECK_CONDITION,
40 .sense = ABORTED_COMMAND,
41 .asc = 0x11,
42 .ascq = SCMD_FAILURE_ASCQ_ANY,
43 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
44 .result = SAM_STAT_CHECK_CONDITION,
47 .sense = HARDWARE_ERROR,
48 .asc = SCMD_FAILURE_ASC_ANY,
49 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
50 .result = SAM_STAT_CHECK_CONDITION,
53 .sense = ILLEGAL_REQUEST,
54 .asc = 0x91,
55 .ascq = 0x36,
56 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
57 .result = SAM_STAT_CHECK_CONDITION,
61 struct scsi_failures failures = {
62 .failure_definitions = multiple_sense_failure_defs,
64 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
65 struct scsi_cmnd sc = {
66 .sense_buffer = sense,
68 int i;
70 /* Match end of array */
71 scsi_build_sense(&sc, 0, ILLEGAL_REQUEST, 0x91, 0x36);
72 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
73 /* Basic match in array */
74 scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x11, 0x0);
75 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
76 /* No matching sense entry */
77 scsi_build_sense(&sc, 0, MISCOMPARE, 0x11, 0x11);
78 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
79 /* Match using SCMD_FAILURE_ASCQ_ANY */
80 scsi_build_sense(&sc, 0, ABORTED_COMMAND, 0x11, 0x22);
81 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
82 /* Fail to match */
83 scsi_build_sense(&sc, 0, ABORTED_COMMAND, 0x22, 0x22);
84 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
85 /* Match using SCMD_FAILURE_ASC_ANY */
86 scsi_build_sense(&sc, 0, HARDWARE_ERROR, 0x11, 0x22);
87 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
88 /* No matching status entry */
89 sc.result = SAM_STAT_RESERVATION_CONFLICT;
90 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
92 /* Test hitting allowed limit */
93 scsi_build_sense(&sc, 0, NOT_READY, 0x11, 0x22);
94 for (i = 0; i < SCSI_LIB_TEST_MAX_ALLOWED; i++)
95 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc,
96 &failures));
97 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
99 /* reset retries so we can retest */
100 failures.failure_definitions = multiple_sense_failure_defs;
101 scsi_failures_reset_retries(&failures);
103 /* Test no retries allowed */
104 scsi_build_sense(&sc, 0, DATA_PROTECT, 0x1, 0x1);
105 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
108 static void scsi_lib_test_any_sense(struct kunit *test)
110 struct scsi_failure any_sense_failure_defs[] = {
112 .result = SCMD_FAILURE_SENSE_ANY,
113 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
117 struct scsi_failures failures = {
118 .failure_definitions = any_sense_failure_defs,
120 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
121 struct scsi_cmnd sc = {
122 .sense_buffer = sense,
125 /* Match using SCMD_FAILURE_SENSE_ANY */
126 failures.failure_definitions = any_sense_failure_defs;
127 scsi_build_sense(&sc, 0, MEDIUM_ERROR, 0x11, 0x22);
128 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
131 static void scsi_lib_test_host(struct kunit *test)
133 struct scsi_failure retryable_host_failure_defs[] = {
135 .result = DID_TRANSPORT_DISRUPTED << 16,
136 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
139 .result = DID_TIME_OUT << 16,
140 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
144 struct scsi_failures failures = {
145 .failure_definitions = retryable_host_failure_defs,
147 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
148 struct scsi_cmnd sc = {
149 .sense_buffer = sense,
152 /* No matching host byte entry */
153 failures.failure_definitions = retryable_host_failure_defs;
154 sc.result = DID_NO_CONNECT << 16;
155 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
156 /* Matching host byte entry */
157 sc.result = DID_TIME_OUT << 16;
158 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
161 static void scsi_lib_test_any_failure(struct kunit *test)
163 struct scsi_failure any_failure_defs[] = {
165 .result = SCMD_FAILURE_RESULT_ANY,
166 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
170 struct scsi_failures failures = {
171 .failure_definitions = any_failure_defs,
173 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
174 struct scsi_cmnd sc = {
175 .sense_buffer = sense,
178 /* Match SCMD_FAILURE_RESULT_ANY */
179 failures.failure_definitions = any_failure_defs;
180 sc.result = DID_TRANSPORT_FAILFAST << 16;
181 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
184 static void scsi_lib_test_any_status(struct kunit *test)
186 struct scsi_failure any_status_failure_defs[] = {
188 .result = SCMD_FAILURE_STAT_ANY,
189 .allowed = SCSI_LIB_TEST_MAX_ALLOWED,
193 struct scsi_failures failures = {
194 .failure_definitions = any_status_failure_defs,
196 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
197 struct scsi_cmnd sc = {
198 .sense_buffer = sense,
201 /* Test any status handling */
202 failures.failure_definitions = any_status_failure_defs;
203 sc.result = SAM_STAT_RESERVATION_CONFLICT;
204 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
207 static void scsi_lib_test_total_allowed(struct kunit *test)
209 struct scsi_failure total_allowed_defs[] = {
211 .sense = UNIT_ATTENTION,
212 .asc = SCMD_FAILURE_ASC_ANY,
213 .ascq = SCMD_FAILURE_ASCQ_ANY,
214 .result = SAM_STAT_CHECK_CONDITION,
216 /* Fail all CCs except the UA above */
218 .sense = SCMD_FAILURE_SENSE_ANY,
219 .result = SAM_STAT_CHECK_CONDITION,
221 /* Retry any other errors not listed above */
223 .result = SCMD_FAILURE_RESULT_ANY,
227 struct scsi_failures failures = {
228 .failure_definitions = total_allowed_defs,
230 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
231 struct scsi_cmnd sc = {
232 .sense_buffer = sense,
234 int i;
236 /* Test total_allowed */
237 failures.failure_definitions = total_allowed_defs;
238 scsi_failures_reset_retries(&failures);
239 failures.total_allowed = SCSI_LIB_TEST_TOTAL_MAX_ALLOWED;
241 scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0);
242 for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++)
243 /* Retry since we under the total_allowed limit */
244 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc,
245 &failures));
246 sc.result = DID_TIME_OUT << 16;
247 /* We have now hit the total_allowed limit so no more retries */
248 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
251 static void scsi_lib_test_mixed_total(struct kunit *test)
253 struct scsi_failure mixed_total_defs[] = {
255 .sense = UNIT_ATTENTION,
256 .asc = 0x28,
257 .result = SAM_STAT_CHECK_CONDITION,
260 .sense = UNIT_ATTENTION,
261 .asc = 0x29,
262 .result = SAM_STAT_CHECK_CONDITION,
265 .allowed = 1,
266 .result = DID_TIME_OUT << 16,
270 u8 sense[SCSI_SENSE_BUFFERSIZE] = {};
271 struct scsi_failures failures = {
272 .failure_definitions = mixed_total_defs,
274 struct scsi_cmnd sc = {
275 .sense_buffer = sense,
277 int i;
280 * Test total_allowed when there is a mix of per failure allowed
281 * and total_allowed limits.
283 failures.failure_definitions = mixed_total_defs;
284 scsi_failures_reset_retries(&failures);
285 failures.total_allowed = SCSI_LIB_TEST_TOTAL_MAX_ALLOWED;
287 scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0);
288 for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++)
289 /* Retry since we under the total_allowed limit */
290 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc,
291 &failures));
292 /* Do not retry since we are now over total_allowed limit */
293 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
295 scsi_failures_reset_retries(&failures);
296 scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0);
297 for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++)
298 /* Retry since we under the total_allowed limit */
299 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc,
300 &failures));
301 sc.result = DID_TIME_OUT << 16;
302 /* Retry because this failure has a per failure limit */
303 KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures));
304 scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x29, 0x0);
305 /* total_allowed is now hit so no more retries */
306 KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures));
309 static void scsi_lib_test_check_passthough(struct kunit *test)
311 scsi_lib_test_multiple_sense(test);
312 scsi_lib_test_any_sense(test);
313 scsi_lib_test_host(test);
314 scsi_lib_test_any_failure(test);
315 scsi_lib_test_any_status(test);
316 scsi_lib_test_total_allowed(test);
317 scsi_lib_test_mixed_total(test);
320 static struct kunit_case scsi_lib_test_cases[] = {
321 KUNIT_CASE(scsi_lib_test_check_passthough),
325 static struct kunit_suite scsi_lib_test_suite = {
326 .name = "scsi_lib",
327 .test_cases = scsi_lib_test_cases,
330 kunit_test_suite(scsi_lib_test_suite);