forwarder(7) forwarder(7)NAME forwarder - forwarder device driver DESCRIPTION The forwarder is a specalized streams device driver written so as to be able to run on a wide range of front end proces- sors (FEP). The FEP generally has a CPU, a memory, I/O circuitry dev- ices, and a means of communicating with the hostTMMacintosh(Reg.) II via the NuBus . (Modules are normallydownloaded onto the FEP, allowing for offloading of the host processor.) The forwarder software is actually duplicated; identical copies are kept in the kernel on the host and in the minioperating system found on the FEP. The two copies work together (as a matched pair) to pass messages and data across the NuBus. From the kernel, the forwarder looks like a stream driver; from the actual stream driver (or modules), it looks like a stream head. The forwarder software knows that there is a processing or space separation (the NuBus) between the operating system and the remote modules and streams driver. It is the only module that needs to know about this division of powers; it hides this fact from the other layers. Because the NuBus exists, however, the implementor must be aware of some stream restrictions. Any operation that uses the forwarder must pass through the forwarder's queue pro- cessing. For example, q->q_next->q_next would be incorrect because it is trying to access the queue beyond the forwarder, and that is impossible. Careful thought and an understanding of the forwarder's task should help prevent such errors. When it is next to a forwarder, the stream head behaves dif- ferently when it receives an I_PUSH ioctl. It first checks the module ID number downstream. If the ID number is > FOR- WARDERMIN but < FORWARDERMAX, it sends an I_PUSH via an M_IOCTL message. The forwarder passes the request to its twin on the board, which tries to open the indicated module. The forwarder then responds with an ``acknowledge'' if the open was completed. If the open was not completed success- fully, a ``negative acknowledge'' is returned. If the module is not found on the board, a message is returned to that effect and the stream head continues the push as if the forwarder were not there. The process is the same for pop- April, 1990 1
forwarder(7) forwarder(7)ping, except that there is no ``not found'' case. Control of the forwarder is done via stream I_STR ioctls. The following stream I_STR ioctls, defined in <fwd.h>, are available. I_FWD_LOOKUP Returns a table of the installed appli- cation strings and places it in the lo- cation pointed to by arg->ic_dp. An I_FWD_LOOKUP call returns a table into arg->ic_dp, where the line entries are of type struct fwd_entry, found in <fwd.h>. The length of the table is found in arg->ic_len but is always less than the stream maximum of 1024 Kbytes. I_FWD_RESET Resets the board into a state ready for downloading. This ioctl must be used when the system first comes up, or when an FEP panic occurs. An I_FWD_RESET call also disables any application currently talking to the board if EIO errors are detected for that applica- tion. Note that with many FEPs, the software cannot issue a reset to the board. In this case, if the forwarder has lost communication with its twin, I_FWD_RESET will have no effect, and you reboot the system to reset the forward- er. I_FWD_DOWNLD Causes the binary data contained in fwd_record.data to be downloaded to the FEP starting at FEP memory location fwd_record.begin. The structure fwd_record is defined in <fwd.h>. I_FWD_UPLD Causes the binary data to be uploaded from the FEP memory into the data field fwd_record.data. The value in fwd_record.ld_length is the number of bytes to be uploaded from the FEP. The structure fwd_record is defined in <fwd.h> . I_FWD_START Instructs the loader to transfer execu- tion to the address contained in fwd_entry.start. The name field is placed in the forwarder's application table. 2 April, 1990
forwarder(7) forwarder(7)EXAMPLES int dev_fd; struct strioctl i_str; if((dev_fd = open(dev_file, O_NDELAY)) < 0) HANDLE_ERROR(); i_str.ic_cmd = I_FWD_DOWNLD; i_str.ic_timout = 4; i_str.ic_len = fwd_record.begin; i_str.ic_dp = fwd_record; if(ioctl(dev_fd, I_STR, &i_str) < 0) HANDLE_ERROR(); FILES /dev/fwdicp11 /etc/startup.d/fwdicp.d/at_load /etc/startup.d/fwdicp.d/tt_load SEE ALSO fwd_lkup(1M), fwdload(1M). AT&T UNIX System V STREAMS Programming Guide. April, 1990 3