This driver provides communication between NDIS (Driver provided by Microsoft that makes interface for calling network drivers and hides different behaviours of different drivers and devices.) and I2C driver (This driver implements communication over I2C bus and communicates with Serial.sys - driver for serial ports.). However, under this driver can be anything that provides the same interface as I2C driver.
I2CNET driver is standard Deserialized Connection-less Miniport Network driver. (These words are according to Microsoft Driver Development Kit Docummentation.)
After installation or when the system starts and the driver was previously installed, DriverEntry is called. DriverEntry calls NdisMInitializeWrapper which says to NDIS that here is a new Miniport driver and NDIS should prepare for it's registering. After this is NdisMRegisterMiniport called and it registers I2CNET driver to NDIS. With this call NDIS becomes entry points to other I2CNET functions that calls if some action from our driver is needed.
The installation has written to registry that there is one hardware network adapter, that we are simulating. For this adapter NDIS calls our MInitialize function. MInitialize allocates memory for data buffers data and for other things we must store with this adapter (MP_ADAPTER structure). It searches for lower layer driver and gets device pointer to it, initializes locks etc. While initializing also LLSThread (Lower Layer Service Thread) is started. This thread is responsible for waiting for data to receive, and sending that data to NDIS.
After initialization our device is ready to work. NDIS calls our Miniport functions for queriing the state and possibilities of the driver (MPQueryInformation) and device and sets some values (MPSetInformation).
First NDIS calls MPSend function and gives handle to packet to send. MPSend queries this packet and gets pointer to buffers where data are stored and copies them to own buffer. After this is made call to LLSendData function that calls other lower layer communication functions (SwitchToMasterMode, StartFirstTransfer, I2CWrite, StopTransfer). Behaviour of these functions is described in I2C driver documentation.
If something goes wrong while sending, ResetDevice is called and reset performed. Data left in buffers and are send together with next sending.
Responsible for receiving data is LLSThread thread that is started while initializing driver. This thread repeatedly calls WaitForTransfer function that block the thread if there are no data for receiving. The thread is woken up if there are some or someone wants to send data. If the reason is sending data, this thread does nothing and waits for end of sending, than calls WaitForTransfer again. If the reason of waking up is receiving, it calls I2CRead immediately and reads data to the buffer. After reading these data are transfered to NDIS and WaitForTransfer is called again.
| NetDriver.c, NetDriver.h | Main NET driver file. DriverEntry function |
| Miniport.c, Miniport.h | Miniport handlers. Functions called by NDIS. |
| LLComm.c, LLComm.h | Lower Layer Communication. Functions that gives instructions directly to lower layer. |
| LLSThread.c, LLSThread.h | Lower Layer Service Thread. Main routine for thread that is created while initializing device and that manages receiving data from network. |
| Functions.c, Functions.h | Common functions. |
| Debug.c, Debug.h | For debugging. Manage debug prints to kernel debugger. |
| Config.h | Configuration constants. |
| I2CNET.inf | INF file that installs I2CNET driver. |
| Sources, makefile | Files for compiling driver. |
| NetDriver.vcproj | MS Visual Studio Project File. |