wiki:ioc_device_api

Version 6 (modified by alain, 5 years ago) (diff)

--

IOC device API

A) General principles

This device allows the kernel to access 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).

The block size is supposed to be 512 bytes.

It supports a first user API, used by the user-level system calls, implementing two command types : the READ and WRITE operations move a given number of contiguous blocks between the block device and a kernel memory buffer.

The I/O operation is blocking for the calling thread, but it is not done by the client thread itself. The general scenario is detailed below:

  1. When a client thread request an I/O operation, the request is registered in the ioc_command_t structure embedded in the client thread descriptor, and the client thread registers itself in the waiting queue rooted in the IOC chdev. Then the client thread blocks on the THREAD_BLOCKED_IO condition, and deschedules.
  2. The DEV server thread attached to the IOC device descriptor handles all commands registered in the IOC device waiting queue. For each pending request, it calls the IOC driver CMD (command) function to ask the hardware device to do the transfer. Then, the server thread blocks on the THREAD_BLOCKED_ISR condition, and deschedules.
  3. When the I/O operation completed, the IOC driver ISR (Interrupt Service Routine) signaling completion reactivates the server thread.
  4. The server thread reactivates the client thread, and handle the next request in the IOC waiting queue, or reschedules if the queue is empty.

Note : According to the scheduling policy, the DEV thread has an higher priority than any user thread, but it is not selected when the associated waiting queue is empty.

  • 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.
  • 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 IOC device implementation have a DMA capability, but some implementations, such as the RDK (Ram Disk) implementation does not use DMA, and don't use an IRQ, as the data transfers are directly executed by the driver CMD function.

To access the various drivers, this FBF device defines a lower-level driver API, that must be implemented by all drivers.

All IOC access functions are defined in the dev_ioc.c et dev_ioc.h files.

B) Initialisation

The void dev_ioc_init() function makes two initializations :

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

It must be called by a local thread.

C) User API

B.1) void dev_ioc_read()

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. The <buffer> argument is a The <lba> argument is the first block index in block device. The <count> argument is the number of blocks to move.

2) void dev_ioc_write()

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. 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.

D) Driver API

The IOC device defines defines four command types to access the IOC driver(s) :

  • IOC_WRITE : move blocks from a kernel buffer to the IOC device, with a descheduling policy.
  • IOC_READ : move blocks from the IOC device to a kernel buffer, with a descheduling policy.
  • IOC_SYNC_WRITE :
  • IOC_SYNC_READ :

These four commands use the three following arguments, that must be registered, with the command type, in the ioc_command_t structure embedded in the client thread descriptor :

  • npixels : number of pixels to be moved.
  • buffer : pointer on buffer in (can be in user space or in kernel space).
  • offset : offset in FBF (number of pixels).