Character device drivers, and other character-oriented support that can perform character-at-a-time I/O, can be implemented by using a common set of services and data buffers to handle characters in the form of character lists. A character list is a list or queue of characters. Some routines put characters in a list, and others remove the characters from the list.
Character lists, known as clists, contain a clist header and a chain of one or more data buffers known as character blocks. Putting characters on a queue allocates space (character blocks) from the common pool and links the character block into the data structure defining the character queue. Obtaining characters from a queue returns the corresponding space back to the pool.
A character list can be used to communicate between a character device driver top and bottom half. The clist header and the character blocks that are used by these routines must be pinned in memory, since they are accessed in the interrupt environment.
Users of the character list services must register (typically in the device driver ddopen routine) the number of character blocks to be used at any one time. This allows the kernel to manage the number of pinned character blocks in the character block pool. Similarly, when usage terminates (for example, when the device driver is closed), the using routine should remove its registration of character blocks. The pincf kernel service provides registration for character block usage.
The kernel provides four services for obtaining characters or character blocks from a character list: the getc, getcb, getcbp, and getcx kernel services. There are also four services that add characters or character blocks to character lists: the putc, putcb, putcbp, and putcx kernel services. The getcf kernel services allocates a free character block while the putcf kernel service returns a character block to the free list. Additionally, the putcfl kernel service returns a list of character buffers to the free list. The waitcfree kernel service determines if any character blocks are on the free list, and waits for one if none are available.
For each character list you use, you must allocate a clist header structure. This clist structure is defined in the /usr/include/sys/cblock.h file.
You do not need to be concerned with maintaining the fields in the clist header, as the character list services do this for you. However, you should initialize the c_cc count field to 0, and both character block pointers (c_cf and c_cl) to null before using the clist header for the first time. The clist structure defines these fields.
Each buffer in the character list is a cblock structure, which is also defined in the /usr/include/sys/cblock.h file.
A character block data area does not need to be completely filled with characters. The c_first and c_last fields are zero-based offsets within the c_data array, which actually contains the data.
Only a limited amount of memory is available for character buffers. All character drivers share this pool of buffers. Therefore, you must limit the number of characters in your character list to a few hundred. When the device is closed, the device driver should make certain all of its character lists are flushed so the buffers are returned to the list of free buffers.
The getc kernel service, getcb kernel service, getcbp kernel service, getcf kernel service, getcx kernel service, pincf kernel service, putc kernel service, putcb kernel service, putcbp kernel service, putcf kernel service, putcfl kernel service, putcx kernel service, waitcfree kernel service.
Device Driver Kernel Extension Overview in AIX® Version 6.1 Kernel Extensions and Device Support Programming Concepts.
Programming in the Kernel Environment Overview in AIX® Version 6.1 Kernel Extensions and Device Support Programming Concepts.