xref: /illumos-gate/usr/src/test/i2c-tests/tests/ioctl/invalid-io.c (revision 0cbe48189888d02563dba9c90132ac391ba233b6)
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