sff(4) declared a get_i2c_bus method and an FDT front-end, but nothing that
actually reads a transceiver's EEPROM, so a consumer had to open-code the
i2c exchange. Add sff_read_eeprom(), which writes the byte offset and reads
the data back in one bus-held exchange (a repeat-start), so nothing else can
move the EEPROM's internal address pointer between the two halves. Holding
the bus across both messages also keeps an i2c mux upstream pointed at this
device throughout: iicbus(4) switches the mux as part of granting the bus,
and would switch it away for another consumer if we let go in between.
dev_addr is the slave address in the form iic_msg(9) uses -- the 7-bit
address shifted left by one -- which for an SFF-8472 module is 0xa0 for the
base page and 0xa2 for the diagnostics page. That is also the form
SIOCGI2C's struct ifi2creq carries, so a NIC driver passes on what it was
given.
A bus request needs an owner sitting on the bus being requested. A front-end
that is itself an i2c slave passes itself; one that only holds a reference to
the bus has to borrow a device on it, so add sff_i2c_requester() for that and
use it from the FDT front-end.
Give both kobj methods a DEFAULT returning ENXIO. kobj(9) turns a method a
class does not implement into a call to kobj_error_method(), and a front-end
may well be able to read the EEPROM but have no way to reach the module's
control lines, or the reverse.
Finally, make the module build match: sff.c was added to sys/conf/files but
not to the module's SRCS, so sff.ko carried neither sff_read_eeprom() nor its
own module record -- which means a MODULE_DEPEND on sff could never be
satisfied and any consumer would fail to load. EXPORT_SYMS is needed for the
same reason: sff(4) exists to be consumed, and kmod.mk localises every symbol
by default, including the kobj method descriptors.
Depends on D60065