In computer science, channel I/O is a high-performance input/output (I/O) architecture that is implemented in various forms on a number of computer architectures, especially on mainframe computers. In the past channels were generally implemented with custom processors, variously named channel, peripheral processor, I/O processor, I/O controller, or DMA controller.
Many I/O tasks can be complex and require logic to be applied to the data to convert formats and other similar duties. In these situations, the simplest solution is to ask the CPU to handle the logic, but because I/O devices are relatively slow, a CPU could waste time (in computer perspective) waiting for the data from the device. This situation is called 'I/O bound'.
Channel architecture avoids this problem by using a separate, independent, low-cost processor. Channel processors are simple, but self-contained, with minimal logic and sufficient on-board scratchpad memory (working storage) to handle I/O tasks. They are typically not powerful or flexible enough to be used as a computer on their own and can be construed as a form of coprocessor.
A CPU sends relatively small channel programs to the controller via the channel to handle I/O tasks, which the channel and controller can, in many cases, complete without further intervention from the CPU (exception: those channel programs which utilize 'program controlled interrupts', PCIs, to facilitate program loading, demand paging and other essential system tasks).
When I/O transfer is complete or an error is detected, the controller communicates with the CPU through the channel using an interrupt. Since the channel has direct access to the main memory, it is also often referred to as DMA controller (where DMA stands for direct memory access), although that term is looser in definition and is often applied to non-programmable devices as well.
In the most recent implementations, the channel program is initiated and the channel processor performs all required processing until either a "success" or a "failure" result occurs. This eliminates much of the CPU—Channel interaction and greatly improves overall system performance. If a "success" is posted to the CPU, the result is obvious: the channel program had run to completion and no errors or exceptions were encountered. If a "failure" is posted to the CPU, the result is less obvious—surely an error or exception of some kind was encountered, and the channel program was incomplete, but enough diagnostic information is provided from the channel processor to the CPU so that the channel program may be restarted with a minimum of overhead. In earlier implementations, any error, no matter how small, required CPU intervention, and the overhead was, consequently, much higher. A program-controlled interruption (PCI) is still supported for certain "legacy" operations, but the trend is to move away from such PCIs, except where unavoidable.
The first use of channel I/O was with the IBM 709 vacuum tube mainframe, whose Model 766 Data Synchronizer was the first channel controller, in 1957. Its transistorized successor, the IBM 7090, had two or more channels (the 7607) and a channel multiplexor (the 7606) which could control up to eight channels.
Later, for larger IBM System/360 computers, and even for early System/370 models, the selector channels and the multiplexor channels still were bulky and expensive separate processors, such as the IBM 2860 Selector channel (one to three selector channels in a single box), the IBM 2870 Byte multiplexor channel (one multiplexer channel, and, optionally, one selector subchannel in a single box) and the IBM 2880 Block multiplexor channel (one or two block multiplexor channels in a single box).
Amdahl Corporation's hardware implementation of System/370 compatible channels was quite different. A single internal unit, called the "C-Unit", supported up to sixteen channels using the very same hardware for all supported channels. Two internal "C-Units" were possible, supporting up to 32 total channels. Each "C-Unit" independently performed a process generally called a "shifting channel state processor" (a type of "barrel processor"), which implemented a specialized type of finite state machine (FSM). Each CPU cycle, every 32 nanoseconds in the 470/V6 and /V5 and every 26 nanoseconds in the 470/V7 and /V8, the "C-unit" read the complete status of next channel in priority sequence and its I/O Channel in-tags. The necessary actions defined by that channel's last state and its in-tags were performed: data was read from or written to main storage, the operating system program was interrupted if such interruption was specified by the channel program's Program Control Interrupt flag, and the "C-Unit" finally stored that channel's next state and set its I/O Channel out-tags, and then went on to the next lower priority channel. Preemption was possible, in some instances. Sufficient FIFO storage was provided within the "C-Unit" for all channels which were emulated by this FSM. Channels could be easily reconfigured to the customer's choice of IBM 2860 (selector) emulation, IBM 2870 (byte multiplexor) emulation or IBM 2880 (block multiplexor) emulation without any significant restrictions by using maintenance console commands. "Two-byte interface" was also supported as was "Data-In/Data-Out" and other high-performance IBM channel options. Built-in channel-to-channel adapters were also offered, called CCAs in Amdahl-speak, but called CTCs in IBM-speak. A real game-changer, and this forced IBM to redesign its mainframes to provide similar channel capability and flexibility. IBM's initial response was to include stripped-down Model 158s, operating in "Channel Mode", only, as the Model 303x channel units. In the Amdahl "C-unit" any channel could be any type, 2860, 2870 or 2880, without reserving channels 0 and 4 for 2870s, as on some IBM models.
For smaller IBM computers, System/360 Models 50 and below, and System/370 Models 158 and below, channels were implemented in the CPU's microcode, and the CPU itself operated in one of two modes, either "CPU Mode" or "Channel Mode", with the channel mode 'blocking' the CPU mode (IBM 2860, 2870 and 2880, and Amdahl channels were 'non-blocking').
Much later, the channels were implemented as an on-board processor residing in the same box as the CPU, generally referred to as a "channel processor", and which was usually a RISC processor, but which could be a System/390 microprocessor with special microcode as in IBM's CMOS mainframes.
One of the earliest non-IBM channel systems was hosted in the CDC 6600 supercomputer in 1965. The CDC utilized 10 logically independent computers called peripheral processors, or PPs for this role. PPs were powerful, a modern version of CDC's first 'personal computer', the CDC 160A. The operating system resided and executed in the primary processor, PP0. Since then, channel controllers have been a standard part of most mainframe designs and a primary advantage mainframes have over smaller, faster, personal computers and network computing.
Channel controllers have also been made as small as single-chip designs with multiple channels on them, used in the NeXT computers for instance. However with the rapid speed increases in computers today, combined with operating systems that don't 'block' when waiting for data, channel controllers have become correspondingly less effective and are not commonly found on small machines.
Channel controllers are making a comeback in the form of bus mastering peripheral devices, such as PCI direct memory access (DMA) devices. The rationale for these devices is the same as for the original channel controllers, namely off-loading transfer, interrupts, and context switching from the main CPU.
The reference implementation of channel I/O is that of the IBM System/360 family of mainframes and its successors, but similar implementations have been adopted by other mainframe vendors, such as Control Data, Bull (General Electric/Honeywell) and Unisys.
Computer systems that use channel I/O have special hardware components that handle all input/output operations in their entirety independently of the systems' CPU(s). The CPU of a system that uses channel I/O typically has only one machine instruction in its repertoire for input and output; this instruction is used to pass input/output commands to the specialized I/O hardware in the form of channel programs. I/O thereafter proceeds without intervention from the CPU until an event requiring notification of the operating system occurs, at which point the I/O hardware signals an interrupt to the CPU.
A channel is an independent hardware component that coordinates all I/O to a set of controllers or devices. It is not merely a medium of communication, despite the name; it is a programmable device that handles all details of I/O after being given a list of I/O operations to carry out (the channel program).
Each channel may support one or more controllers and/or devices, but each channel program may only be directed at one of those connected devices. A channel program contain lists of commands to the channel itself and to the controller and device to which it is directed. Once the operating system has prepared a complete list of channel commands, it executes a single I/O machine instruction to initiate the channel program; the channel thereafter assumes control of the I/O operations until they are completed.
It is possible to develop very complex channel programs, including testing of data and conditional branching within that channel program. This flexibility frees the CPU from the overhead of starting, monitoring, and managing individual I/O operations. The specialized channel hardware, in turn, is dedicated to I/O and can carry it out more efficiently than the CPU (and entirely in parallel with the CPU). Channel I/O is not unlike the Direct Memory Access (DMA) of microcomputers, only more complex and advanced.
On large mainframe computer systems, CPUs are only one of several powerful hardware components that work in parallel. Special input/output controllers (the exact names of which vary from one manufacturer to another) handle I/O exclusively, and these in turn are connected to hardware channels that also are dedicated to input and output. There may be several CPUs and several I/O processors. The overall architecture optimizes input/output performance without degrading pure CPU performance. Since most real-world applications of mainframe systems are heavily I/O-intensive business applications, this architecture helps provide the very high levels of throughput that distinguish mainframes from other types of computer.
In IBM ESA/390 terminology, a channel is a parallel data connection inside the tree-like or hierarchically organized I/O subsystem. In System/390 I/O cages, channels either directly connect to devices which are installed inside the cage (communication adapter such as ESCON, FICON, Open Systems Adapter) or they run outside of the cage, below the raised floor as cables of the thickness of a thumb and directly connect to channel interfaces on bigger devices like tape subsystems, direct access storage devices (DASDs), terminal concentrators and other ESA/390 systems.
A channel program is a sequence of channel command words (CCWs) which are executed by the I/O channel subsystem in the IBM System/360 and subsequent architectures. A channel program consists of one or more channel command words. The operating system signals the I/O channel subsystem to begin executing the channel program with a SSCH (start sub-channel) instruction. The central processor is then free to proceed with non-I/O instructions until interrupted. When the channel operations are complete, the channel interrupts the central processor with an I/O interruption. In earlier models of the IBM mainframe line, the channel unit was an identifiable component, one for each channel. In modern mainframes, the channels are implemented using an independent RISC processor, the channel processor, one for all channels. IBM System/370 Extended Architecture and its successors replaced the earlier SIO (start I/O) and SIOF (start I/O fast release) assembler instructions (System/360 and early System/370) with the SSCH (start sub-channel) instruction (late System/370 and successors).
Channel I/O provides considerable economies in input/output. For example, on IBM's Linux/390, the formatting of an entire track of a DASD requires only one channel program (and thus only one I/O instruction), but multiple channel command words (one per block). The program is executed by the dedicated I/O processor, while the application processor (the CPU) is free for other work.
Channel command words
A channel command word (CCW) is an instruction to a specialized I/O channel processor which is, in fact, a finite state machine. It is used to initiate an I/O operation, such as "read", "write" or "sense", on a channel-attached device. On system architectures which implement channel I/O, typically all devices are connected by channels, and so all I/O requires the use of CCWs.
CCWs are organized into channel programs by the operating system, an I/O subroutine, a utility program, or by standalone software (such as test and diagnostic programs). A limited "branching" capability, hence a dynamically programmable capability, is available within such channel programs, by use of the "status modifier" channel flag and the "transfer-in-channel" CCW.
IBM CCWs are chained to form the channel program. Bits in the CCW indicates that the following location in storage contains a CCW that is part of the same channel program. The channel program normally executes sequential CCWs until an exception occurs, a Transfer-in-Channel (TIC) CCW is executed, or a CCW is executed without chaining indicated. Command chaining tells the channel that the next CCW contains a new command. Data chaining indicates that the next CCW contains the address of additional data for the same command, allowing, for example, portions of one record to be written from or read to multiple data areas in storage (gather-writing and scatter-reading).
Self-modifying channel programs
Channel program example
The following example reads a disk record identified by a recorded key. The track containing the record and the desired value of the key is known. The device control unit will search the track to find the requested record. In this example <> indicate that the channel program contains the storage address of the specified field.
SEEK <cylinder/head number> SEARCH KEY EQUAL <key value> TIC *-8 Back to search if not equal READ DATA <buffer>
The TIC (transfer in channel) will cause the channel program to branch to the SEARCH command until a record with a matching key (or the end of the track) is encountered. When a record with a matching key is found the DASD controller will include Status Modifier in the channel status, causing the channel to skip the TIC CCW; thus the channel program will not branch and the channel will execute the READ command.
The above example is correct for unblocked records (one record per block). For blocked records (more than one record per block), the recorded key must be the same as the highest key within that block (and the records must be in recorded key sequence), and the following channel program would be utilized:
SEEK <cylinder/head number> SEARCH KEY HIGH OR EQUAL <key value> TIC *-8 Back to search if not high or equal READ DATA <buffer>
If the dataset is allocated in tracks, and the end of the track is reached without the requested record being found the channel program terminates and returns a "no record found" status indication. Similarly, if the dataset is allocated in cylinders, and the end of the cylinder is reached without the requested record being found the channel program terminates and returns a "no record found" status indication. In some cases the system software has the option of updating the track or cylinder number and redriving the I/O operation without interrupting the application program.
Channel programs in virtual storage systems
On most systems channels operate using real (or physical) addresses, while the channel programs are built using virtual addresses. The operating system is responsible for translating these channel programs before executing them, and for this particular purpose the Input/Output Supervisor (IOS) has a special "fast fix" function which was designed into the OS Supervisor just for those "fixes" which are of relatively short duration (i.e., significantly shorter than "wall-clock time"). Pages containing data to be used by the I/O operation are locked into real memory, or page fixed. The channel program is copied and all virtual addresses are replaced by real addresses before the I/O operation is started. After the operation completes, the pages are unfixed.
As page fixing and unfixing is a CPU-expensive process long-term page fixing is sometimes used to reduce the CPU cost. Here the virtual memory is page-fixed for the life of the application, rather than fixing and freeing around each I/O operation. An example of a program that can use long-term page fixing is DB2.
An alternative to long-term page fixing is moving the entire application, including all its data buffers, to a preferred area of main storage. This is accomplished by a special SYSEVENT in MVS/370 through z/OS operating systems, wherein the application is, first, swapped-out from wherever it may be, presumably from a non-preferred area, to swap and page external storage, and is, second, swapped-in to a preferred area (SYSEVENT TRANSWAP). Thereafter, the application may be marked non-swappable by another special SYSEVENT (SYSEVENT DONTSWAP). Whenever such an application terminates, whether normally or abnormally, the operating system implicitly issues yet another special SYSEVENT on the application's behalf, if it has not already done so (SYSEVENT OKSWAP).
Booting with channel I/O
Even bootstrapping of the system, or Initial Program Load (IPL) in IBM nomenclature, is carried out by channels, although the process is partially simulated by the CPU (through an "implied" SIO [ Start I/O ] instruction, an "implied" Channel Address Word [ CAW ] at location 0 and an "implied" channel program [ CCW ] , also at location 0). Command chaining is assumed, so the "implied" CCW at location 0 falls through to the continuation of the channel program at locations 8 and 16, and possibly elsewhere should one of those CCWs be a transfer-in-channel (TIC).
To load a system, a 24-byte data area is loaded into main storage from the first block of the selected IPL device at location 0 and the second and third 8 byte data areas, which are Read IPL-type CCWs, are initiated from the "implied" CCW, and this channel program continuation causes the first portion of the system loading software to be loaded elsewhere in main storage. The first 8 byte date area contains a PSW which causes the CPU to branch to the bootstrap loader (called "IPL Text") at the main storage address where it was just loaded. The IPL Text is then executed, and eventually the operating system's nucleus is loaded and is branched to, after which normal OS operations commences.
This IPL concept is device independent. It is capable of IPL-ing from a card deck, from a magnetic tape, or from a hard disk. For this purpose, the normal X'02' command, which is simulated by the CPU, is taken to be a standard sequential read command on card and tape media (which are inherently sequential access in nature), but a special Read-IPL command on hard disks (which are inherently random access in nature; hard disks use a related, but different, read-type command, X'06', and others, for sequential, non-IPL reads).
Hard disk controllers (IBM 2844, 3830, among others, and compatibles) accept the X'02' command, but first cause a seek to cylinder X'0000', and head X'0000', and a search for record X'01', before executing the sequential read command as if it was a X'06'. Without this special hard disk controller behavior, device independent IPL would not be possible. On a hard drive, the IPL Text is contained on cylinder X'0000', track X'0000', and block X'01' (24 bytes), and cylinder X'0000', track X'0000', and block X'02' (fairly large). The volume label is always contained on cylinder X'0000', track X'0000', and block X'03' (80 bytes). The volume label always points to the VTOC, with a pointer of the form HHHH (that is, the VTOC must reside within the first 65,536 tracks). The VTOC's Format 4 DSCB defines the extent (size) of the VTOC, so the volume label only needs a pointer to the first track in the VTOC's extent, and as the Format 4 DSCB, which describes the VTOC, is always the very first DSCB in the VTOC, HHHH also points to the Format 4 DSCB.
If an attempt is made to IPL from a device which was not initialized with IPL Text, the system simply enters a wait state. The DASD (direct access storage device) initialization program, IBCDASDI, or the DASD initialization application, ICKDSF, places a wait state PSW and a dummy CCW string in the 24 bytes, should the device be designated for data only, not for IPL, after which these programs format the VTOC and perform other hard drive initialization functions.
- "IBM Archives: 709 Data Processing System". 03.ibm.com. Retrieved 2014-01-22.
- "IBM Archives: 7090 Data Processing System (continued)". 03.ibm.com. 1958-12-30. Retrieved 2014-01-22.
- IBM System/370 Extended Architecture Principles of Operation, SA22-7085-0
- IBM Corporation (1968). Student Text: Introduction to IBM System/360 Architecture (PDF). IBM Corporation. p. 22.
- Attanasio, C.R.; Markstein, P.W.; Phillips, R.J. (1976). "Penetrating an Operating System: a Study of VM/370 Integrity". IBM Systems Journal 15 (1): 102–116. doi:10.1147/sj.151.0102.
- IBM Corporation (1969). IBM System/360 Component Descriptions: 2314 Direct Access Storage Facility and 2844 Auxiliary Storage Control (PDF). IBM Corporation. p. 50.2.
- IBM Corporation (1978). OS/VS2 MVS Overview (PDF). pp. 8–12.
- See System/370 Principles of Operation, GA22–7000–4, pp 54—55, Initial Program Loading; System/370 Extended Architecture is quite similar, although XA utilizes an "implied" Start Subchannel (SSCH) instead of an "implied" Start I/O.