1*0cbe4818SRobert Mustacchi /*
2*0cbe4818SRobert Mustacchi * This file and its contents are supplied under the terms of the
3*0cbe4818SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*0cbe4818SRobert Mustacchi * You may only use this file in accordance with the terms of version
5*0cbe4818SRobert Mustacchi * 1.0 of the CDDL.
6*0cbe4818SRobert Mustacchi *
7*0cbe4818SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*0cbe4818SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*0cbe4818SRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*0cbe4818SRobert Mustacchi */
11*0cbe4818SRobert Mustacchi
12*0cbe4818SRobert Mustacchi /*
13*0cbe4818SRobert Mustacchi * Copyright 2025 Oxide Computer Company
14*0cbe4818SRobert Mustacchi */
15*0cbe4818SRobert Mustacchi
16*0cbe4818SRobert Mustacchi /*
17*0cbe4818SRobert Mustacchi * This tests the kernel's ability to detect invalid I/O requests. For I2C
18*0cbe4818SRobert Mustacchi * requests this includes:
19*0cbe4818SRobert Mustacchi *
20*0cbe4818SRobert Mustacchi * - Invalid addresses
21*0cbe4818SRobert Mustacchi * - Invalid flags
22*0cbe4818SRobert Mustacchi * - Bad read and write combinations
23*0cbe4818SRobert Mustacchi *
24*0cbe4818SRobert Mustacchi * For SMBus operations this incldues:
25*0cbe4818SRobert Mustacchi *
26*0cbe4818SRobert Mustacchi * - Invalid addresses
27*0cbe4818SRobert Mustacchi * - Invalid flags, both general and operation-specific
28*0cbe4818SRobert Mustacchi * - Invalid operations
29*0cbe4818SRobert Mustacchi * - Operations which are unsupported
30*0cbe4818SRobert Mustacchi * - Specifying read and write length on operations that where it is fixed by
31*0cbe4818SRobert Mustacchi * the specification.
32*0cbe4818SRobert Mustacchi * - Bad read and write lengths for block requests
33*0cbe4818SRobert Mustacchi *
34*0cbe4818SRobert Mustacchi * All of the I/O tests operate against a non-existent on smbussim1. They should
35*0cbe4818SRobert Mustacchi * never succeed as a result; however, they could fail for the wrong reason.
36*0cbe4818SRobert Mustacchi */
37*0cbe4818SRobert Mustacchi
38*0cbe4818SRobert Mustacchi #include <stdlib.h>
39*0cbe4818SRobert Mustacchi #include <unistd.h>
40*0cbe4818SRobert Mustacchi #include <err.h>
41*0cbe4818SRobert Mustacchi #include <stdio.h>
42*0cbe4818SRobert Mustacchi #include <sys/debug.h>
43*0cbe4818SRobert Mustacchi #include <sys/stat.h>
44*0cbe4818SRobert Mustacchi #include <fcntl.h>
45*0cbe4818SRobert Mustacchi #include <string.h>
46*0cbe4818SRobert Mustacchi #include <errno.h>
47*0cbe4818SRobert Mustacchi #include <sys/sysmacros.h>
48*0cbe4818SRobert Mustacchi
49*0cbe4818SRobert Mustacchi #include <sys/i2c/ioctl.h>
50*0cbe4818SRobert Mustacchi #include "i2c_ioctl_util.h"
51*0cbe4818SRobert Mustacchi
52*0cbe4818SRobert Mustacchi static bool
test_one_i2c(int fd,i2c_req_t * req,i2c_errno_t err,const char * desc)53*0cbe4818SRobert Mustacchi test_one_i2c(int fd, i2c_req_t *req, i2c_errno_t err, const char *desc)
54*0cbe4818SRobert Mustacchi {
55*0cbe4818SRobert Mustacchi bool ret = true;
56*0cbe4818SRobert Mustacchi
57*0cbe4818SRobert Mustacchi req->ir_error.i2c_error = INT32_MAX;
58*0cbe4818SRobert Mustacchi req->ir_error.i2c_ctrl = INT32_MAX;
59*0cbe4818SRobert Mustacchi if (ioctl(fd, UI2C_IOCTL_I2C_REQ, req) != 0) {
60*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: unexpected ioctl failure: %s",
61*0cbe4818SRobert Mustacchi desc, strerrordesc_np(errno));
62*0cbe4818SRobert Mustacchi return (false);
63*0cbe4818SRobert Mustacchi }
64*0cbe4818SRobert Mustacchi
65*0cbe4818SRobert Mustacchi if (req->ir_error.i2c_error != err) {
66*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: I2C ioctl failed with I2C error 0x%x, "
67*0cbe4818SRobert Mustacchi "expected 0x%x", desc, req->ir_error.i2c_error, err);
68*0cbe4818SRobert Mustacchi ret = false;
69*0cbe4818SRobert Mustacchi }
70*0cbe4818SRobert Mustacchi
71*0cbe4818SRobert Mustacchi if (req->ir_error.i2c_ctrl != I2C_CTRL_E_OK) {
72*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: I2C ioctl has unexpected controller "
73*0cbe4818SRobert Mustacchi "error 0x%x", desc, req->ir_error.i2c_ctrl);
74*0cbe4818SRobert Mustacchi ret = false;
75*0cbe4818SRobert Mustacchi }
76*0cbe4818SRobert Mustacchi
77*0cbe4818SRobert Mustacchi if (ret) {
78*0cbe4818SRobert Mustacchi (void) printf("TEST PASSED: %s correctly failed with I2C "
79*0cbe4818SRobert Mustacchi "error 0x%x\n", desc, err);
80*0cbe4818SRobert Mustacchi }
81*0cbe4818SRobert Mustacchi
82*0cbe4818SRobert Mustacchi return (ret);
83*0cbe4818SRobert Mustacchi }
84*0cbe4818SRobert Mustacchi
85*0cbe4818SRobert Mustacchi static bool
test_i2c_reqs(int fd)86*0cbe4818SRobert Mustacchi test_i2c_reqs(int fd)
87*0cbe4818SRobert Mustacchi {
88*0cbe4818SRobert Mustacchi bool ret = true;
89*0cbe4818SRobert Mustacchi i2c_req_t req;
90*0cbe4818SRobert Mustacchi
91*0cbe4818SRobert Mustacchi /*
92*0cbe4818SRobert Mustacchi * Set up the request as a one byte read request.
93*0cbe4818SRobert Mustacchi */
94*0cbe4818SRobert Mustacchi (void) memset(&req, 0, sizeof (i2c_req_t));
95*0cbe4818SRobert Mustacchi req.ir_rlen = 1;
96*0cbe4818SRobert Mustacchi
97*0cbe4818SRobert Mustacchi for (size_t i = 0; i < nbad_addrs; i++) {
98*0cbe4818SRobert Mustacchi char desc[128];
99*0cbe4818SRobert Mustacchi
100*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "i2c: bad address %zu "
101*0cbe4818SRobert Mustacchi "(0x%x,0x%x)", i, bad_addrs[i].ba_type,
102*0cbe4818SRobert Mustacchi bad_addrs[i].ba_addr);
103*0cbe4818SRobert Mustacchi req.ir_addr.ia_type = bad_addrs[i].ba_type;
104*0cbe4818SRobert Mustacchi req.ir_addr.ia_addr = bad_addrs[i].ba_addr;
105*0cbe4818SRobert Mustacchi
106*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, bad_addrs[i].ba_error, desc)) {
107*0cbe4818SRobert Mustacchi ret = false;
108*0cbe4818SRobert Mustacchi }
109*0cbe4818SRobert Mustacchi }
110*0cbe4818SRobert Mustacchi
111*0cbe4818SRobert Mustacchi req.ir_addr.ia_type = I2C_ADDR_7BIT;
112*0cbe4818SRobert Mustacchi req.ir_addr.ia_addr = 0x23;
113*0cbe4818SRobert Mustacchi
114*0cbe4818SRobert Mustacchi uint32_t bad_flags[] = { I2C_IO_REQ_F_QUICK_WRITE, 0x23, 0x777,
115*0cbe4818SRobert Mustacchi INT32_MAX, UINT32_MAX, 0x42 };
116*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(bad_flags); i++) {
117*0cbe4818SRobert Mustacchi char desc[128];
118*0cbe4818SRobert Mustacchi
119*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "i2c: bad flags 0x%x",
120*0cbe4818SRobert Mustacchi bad_flags[i]);
121*0cbe4818SRobert Mustacchi req.ir_flags = bad_flags[i];
122*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_BAD_I2C_REQ_FLAGS,
123*0cbe4818SRobert Mustacchi desc)) {
124*0cbe4818SRobert Mustacchi ret = false;
125*0cbe4818SRobert Mustacchi }
126*0cbe4818SRobert Mustacchi }
127*0cbe4818SRobert Mustacchi
128*0cbe4818SRobert Mustacchi req.ir_flags = 0;
129*0cbe4818SRobert Mustacchi req.ir_rlen = 0;
130*0cbe4818SRobert Mustacchi req.ir_wlen = 0;
131*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_NEED_READ_OR_WRITE,
132*0cbe4818SRobert Mustacchi "i2c r=0, w=0")) {
133*0cbe4818SRobert Mustacchi ret = false;
134*0cbe4818SRobert Mustacchi }
135*0cbe4818SRobert Mustacchi
136*0cbe4818SRobert Mustacchi req.ir_rlen = 1;
137*0cbe4818SRobert Mustacchi req.ir_wlen = I2C_REQ_MAX + 1;
138*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_BAD_I2C_REQ_WRITE_LEN,
139*0cbe4818SRobert Mustacchi "i2c r=1, w=257")) {
140*0cbe4818SRobert Mustacchi ret = false;
141*0cbe4818SRobert Mustacchi }
142*0cbe4818SRobert Mustacchi
143*0cbe4818SRobert Mustacchi req.ir_rlen = 1;
144*0cbe4818SRobert Mustacchi req.ir_wlen = UINT16_MAX;
145*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_BAD_I2C_REQ_WRITE_LEN,
146*0cbe4818SRobert Mustacchi "i2c r=1, w=ffff")) {
147*0cbe4818SRobert Mustacchi ret = false;
148*0cbe4818SRobert Mustacchi }
149*0cbe4818SRobert Mustacchi
150*0cbe4818SRobert Mustacchi req.ir_rlen = I2C_REQ_MAX + 1;
151*0cbe4818SRobert Mustacchi req.ir_wlen = 0;
152*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_BAD_I2C_REQ_READ_LEN,
153*0cbe4818SRobert Mustacchi "i2c r=257, w=0")) {
154*0cbe4818SRobert Mustacchi ret = false;
155*0cbe4818SRobert Mustacchi }
156*0cbe4818SRobert Mustacchi
157*0cbe4818SRobert Mustacchi req.ir_rlen = UINT16_MAX;
158*0cbe4818SRobert Mustacchi req.ir_wlen = 0;
159*0cbe4818SRobert Mustacchi if (!test_one_i2c(fd, &req, I2C_CORE_E_BAD_I2C_REQ_READ_LEN,
160*0cbe4818SRobert Mustacchi "i2c r=UINT16_MAX, w=0")) {
161*0cbe4818SRobert Mustacchi ret = false;
162*0cbe4818SRobert Mustacchi }
163*0cbe4818SRobert Mustacchi
164*0cbe4818SRobert Mustacchi return (ret);
165*0cbe4818SRobert Mustacchi }
166*0cbe4818SRobert Mustacchi
167*0cbe4818SRobert Mustacchi static bool
test_one_smbus(int fd,smbus_req_t * req,i2c_errno_t err,const char * desc)168*0cbe4818SRobert Mustacchi test_one_smbus(int fd, smbus_req_t *req, i2c_errno_t err, const char *desc)
169*0cbe4818SRobert Mustacchi {
170*0cbe4818SRobert Mustacchi bool ret = true;
171*0cbe4818SRobert Mustacchi
172*0cbe4818SRobert Mustacchi req->smbr_error.i2c_error = INT32_MAX;
173*0cbe4818SRobert Mustacchi req->smbr_error.i2c_ctrl = INT32_MAX;
174*0cbe4818SRobert Mustacchi if (ioctl(fd, UI2C_IOCTL_SMBUS_REQ, req) != 0) {
175*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: unexpected smbus ioctl failure: %s",
176*0cbe4818SRobert Mustacchi desc, strerrordesc_np(errno));
177*0cbe4818SRobert Mustacchi return (false);
178*0cbe4818SRobert Mustacchi }
179*0cbe4818SRobert Mustacchi
180*0cbe4818SRobert Mustacchi if (req->smbr_error.i2c_error != err) {
181*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: SMBus ioctl failed with I2C error "
182*0cbe4818SRobert Mustacchi "0x%x, expected 0x%x", desc, req->smbr_error.i2c_error,
183*0cbe4818SRobert Mustacchi err);
184*0cbe4818SRobert Mustacchi ret = false;
185*0cbe4818SRobert Mustacchi }
186*0cbe4818SRobert Mustacchi
187*0cbe4818SRobert Mustacchi if (req->smbr_error.i2c_ctrl != I2C_CTRL_E_OK) {
188*0cbe4818SRobert Mustacchi warnx("TEST FAILED: %s: SMBus ioctl has unexpected controller "
189*0cbe4818SRobert Mustacchi "error 0x%x", desc, req->smbr_error.i2c_ctrl);
190*0cbe4818SRobert Mustacchi ret = false;
191*0cbe4818SRobert Mustacchi }
192*0cbe4818SRobert Mustacchi
193*0cbe4818SRobert Mustacchi if (ret) {
194*0cbe4818SRobert Mustacchi (void) printf("TEST PASSED: %s correctly failed with I2C "
195*0cbe4818SRobert Mustacchi "error 0x%x\n", desc, err);
196*0cbe4818SRobert Mustacchi }
197*0cbe4818SRobert Mustacchi
198*0cbe4818SRobert Mustacchi return (ret);
199*0cbe4818SRobert Mustacchi }
200*0cbe4818SRobert Mustacchi
201*0cbe4818SRobert Mustacchi
202*0cbe4818SRobert Mustacchi static bool
test_smbus_reqs(int fd)203*0cbe4818SRobert Mustacchi test_smbus_reqs(int fd)
204*0cbe4818SRobert Mustacchi {
205*0cbe4818SRobert Mustacchi bool ret = true;
206*0cbe4818SRobert Mustacchi smbus_req_t req;
207*0cbe4818SRobert Mustacchi
208*0cbe4818SRobert Mustacchi /*
209*0cbe4818SRobert Mustacchi * Set up the request as a read byte.
210*0cbe4818SRobert Mustacchi */
211*0cbe4818SRobert Mustacchi (void) memset(&req, 0, sizeof (i2c_req_t));
212*0cbe4818SRobert Mustacchi req.smbr_cmd = 0x23;
213*0cbe4818SRobert Mustacchi req.smbr_op = SMBUS_OP_READ_BYTE;
214*0cbe4818SRobert Mustacchi
215*0cbe4818SRobert Mustacchi for (size_t i = 0; i < nbad_addrs; i++) {
216*0cbe4818SRobert Mustacchi char desc[128];
217*0cbe4818SRobert Mustacchi
218*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: bad address %zu "
219*0cbe4818SRobert Mustacchi "(0x%x,0x%x)", i, bad_addrs[i].ba_type,
220*0cbe4818SRobert Mustacchi bad_addrs[i].ba_addr);
221*0cbe4818SRobert Mustacchi req.smbr_addr.ia_type = bad_addrs[i].ba_type;
222*0cbe4818SRobert Mustacchi req.smbr_addr.ia_addr = bad_addrs[i].ba_addr;
223*0cbe4818SRobert Mustacchi
224*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, bad_addrs[i].ba_error, desc)) {
225*0cbe4818SRobert Mustacchi ret = false;
226*0cbe4818SRobert Mustacchi }
227*0cbe4818SRobert Mustacchi }
228*0cbe4818SRobert Mustacchi
229*0cbe4818SRobert Mustacchi /*
230*0cbe4818SRobert Mustacchi * The quick flag should work only with the quick operation, hence why
231*0cbe4818SRobert Mustacchi * it's included in the group below.
232*0cbe4818SRobert Mustacchi */
233*0cbe4818SRobert Mustacchi req.smbr_addr.ia_type = I2C_ADDR_7BIT;
234*0cbe4818SRobert Mustacchi req.smbr_addr.ia_addr = 0x23;
235*0cbe4818SRobert Mustacchi
236*0cbe4818SRobert Mustacchi uint32_t bad_flags[] = { I2C_IO_REQ_F_QUICK_WRITE, 0x23, 0x777,
237*0cbe4818SRobert Mustacchi INT32_MAX, UINT32_MAX, 0x42 };
238*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(bad_flags); i++) {
239*0cbe4818SRobert Mustacchi char desc[128];
240*0cbe4818SRobert Mustacchi
241*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: bad flags 0x%x",
242*0cbe4818SRobert Mustacchi bad_flags[i]);
243*0cbe4818SRobert Mustacchi req.smbr_flags = bad_flags[i];
244*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_REQ_FLAGS,
245*0cbe4818SRobert Mustacchi desc)) {
246*0cbe4818SRobert Mustacchi ret = false;
247*0cbe4818SRobert Mustacchi }
248*0cbe4818SRobert Mustacchi }
249*0cbe4818SRobert Mustacchi
250*0cbe4818SRobert Mustacchi req.smbr_flags = 0;
251*0cbe4818SRobert Mustacchi uint32_t bad_ops[] = { SMBUS_OP_I2C_READ_BLOCK + 1,
252*0cbe4818SRobert Mustacchi SMBUS_OP_I2C_READ_BLOCK << 1, 0x42, 0x7777, INT32_MAX };
253*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(bad_ops); i++) {
254*0cbe4818SRobert Mustacchi char desc[128];
255*0cbe4818SRobert Mustacchi
256*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: bad operation "
257*0cbe4818SRobert Mustacchi "0x%x", bad_ops[i]);
258*0cbe4818SRobert Mustacchi req.smbr_op = bad_ops[i];
259*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_OP, desc)) {
260*0cbe4818SRobert Mustacchi ret = false;
261*0cbe4818SRobert Mustacchi }
262*0cbe4818SRobert Mustacchi }
263*0cbe4818SRobert Mustacchi
264*0cbe4818SRobert Mustacchi smbus_op_t unsup_ops[] = { SMBUS_OP_READ_BLOCK, SMBUS_OP_HOST_NOTIFY,
265*0cbe4818SRobert Mustacchi SMBUS_OP_BLOCK_PROCESS_CALL };
266*0cbe4818SRobert Mustacchi
267*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(unsup_ops); i++) {
268*0cbe4818SRobert Mustacchi char desc[128];
269*0cbe4818SRobert Mustacchi
270*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: unsupported "
271*0cbe4818SRobert Mustacchi "operation 0x%x", unsup_ops[i]);
272*0cbe4818SRobert Mustacchi req.smbr_op = unsup_ops[i];
273*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_UNSUP_SMBUS_OP,
274*0cbe4818SRobert Mustacchi desc)) {
275*0cbe4818SRobert Mustacchi ret = false;
276*0cbe4818SRobert Mustacchi }
277*0cbe4818SRobert Mustacchi }
278*0cbe4818SRobert Mustacchi
279*0cbe4818SRobert Mustacchi smbus_op_t norw_ops[] = { SMBUS_OP_QUICK_COMMAND, SMBUS_OP_SEND_BYTE,
280*0cbe4818SRobert Mustacchi SMBUS_OP_RECV_BYTE, SMBUS_OP_WRITE_BYTE, SMBUS_OP_READ_BYTE,
281*0cbe4818SRobert Mustacchi SMBUS_OP_WRITE_WORD, SMBUS_OP_READ_WORD, SMBUS_OP_PROCESS_CALL,
282*0cbe4818SRobert Mustacchi SMBUS_OP_WRITE_U32, SMBUS_OP_READ_U32, SMBUS_OP_WRITE_U64,
283*0cbe4818SRobert Mustacchi SMBUS_OP_READ_U64 };
284*0cbe4818SRobert Mustacchi
285*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(norw_ops); i++) {
286*0cbe4818SRobert Mustacchi char desc[128];
287*0cbe4818SRobert Mustacchi
288*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: op 0x%x fails "
289*0cbe4818SRobert Mustacchi "with read length", norw_ops[i]);
290*0cbe4818SRobert Mustacchi req.smbr_op = norw_ops[i];
291*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x4;
292*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
293*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
294*0cbe4818SRobert Mustacchi desc)) {
295*0cbe4818SRobert Mustacchi ret = false;
296*0cbe4818SRobert Mustacchi }
297*0cbe4818SRobert Mustacchi
298*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus: op 0x%x fails "
299*0cbe4818SRobert Mustacchi "with write length", norw_ops[i]);
300*0cbe4818SRobert Mustacchi req.smbr_op = norw_ops[i];
301*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
302*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x4;
303*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_WRITE_LEN,
304*0cbe4818SRobert Mustacchi desc)) {
305*0cbe4818SRobert Mustacchi ret = false;
306*0cbe4818SRobert Mustacchi }
307*0cbe4818SRobert Mustacchi }
308*0cbe4818SRobert Mustacchi
309*0cbe4818SRobert Mustacchi smbus_op_t wrblk_ops[] = { SMBUS_OP_WRITE_BLOCK,
310*0cbe4818SRobert Mustacchi SMBUS_OP_I2C_WRITE_BLOCK };
311*0cbe4818SRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(wrblk_ops); i++) {
312*0cbe4818SRobert Mustacchi char desc[128];
313*0cbe4818SRobert Mustacchi
314*0cbe4818SRobert Mustacchi req.smbr_op = wrblk_ops[i];
315*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus op 0x%x fails with "
316*0cbe4818SRobert Mustacchi "read and write", wrblk_ops[i]);
317*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x1;
318*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x8;
319*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
320*0cbe4818SRobert Mustacchi desc)) {
321*0cbe4818SRobert Mustacchi ret = false;
322*0cbe4818SRobert Mustacchi }
323*0cbe4818SRobert Mustacchi
324*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus op 0x%x fails with "
325*0cbe4818SRobert Mustacchi "read and no write", wrblk_ops[i]);
326*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x2;
327*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
328*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
329*0cbe4818SRobert Mustacchi desc)) {
330*0cbe4818SRobert Mustacchi ret = false;
331*0cbe4818SRobert Mustacchi }
332*0cbe4818SRobert Mustacchi
333*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus op 0x%x fails with "
334*0cbe4818SRobert Mustacchi "no read and no write", wrblk_ops[i]);
335*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
336*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
337*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_WRITE_LEN,
338*0cbe4818SRobert Mustacchi desc)) {
339*0cbe4818SRobert Mustacchi ret = false;
340*0cbe4818SRobert Mustacchi }
341*0cbe4818SRobert Mustacchi
342*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus op 0x%x fails with "
343*0cbe4818SRobert Mustacchi "oversize write 1", wrblk_ops[i]);
344*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
345*0cbe4818SRobert Mustacchi req.smbr_wlen = I2C_REQ_MAX + 1;
346*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_WRITE_LEN,
347*0cbe4818SRobert Mustacchi desc)) {
348*0cbe4818SRobert Mustacchi ret = false;
349*0cbe4818SRobert Mustacchi }
350*0cbe4818SRobert Mustacchi
351*0cbe4818SRobert Mustacchi (void) snprintf(desc, sizeof (desc), "smbus op 0x%x fails with "
352*0cbe4818SRobert Mustacchi "oversize write 2", wrblk_ops[i]);
353*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
354*0cbe4818SRobert Mustacchi req.smbr_wlen = UINT16_MAX;
355*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_WRITE_LEN,
356*0cbe4818SRobert Mustacchi desc)) {
357*0cbe4818SRobert Mustacchi ret = false;
358*0cbe4818SRobert Mustacchi }
359*0cbe4818SRobert Mustacchi }
360*0cbe4818SRobert Mustacchi
361*0cbe4818SRobert Mustacchi req.smbr_op = SMBUS_OP_I2C_READ_BLOCK;
362*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x2;
363*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x2;
364*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_WRITE_LEN,
365*0cbe4818SRobert Mustacchi "block read fails with read and write")) {
366*0cbe4818SRobert Mustacchi ret = false;
367*0cbe4818SRobert Mustacchi }
368*0cbe4818SRobert Mustacchi
369*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
370*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x2;
371*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
372*0cbe4818SRobert Mustacchi "block read fails with no read and write")) {
373*0cbe4818SRobert Mustacchi ret = false;
374*0cbe4818SRobert Mustacchi }
375*0cbe4818SRobert Mustacchi
376*0cbe4818SRobert Mustacchi req.smbr_rlen = 0x0;
377*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
378*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
379*0cbe4818SRobert Mustacchi "block read fails with no read and no write")) {
380*0cbe4818SRobert Mustacchi ret = false;
381*0cbe4818SRobert Mustacchi }
382*0cbe4818SRobert Mustacchi
383*0cbe4818SRobert Mustacchi req.smbr_rlen = I2C_REQ_MAX + 1;
384*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
385*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
386*0cbe4818SRobert Mustacchi "block read fails with oversize read 1")) {
387*0cbe4818SRobert Mustacchi ret = false;
388*0cbe4818SRobert Mustacchi }
389*0cbe4818SRobert Mustacchi
390*0cbe4818SRobert Mustacchi req.smbr_rlen = UINT16_MAX;
391*0cbe4818SRobert Mustacchi req.smbr_wlen = 0x0;
392*0cbe4818SRobert Mustacchi if (!test_one_smbus(fd, &req, I2C_CORE_E_BAD_SMBUS_READ_LEN,
393*0cbe4818SRobert Mustacchi "block read fails with oversize read 2")) {
394*0cbe4818SRobert Mustacchi ret = false;
395*0cbe4818SRobert Mustacchi }
396*0cbe4818SRobert Mustacchi
397*0cbe4818SRobert Mustacchi return (ret);
398*0cbe4818SRobert Mustacchi }
399*0cbe4818SRobert Mustacchi
400*0cbe4818SRobert Mustacchi int
main(void)401*0cbe4818SRobert Mustacchi main(void)
402*0cbe4818SRobert Mustacchi {
403*0cbe4818SRobert Mustacchi int ret = EXIT_SUCCESS;
404*0cbe4818SRobert Mustacchi int fd = i2c_ioctl_test_get_fd(I2C_D_PORT, "smbussim1/0", O_RDWR);
405*0cbe4818SRobert Mustacchi
406*0cbe4818SRobert Mustacchi if (!test_i2c_reqs(fd)) {
407*0cbe4818SRobert Mustacchi ret = EXIT_FAILURE;
408*0cbe4818SRobert Mustacchi }
409*0cbe4818SRobert Mustacchi
410*0cbe4818SRobert Mustacchi if (!test_smbus_reqs(fd)) {
411*0cbe4818SRobert Mustacchi ret = EXIT_FAILURE;
412*0cbe4818SRobert Mustacchi }
413*0cbe4818SRobert Mustacchi
414*0cbe4818SRobert Mustacchi VERIFY0(close(fd));
415*0cbe4818SRobert Mustacchi if (ret == EXIT_SUCCESS) {
416*0cbe4818SRobert Mustacchi (void) printf("All tests passed successfully\n");
417*0cbe4818SRobert Mustacchi }
418*0cbe4818SRobert Mustacchi return (ret);
419*0cbe4818SRobert Mustacchi }
420