Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: loopback-test: add ability to test zero-length transfer

The spi-loopback-test module currently cannot test the spi_message
including a zero-length transfer. Because the zero-length transfer is
treated as a special value in several meanings.

1. The number of spi_transfer to execute in one test case is described
by spi_test.transfer_count. It is normally computed by counting number
of transfers with len > 0 in spi_test.transfers array.

This change stops the detection for the number of spi_transfer. Each
spi_test.transfer_count needs to be filled by hand now.

2. The spi_test.iterate_len is a list of transfer length to iterate on.
This list is terminated by zero, so zero-length transfer cannot be
included.

This changes the terminal value from 0 to -1.

3. The length for the spi_transfer masked by spi_test.iterate_transfer_mask
is iterated. Before starting the iteration, the default value which
is statically initialized is applied. In order to specify the default
value, zero-length is reserved.

Currently, the default values are always '1'. So this removes this
trick and add '1' to iterate_len list.

By applying all these changes, the spi-loopback-test can execute spi
messages with zero-length transfer.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Akinobu Mita and committed by
Mark Brown
8916671e 8494801d

+26 -48
+17 -38
drivers/spi/spi-loopback-test.c
··· 63 63 .iterate_len = { ITERATE_MAX_LEN }, 64 64 .iterate_tx_align = ITERATE_ALIGN, 65 65 .iterate_rx_align = ITERATE_ALIGN, 66 + .transfer_count = 1, 66 67 .transfers = { 67 68 { 68 - .len = 1, 69 69 .tx_buf = TX(0), 70 70 .rx_buf = RX(0), 71 71 }, ··· 77 77 .iterate_len = { ITERATE_MAX_LEN }, 78 78 .iterate_tx_align = ITERATE_ALIGN, 79 79 .iterate_rx_align = ITERATE_ALIGN, 80 + .transfer_count = 1, 80 81 .transfers = { 81 82 { 82 - .len = 1, 83 83 .tx_buf = TX(PAGE_SIZE - 4), 84 84 .rx_buf = RX(PAGE_SIZE - 4), 85 85 }, ··· 90 90 .fill_option = FILL_COUNT_8, 91 91 .iterate_len = { ITERATE_MAX_LEN }, 92 92 .iterate_tx_align = ITERATE_ALIGN, 93 + .transfer_count = 1, 93 94 .transfers = { 94 95 { 95 - .len = 1, 96 96 .tx_buf = TX(0), 97 97 }, 98 98 }, ··· 102 102 .fill_option = FILL_COUNT_8, 103 103 .iterate_len = { ITERATE_MAX_LEN }, 104 104 .iterate_rx_align = ITERATE_ALIGN, 105 + .transfer_count = 1, 105 106 .transfers = { 106 107 { 107 - .len = 1, 108 108 .rx_buf = RX(0), 109 109 }, 110 110 }, ··· 115 115 .iterate_len = { ITERATE_LEN }, 116 116 .iterate_tx_align = ITERATE_ALIGN, 117 117 .iterate_transfer_mask = BIT(0) | BIT(1), 118 + .transfer_count = 2, 118 119 .transfers = { 119 120 { 120 - .len = 1, 121 121 .tx_buf = TX(0), 122 122 }, 123 123 { 124 - .len = 1, 125 124 /* this is why we cant use ITERATE_MAX_LEN */ 126 125 .tx_buf = TX(SPI_TEST_MAX_SIZE_HALF), 127 126 }, ··· 132 133 .iterate_len = { ITERATE_MAX_LEN }, 133 134 .iterate_tx_align = ITERATE_ALIGN, 134 135 .iterate_transfer_mask = BIT(0), 136 + .transfer_count = 2, 135 137 .transfers = { 136 138 { 137 - .len = 1, 138 139 .tx_buf = TX(64), 139 140 }, 140 141 { ··· 149 150 .iterate_len = { ITERATE_MAX_LEN }, 150 151 .iterate_tx_align = ITERATE_ALIGN, 151 152 .iterate_transfer_mask = BIT(1), 153 + .transfer_count = 2, 152 154 .transfers = { 153 155 { 154 156 .len = 16, 155 157 .tx_buf = TX(0), 156 158 }, 157 159 { 158 - .len = 1, 159 160 .tx_buf = TX(64), 160 161 }, 161 162 }, ··· 166 167 .iterate_len = { ITERATE_MAX_LEN }, 167 168 .iterate_tx_align = ITERATE_ALIGN, 168 169 .iterate_transfer_mask = BIT(0) | BIT(1), 170 + .transfer_count = 2, 169 171 .transfers = { 170 172 { 171 - .len = 1, 172 173 .tx_buf = TX(0), 173 174 }, 174 175 { 175 - .len = 1, 176 176 .rx_buf = RX(0), 177 177 }, 178 178 }, ··· 182 184 .iterate_len = { ITERATE_MAX_LEN }, 183 185 .iterate_tx_align = ITERATE_ALIGN, 184 186 .iterate_transfer_mask = BIT(0), 187 + .transfer_count = 2, 185 188 .transfers = { 186 189 { 187 - .len = 1, 188 190 .tx_buf = TX(0), 189 191 }, 190 192 { ··· 199 201 .iterate_len = { ITERATE_MAX_LEN }, 200 202 .iterate_tx_align = ITERATE_ALIGN, 201 203 .iterate_transfer_mask = BIT(1), 204 + .transfer_count = 2, 202 205 .transfers = { 203 206 { 204 207 .len = 1, 205 208 .tx_buf = TX(0), 206 209 }, 207 210 { 208 - .len = 1, 209 211 .rx_buf = RX(0), 210 212 }, 211 213 }, ··· 216 218 .iterate_len = { ITERATE_LEN }, 217 219 .iterate_tx_align = ITERATE_ALIGN, 218 220 .iterate_transfer_mask = BIT(0) | BIT(1), 221 + .transfer_count = 2, 219 222 .transfers = { 220 223 { 221 - .len = 1, 222 224 .tx_buf = TX(0), 223 225 .rx_buf = RX(0), 224 226 }, 225 227 { 226 - .len = 1, 227 228 /* making sure we align without overwrite 228 229 * the reason we can not use ITERATE_MAX_LEN 229 230 */ ··· 237 240 .iterate_len = { ITERATE_MAX_LEN }, 238 241 .iterate_tx_align = ITERATE_ALIGN, 239 242 .iterate_transfer_mask = BIT(0), 243 + .transfer_count = 2, 240 244 .transfers = { 241 245 { 242 - .len = 1, 243 246 /* making sure we align without overwrite */ 244 247 .tx_buf = TX(1024), 245 248 .rx_buf = RX(1024), ··· 258 261 .iterate_len = { ITERATE_MAX_LEN }, 259 262 .iterate_tx_align = ITERATE_ALIGN, 260 263 .iterate_transfer_mask = BIT(1), 264 + .transfer_count = 2, 261 265 .transfers = { 262 266 { 263 267 .len = 1, ··· 266 268 .rx_buf = RX(0), 267 269 }, 268 270 { 269 - .len = 1, 270 271 /* making sure we align without overwrite */ 271 272 .tx_buf = TX(1024), 272 273 .rx_buf = RX(1024), ··· 500 503 /* if applicable to transfer check that rx_buf is equal to tx_buf */ 501 504 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 502 505 /* if there is no rx, then no check is needed */ 503 - if (!xfer->rx_buf) 506 + if (!xfer->len || !xfer->rx_buf) 504 507 continue; 505 508 /* so depending on tx_buf we need to handle things */ 506 509 if (xfer->tx_buf) { ··· 742 745 /* copy the test template to test */ 743 746 memcpy(&test, testtemplate, sizeof(test)); 744 747 745 - /* set up test->transfers to the correct count */ 746 - if (!test.transfer_count) { 747 - for (i = 0; 748 - (i < SPI_TEST_MAX_TRANSFERS) && test.transfers[i].len; 749 - i++) { 750 - test.transfer_count++; 751 - } 752 - } 753 - 754 748 /* if iterate_transfer_mask is not set, 755 749 * then set it to first transfer only 756 750 */ ··· 787 799 /* only when bit in transfer mask is set */ 788 800 if (!(test.iterate_transfer_mask & BIT(i))) 789 801 continue; 790 - if (len) 791 - test.transfers[i].len = len; 802 + test.transfers[i].len = len; 792 803 if (test.transfers[i].tx_buf) 793 804 test.transfers[i].tx_buf += tx_off; 794 805 if (test.transfers[i].tx_buf) ··· 897 910 /* iterate over all the iterable values using macros 898 911 * (to make it a bit more readable... 899 912 */ 900 - #define FOR_EACH_ITERATE(var, defaultvalue) \ 901 - for (idx_##var = -1, var = defaultvalue; \ 902 - ((idx_##var < 0) || \ 903 - ( \ 904 - (idx_##var < SPI_TEST_MAX_ITERATE) && \ 905 - (var = test->iterate_##var[idx_##var]) \ 906 - ) \ 907 - ); \ 908 - idx_##var++) 909 913 #define FOR_EACH_ALIGNMENT(var) \ 910 914 for (var = 0; \ 911 915 var < (test->iterate_##var ? \ ··· 906 928 1); \ 907 929 var++) 908 930 909 - FOR_EACH_ITERATE(len, 0) { 931 + for (idx_len = 0; idx_len < SPI_TEST_MAX_ITERATE && 932 + (len = test->iterate_len[idx_len]) != -1; idx_len++) { 910 933 FOR_EACH_ALIGNMENT(tx_align) { 911 934 FOR_EACH_ALIGNMENT(rx_align) { 912 935 /* and run the iteration */
+9 -10
drivers/spi/spi-test.h
··· 48 48 * 49 49 * @msg: a template @spi_message usedfor the default settings 50 50 * @transfers: array of @spi_transfers that are part of the 51 - * resulting spi_message. The first transfer with len == 0 52 - * signifies the end of the list 53 - * @transfer_count: normally computed number of transfers with len > 0 51 + * resulting spi_message. 52 + * @transfer_count: number of transfers 54 53 * 55 54 * @run_test: run a specific spi_test - this allows to override 56 55 * the default implementation of @spi_test_run_transfer ··· 61 62 * @expected_return: the expected return code - in some cases we want to 62 63 * test also for error conditions 63 64 * 64 - * @iterate_len: list of length to iterate on (in addition to the 65 - * explicitly set @spi_transfer.len) 65 + * @iterate_len: list of length to iterate on 66 66 * @iterate_tx_align: change the alignment of @spi_transfer.tx_buf 67 67 * for all values in the below range if set. 68 68 * the ranges are: ··· 87 89 int (*execute_msg)(struct spi_device *spi, struct spi_test *test, 88 90 void *tx, void *rx); 89 91 int expected_return; 90 - /* iterate over all the non-zero values */ 92 + /* iterate over all values, terminated by a -1 */ 91 93 int iterate_len[SPI_TEST_MAX_ITERATE]; 92 94 int iterate_tx_align; 93 95 int iterate_rx_align; ··· 124 126 int spi_test_run_tests(struct spi_device *spi, 125 127 struct spi_test *tests); 126 128 127 - /* some of the default @spi_transfer.len to test */ 128 - #define ITERATE_LEN 2, 3, 7, 11, 16, 31, 32, 64, 97, 128, 251, 256, \ 129 + #define ITERATE_LEN_LIST 1, 2, 3, 7, 11, 16, 31, 32, 64, 97, 128, 251, 256, \ 129 130 1021, 1024, 1031, 4093, PAGE_SIZE, 4099, 65536, 65537 130 - 131 - #define ITERATE_MAX_LEN ITERATE_LEN, SPI_TEST_MAX_SIZE - 1, SPI_TEST_MAX_SIZE 131 + /* some of the default @spi_transfer.len to test, terminated by a -1 */ 132 + #define ITERATE_LEN ITERATE_LEN_LIST, -1 133 + #define ITERATE_MAX_LEN ITERATE_LEN_LIST, (SPI_TEST_MAX_SIZE - 1), \ 134 + SPI_TEST_MAX_SIZE, -1 132 135 133 136 /* the default alignment to test */ 134 137 #define ITERATE_ALIGN sizeof(int)