This hardware is claimed to be software compatible with the 4361 Integrated Communication Adapter. It executes HDLC's link level protocol and deals with the 370 software at the level of I-fields of the underlying HDLC frames.
We propose an object, the adaptor, that wields the sole keys to the 9370 HDLC interface. It implements the CK key as used by the X.25 multiplexor that works with our Series One X.25 support.
The hardware architecture (appearance of hardware to the software)
A phone conversation with IBM developers revealed a concept about the hardware that we did not get from the manual (SA24-4041). When the Link Control Program executes a Control-Read or a Control-Write CCW a list of buffer numbers is transmitted to the subsystem. The CCW is described as conveying responsibility to the subsystem of that set of buffers. IBM recommends a channel program with a TIC which causes such CCWs to be executed repeatedly and asynchronously with the 370 program. The confusion was over the propriety of re-conveying the same buffer numbers repeatedly on successive executions of the CCW.
The subsystem is aware of the SIO for the program with the CCWs. Subsequent executions of the CCW for one SIO require that any initial portion of the buffer number list that was already examined on earlier CCW executions for the same SIO not be modified. There is a count at the head of the list and a 370 program can safely add to the list and then modify the count asynchronously with the channel program.
This scheme allows the subsystem to meet time requirements on the HDLC link that may be more stringent than those that the program that builds the channel programs could meet.
It seems that the two channel addresses are interchangeable although they execute different kinds of channel programs. The “Sense-Status Data” is divided into three fields. The manual is hazy about their lengths. Experiments indicate that the “Error Information” is always 6 bytes long and the counters are always 4 bytes long. That is how it is coded anyway. Also the “link Status” field in “Error Information” seems to be 0 at least when the “Error Type” is 0.
In addition to the three buffer states defined by the hardware (free, filled & transmit) we introduce two states to cover the buffers that are “controlled by the software”. We will call them full and empty. (“Full” is what filled buffers become when they are reported to the software by the link control program's Sense Status CCW.)
These are the transitions between states and their causes:
When a frame arrives from the DCE it is placed in one or more free buffers that are then placed in the filled state (by the subsystem).
When the link control channel program executes a Sense Status CCW, the filled buffers become full buffers, and are then known to the 370 program (and not to the hardware).
When the 370 program has removed the data from the full buffers they become empty.
When empty buffers are filled with new data destined for the DCE, their buffer number is then added to the buffer list in the data area addressed by the Control Write CCW, at which point the buffer enters (asynchronously) the transmit state.
When the software includes a buffer number in the data area addressed by the Control Read CCW, the buffer moves from the empty state to the free state.
When the hardware return buffers in the free state via the execution of the Sense Status CCW, the buffers enter the empty state.
Either act of this domain may be blocked so as to require storage of the return key. Upon such events this domain leaves a mark in shared memory asking the LCP domain to fork it when the block is removed.
LCP domain: If n transmit buffers were accepted during previous execution of LCP then delete n bytes from the buffer number list in the data area of the control-write CCW. By this I mean an MVC instruction whose destination address is byte one of the data area and whose source address is n larger -- then subtract n from byte 0 with a CS. There is room in the data area for the maximum possible number of buffers and the above MVC assumes that maximum.
The logic of this stuff depends on the fact that the LCP does not run while the LCP domain is running.
The LCP domain would add or remove members from this set of empty buffers as it transfers buffers between the free and empty states.
Add returned free buffers to the empty word. If new free buffers are requested by the subsystem supply them and update the empty word.
If there are new filled buffers reported by the subsystem and fork-on-FB is set then fork the CK domain. If there are new empty buffers (Had been free in the subsystem) and fork-on-ROOM is set then fork the CK domain.
Reinitialize the data area of the control-write CCW to describe any buffers that were not noticed before the LCP ended. This can be determined by the “accepted write buffers” field in the yield of the control-sense CCW of the LCP.
A set of buffers must be allocated. They are presumably all the same size. We must select their number and size. Here are some considerations:
The advantage of small buffers is that there is less “wasted storage” since one buffer cannot hold more than one I-frame and one I-frame can span several buffers.
The advantage of more and bigger buffers is that the subsystem will be less likely to run out of free buffers, or the X.25 domain can process its work in larger batches.
I presume that the subsystem does a Receive Not Ready when it has no free buffers. By some such scheme input overruns can be avoided.
Sizes (transmissions, frames, buffers, packets, etc.)
The hardware must be able to finish delivering a frame on a fixed schedule once it has begun. If a frame were to span buffers and we exhausted buffers in mid-frame there would be a danger that the 370 CPU would not deliver the remainder of the frame soon enough.
It may be that we must wait for a frame's worth of data to arrive from our client before we place any of the buffers in the transmit state. This means that a write order on the CK key must be be even before we add buffer numbers to the data area of the control-write CCW.