All of these in/out instructions work.
And, Z64k and Vice correctly emulate them.
Note: outi first decreases B (so you must preincrement B)
And ini decreases B after the in.
This works, B-- gives D020 and output is sent to io on D020
ld bc,$D120
ld hl,mydata
outi
ret
mydata: db 3
Using 'INIR' (so, with repeat), you can see how that is a issue.
In theory one might get data from CIA2 and CIA1 (DDxx and DCxx) but that would require B to be $DC at start (thus keeps going until B=0)
One might use OTIR for a funny trick: on the c128, under z80, the IO memory of 0000-$1000 is mapped to RAM at $D000-$E000
Thus, a single OTIR/OTDR can, for instance, write to 04xx, 03xx, 02xx, 01xx, 00xx and this fills memory at D4xx etc.
If you had a VIC screen there, this would have an effect (a dedicated effect perhaps). I haven't thought of a hypothetical INIR though.
Tests in the VICE (since 3.8) test-repo check the behavior of in, out, ini, outi, inir, outi, ind, outd, indr, outdr compared to real HW.
I love to point out that Commodore CPM for the c128 contains the INI instruction to read from fast devices (1571, 1581, CMDhd, 1541UlitmateII+,...) so that tells you all of his is 'by design'. It is possibly unexpected that OUTI isn't used.
Sometimes people say the CPM BIOS for c128 is 'not using z80' but that is also a misunderstanding. You will find several z80 instructions (djnz, ini, out (c), in (c), relative jumps, ...) in the code. The c128 relies on z80 using BC on the IN and OUT instruction.
You are, perhaps, referring to (https://dr.ea.ms/c128hardwarebug.html) which explains that OUTI does not work. Note: in this forum people have mentioned (quite a while ago) that outi begins by a decrement of B, and if you take that into account it works fine.
While on this subject: you can also use the "IN $xx" instruction to read a 16bit port. You do this like so:
ld a,$d0
in $20
Now A = value of IO $D020. You didn't need BC (this can save you speed on the poor slow z80).
For 'out $xx' it is not so simple, since the value you're outputting is linked to the port. You could do:
ld a,$d0
out $20
And you end up setting black (the use of this would seem prohibitively situational).