DRQIO NOTES. The contents of this file are notes taken on the module DRQIO (RSX-11M V3.0) by Ralph Stamerjohn. This module is used to processed the QIO and QIOW executive request. The notes assume the following features have been selected/not selected/optional: A$$CHK Address checking selected A$$CPS ACP support selected D$$IAG On-line diagnostics not selected L$$DRV Loadable drivers optional M$$MGE Memory management selected M$$MUP Multi-user protection optional M$$NET Network support selected 1.0 CHECK QIO LEGAL AT THIS TIME (265 - 292) This section of code checks that a QIO is legal at for the current task and device state. The following checks are made. If all checks prove false, control is continues with the next section. 1. If the task is checkpointable (bt[T2.CHK]wd[T.ST2]=0), the current I/O count is nonzero (by[T.IOC]#0), and the I/O function not a kill request (by[Q.IOFN+1]#0), the task PC is backed to reissue the QIO and the task is placed in WAIT FOR SIGNIFICANT EVENT state. 2. If the lun is illegal (by[Q.IOLN]>H.NLUN), a directive error of -96. is returned. 3. If the lun is unassigned ([first lun word]=0), a directive error of -5. is returned. 4. If the lun is interlocked for use (bt[0]wd[second lun word]=1), the task PC is backed up to reissue the QIO and the task is placed in WAIT FOR SIGNIFICANT EVENT state. NOTE This feature is used by certain ACP functions to block further I/O request until the function is complete. DRQIO NOTES - SEP, 77 PAGE 2 5. If the driver is not resident (wd[D.DSP]=0), a directive error of -6. is returned. 2.0 INITIALIZE I/O ENVIRONMENT (293 - 341) This section gets various parameters from the QIO DPB, checks for legal ranges, and initaiize various environmental elements for the I/O request. The following steps are performed. 1. If an event flag was specified, clear it. A directive error of -97. is returned if the event flag is illegal. 2. If an I/O status block was specified, clear both words. 3. Allocate an I/O PACKET. If this fails a directive error of -1. is returned. NOTE This is the last possible directive error. Both the event flag and I/O status are cleared before this error can be detected. 4. Increment the outstanding I/O count (by[T.IOC]_T.IOC+1). 5. If the function was QIOW and an event flag was specified, place the task in WAIT FOR EVENT FLAG state for the specified event flag. 3.0 FILL IN I/O PACKET (341 - 361) This section of code fills in I/O PACKET locations I.PRI to I.AST. DRQIO NOTES - SEP, 77 PAGE 3 4.0 DECODE I/O FUNCTION (362 - 469) This section of code determines what to do with the I/O function depending on the device type and I/O function tables. The following steps are performed. 1. If the I/O function code was kill I/O (by[Q.IOFN+1]=0), control is passed to the kill I/O code. This code calls $IOKIL and returns success for the kill I/O function. 2. If multiuser support was selected (M$$MUP), the I/O request access to the device is checked. Access is denied and an I/O status code of IE.PRI is returned if the all of the following are true. 1. The device is owned (wd[U.OWN]#0). 2. Public access is not allowed (bt[US.PUB]by[U.ST2]=0). 3. The current owner is not the task that issued the I/O request (wd[U.OWN]#wd[T.UCB of current task]). 4. The current task is not priviledged (bt[T3.PRV]wd[T.ST3]=0). 3. The I/O function code is checked to make sure it is in range (1-31.). If it is not, an I/O status code of IE.IFC is returned. 4. The I/O function code is changed into a bit mask. 5. The I/O function code is checked against the legal function table in the DCB. If it is not, an I/O status code of IE.IFC is returned. 6. The device is checked to see if it is offline (bt[US.OFL]by[U.ST2]=1). If it is, an I/O status code of IE.OFL is returned. 7. The I/O function code is checked against the control function table in the DCB. If it is, control is passed to control function service. See section 5.2. 8. The I/O function code is checked against the no-op function table in the DCB. If it is, an I/O status code of IS.SUC is returned. DRQIO NOTES - SEP, 77 PAGE 4 9. The device is checked to see if it is not mountable (wd[U.CW1]>0). If so the following checks are made. 1. The I/O function code is checked against the ACP function table in the DCB. If it is not an ACP function, control is passed to the transfer function service code. See section 5.1. 2. If function is an ACP function, the function code is changed to IO.WLB unless the I/O function code was IO.RVB which is converted to IO.RLB. Control is then passed to the transfer function service code. See section 5.1. NOTE If you get here, the I/O function code must be either IO.RVB or IO.WVB. All others will be handled incorrectly. 10. If the device is not mounted or mounted as foreign (bt[US.MNT!US.FOR]by[U.STS]=0), the following occurs. 1. If the function is an ACP function, an I/O status return of IE.PRI is made. 2. Otherwise the control is passed to the transfer function service code. See section 5.1. 11. If the device is mounted and the I/O function code is not an ACP function, the following occurs. 1. If the I/O function code is load overlay (IO.LOV) control is passed to the transfer function service code. See section 5.1. 2. If the issuing task is priveledged (bt[T3.PRV]wd[T.ST3]=1), control is passed to the transfer function service code. See section 5.1. 3. Otherwise an I/O status code of IE.PRI is returned. 12. If the I/O function code is an ACP function and the DRQIO NOTES - SEP, 77 PAGE 5 device is mounted, control is passed to the appropriate polish code based on the function code. See section 6. 5.0 COMPLETE NON-ACP I/O REQUEST This section of code completes the processing of non-ACP I/O request. It is broken up into two parts: transfer request service and control request service. 5.1 Transfer Request Service (470#-#509) This section of code checks the users buffer for correct attributes and sets up the mapping into the user buffer for the I/O driver. The following steps are performed: 1. Get address (Q.IOPM) and length (Q.IOPM+2) of user buffer. 2. If word alignment is required (by[U.CTL]<0), check that buffer starts on word boundary. If it does not, return an I/O status code of IE.BYT. 3. Check that the buffer length has the correct modulo. If it does not, return an I/O status code of IE.BYT. 4. Address check the buffer to make sure it is inside the users task space. If it is not, return an I/O status code of IE.SPC. 5. Convert user buffer address into relocation bias and APR6 offset. 6. If the device is an NPR device (bt[UC.NPR]by[U.CTL]=1), convert to proper form for device setup. NOTE The above step is done only if the I/O function code on the stack is nonzero. The read/write virtual functions for a mounted, ACP devices zero this word. DRQIO NOTES - SEP, 77 PAGE 6 7. Store relocation bias and displacement into I/O PACKET. 5.2 Control Request Service (542#-#594) This section of code completes the processing of non-ACP I/O functions. Transfer request fall into this code (see above section). The following steps are performed: 1. Complete copying the QIO parameters into the I/O PACKET. NOTE Control functions copy all 6 parameter locations. Transfer function copy only the last five. NOTE Control functions set I/O PACKET locations I.PRM to I.PRM+14 to location Q.IOPM to Q.IOPM+14. Transfer functions set I/O PACKET location I.PRM to the relocation bias, I.PRM+2 to the displacement address, and I.PRM+4 to I.PRM+16 to locations Q.IOPM+2 to Q.IOPM+14. 2. If the function is load overlay (IO.LOV) and the device is mountable (wd[U.CW1<0), calculate the correct disk block address for the function. 3. Control is passed to the queue I/O PACKET code. See section 7. DRQIO NOTES - SEP, 77 PAGE 7 6.0 COMPLETE ACP I/O REQUEST This section of code completes the processing of ACP functions. It is broken into two parts: the polish interpreter data base and the various polish routines: 6.1 Polish Interpreter Data Base (94#-#221) These tables are used to correctly dispatch ACP functions to the appropriate setup routines. The tables have two parts. Table FCDSP contains the starting address of the appropriate polish table for each function. This is followed by the polish tables. NOTE An ACP function with a function code of 0 - 7 will cause the system to crash. The following code is a copy of the polish interpreter data base take directly from the module DRQIO. See the next section for a description of each routine referenced by these tables. ; POLISH INTERPRETER DATA BASE ; ; FUNCTION CODE DISPATCH VECTOR ; .IF DF A$$CPS FCDSP: .WORD FCIFC ;10-ILLEGAL FUNCTION .WORD FCPKT ;11-FIND FILE NAME IN DIRECTORY .WORD FCIFC ;12-ILLEGAL FUNCTION .WORD FCPKT ;13-REMOVE FILE NAME FROM DIRECTORY .WORD FCPKT ;14-ENTER FILE NAME IN DIRECTORY .WORD FCACC ;15-ACCESS FILE FOR READ .WORD FCACC ;16-ACCESS FILE FOR READ AND WRITE .WORD FCACC ;17-ACCESS FILE FOR RWE .WORD FCDAC ;20-DEACCESS FILE .WORD FCRVB ;21-READ VIRTUAL BLOCK .WORD FCWVB ;22-WRITE VIRTUAL BLOCK .WORD FCPKT ;23-EXTEND FILE .WORD FCCRE ;24-CREATE FILE DRQIO NOTES - SEP, 77 PAGE 8 .WORD FCPKT ;25-MARK FILE FOR DELETE .WORD FCPKT ;26-READ FILE ATTRIBUTES .WORD FCPKT ;27-WRITE FILE ATTRIBUTES .WORD FCPKT ;30-USER MAGTAPE CONTROL FUNCTION .WORD FCWVB ;31-TRANSMIT PROCESS MESSAGE .WORD FCRVB ;32-RECEIVE PROCESS MESSAGE .WORD FCCON ;33-CONNECT TO PROCESS .WORD FCDIS ;34-DISCONNECT FROM PROCESS .WORD FCNCT ;35-NETWORK CONTROL FUNCTION .WORD FCIFC ;36-ILLEGAL FUNCTION .WORD FCIFC ;37-ILLEGAL FUNCTION .IF NDF M$$NET FCCON: ;REF LABEL IF NO NETWORK SUPPORT FCDIS: ;REF LABEL IF NO NETWORK SUPPORT FCNCT: ;REF LABEL IF NO NETWORK SUPPORT .IFTF ; ; ILLEGAL FUNCTION ; FCIFC: .WORD IEIFC ;SET ILLEGAL FUNCTION STATUS ; ; ACCESS FILE FOR READ, READ/WRITE, OR READ/WRITE/EXTEND ; FCACC: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT FCCAW: .WORD CKALN ;CHECK IF FILE ACCESSED ON LUN .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKRLK ;SYNCHRONIZE ACCESS AND EXIT ; ; DEACCESS FILE ; FCDAC: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKRLK ;EXIT ; ; READ VIRTUAL BLOCK ; FCRVB: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD CKRAC ;CHECK READ ACCESS AND EXIT ; ; WRITE VIRTUAL BLOCK DRQIO NOTES - SEP, 77 PAGE 9 ; FCWVB: .WORD CKNLN ;CHECK IF FILE ACCESSED ON LUN .WORD CKWAC ;CHECK WRITE ACCESS AND EXIT ; ; CREATE FILE ; FCCRE: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKACC ;CHECK IF ACCESS ALSO REQUESTED ; ; BUILD AN I/O PACKET FOR FIND, ENTER, REMOVE, EXTEND, ; DELETE, READ ATTRIBUTES, AND WRITE ATTRIBUTES ; FCPKT: .WORD BDPKT ;BUILD AN I/O PACKET .WORD CKXIT ;EXIT .IFF ; ; CONNECT TO PROCESS ; FCCON: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKALN ;CHECK IF PROCESS CONNECTED ON LUN .WORD CKCON ;ADDRESS CHECK CONNECT BUFFER .WORD CKRLK ;INTERLOCK LUN USAGE AND EXIT ; ; DISCONNECT FROM PROCESS ; FCDIS: .WORD CKNLN ;CHECK IF PROCESS CONNECTED ON LUN .WORD CKDIS ;CHECK BUFFER AND COPY PARAMETERS .WORD CKRLK ;INTERLOCK LUN USAGE AND EXIT ; ; NETWORK CONTROL FUNCTION ; FCNCT: .WORD CKDMO ;CHECK IF VOLUME MARKED FOR DISMOUNT .WORD CKCON ;ADDRESS CHECK BUFFER .WORD CKXIT ;EXIT .ENDC .ENDC DRQIO NOTES - SEP, 77 PAGE 10 The registers and stack are setup as shown below when the dispatch into the polish code begins. R0 = Address of UCB. R1 = Address of second lun word. R2 = Index into polish function dispatch table. R3 = Address of Q.IOPM in QIO DPB. R4 = Address of I.PRM in I/O PACKET. R5 = Address of next polish dispatch vector. (SP) = Address of second lun word. (SP)+2 = Address of UCB. (SP)+4 = I/O function code. 6.2 Polish Routines This section describes the various polish routines used to complete the processing of ACP functions. To see which routines are used by a particular functions, see the above section. The routines are listed in alphabetical order. 6.2.1 BDPKT (724#-#867) - This routine completes the I/O PACKET for various ACP I/O request. It expects the following I/O parameters in the QIO request: Q.IOPM+0 Address of file ID block. Q.IOPM+2 Address of attribute descriptor block. Q.IOPM+4 Extend control word 1. Q.IOPM+6 Extend control word 2. Q.IOPM+10 Access control word. Q.IOPM+12 Address of filename block. The file ID block and filename block are relocated if present. The attribute descriptor blocks addresses are relocated and stored in the secondary control block. If any address do not check out, an I/O status code of IE.SPC is returned. Otherwise it dispatches to the next entry. DRQIO NOTES - SEP, 77 PAGE 11 6.2.2 CKACC (953#-#961) - This routine checks if access is requested on a create (wd[Q.IOPM+10]<0) and changes the dispatch pointer (R5) to FCCAW if true. Otherwise it dispatches to the next entry. 6.2.3 CKALN (936#-#944) - This routine checks if a file is already accessed on the lun (wd[second lun word]#0) and returns an I/O status code of IE.ALN if so. Otherwise it dispatches to the next entry. 6.2.4 CKCON (880#-#893) - This routine copies the QIO parameters into the I/O packet. The routine requires the first two parameters to be a buffer address and size and relocates the buffer before storing. If the buffer is not specified or is illegal, an I/O status code of IE.BAD is returned. Otherwise it dispatches to the next entry. 6.2.5 CKDIS (868#-#879) - This routine copies the QIO parameters into the I/O packet and dispatches to the next entry. 6.2.6 CKDMO (898#-#905) - This routine checks if the volume is marked for dismount (bt[US.MDM]by[U.STS]=1) and returns an I/O status code of IE.PRI if so. Otherwise it dispatches to the next entry. 6.2.7 CKNLN (945#-#952) - This routine checks if a files is accessed on the lun (wd[second lun word]#0) and returns an I/O status code of IE.NLN if not. Otherwise it dispatches to the next entry. 6.2.8 CKRAC (906#-#913) - This routine sets R2 to check for read access (bt[WI.RDV]) and falls into the CKWAC code. 6.2.9 CKRLK (963#-#968) - This routine locks the lun (wd[second lun word]_wd[second lun word]+1) and falls into the CKXIT code. DRQIO NOTES - SEP, 77 PAGE 12 6.2.10 CKWAS (914#-#934) - This routine performs the following steps. 1. Set R2 to check for write access (bt[WI.WRV]) 2. Pop address of second lun word off stack. NOTE CKRAC continues at the above step. 3. Mark function as ACP transfer function (see Transfer Request Service, step 6). 4. Check if desired access allowed to file. If not, return I/O status code of IE.PRI. 5. Pop UCB address of of stack. 6. Continue in Transfer Request Service (see section 5.1). 6.2.11 CKXIT (969#-#978) - This routine cleans the stack, increments the volume transaction count (wd[V.TRCT]_wd[V.TRCT]+1), and exits queue I/O PACKET code (see section 7). 7.0 QUEUE I/O REQUEST TO DRIVER (595#-#645) This section of code queues the I/O packet to the device driver and calls the driver at the initiator. The following steps are performed. NOTE The entry $DRQRQ can be used to queue an I/O packet that has been constructed by other means. R1 should be the packet address and R5 the UCB address. DRQIO NOTES - SEP, 77 PAGE 13 1. Get the SCB address (wd[U.SCB]). 2. If the packet is not to be queued (bt[UC.QUE]by[U.CTL]=1), goto step 4. 3. Queue the I/O packet to the SCB I/O queue. 4. If the driver is loadable, map KISAR5 into the driver. 5. Call the driver at the initaitor entry point. 6. If the driver is loadable, restore KISAR5 to its orginal contents. 7. Exit from the DRQIO code.