xref: /illumos-gate/usr/src/test/i2c-tests/tests/i2cadm/i2cadm-io.ksh (revision 0cbe48189888d02563dba9c90132ac391ba233b6)
1*0cbe4818SRobert Mustacchi#! /usr/bin/ksh
2*0cbe4818SRobert Mustacchi#
3*0cbe4818SRobert Mustacchi# This file and its contents are supplied under the terms of the
4*0cbe4818SRobert Mustacchi# Common Development and Distribution License ("CDDL"), version 1.0.
5*0cbe4818SRobert Mustacchi# You may only use this file in accordance with the terms of version
6*0cbe4818SRobert Mustacchi# 1.0 of the CDDL.
7*0cbe4818SRobert Mustacchi#
8*0cbe4818SRobert Mustacchi# A full copy of the text of the CDDL should have accompanied this
9*0cbe4818SRobert Mustacchi# source.  A copy of the CDDL is also available via the Internet at
10*0cbe4818SRobert Mustacchi# http://www.illumos.org/license/CDDL.
11*0cbe4818SRobert Mustacchi#
12*0cbe4818SRobert Mustacchi
13*0cbe4818SRobert Mustacchi#
14*0cbe4818SRobert Mustacchi# Copyright 2025 Oxide Computer Company
15*0cbe4818SRobert Mustacchi#
16*0cbe4818SRobert Mustacchi
17*0cbe4818SRobert Mustacchi#
18*0cbe4818SRobert Mustacchi# Perform various I/O tests against our virtual devices. Several of the at24c
19*0cbe4818SRobert Mustacchi# devices have content pre-loaded into them with parts of Tolkienian rhymes. We
20*0cbe4818SRobert Mustacchi# can only perform SMBus operations against the at24c08 as the others require a
21*0cbe4818SRobert Mustacchi# two byte I/O pattern.
22*0cbe4818SRobert Mustacchi#
23*0cbe4818SRobert Mustacchi
24*0cbe4818SRobert Mustacchi. $(dirname $0)/common.ksh
25*0cbe4818SRobert Mustacchi
26*0cbe4818SRobert Mustacchi#
27*0cbe4818SRobert Mustacchi# Variable where the results of performing I/O will be sent.
28*0cbe4818SRobert Mustacchi#
29*0cbe4818SRobert Mustacchiio_data=
30*0cbe4818SRobert Mustacchiio_eedev=
31*0cbe4818SRobert Mustacchiio_dd=
32*0cbe4818SRobert Mustacchi
33*0cbe4818SRobert Mustacchifunction i2c_at24c_to_eedev
34*0cbe4818SRobert Mustacchi{
35*0cbe4818SRobert Mustacchi	typeset path="$1"
36*0cbe4818SRobert Mustacchi	typeset drv="$2"
37*0cbe4818SRobert Mustacchi	typeset part=
38*0cbe4818SRobert Mustacchi
39*0cbe4818SRobert Mustacchi	part=$(i2cadm device list -Hpo instance $path | sed "s/$drv/$drv\//")
40*0cbe4818SRobert Mustacchi	[[ -z "$part" ]] && fatal "failed to translate $path"
41*0cbe4818SRobert Mustacchi	io_eedev="/dev/eeprom/$part/eeprom"
42*0cbe4818SRobert Mustacchi}
43*0cbe4818SRobert Mustacchi
44*0cbe4818SRobert Mustacchifunction do_io
45*0cbe4818SRobert Mustacchi{
46*0cbe4818SRobert Mustacchi	io_data=$($I2CADM io -o /dev/stdout $@)
47*0cbe4818SRobert Mustacchi	if (( $? != 0 )); then
48*0cbe4818SRobert Mustacchi		fatal "failed to perform I/O $@"
49*0cbe4818SRobert Mustacchi	fi
50*0cbe4818SRobert Mustacchi}
51*0cbe4818SRobert Mustacchi
52*0cbe4818SRobert Mustacchifunction check_io
53*0cbe4818SRobert Mustacchi{
54*0cbe4818SRobert Mustacchi	typeset desc="$1"
55*0cbe4818SRobert Mustacchi	typeset targ="$2"
56*0cbe4818SRobert Mustacchi	shift
57*0cbe4818SRobert Mustacchi	shift
58*0cbe4818SRobert Mustacchi
59*0cbe4818SRobert Mustacchi	do_io $@
60*0cbe4818SRobert Mustacchi	if [[ "$targ" != "$io_data" ]]; then
61*0cbe4818SRobert Mustacchi		warn "$desc: I/O mismatch: found [$io_data], expected [$targ]"
62*0cbe4818SRobert Mustacchi	else
63*0cbe4818SRobert Mustacchi		printf "TEST PASSED: %s\n" "$desc"
64*0cbe4818SRobert Mustacchi	fi
65*0cbe4818SRobert Mustacchi}
66*0cbe4818SRobert Mustacchi
67*0cbe4818SRobert Mustacchifunction get_dd
68*0cbe4818SRobert Mustacchi{
69*0cbe4818SRobert Mustacchi	typeset off="$1"
70*0cbe4818SRobert Mustacchi	typeset len="$2"
71*0cbe4818SRobert Mustacchi
72*0cbe4818SRobert Mustacchi	[[ -z "$io_eedev" ]] && fatal "missing required eedev path"
73*0cbe4818SRobert Mustacchi
74*0cbe4818SRobert Mustacchi	io_dd=$(dd iseek=$off bs=1 count="$len" if=$io_eedev of=/dev/stdout \
75*0cbe4818SRobert Mustacchi	    status=none)
76*0cbe4818SRobert Mustacchi	if (( $? != 0 )); then
77*0cbe4818SRobert Mustacchi		fatal "failed to dd on $io_eedev"
78*0cbe4818SRobert Mustacchi	fi
79*0cbe4818SRobert Mustacchi}
80*0cbe4818SRobert Mustacchi
81*0cbe4818SRobert Mustacchifunction compare_io_dd
82*0cbe4818SRobert Mustacchi{
83*0cbe4818SRobert Mustacchi	typeset desc="$1"
84*0cbe4818SRobert Mustacchi
85*0cbe4818SRobert Mustacchi	if [[ "$io_dd" != "$io_data" ]]; then
86*0cbe4818SRobert Mustacchi		warn "$desc: dd and i2c disagree, found $io_dd (dd) and " \
87*0cbe4818SRobert Mustacchi		"$io_data (i2c)"
88*0cbe4818SRobert Mustacchi	else
89*0cbe4818SRobert Mustacchi		printf "TEST PASSED: %s\n" "$desc"
90*0cbe4818SRobert Mustacchi	fi
91*0cbe4818SRobert Mustacchi}
92*0cbe4818SRobert Mustacchi
93*0cbe4818SRobert Mustacchifunction write_io
94*0cbe4818SRobert Mustacchi{
95*0cbe4818SRobert Mustacchi	typeset desc="$1"
96*0cbe4818SRobert Mustacchi	typeset targ="$2"
97*0cbe4818SRobert Mustacchi	typeset len="$3"
98*0cbe4818SRobert Mustacchi	typeset off="$4"
99*0cbe4818SRobert Mustacchi	typeset dev="$5"
100*0cbe4818SRobert Mustacchi	shift
101*0cbe4818SRobert Mustacchi	shift
102*0cbe4818SRobert Mustacchi	shift
103*0cbe4818SRobert Mustacchi	shift
104*0cbe4818SRobert Mustacchi	shift
105*0cbe4818SRobert Mustacchi
106*0cbe4818SRobert Mustacchi	#
107*0cbe4818SRobert Mustacchi	# Bump len by one to write the offset
108*0cbe4818SRobert Mustacchi	#
109*0cbe4818SRobert Mustacchi	if ! $I2CADM io -d "$dev" $@; then
110*0cbe4818SRobert Mustacchi		fatal "failed to perform I/O $@"
111*0cbe4818SRobert Mustacchi	fi
112*0cbe4818SRobert Mustacchi
113*0cbe4818SRobert Mustacchi	check_io "$desc" "$targ" -d $dev -w 1 -r $len $off
114*0cbe4818SRobert Mustacchi}
115*0cbe4818SRobert Mustacchi
116*0cbe4818SRobert Mustacchi#
117*0cbe4818SRobert Mustacchi# First Verify that basic I/O makes sense.
118*0cbe4818SRobert Mustacchi#
119*0cbe4818SRobert Mustacchicheck_io "Three Rings i2c" "Three rings" -d i2csim0/0/0x20 -r 11 -w 1 0x00
120*0cbe4818SRobert Mustacchicheck_io "Three Rings offset i2c" "rings" -d i2csim0/0/0x20 -r 5 -w 1 0x06
121*0cbe4818SRobert Mustacchicheck_io "Three Rings recv-u8 (1)" " " -d i2csim0/0/0x20 -m recv-u8
122*0cbe4818SRobert Mustacchicheck_io "Three Rings recv-u8 (2)" "f" -d i2csim0/0/0x20 -m recv-u8
123*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u8 (1)" "E" -d i2csim0/0/0x20 -m read-u8 -c 0x10
124*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u8 (2)" "-" -d i2csim0/0/0x20 -m read-u8 -c 0x15
125*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u16" "El" -d i2csim0/0/0x20 -m read-u16 -c 0x10
126*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u32" "king" -d i2csim0/0/0x20 -m read-u32 -c 0x16
127*0cbe4818SRobert Mustacchicheck_io "Three Rings read-u64" "the sky," -d i2csim0/0/0x20 -m read-u64 -c 0x23
128*0cbe4818SRobert Mustacchicheck_io "Three Rings read-block-i2c" "Elven-kings, und" -d i2csim0/0/0x20 \
129*0cbe4818SRobert Mustacchi    -m read-block-i2c -c 0x10 -r 0x10
130*0cbe4818SRobert Mustacchicheck_io "Three Rings i2c (all)" "Three rings for Elven-kings, under the sky," \
131*0cbe4818SRobert Mustacchi    -d i2csim0/0/0x20 -r 0x2b -w 1 0x00
132*0cbe4818SRobert Mustacchicheck_io "Three Rings block (all)" "Three rings for Elven-kings, under the sky," \
133*0cbe4818SRobert Mustacchi    -d i2csim0/0/0x20 -m read-block-i2c -c 0x00 -r 0x2b
134*0cbe4818SRobert Mustacchi
135*0cbe4818SRobert Mustacchi#
136*0cbe4818SRobert Mustacchi# Next, we want to verify that using /dev/eeprom and the io mechanism is
137*0cbe4818SRobert Mustacchi# similar. First we'll verify reads across all the different segments of the
138*0cbe4818SRobert Mustacchi# at24c08.
139*0cbe4818SRobert Mustacchi#
140*0cbe4818SRobert Mustacchii2c_at24c_to_eedev i2csim0/0/0x20 at24c
141*0cbe4818SRobert Mustacchiget_dd 0 43
142*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 0 comparison"
143*0cbe4818SRobert Mustacchi
144*0cbe4818SRobert Mustacchicheck_io "Seven i2c (all)" "Seven for the Dwarf-lords in their halls of stone," \
145*0cbe4818SRobert Mustacchi    -d i2csim0/0 -a 0x21 -r 0x32 -w 1 0x00
146*0cbe4818SRobert Mustacchiget_dd 256 50
147*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 1 comparison"
148*0cbe4818SRobert Mustacchi
149*0cbe4818SRobert Mustacchicheck_io "Nine i2c (all)" "Nine for Moral Men, doomed to die," \
150*0cbe4818SRobert Mustacchi    -d i2csim0/0 -a 0x22 -r 0x22 -w 1 0x00
151*0cbe4818SRobert Mustacchiget_dd 512 34
152*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 2 comparison"
153*0cbe4818SRobert Mustacchi
154*0cbe4818SRobert Mustacchicheck_io "One i2c (all)" "One for the dark Lord on his dark throne" \
155*0cbe4818SRobert Mustacchi    -d i2csim0/0 -a 0x23 -r 0x28 -w 1 0x00
156*0cbe4818SRobert Mustacchiget_dd 768 40
157*0cbe4818SRobert Mustacchicompare_io_dd "at24cs08 block 3 comparison"
158*0cbe4818SRobert Mustacchi
159*0cbe4818SRobert Mustacchi#
160*0cbe4818SRobert Mustacchi# Now it's time to do our write testing. One caveat with the at24c08 is that
161*0cbe4818SRobert Mustacchi# writes that are larger than a 16-byte segment will wrap and start over at the
162*0cbe4818SRobert Mustacchi# beginning. This means that we'll need to be a bit more mindful of our offsets.
163*0cbe4818SRobert Mustacchi# We start an offset of 128 (0x80) to avoid our existing data.
164*0cbe4818SRobert Mustacchi#
165*0cbe4818SRobert Mustacchiwrite_io "i2c write" "All that is gold" 16 0x80 i2csim0/0/0x20 -w 17 0x80 0x41 \
166*0cbe4818SRobert Mustacchi    0x6c 0x6c 0x20 0x74 0x68 0x61 0x74 0x20 0x69 0x73 0x20 0x67 0x6f 0x6c 0x64
167*0cbe4818SRobert Mustacchiget_dd 128 16
168*0cbe4818SRobert Mustacchicompare_io_dd "All that is gold i2c write"
169*0cbe4818SRobert Mustacchiwrite_io "write-u8" " " 1 0x90 i2csim0/0/0x20 -m write-u8 -c 0x90 0x20
170*0cbe4818SRobert Mustacchiwrite_io "write-u16" "do" 2 0x91 i2csim0/0/0x20 -m write-u16 -c 0x91 0x6f64
171*0cbe4818SRobert Mustacchiwrite_io "write-u8" "e" 1 0x93 i2csim0/0/0x20 -m write-u8 -c 0x93 0x65
172*0cbe4818SRobert Mustacchiwrite_io "write-u32" "s no" 4 0x94 i2csim0/0/0x20 -m write-u32 -c 0x94 \
173*0cbe4818SRobert Mustacchi    0x6f6e2073
174*0cbe4818SRobert Mustacchiwrite_io "write-u64" "t glitte" 8 0x98 i2csim0/0/0x20 -m write-u64 -c 0x98 \
175*0cbe4818SRobert Mustacchi    0x657474696c672074
176*0cbe4818SRobert Mustacchicheck_io "write stanza 2 (block)" " does not glitte" -d i2csim0/0/0x20 \
177*0cbe4818SRobert Mustacchi    -m read-block-i2c -c 0x90 -r 0x10
178*0cbe4818SRobert Mustacchiget_dd 144 16
179*0cbe4818SRobert Mustacchicompare_io_dd "does not glitter i2c write"
180*0cbe4818SRobert Mustacchi
181*0cbe4818SRobert Mustacchi#
182*0cbe4818SRobert Mustacchi# Do a 16 byte block write over the existing portion and show that it
183*0cbe4818SRobert Mustacchi# overwrites. Do this manually as the general I/O check logic is going to have
184*0cbe4818SRobert Mustacchi# trouble with this. This takes the string 'r, Not all those' and offsets it 4
185*0cbe4818SRobert Mustacchi# bytes.
186*0cbe4818SRobert Mustacchi#
187*0cbe4818SRobert Mustacchiif ! $I2CADM io -d i2csim0/0/0x20 -m write-block-i2c -c 0x94 -w 16 \
188*0cbe4818SRobert Mustacchi    0x72 0x2c 0x20 0x4e 0x6f 0x74 0x20 0x61 0x6c 0x6c 0x20 0x74 0x68 0x6f 0x73 \
189*0cbe4818SRobert Mustacchi    0x65; then
190*0cbe4818SRobert Mustacchi	fatal "failed to perform i2c block write"
191*0cbe4818SRobert Mustacchifi
192*0cbe4818SRobert Mustacchicheck_io "write stanza 3 (block)" "hoser, Not all t" -d i2csim0/0/0x20 \
193*0cbe4818SRobert Mustacchi    -m read-block-i2c -c 0x90 -r 0x10
194*0cbe4818SRobert Mustacchiget_dd 144 16
195*0cbe4818SRobert Mustacchicompare_io_dd "i2c block overwrite"
196*0cbe4818SRobert Mustacchi
197*0cbe4818SRobert Mustacchiif (( i2c_exit == 0 )); then
198*0cbe4818SRobert Mustacchi	printf "All tests passed successfully!\n"
199*0cbe4818SRobert Mustacchifi
200*0cbe4818SRobert Mustacchi
201*0cbe4818SRobert Mustacchiexit $i2c_exit
202