Page MenuHomeFreeBSD

Give IG4_IIC a real bus lock
Needs ReviewPublic

Authored by phk on Sat, Nov 30, 2:28 PM.
Tags
Referenced Files
Unknown Object (File)
Sun, Dec 8, 7:20 PM
Unknown Object (File)
Tue, Dec 3, 11:57 PM
Subscribers

Details

Reviewers
emaste
mav
wulf
Summary

The iic_callback/sc->call_lock is an advisory lock which some I²C clients use and which some do not.

To work around this, the IG4_IIC driver checks if the sc->call_lock is already held, and only grabs it if not.

Problem is, if one thread holds the sc->call_lock, everybody else get free access, even in the middle of transactions.

Reduce sc->call_lock to its advisory function, and introduce a new water-tight sc->bus_lock to serialize access to the I²C bus for all clients.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

phk requested review of this revision.Sat, Nov 30, 2:28 PM
sys/dev/ichiic/ig4_iic.c
602

The iic_callback/sc->call_lock is not an advisory lock according to sx(9):

sx_xlocked() will return non-zero if the current thread holds the
exclusive lock; otherwise, it will return zero.

The whole point of this dances with sc->call_lock is to replace sx_xlock() with sx_try_xlock() when ig4iic_transfer() is called from ithread.
That is what iichid does if interrupts are available for HID devices. It calls iicbus_request_bus() passing IIC_DONTWAIT as flag parameter that triggers sx_try_xlock() in ig4 ig4iic_callback() method that allow skipping of sx_xlock() one line of code below.

Looks slightly hackish but should work.