wiki:ioc_device_api

Version 3 (modified by alain, 7 years ago) (diff)

--

IOC device API

A) General principles

This device provide access to various external mass storage peripherals such as a magnetic hard disk or a SD card, that can store blocks of data in a linear array of sectors indexed by a simple lba (logic block address). It supports two command types of I/O operations:

  • READ : move a given number of contiguous blocks from device to a memory buffer.
  • WRITE : move a given number of contiguous blocks from a memory buffer to device.

An I/O operation requires dynamic ressource allocation for IRQ routing to the dore running the client thread. It is always blocking for the client thread. The general scenario is detailed below:

  1. The client thread start the I/O operation, by calling the dev_ioc_read() or the dev_ioc_write() kernel functions that perform the following actions:
    • it get a free WTI mailbox from the client cluster WTI allocator.
    • it enables the WTI IRQ on the client cluster ICU and update the WTI interrupt vector.
    • it access the PIC to link the WTI mailbox to the IOC IRQ.
    • it builds the command descriptor stored in the thread descriptor.
    • the client thread registers in the IOC device waiting queue, block on the THREAD_BLOCKED_IO condition, and deschedule.
  2. The server thread attached to the IOC device descriptor handles all commands registered in the IOC device waiting queue, calling the IOC driver CMD function to start the I/O operation.
  3. The IOC driver ISR (Interrupt Service Routine) signaling the I/O operation completion reactivates the client thread, that releases the allocated resources:
    • it access the PIC to unlink the IOC IRQ.
    • it disables the WTI IRQ in the client cluster ICU and reset the interrupt vector entry.
    • it releases the WTI mailbox to the client cluster WTI allocator.

Most hardware implementation have a DMA capability, but some implementations, such as the RDK (Ram Disk) implementation does not use DMA, and don't use IRQ.

B) Access functions

1) void dev_ioc_init( xptr_t xp_dev )

This function makes two initialisations:

  • it initialises the IOC specific fields of the device descriptor.
  • it initialises the implementation specific IOC hardware device and associated data structures if required.

It can be executed in another cluster than the cluster containing the IOC device descriptor or the IOC hardware device itself. The <xp_dev> argument is an extended pointer on the IOC device descriptor.

2) void dev_ioc_read( char * buffer , uint32_t lba , uint32_t count)

This blocking function try to tranfer one or several contiguous blocks of data from the block device to a memory buffer. The calling thread is registered in the device pending request queue, and descheduled, waiting on transfer completion. It is re-activared by the IRQ signaling completion. It must be called in the client cluster. The <buffer> argument is... The <lba> argument is the first block index in block device. The <count> argument is the number of blocks to move.

3) void dev_ioc_write( char * buffer , uint32_t lba , uint32_t count)

This blocking function try to tranfer one or several contiguous blocks of data from a memory buffer to the block device. The calling thread is actually registered in the device pending request queue, and descheduled, waiting on transfer completion. It is re-activared by the IRQ signaling completion. It must be called in the client cluster. The <buffer> argument is... The <lba> argument is the first block index in block device. The <count> argument is the number of blocks to move.