TITLE RAXKON - DRIVER FOR DISKS ON AN HSC-50 V16 SUBTTL JOOCTH A. DZIEDZIC/JAD 21 JAN 86 SEARCH F,S,SCAPRM,MSCPAR,MACSYM $RELOC $HIGH ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; .CPYRT<1984,1986> ;COPYRIGHT (C) 1984,1986 ;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ;ALL RIGHTS RESERVED. XP VRXKON,16 RAXKON:!ENTRY RAXKON ;LOAD IF LIBRARY SEARCH SUBTTL LOOSE ENDS COMMENT | Propagate UF.RMV to U2PNRM (sense of bits is opposite). |; END OF COMMENT SUBTTL COMMENTARY COMMENT | RAXKON IS INTENDED AS A BLACK BOX INTERFACE BETWEEN FILSER AND THE SYSTEMS COMMUNICATION ARCHITECTURE. MANY OF THE ENTRY POINTS IN RAXKON SPECIFIED BY THE "IDEAL" CONTROLLER HAVE NO COUNTERPART IN OUR DEALINGS WITH THE HSC-50 STORAGE CONTROLLER, AS IT HANDLES ALL POSITIONING, LATENCY OPTIMIZATION, AND ERROR RECOVERY. WHERE THIS IS THE CASE THE REQUIRED GLOBAL ROUTINES ARE AN ELABORATE NO-OP. |; END OF COMMENT SUBTTL PROCESS NAME AND BUFFERING DEFINITIONS ;THE PROCESS NAME STRINGS ARE REQUIRED BY SCA TO BE 16 BYTE ;8-BIT ASCII STRINGS ;SOURCE PROCESS NAME STRING FOR THE TOPS-10 MSCP DISK DRIVER OURDNM: ASCI8 () ;DESTINATION PROCESS NAME STRING FOR THE MSCP DISK SERVER YURDNM: ASCI8 () ;BUFFERING/CREDIT DEFINITIONS FOR THE CALL TO SC.CON DCREDT==^D1 ;MINIMUM RECEIVE CREDIT HSCBFN==^D25 ;NUMBER OF BUFFERS HSC SHOULD KEEP FOR US DGNUM==^D5 ;NUMBER OF DATAGRAM BUFFERS WE NEED SUBTTL START DRIVE POSITIONING ;ROUTINE TO CAUSE THE DRIVE TO DO A RECALIBRATE OPERATION. ;CALL: ; J/ KDB ADDRESS ; U/ UDB ADDRESS ; PUSHJ P,RAXRCL ;RETURN: ; CPOPJ IF ERROR ; CPOPJ1 WITH RECAL STARTED ; ;NOTE: FILSER NEVER CALLS THIS ROUTINE, BUT COMMON DOES ON ;RESUMPTION AFTER A SYSTEM SLEEP. OTHERWISE IT COULD BE A ;PUSHJ P,RAXDIE TO CATCH FILSER ERRORS. RAXRCL==:CPOPJ1## ;STARTED ;ROUTINE TO START A POSITION OPERATION GOING. CALL WITH UNIBLK(U) ;CONTAINING THE DESIRED BLOCK NUMBER. ;CALL: ; J/ KDB ADDRESS ; U/ UDB ADDRESS ; PUSHJ P,RAXPOS ;RETURN: ; CPOPJ IF ERRORS ; CPOPJ1 WITH POSITION STARTED RAXPOS==:RAXDIE ;FILSER SHOULDN'T GET HERE SUBTTL START DATA TRANSFER ;ROUTINES TO START A DATA TRANSFER GOING ON A DRIVE. ENTRY POINTS: ; ; RAXRED - READ DATA, DON'T STOP ON ERROR ; RAXRDS - READ DATA, STOP ON ERROR ; RAXRDF - READ FORMAT ; RAXWRT - WRITE DATA, DON'T STOP ON ERROR ; RAXWTS - WRITE DATA, STOP ON ERROR ; RAXWTF - WRITE FORMAT ; ;CALL: ; J/ KDB ADDRESS ; U/ UDB ADDRESS ; P1/ CHN ADDRESS ; T1/ DRB ADDRESS ; PUSHJ P,RAXxxx ;RETURN: ; CPOPJ IF ERRORS WITH ERROR BITS IN T1 ; CPOPJ1 IF TRANSFER STARTED SUCCESSFULLY ;HERE TO START TRANSFER TO READ/WRITE FORMATS RAXRDF::SKIPA T2,[OP.RD] ;GET FUNCTION CODE FOR READ RAXWTF::MOVEI T2,OP.WR ;GET FUNCTION CODE FOR WRITE PUSHJ P,RAXDIE ;I DON'T THINK WE CAN FORMAT THESE DISKS, CAN WE? JRST RAXDGO ;JOIN COMMON TRANSFER CODE ;HERE TO START TRANSFER TO READ/WRITE DATA, NOT STOPPING ON ERRORS RAXRED::SKIPA T2,[OP.RD] ;GET FUNCTION CODE FOR READ RAXWRT::MOVEI T2,OP.WR ;GET FUNCTION CODE FOR WRITE JRST RAXDGO ;JOIN COMMON TRANSFER CODE ;HERE TO START TRANSFER TO READ/WRITE DATA, STOPPING ON ERRORS RAXRDS::SKIPA T2,[OP.RD] ;GET FUNCTION CODE FOR READ RAXWTS::MOVEI T2,OP.WR ;GET FUNCTION CODE FOR WRITE ;HERE FROM ALL TRANSFER OPERATIONS TO ACTUALLY DO THE WORK WITH ;T1 CONTAINING THE DRB ADDRESS AND T2 CONTAINING THE FUNCTION ;THROUGHOUT THIS CODE, P1 CONTAINS KDB ADDRESS OFFSET BY OUR CPU NUMBER ;TO MAKE REFERENCES TO THE VARIOUS INDEXED BY CPU TABLES EASIER. RAXDGO: SE1ENT ;ENSURE WE RUN IN NZS PUSHJ P,SAVE4## ;SAVE AC'S WE WILL CLOBBER PUSHJ P,SAVR## ;THIS LOOKS LIKE A SEMI-PRESERVED AC NOW HRRZ P1,J ;GET THE KDB ADDRESS ADD P1,.CPCPN## ;OFFSET KDB ADDRESS BY OUR CPU NUMBER MOVE P3,T1 ;COPY DRB ADDRESS MOVEM T2,DRBOPC##(P3) ;SAVE THE OPERATION CODE MOVE T1,T2 ;COPY THE OPERATION CODE FOR CONECT MOVE T3,P3 ;COPY THE DRB ADDRESS FOR POSSIBLE ERROR RETURN PUSHJ P,CONECT ;CONNECT TO THE DRIVE POPJ P, ;DRIVE IS DOWN, RETURN WITH ERROR FLAGS IN T1 MOVE T1,DRBOPC##(P3) ;GET THE OPERATION CODE MOVX T2,BS.HDM ;GET THE TRANSFER MODE MOVE T3,DRBPRG##(P3) ;GET ADDRESS OF THE CHANNEL PROGRAM PUSH P,P3 ;SAVE DRB ADDRESS PUSHJ P,MSCMIO## ;MAP THE I/O JRST [POP P,P3 ;COULDN'T, RESTORE DRB ADDRESS JRST RAXGE2] ;LET FILIO QUEUE THE REQUEST POP P,P3 ;RESTORE DRB ADDRESS HRRZ T1,J ;GET KDB ADDRESS ADD T1,.CPCPN## ;OFFSET BY OUR CPU NUMBER EXCH T1,P1 ;PUT IT BACK IN P1, GET BUFFER NAME IN T1 MOVEM T1,DRBBHD##(P3) ;STORE BUFFER NAME MOVE T1,P.CRF(P2) ;GET COMMAND REFERENCE NUMBER MOVEM T1,DRBCRF##(P3) ;STORE MOVE T1,DRBBLK##(P3) ;GET LOGICAL BLOCK NUMBER LSH T1,4 ;POSITION IT IN 32 BITS PUSHJ P,REVFUL## ;REVERSE IT FOR THE HSC MOVEM T1,P.LBN(P2) ;STORE LDB T1,UNYPUN## ;GET PHYSICAL UNIT NUMBER LSH T1,4 ;POSITION IT IN 32 BITS PUSHJ P,REVFUL## ;REVERSE IT FOR THE HSC MOVEM T1,P.UNIT(P2) ;STORE MOVE P4,RAKCTI##(P1) ;GET CONNECT TABLE INDEX SKIPG MSCCID##(P4) ;MAKE SURE WE HAVE A CONNECTION PUSHJ P,RAXDIE ;NO, WE SHOULD HAVE CAUGHT THIS SOONER BLCAL. (SC.DCI##,) ;GET DESTINATION CONNECT ID JRST RAXGE1 ;ERROR, VC MUST HAVE BEEN CLOSED MOVEM T1,P.BUFF+2(P2) ;STORE LAST PART OF BUFFER NAME BLCAL. (SC.SMG##,) ;DO IT SKIPA ;ERROR ON THE SEND JRST CPOPJ1## ;SKIP RETURN ;HERE IF WE HAD AN ERROR ON THE MESSAGE SEND - FIGURE OUT WHY ;AND TAKE SOME APPROPRIATE ACTION CAIE T1,.SCFNC ;NOT ENOUGH CREDIT? CAIN T1,.SCFWS ;OR CONNECTION IN WRONG STATE? SKIPA ;YES PUSHJ P,RAXDIE ;NO, DIE FOR NOW CAIE T1,.SCFNC ;NO CREDITS? JRST RAXGE1 ;NO, DON'T LIGHT KOPCNA MOVSI T1,KOPCNA## ;NO CREDIT IS AVAILABLE IORM T1,KONCNA##(J) ; SO TELL FILSER TO SHUT UP FOR A WHILE ;RETURN THE BHD/BSD(S) WE USED TO MAP THIS TRANSFER RAXGE1: SKIPE T1,DRBBHD##(P3) ;GET BUFFER NAME PUSHJ P,PPDRHD## ;RETURN BHD AND BSD(S) SETZM DRBBHD##(P3) ;DON'T DO THIS TWICE MOVSI T1,KOPCNA## ;DID WE RUN OUT OF CREDITS? TDNN T1,KONCNA##(J) ;... SKIPA T1,[KOPOFL##] ;NO, CALL THE ERROR OFFLINE ;HERE WHEN MSCCOM COULDN'T MAP THE I/O LIST - QUEUE THE REQUEST RAXGE2: MOVEI T1,KOPNOC## ;TELL FILSER WE DIDN'T HAVE CREDITS MOVE T3,P3 ;DRB ADDRESS BACK WHERE FILSER EXPECTS POPJ P, ;RETURN WITH ERROR FLAG SUBTTL INTERRUPT HANDLER ;ROUTINE CALLED WHEN AN INTERRUPT OCCURS. THE HSC-50 DOESN'T ;INTERRUPT SO IF WE GET HERE SOMETHING TERRIBLE HAS HAPPENED. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXINT ;RETURN: ; CPOPJ ALWAYS THROUGH FILINT WITH: ; ; T1/ COMMUNICATION WORDS ; T2/ CONI ; T3/ ENDING STATUS ; T4/ MASK OF INTERRUPTING UNITS RAXINT==:RAXDIE ;FILSER SHOULDN'T GET HERE SUBTTL STOP TRANSFER FOR HUNG RECOVERY ;ROUTINE TO STOP THE CURRENT TRANSFER WHEN THE HUNG TIMER TIMES OUT. ;ONCMOD WILL CALL THIS ROUTINE IF A DRIVE TIMES OUT DURING ONCE, ;OTHERWISE IT COULD BE MADE A CALL TO RAXDIE. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXSTP ;RETURN: ; CPOPJ IF COULDN'T STOP DRIVE ; CPOPJ1 IF SUCCESSFUL RAXSTP==:CPOPJ1## ;TELL ONCMOD IT WAS STOPPED SUBTTL DETERMINE CAPACITY AND STATUS ;ROUTINE TO RETURN CAPACITY AND STATUS OF AN HSC-50 DRIVE TO FILSER. ;CALL: ; J/ KDB ADDRESS ; U/ UDB ADDRESS ; PUSHJ P,RAXCPY ;RETURN: ; CPOPJ IF ERROR ; CPOPJ1 IF DRIVE EXISTS AND IS OK TO USE WITH: ; ; T1/ BLOCKS PER UNIT ; T2/ BLOCKS PER UNIT INCLUDING MAINTENANCE CYLINDERS ; T3/ BLOCKS PER UNIT IN 10/11 COMPATIBILITY MODE ; T4/ STATUS BITS (KOPUHE,KOPNSU,KOP22B),,UNIT TYPE ; W/ BLOCKS PER TRACK,,BLOCKS PER CYLINDER RAXCPY::PUSHJ P,SAVE1## ;SAVE P1 SETZ P1, ;GET A ZERO MOVS T1,.CPBIT## ;BIT FOR THIS CPU TDNE T1,UNIALT##(U) ;IS UNIT ATTACHED THROUGH THIS CPU? AOSA (P) ;YES, SET FOR SKIP RETURN MOVSI P1,KOPNSU##!KOPUHE## ;NO, GET SOME ERROR BITS MOVE T1,UNIBPU##(U) ;LOAD UP THE VALUES I PREVIOUSLY STORED MOVE T2,UNIBPM##(U) ;... MOVE T3,UNIBUC##(U) ;... LDB W,UNYBPY## ;GET BLOCKS/CYLINDER LDB T4,UNYBPT## ;GET BLOCKS/TRACK HRL W,T4 ;IN W LDB T4,UNYUTP## ;GET UNIT TYPE TLO T4,KOP22B## ;THIS IS A 22-BIT KONTROLLER IOR T4,P1 ;INCLUDE ERROR BITS IF UNIT WASN'T ATTACHED POPJ P, ;RETURN SUBTTL RETURN ECC MASK AND POSITION ;AS THE HSC-50 DOES ALL ERROR RECOVERY THIS ROUTINE IS AN ELABORATE NO-OP. ;ROUTINE TO RETURN THE ECC POSITION AND MASK TO FILIO FOR AN ECC ;CORRECTABLE ERROR IN A BLOCK. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXECC ;RETURN: ; CPOPJ IF NO ECC INFORMATION AVAILABLE ; CPOPJ1 WITH CORRECTION DATA AS FOLLOWS: ; ; T1/ WORD POSITION OF START OF ERROR RELATIVE TO START OF BLOCK ; T2-T3/ MASK RAXECC==:RAXDIE ;FILSER SHOULDN'T GET HERE SUBTTL DIRECT FILIO IN ERROR RECOVERY ;ROUTINE TO DIRECT FILIO IN ERROR RECOVERY. ;CALL: ; J/ KDB ADDRESS ; T1/ RETRY NUMBER ; P1/ CHN ADDRESS ; PUSHJ P,RAXERR ;RETURN: ; CPOPJ ALWAYS WITH: ; ; T1/ 0 IF STRAIGHT RETRY ; 2 IF LAST TIME ; 3 IF GIVE UP RAXERR::MOVEI T1,3 ;GIVE UP, YOU CAN'T DO ANYTHING THE HSC-50 CAN'T POPJ P, ;RETURN SUBTTL MISCELLANEOUS GLOBAL FUNCTIONS ;ROUTINE TO RETURN THE LATENCY TIME. WE ALWAYS LIE AND SAY WE ;ARE ON CYLINDER (ZERO LATENCY TIME) SO FILSER WILL START I/O. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXLTM ;RETURN: ; CPOPJ1 ALWAYS WITH: ; T1/ LATENCY TIME RAXLTM::MOVEI T1,0 ;ZERO LATENCY TIME JRST CPOPJ1## ;SKIP RETURN ;ROUTINE TO RETURN THE DISTANCE TO THE TARGET CYLINDER. WE ALWAYS ;LIE AND SAY WE ARE ON CYLINDER (ZERO DISTANCE) SO FILSER WILL START ;I/O. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXCCM ;RETURN: ; CPOPJ WITH: ; T1/ DISTANCE FROM CURRENT CYLINDER TO TARGET CYLINDER RAXCCM::MOVEI T1,0 ;RETURN A ZERO POPJ P, ;RETURN ;ROUTINES WHICH SHOULD NEVER BE CALLED SINCE THE DISPATCH BITS IN ;COMMOD PROHIBIT THIS. IF WE DO GET HERE IT IS PROBABLY A SIGN ;SOMEONE HAS GOOFED VERY BADLY, SO DIE WITHOUT FURTHER ADO. RAXRDC:: ;READ 10/11 COMPATIBILITY MODE RAXWTC:: ;WRITE 10/11 COMPATIBILITY MODE RAXUNL:: ;UNLOAD DRIVE STOPCD .,STOP,XIF, ;++ RAXKON ISN'T FANCY SUBTTL CHECK DRIVE/CONTROLLER STATUS ;ROUTINE TO ENSURE THE HSC-50 VIRTUAL CIRCUIT IS IN AN ACCEPTABLE ;STATE FOR THE DATA TRANSFER OPERATION ABOUT TO BE DONE. ;CALL: ; J/ KDB ADDRESS ; U/ UDB ADDRESS ; T1/ FUNCTION CODE ; T3/ DRB ADDRESS ; PUSHJ P,CONECT ;RETURN: ; CPOPJ IF ERROR WITH: ; T1/ ERROR BITS ; CPOPJ1 IF OK WITH: ; T1/ FUNCTION CODE CONECT: MOVS T2,.CPBIT## ;BIT FOR THIS CPU TDNN T2,UNIALT##(U) ;IS THIS CPU ATTACHED TO THIS UNIT? JRST CONOFL ;NO, CALL THE UNIT OFFLINE SKIPGE KONCNA##(J) ;NO CREDIT AVAILABLE? JRST CONCNA ;YES CAIE T1,OP.WR ;IS THIS A WRITE FUNCTION? JRST CONEC1 ;NO, DON'T CARE ABOUT WRITE PROTECT MOVSI T2,UNPHWP## ;GET HARDWARE WRITE PROTECT BIT TDNE T2,UNIDES##(U) ;IS THE UNIT WRITE PROTECTED? JRST CONHWP ;YES CONEC1: MOVSI T2,UNPOFL## ;GET OFF-LINE BIT TDNE T2,UNIDES##(U) ;IS THE DRIVE OFF-LINE? JRST CONOFL ;YES JRST CPOPJ1## ;THAT WAS HARD CONHWP: MOVEI T1,KOPWLK## ;GET THE WRITE LOCK BIT POPJ P, ;RETURN CONOFL: MOVEI T1,KOPOFL## ;GET THE OFF-LINE BIT POPJ P, ;RETURN CONCNA: MOVEI T1,KOPNOC## ;GET THE NO CREDITS BIT POPJ P, ;RETURN ;ROUTINE TO MAKE SURE THE KONTROLLER HAS A PI ASSIGNMENT. ;YOU GUESSED IT, ANOTHER SUPERFLUOUS GLOBAL. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXALV ;RETURN: ; CPOPJ ALWAYS RAXALV==:CPOPJ## ;IT HAS A PI ASSIGNMENT SUBTTL ERROR LOGGING ROUTINES ;ROUTINE TO READ THE "REGISTERS" INTO KONEBK FOR THE HSC-50. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXREG ;RETURN: ; CPOPJ ALWAYS RAXREG==:CPOPJ## ;NO REGISTERS TO READ ;AUTO CONFIGURE ENTRY POINT - NOT USED RAXCFG==:RAXDIE ;NO WAY, JOSE SUBTTL KONTROLLER ONCE PER SECOND CODE ;ROUTINE CALLED ONCE PER SECOND TO DO TIMING, ETC., FOR THE HSC. ;CALL: ; J/ KDB ADDRESS ; PUSHJ P,RAXSEC ;RETURN: ; CPOPJ ALWAYS RAXSEC::SE1ENT ;ENSURE WE RUN IN NZS PUSHJ P,SAVE4## ;SAVE AC'S WE WILL CLOBBER PUSHJ P,SAVR## ;THIS LOOKS LIKE A SEMI-PRESERVED AC NOW HRRZ P1,J ;GET KDB ADDRESS ADD P1,.CPCPN## ;OFFSET BY OUR CPU NUMBER SKIPE RAKTIM##(P1) ;SKIP IF TIMER IS NOT RUNNING SOSLE RAKTIM##(P1) ;DECREMENT AND TEST FOR TIMEOUT POPJ P, ;TIMER STILL RUNNING MOVE T1,RAKTMO##(P1) ;GET THE TIMEOUT MOVEM T1,RAKTIM##(P1) ;RESET FOR NEXT PASS SKIPL P4,RAKCTI##(P1) ;GET CONNECT TABLE INDEX, SKIP IF DISCONNECTED SKIPG MSCCID##(P4) ;STILL CONNECTED? POPJ P, ;NO, QUIT NOW MOVX T1,DT.GCS ;IS A MESSAGE STILL OUTSTANDING? TDNE T1,MSCFLG(P4) ;... JFCL ;YES, WHAT DO WE DO NEXT? SETZB T1,T2 ;UNIT AND COMMAND REFERENCE NUMBER OF ZERO FOR NOW PUSHJ P,MSCGCS## ;SEND A GET COMMAND STATUS PACKET MOVX T1,DT.GCS ;INDICATE WE'VE DONE SO IORM T1,MSCFLG(P4) ;... POPJ P, ;RETURN AND WAIT FOR THE RESPONSE ;HERE ON RETURN FROM GET COMMAND STATUS COMMAND RAXGCS: MOVX T1,DT.GCS ;WE'VE GOTTEN AN ANSWER ANDCAM T1,MSCFLG##(P4) ; SO CLEAR THE FLAG SKIPN T1,P.OTRF(P2) ;GET THE COMMAND REFERENCE NUMBER JRST RAXGC1 ;JUST AN HSC POLL ;CHECK FOR OUTSTANDING REQUEST HERE RAXGC1: PJRST MSCRBF## ;RETURN THE PACKET AND RETURN SUBTTL INTERFACE TO MSCCOM - DRIVER DISPATCH TABLE ;DISPATCH TABLE FOR MSCCOM RECALLS AFTER CALLS TO MSCCOM ROUTINES. ;THESE ARE NEGATIVE INDEXES INTO RAXDDT. SEE .RR??? IN MSCPAR. ;DISPATCH TABLE FOR SCS NOTIFICATION CALLS ROUTED HERE VIA MSCCOM. ;ENTRIES FLAGGED BY "*" ARE CALLED WITH THE CTI IN T2 (AS OPPOSED ;TO THE CID WHICH IS SUPPLIED FROM SCS ON THE CALL TO MSCCOM). ;THE KDB ADDRESS (IF ANY) IS PASSED IN J. ;OTHER NOTES: WE NEVER GET HERE FOR THE DATAGRAM/MESSAGE RECEIVED ;ENTRIES BUT THEY ARE IN THE TABLE TO MAKE IT CONSISTENT WITH THE ;TABLE IN MSCCOM. IFIW RAXCUS ;.RRCUS - UNIT STATUS RETURNED IFIW RAXXFR ;.RRXFR - TRANSFER COMPLETE IFIW RAXAVA ;.RRAVA - UNSOLICITED UNIT AVAILABLE IFIW RAXGUS ;.RRGUS - UNIT STATUS RETURNED IFIW RAXGCS ;.RRGCS - COMMAND STATUS IFIW RAXAON ;.RRAON - UNIT AVAILABLE ONLINE COMPLETE IFIW RAXOON ;.RROON - ONCE BIND ONLINE COMPLETE IFIW RAXUON ;.RRONL - UNIT ONLINE COMMAND COMPLETE IFIW RAXGNU ;.RRGNU - RETURN FROM GET NEXT UNIT IFIW RAXSCC ;.RRSCC - RETURN FROM SET CONTROLLER CHARACTERISTICS RAXDDT::IFIW CPOPJ## ;.SSDGR - DATAGRAM RECEIVED * IFIW CPOPJ## ;.SSMGR - MESSAGE RECEIVED * IFIW RAXPBC ;.SSPBC - PORT BROKE CONNECTION * IFIW CPOPJ## ;.SSCTL - CONNECTION TO LISTEN IFIW RAXCRA ;.SSCRA - CONNECTION RESPONSE AVAILABLE * IFIW CPOPJ## ;.SSMSC - MESSAGE/DATAGRAM SEND COMPLETE IFIW CPOPJ## ;.SSDDG - DATAGRAM DROPPED IFIW CPOPJ## ;.SSLCL - LITTLE CREDIT LEFT IFIW RAXONL ;.SSNCO - NODE COMING ONLINE IFIW CPOPJ## ;.SSOSD - OK TO SEND DATA IFIW CPOPJ## ;.SSRID - REQUEST DISCONNECT IFIW RAXCIA ;.SSCIA - CREDIT IS AVAILABLE * IFIW CPOPJ## ;.SSDMA - DMA OPERATION COMPLETE IF1,-.SSAFT,> SUBTTL DRIVER DISPATCH - DATA TRANSFER COMPLETE RAXXFR: HRRZ P1,J ;GET KDB ADDRESS ADD P1,.CPCPN## ;OFFSET BY OUR CPU NUMBER LOAD T1,PKYECD,(P2) ;GET THE END CODE CAIG T1,OP%GUS ;IS THIS A "REAL" MESSAGE PJRST MSCRBF## ;NO, RETURN THE PACKET AND EXIT PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER PUSHJ P,GETUDB ;GET THE UDB FOR THAT UNIT STOPCD MSCRBF##,DEBUG,UGA, ;++UDB GONE AWAY MOVE T1,P.CRF(P2) ;GET THE COMMAND REFERENCE NUMBER PUSHJ P,FNDDRB ;FIND THE DRB FOR THIS ONE STOPCD MSCRBF##,EVENT,CRM, ;++COMMAND REFERENCE NUMBER MISSING MOVE P3,T3 ;SAVE THE DRB ADDRESS SOMEWHERE SAFE LOAD T1,PKYEST,(P2) ;GET THE END STATUS JUMPE T1,RAXXF2 ;GO IF SUCCESSFUL TRANSFER CAIE T1,ST%AVL ;AVAILABLE? JRST RAXXF1 ;NO LDB T1,UNYPUN## ;GET THE PHYSICAL UNIT NUMBER PUSH P,T1 ;STUFF IT ON THE STACK PJRST RAXAVU ;FAKE LIKE THIS WAS AN AVAILABLE INTERRUPT RAXXF1: SETZ T2, ;GET A ZERO CAIN T1,ST%OFL ;OFFLINE? MOVEI T2,KOPOFL## ;YES CAIN T1,ST%WPR ;WRITE PROTECTED? MOVEI T2,KOPWLK## ;YES SKIPN T1,T2 ;ANYTHING? MOVEI T1,KOPDER## ;NO, CALL IT DEVICE ERROR IORM T1,DRBSTS##(P3) ;... JRST RAXXF3 ;PROCEED TO CALL FILSER RAXXF2: MOVE T2,P.STS(P2) ;GET THE STATUS WORD TXNN T2,EF.LOG ;ERROR LOG REQUEST? JUMPE T1,RAXXF3 ;JUMP IF NO ERRORS PUSHJ P,MSCRSW## ;PUT STATUS WORD BACK IN ORIGINAL ORDER MOVEI T1,CI%LEN ;LENGTH OF ERROR BLOCK PUSHJ P,ALCSEB## ;GRAB A SYSTEM ERROR BLOCK JRST RAXXF3 ;SORRY, WE TRIED MOVEI T2,SEC%CI ;GET THE CODE DPB T2,[POINT 9,.EBTYP(T1),8] ;STORE IN HEADER $LDCID T2,MSCCID##(P4) ;GET CONNECT BLOCK ADDRESS MOVE T2,.CBPBK(T2) ;GET THE PATH BLOCK ADDRESS LOAD T2,PBDPN,(T2) ;GET THE DESTINATION PORT (NODE) NUMBER MOVEM T2,.EBHDR+CI%NOD(T1) ;STORE MOVE T2,UNIHID##(U) ;GET VOLUME ID MOVEM T2,.EBHDR+CI%VID(T1) ;STUFF IT MOVE T2,UNIBRC##(U) ;COMPUTE TOTAL BLOCKS READ ADD T2,UNIDRC##(U) ;... ADD T2,UNIMRC##(U) ;... MOVEM T2,.EBHDR+CI%RED(T1) ;STUFF IT MOVE T2,UNIBWC##(U) ;COMPUTE TOTAL BLOCKS WRITTEN ADD T2,UNIDWC##(U) ;... ADD T2,UNIMWC##(U) ;... MOVEM T2,.EBHDR+CI%WRT(T1) ;STUFF IT ;CI%PS1, CI%PS2 MOVEI T2,P.TRBC-P.CRF+1 ;NUMBER OF WORDS TO MOVE XMOVEI T3,P.CRF(P2) ;SOURCE MOVEI T4,.EBHDR+CI%PAK(T1) ;DESTINATION EXTEND T2,[XBLT] ;MOVE THE DATA PUSHJ P,QUESEB## ;QUEUE THE BLOCK RAXXF3: PUSHJ P,MSCRBF## ;RETURN THE BUFFER MOVE T1,DRBOPC##(P3) ;GET SAVED OPERATION CODE CAIN T1,OP.RD ;READ? SKIPA T1,[OPRED] ;YES, GET CODE FOR FILSER MOVEI T1,OPWRT ;NO, GET WRITE CODE LDB T2,UNYPUN## ;GET THE PHYSICAL UNIT NUMBER HRL T1,T2 ;STUFF IN LEFT HALF OF T1 MOVEI T2,KOPDER## ;BIT TO TEST TDNE T2,DRBSTS##(P3) ;WAS THERE A HARD DATA ERROR? TRO T1,IODERR ;TELL FILINT ANDCAM T2,DRBSTS##(P3) ;MAKE SURE BIT IS OFF SETZ T2, ;CLEAR THE CONI WORD (NO USEFUL DATA) MOVE T3,P3 ;COPY DRB ADDRESS SETZ T4, ;NO ONE HAS POSITIONED S0JRST FLHTID## ;CALL FILSER AND RETURN SUBTTL DRIVER DISPATCH - PORT BROKE CONNECTION/CREDIT AVAILABLE RAXPBC: SETOM MSCCID##(P4) ;MAKE THE CONNECT ID LOOK INVALID SETZM MSCFLG##(P4) ;ALLOW RE-USE OF THIS CTI SLOT JUMPE J,CPOPJ## ;RETURN IF NO KDB SET UP YET HRRZ T1,J ;GET KDB ADDRESS ADD T1,.CPCPN## ;OFFSET BY OUR CPU NUMBER SETOM RAKCTI##(T1) ;MAKE SURE OUR CTI LOOKS INVALID SETZM RAKTIM##(T1) ;TURN OFF POLLING TIMER ALSO MOVE P1,.CPBIT## ;BIT FOR THIS CPU ANDCAM P1,KONCAM##(J) ;THIS CPU CAN NO LONGER SEE THIS KONTROLLER MOVSS P1 ;MOVE CPU BIT TO LH NOW MOVE P2,KONTBP##(J) ;GET AOBJN POINTER TO UNITS ON THIS KDB RAXPB1: SKIPE U,(P2) ;GET UDB ADDRESS TDNN P1,UNIALT##(U) ;IS THIS CPU ATTACHED TO THIS UNIT? JRST RAXPB2 ;NO UNIT OR THIS CPU NOT ATTACHED ANDCAM P1,UNIALT##(U) ;CLEAR THE BIT MOVSI T1,CPUMSK## ;MASK FOR ALL CPUS TDNN T1,UNIALT##(U) ;CAN ANY OTHER CPU SEE THIS UNIT? S0PSHJ FILDN## ;NO, TELL FILSER THIS UNIT IS DOWN, AND ; REQUEUE ALL ACTIVE DRBS FOR THE UNIT RAXPB2: AOBJN P2,RAXPB1 ;LOOP FOR OTHER UNITS POPJ P, ;RETURN RAXCIA: MOVSI T1,KOPCNA## ;TELL FILSER IT'S OK TO DO MORE I/O ANDCAM T1,KONCNA##(J) ;... POPJ P, ;RETURN SUBTTL DRIVER DISPATCH - CONNECTION RESPONSE AVAILABLE ;HERE WHEN A CONNECTION RESPONSE IS AVAILABLE. IF IT WAS ;ACCEPTED, BUILD A CHN AND KDB AND START LOOKING AT UNITS. ;CALL: ; T3/ -1 IF ACCEPTED, 0 IF REJECTED ; T4/ REJECTED REASON IF REJECTED ; P4/ CTI ; PUSHJ P,RAXCRA ;RETURN: ; CPOPJ ALWAYS RAXCRA: MOVX T1,DT.IRC ;INDICATE CONNECT DONE ANDCAM T1,MSCFLG##(P4) ;... JUMPN T3,MSCSCC## ;IF CONNECTION ACCEPTED GO SET UP CONTROLLER SETZM MSCFLG##(P4) ;CLEAR FLAGS (ALLOW CTI REUSE) POPJ P, ;RETURN ;HERE ON RETURN FROM SET CONTROLLER CHARACTERISTICS COMMAND RAXSCC: MOVE T1,P.CNTF(P2) ;GET THE CONTROLLER FLAGS FIELD PUSHJ P,REVFUL## ;REVERSE THE BYTES FROM THE HSC TXNN T1,CF.576 ;IS IT A 576-BYTE CONTROLLER? STOPCD MSCRBF##,NODUMP,KN5,DIEKN5 ;++KONTROLLER NOT IN 576-BYTE SECTOR MODE $LDCID T1,MSCCID##(P4) ;GET THE CB ADDRESS MOVE T1,.CBPBK(T1) ;GET THE PATH BLOCK ADDRESS LOAD P3,PBSBI,(T1) ;GET THE SYSTEM BLOCK INDEX LOAD T1,PBDPN,(T1) ;GET THE DESTINATION PORT (NODE) NUMBER SKIPE J,MSCDKA##-1(P3) ;IS THERE ALREADY A DISK KDB ADDRESS? JRST RAXSC1 ;YES S0PSHJ AUTHSC## ;BUILD A CHN AND KDB FOR THIS HSC PJRST MSCRBF## ;NO FREE CORE, RETURN MESSAGE AND RETURN MOVEM J,MSCDKA##-1(P3) ;STORE KDB ADDRESS FOR FUTURE REFERENCE SETOM RAKCTI##(J) ;MAKE ALL CONNECT ID'S LOOK INVALID MOVEI T1,5 ;NUMBER OF CPU'S MAXIMUM -1 XMOVEI T2,RAKCTI##(J) ;SOURCE XMOVEI T3,RAKCTI##+1(J) ;DESTINATION EXTEND T1,[XBLT] ;GET THEM ALL DMOVE T1,P.CNTI(P2) ;GET THE CONTROLLER ID FIELD DMOVEM T1,RAKCID##(J) ;STORE IN KDB JRST RAXSC2 ;CONTINUE RAXSC1: DMOVE T1,P.CNTI(P2) ;GET THE CONTROLLER ID FIELD CAMN T1,RAKCID##(J) ;SHOULD MATCH EXISTING VALUES CAME T2,RAKCID##+1(J) ;... STOPCD MSCRBF##,DEBUG,KIM, ;++KONTROLLER ID MISMATCH RAXSC2: MOVEM J,MSCKDB##(P4) ;STORE KDB ADDRESS IN TABLE INDEXED BY CTI HRRZ P1,J ;GET KDB ADDRESS ADD P1,.CPCPN## ;OFFSET BY OUR CPU NUMBER MOVEM P4,RAKCTI##(P1) ;SAVE THE CONNECT TABLE INDEX MOVE T1,P.CTMO(P2) ;GET KONTROLLLER TIMEOUT PUSHJ P,REVFUL## ;MAKE IT MEANINGFUL LDB T1,[POINT 8,T1,31] ;GET JUST THE LOW ORDER BYTE SUBI T1,2 ;MAKE SURE WE GET THERE BEFORE THE HSC DROPS US MOVEM T1,RAKTMO##(P1) ;... MOVEM T1,RAKTIM##(P1) ;SET INITIAL TIMER VALUE MOVE T1,.CPBIT## ;GET THE BIT FOR THIS CPU IORM T1,KONCAM##(J) ;I CAN SEE THIS KONTROLLER MOVX T1,DT.NXU ;SHOW THIS IS THE FIRST TIME IORM T1,MSCFLG##(P4) ; SO WE CAN HANDLE UNIT ZERO SETZ T1, ;GET A ZERO FOR UNIT NUMBER JRST MSCGNU## ;ASK FOR STATUS OF FIRST UNIT ;LOOP OVER ALL UNITS ON THIS HSC AND BUILD UDBS IF REQUIRED RAXGUL: POP P,T1 ;RESTORE CURRENT UNIT NUMBER AOJA T1,MSCGNU## ;INCREMENT UNIT NUMBER AND CHECK NEXT UNIT ;HERE ON RETURN FROM GET NEXT UNIT COMMAND RAXGNU: PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER FROM THE PACKET JUMPN T1,RAXGU1 ;GO IF UNIT NUMBER NON-ZERO LOAD T2,PKYEST,(P2) ;GET THE UNIT STATUS CAIN T3,ST%OFL ;CHECK FOR OFFLINE JRST MSCRBF## ;WE'RE NOT INTERESTED IF NO DRIVES MOVX T2,DT.NXU ;IS THIS THE FIRST TIME WE SAW A ZERO? TDNN T2,MSCFLG##(P4) ;... JRST MSCRBF## ;NO, THIS ZERO MEANT NO MORE UNITS RAXGU1: MOVX T2,DT.NXU ;SHOW WE'VE HANDLED UNIT ZERO IF IT EXISTS ANDCAM T2,MSCFLG##(P4) ;... PUSH P,T1 ;SAVE CURRENT UNIT NUMBER PUSHJ P,RAXPUS ;PROCESS THE UNIT STATUS JRST RAXGUL ;UNIT IS UNACCEPTABLE FOR SOME REASON SKIPN BNDFLG## ;HAVE WE CALLED ONCBND YET? JRST RAXGUL ;NO, JUST PROCEED TO NEXT UNIT HRRZ T1,UNIALT##(U) ;IS THERE AN ALTERNATE PORT? JUMPE T1,RAXGU2 ;NO, BIND THE UNIT TO THIS PORT MOVSI T2,CPUMSK## ;MASK FOR ALL CPUS TDNE T2,UNIALT##(T1) ;IS THE PORT ATTACHED ELSEWHERE? JRST RAXGUL ;YES, DON'T BIND THIS UNIT RAXGU2: POP P,T1 ;RESTORE CURRENT UNIT NUMBER MOVEI R,.RRONL ;RECALL CODE PJRST MSCUON## ;DO AN ONLINE FOR THIS UNIT SUBTTL DRIVER DISPATCH - RETURN FROM SET ONLINE COMMANDS ;HERE ON RETURN FROM SET ONLINE COMMAND RAXAON: MOVEI P1,1 ;SET P1 TO +1 JRST RAXUO1 ;JOIN COMMON CODE RAXOON: TDZA P1,P1 ;CLEAR P1 AND SKIP RAXUON: SETO P1, ;SET P1 TO -1 RAXUO1: PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER PUSH P,T1 ;SAVE CURRENT UNIT NUMBER PUSHJ P,GETUDB ;GET THE UDB ADDRESS STOPCD RAXUO4,DEBUG,UWA, ;++UDB WENT AWAY?! LOAD T1,PKYEST,(P2) ;GET THE END CODE JUMPE T1,RAXUO2 ;JUMP IF IT SUCCEEDED IFN FTMP,< CAIN T1,ST%CMD ;INVALID COMMAND? JRST RAXAV1 ;YES, ONE CPU BEAT US TO IT, ASK AGAIN >; END IFN FTMP CAIE T1,ST%OFL ;IT COULD FAIL WITH OFFLINE IF BOTH HSC'S ; TELL US ABOUT THE SAME UNIT SIMULTANEOUSLY CAIN T1,ST%MFE ;OR MEDIA FORMAT ERROR? JRST RAXUO4 ;CAN THIS RESPONSE AND IGNORE THE UNIT STOPCD RAXUO4,DEBUG,UOF,DIEUNI##, ;++UNIT ONLINE FAILED RAXUO2: MOVE T1,P.UNFL(P2) ;GET UNIT FLAGS PUSHJ P,REVFUL## ;REVERSE THE BYTES SKIPE DINITF## ;IN DISK ONCE-ONLY CODE? MOVEM T1,ONLFLG## ;YES, SAVE FLAGS FOR SUBSEQUENT ONLINE COMMANDS TXNN T1,UF.576 ;IS IT IN 576-BYTE SECTOR MODE? STOPCD RAXUO3,NODUMP,UN5,DIEUNI## ;++UNIT NOT IN 576-BYTE SECTOR MODE MOVSI T2,UNPHWP## ;GET HARDWARE WRITE PROTECT FLAG ANDCAM T2,UNIDES##(U) ;CLEAR IT FIRST TXNE T1,UF.WPH!UF.WPS ;UNIT WRITE LOCKED? IORM T2,UNIDES##(U) ;YES, SET THE FLAG MOVSI T1,UNPOFL##!UNPWMD## ;CLEAR OFFLINE BITS ANDCAM T1,UNIDES##(U) ;... MOVS T1,.CPBIT## ;BIT FOR THIS CPU IORM T1,UNIALT##(U) ;SHOW THIS PORT IS ATTACHED VIA THIS CPU MOVE T1,P.UNSZ(P2) ;GET UNIT SIZE PUSHJ P,REVFUL## ;MAKE IT SENSIBLE LSH T1,-4 ;RIGHT-JUSTIFY IT MOVEM T1,UNIBPU##(U) ;STORE THE VALUES IN THE UDB MOVEM T1,UNIBPM##(U) ;... MOVEM T1,UNIBUC##(U) ;... JUMPE P1,RAXUO4 ;ON TO NEXT UNIT IF ONCE ONLINE CALL PUSHJ P,GIVINT ;GIVE FILSER A FREE INTERRUPT FOR THIS UNIT IF NECESSARY JRST RAXUO4 ;PROCEED ;HERE TO SET UNIT OFFLINE IF WE DON'T LIKE IT RAXUO3: MOVE T1,(P) ;GET THE CURRENT UNIT NUMBER PUSHJ P,MSCUOF## ;SET IT OFFLINE (NO RECALL) RAXUO4: JUMPL P1,RAXGUL ;ON TO NEXT UNIT IF NOT ONCE BIND COMPLETE SKIPG P1 ;IF ONCE ONLINE COMPLETE, SETOM ONLDON## ; SHOW THE ONLINE COMPLETED ADJSP P,-1 ;CLEAN UP THE STACK PJRST MSCRBF## ;RETURN THE BUFFER AND RETURN SUBTTL DRIVER DISPATCH - UNSOLICITED UNIT AVAILABLE INTERRUPT ;HERE ON AN UNSOLICITED UNIT AVAILABLE INTERRUPT RAXAVA: PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER PUSH P,T1 ;SAVE THE UNIT NUMBER PUSHJ P,GETUDB ;GET THE ASSOCIATED UDB JRST RAXAV1 ;NONE, MUST BE FIRST TIME WE SAW THIS UNIT(?) RAXAVU: MOVSI T1,CPUMSK## ;CLEAR PORT ATTACHED BITS ANDCAM T1,UNIALT##(U) ; FOR ALL CPUS S0PSHJ FILDN## ;TELL FILSER THIS UNIT IS DOWN HRRZ U,UNIALT##(U) ;GET UDB FOR ALTERNATE UNIT JUMPE U,RAXAV1 ;JUMP IF NO ALTERNATE MOVSI T1,CPUMSK## ;CLEAR PORT ATTACHED BITS ANDCAM T1,UNIALT##(U) ; FOR ALL CPUS PUSH P,J ;SAVE J HRRZ J,UNIKON##(U) ;LOAD WITH CORRECT KDB S0PSHJ FILDN## ;TELL FILSER THIS UNIT IS DOWN POP P,J ;RESTORE J RAXAV1: POP P,T1 ;RESTORE THE UNIT NUMBER PJRST MSCGUS## ;ASK FOR UNIT STATUS ;HERE ON RETURN FROM GET UNIT STATUS COMMAND RAXGUS: PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER PUSH P,T1 ;SAVE THE UNIT NUMBER PUSHJ P,RAXPUS ;PROCESS THE UNIT STATUS JRST RAXGS2 ;NOT ACCEPTABLE, DON'T DO AN ONLINE SKIPN BNDFLG## ;HAVE WE CALLED RAXBND YET? JRST RAXGS2 ;NO (STRANGE), DON'T BIND THE UNIT YET HRRZ T1,UNIALT##(U) ;GET ALTERNATE UDB ADDRESS JUMPE T1,RAXGS1 ;JUMP IF NO ALTERNATE MOVSI T2,CPUMSK## ;MASK FOR ALL CPUS ANDCAM T2,UNIALT##(T1) ;OBVIOUSLY NO LONGER ATTACHED HERE RAXGS1: POP P,T1 ;RESTORE CURRENT UNIT NUMBER MOVEI R,.RRAON ;RECALL CODE PJRST MSCUON## ;DO AN ONLINE FOR THIS UNIT RAXGS2: ADJSP P,-1 ;CLEAN UP THE STACK PJRST MSCRBF## ;RETURN THE BUFFER AND RETURN SUBTTL UNIT STATUS PROCESSING ;ROUTINE CALLED AFTER A CHECK UNIT STATUS (GET UNIT STATUS FROM ONCMOD). ;CALL: ; P2/ PACKET ADDRESS ; PUSHJ P,RAXCUS ;RETURN: ; CPOPJ ALWAYS RAXCUS: SETZM ONLFLG## ;CLEAR THIS IN CASE ERROR PUSHJ P,MSCGUN## ;GET THE UNIT NUMBER PUSHJ P,GETUDB ;GET THE UDB ADDRESS JRST RAXCU1 ;RATHER ODD MOVE T1,P.UNFL(P2) ;GET UNIT FLAGS PUSHJ P,REVFUL## ;REVERSE BYTES MOVEM T1,ONLFLG## ;SAVE FOR ONCMOD RAXCU1: SETOM ONLDON## ;SHOW THE COMMAND COMPLETED PJRST MSCRBF## ;RETURN PACKET AND RETURN SUBTTL PROCESS UNIT STATUS ;ROUTINE CALLED AFTER A GET NEXT UNIT OR GET UNIT STATUS COMMAND. ;CREATE A UDB IF REQUIRED AND FILL IN THE UDB DATA. ;CALL: ; T1/ UNIT NUMBER (ALA HSC) ; P2/ PACKET ADDRESS ; J/ KDB ADDRESS ; PUSHJ P,RAXPUS ;RETURN: ; CPOPJ IF UNIT IS NOT USABLE (OFFLINE/NO PACK MOUNTED) ; CPOPJ1 IF UNIT MAY BE USED WITH: ; T1/ UNIT STATUS,,REASON FOR OFFLINE ;P1 AND P3 ARE USABLE BY THIS ROUTINE. RAXPUS: PUSH P,T1 ;SAVE THE UNIT NUMBER FOR LATER REFERENCE PUSHJ P,GETUDB ;DOES THIS UNIT ALREADY EXIST? JRST RAXPU3 ;NO ADJSP P,-1 ;CLEAN OFF THE STACK MOVS T1,.CPBIT## ;BIT FOR THIS CPU ANDCAM T1,UNIALT##(U) ;WE NO LONGER HAVE IT ATTACHED ;CHECK FOR CONSISTANCY OF SERIAL NUMBERS, ETC. LOAD T1,PKYEST,(P2) ;GET STATE OF UNIT MOVS P1,T1 ;SAVE FOR RETURN TO CALLER CAIE T1,ST%OFL ;OFFLINE? JRST RAXPU1 ;NO LOAD T1,PKYQSB,(P2) ;YES, GET REASON FOR OFFLINE HRR P1,T1 ;SAVE FOR RETURN TO CALLER CAIE T1,SB%NVM ;NO VOLUME MOUNTED? POPJ P, ;UNIT IS NO GOOD, FORGET ABOUT IT JRST RAXPU2 ;GO CHECK CONSISTANCY RAXPU1: CAIE T1,ST%AVL ;UNIT ISN'T OFFLINE, IS IT AVAILABLE? JUMPN T1,CPOPJ## ;NOT AVAILABLE, IF NOT ONLINE THEN NOT USABLE RAXPU2: MOVE T1,P.UNTI(P2) ;GET THE UNIT ID PUSHJ P,REVFUL## ;MAKE IT SOMEWHAT REASONABLE LSH T1,-4 ;RIGHT-JUSTIFY IT CAME T1,UNISER##(U) ;MATCH? POPJ P, ;NO, UNIT IS NOT USABLE MOVE T1,P.UNTI+1(P2) ;GET THE UNIT ID SECOND WORD PUSHJ P,REVFUL## ;MAKE IT SOMEWHAT REASONABLE LSH T1,-4 ;RIGHT-JUSTIFY IT CAME T1,UNISER##+1(U) ;MATCH? POPJ P, ;NO, UNIT IS NOT USABLE JRST RAXPU7 ;SKIP RETURN ;HERE IF THIS IS A BRAND NEW UNIT RAXPU3: SKIPGE P3,T1 ;WAS THERE A FREE SLOT FOR THIS UNIT? JRST TPOPJ## ;NO, FORGET ABOUT THIS UNIT LOAD T1,PKYEST,(P2) ;GET STATE OF UNIT MOVS P1,T1 ;SAVE FOR RETURN TO CALLER CAIE T1,ST%OFL ;OFFLINE? JRST RAXPU4 ;NO LOAD T1,PKYQSB,(P2) ;YES, GET REASON FOR OFFLINE HRR P1,T1 ;SAVE FOR RETURN TO CALLER CAIE T1,SB%NVM ;NO VOLUME MOUNTED? JRST TPOPJ## ;UNIT IS NO GOOD, FORGET ABOUT IT JRST RAXPU5 ;SEE IF WE KNOW ABOUT THIS TYPE OF UNIT RAXPU4: CAIE T1,ST%AVL ;UNIT ISN'T OFFLINE, IS IT AVAILABLE? JUMPN T1,TPOPJ## ;NOT AVAILABLE, IF NOT ONLINE THEN NOT USABLE RAXPU5: MOVE T1,P.MEDI(P2) ;GET THE MEDIA TYPE WORD PUSHJ P,REVFUL## ;REVERSE IT SO IT MAKES SENSE PUSHJ P,UNTYPE ;DETERMINE IF WE KNOW ABOUT THIS TYPE OF UNIT JRST TPOPJ## ;NO, FORGET ABOUT THIS UNIT $LDCID T2,MSCCID##(P4) ;GET CONNECTION BLOCK ADDRESS MOVE T2,.CBPBK(T2) ;GET THE PATH BLOCK ADDRESS LOAD T2,PBDPN,(T2) ;GET THE CI NODE NUMBER ADDI T2,1 ;MAKE IT 1-BASED MOVEM T2,NUMRAA## ;TELL AUTCON THE NAME OF THIS UNIT POP P,T2 ;GET THE PHYSICAL UNIT NUMBER (LAP PLUG NUMBER) HRL T2,P3 ;GET THE UNIT NUMBER TO USE ("KONTAB" INDEX) S0PSHJ NEWDSK## ;CALL AUTCON (IN SECTION ZERO) JUMPE U,CPOPJ## ;IN CASE AUTCON WIMPED OUT ON US RAXPU6: MOVE T1,P.UNTI(P2) ;GET THE UNIT ID PUSHJ P,REVFUL## ;MAKE IT SOMEWHAT REASONABLE LSH T1,-4 ;RIGHT-JUSTIFY IT MOVEM T1,UNISER##(U) ;SAVE IN UDB MOVE T1,P.UNTI+1(P2) ;GET THE UNIT ID SECOND WORD PUSHJ P,REVFUL## ;MAKE IT SOMEWHAT REASONABLE LSH T1,-4 ;RIGHT-JUSTIFY IT MOVEM T1,UNISER##+1(U) ;SAVE IN UDB MOVE T1,P.TRCK(P2) ;GET TRACK/GROUP SIZE WORD PUSHJ P,REVFUL## ;MAKE IT SENSIBLE LDB T2,[POINT 16,T1,15] ;GET THE GROUP SIZE IN TRACKS LDB T1,[POINT 16,T1,31] ;GET THE TRACK SIZE IN SECTORS IMUL T2,T1 ;CONVERT THE GROUP SIZE TO SECTORS AND SAVE IN T2 DPB T1,UNYBPT## ;STORE BLOCKS/TRACK (= BLOCKS/SECTOR) IN UDB MOVE T1,P.CYL(P2) ;GET CYLINDER SIZE WORD PUSHJ P,REVFUL## ;MAKE IT SENSIBLE LSH T1,-4 ;RIGHT-JUSTIFY IT ANDI T1,177777 ;KEEP JUST 16 BITS WORTH IMUL T1,T2 ;CYLINDER SIZE IN GROUPS TIMES GROUP SIZE IN SECTORS ; GIVES CYLINDER SIZE IN SECTORS (BLOCKS) DPB T1,UNYBPY## ;STORE IN UDB S0PSHJ MATUN## ;CHECK FOR SERIAL NUMBER MATCH, SET UP UNIALT JFCL ;SHOULD NEVER SKIP RETURN RAXPU7: MOVE T1,P1 ;RETURN STATUS IN T1 AS ADVERTISED JRST CPOPJ1## ;SKIP RETURN SUBTTL MISCELLANEOUS ROUTINES ;ROUTINE TO RETURN THE DRB ADDRESS FOR A COMMAND REFERENCE NUMBER. ;CALL: ; T1/ COMMAND REFERENCE NUMBER ; J/ KDB ADDRESS ; PUSHJ P,FNDDRB ;RETURN: ; CPOPJ IF NO MATCHING DRB ; CPOPJ1 IF MATCHING DRB WITH: ; T3/ DRB ADDRESS FNDDRB: MOVEI T3,ACTDRB##-DRBLNK## ;PRESET PREDECESSOR FNDDR1: HRRZ T3,DRBLNK##(T3) ;GET LINK TO NEXT DRB CAIN T3,ACTDRB##-DRBLNK## ;BACK TO BEGINNING? POPJ P, ;YES, NOT FOUND CAME T1,DRBCRF##(T3) ;COMMAND REFERENCE NUMBER MATCH? JRST FNDDR1 ;NO, KEEP LOOKING JRST CPOPJ1## ;YES, SKIP RETURN ;ROUTINE CALLED ON KN5 STOPCODE FROM DIE TO PRINT INFORMATION. ;CALL: ; PUSHJ P,DIEKN5 ;RETURN: ; CPOPJ ALWAYS DIEKN5: PUSHJ P,INLMES## ;START THE MESSAGE ASCIZ /CI node / $LDCID T1,MSCCID##(P4) ;GET THE CB ADDRESS MOVE T1,.CBPBK(T1) ;GET THE PATH BLOCK ADDRESS LOAD T1,PBDPN,(T1) ;GET THE DESTINATION NODE PUSHJ P,RADX10## ;PRINT CI NODE NUMBER PJSP T1,CONMES## ;MORE STUFF AND RETURN ASCIZ / set to 512-byte sector mode - controller ignored/ ;ROUTINE TO RETURN THE UDB ADDRESS FOR A PARTICULAR UNIT. ;CALL: ; T1/ ONE-BASED UNIT NUMBER (ALA HSC) ; J/ KDB ADDRESS ; PUSHJ P,GETUDB ;RETURN: ; CPOPJ IF NO SUCH UNIT WITH: ; T1/ PHYSICAL UNIT SLOT IN KONTAB TO USE OR -1 ; IF NO FREE SLOT FOR UNIT ; CPOPJ1 IF UNIT EXISTS WITH: ; U/ UDB ADDRESS GETUDB: MOVE T2,KONTBP##(J) ;GET AOBJN POINTER TO KONTAB FOR THIS KDB SETZ T3, ;HAVEN'T FOUND A FREE SLOT YET GETUD1: SKIPN U,0(T2) ;GET A UDB ADDRESS JRST GETUD2 ;NONE HERE LDB T4,UNYPUN## ;GET PHYSICAL UNIT NUMBER CAMN T1,T4 ;NUMBERS MATCH? JRST CPOPJ1## ;YES, SKIP RETURN JRST GETUD3 ;NO, BUT THERE WAS A UDB, SKIP A TEST GETUD2: SKIPN T3 ;ALREADY FOUND A FREE SLOT? MOVE T3,T2 ;NO, SAVE POINTER TO IT GETUD3: AOBJN T2,GETUD1 ;LOOP FOR ALL UNITS SKIPN T1,T3 ;DID WE FIND A FREE SLOT? JRST [SETO T1, ;NO, RETURN MINUS ONE POPJ P,] ;RETURN HRRZS T1 ;ISOLATE OFFSET FROM START OF RAKNTB HRRZ T2,KONTBP##(J) ;GET START OF RAKNTB SUB T1,T2 ;CALCULATE A PHYSICAL UNIT NUMBER TO USE POPJ P, ;RETURN ;ROUTINE TO GIVE FILSER A FREE INTERRUPT WHEN A DRIVE COMES ONLINE. ;CALL: ; U/ UDB ADDRESS FOR ONLINE UNIT ; PUSHJ P,GIVINT ;RETURN: ; CPOPJ ALWAYS GIVINT: HLRZ T1,UNIALT##(U) ;ANY OTHER CPU'S HAVE THIS UNIT ATTACHED? CAME T1,.CPBIT## ;... POPJ P, ;YES, NO NEED FOR FREE INTERRUPT PUSH P,U ;SAVE UDB ADDRESS PUSH P,J ;SAVE KDB ADDRESS S0PSHJ FLPUDB## ;TAKE OVER FROM THE ALTERNATE PORT MOVE U,-1(P) ;GET BACK UDB ADDRESS S0PSHJ ATTUDB ;CALL UNIT ATTACH CODE IN FILIO MOVE J,(P) ;GET BACK KDB ADDRESS MOVE U,-1(P) ;GET BACK UDB ADDRESS SKIPN UNILOG##(U) ;PACK MOUNTED? JRST JUPOPJ ;NO, GALAXY READ HOME BLOCKS UPON ATTACH MOVEI T1,OPPOS ;GET POSITION INTERRUPT CODE FOR FILSER LDB T2,UNYPUN## ;GET PHYSICAL UNIT NUMBER HRL T1,T2 ;STUFF IN LEFT HALF OF T1 SETZB T2,T3 ;NO CONI OR DRB LDB T4,UNYKOF## ;GET KONTAB OFFSET MOVE T4,BITTBL##(T4) ;GET THE APPROPRIATE BIT FOR THIS UNIT S0PSHJ FLHTID## ;GIVE FILSER THE POSITION INTERRUPT JUPOPJ: POP P,J ;RESTORE KDB ADDRESS JRST UPOPJ## ;RESTORE UDB ADDRESS AND RETURN ;ROUTINE TO CALL ATTCPD IN FILIO. ATTCPD MUST BE CALLED IN SECTION ;ZERO AND WE CAN'T USE S0PSHJ DIRECTLY BECAUSE SSEC0 DOESN'T SUPPORT ;THE CPOPJ2 RETURN. ;CALL: ; U/ UDB ADDRESS ; PUSHJ P,ATTUDB ;RETURN: ; CPOPJ ALWAYS ATTUDB: PUSHJ P,ATTCPD## ;CALL FILIO POPJ P, ;UNIT NOT DOWN, WE DON'T CARE PUSHJ P,RAXDIE ;KONTROLLER BUSY, SHOULD NEVER HAPPEN POPJ P, ;UNIT IS ATTACHED ;ROUTINE TO RETURN A DRIVE TYPE CODE FOR AUTCON BASED ON THE ;MEDIA TYPE RETURNED IN THE GET UNIT STATUS PACKET. ;CALL: ; T1/ MEDIA TYPE WORD ; PUSHJ P,UNTYPE ;RETURN: ; CPOPJ IF NO MATCH ; CPOPJ IF MEDIA TYPE FOUND WITH: ; T1/ DRIVE TYPE CODE UNTYPE: MOVSI T2,-UNTYPL ;-VE LENGTH OF TABLE CAME T1,UNTYPT(T2) ;FIND A MATCH? AOBJN T2,.-1 ;NO, KEEP LOOKING JUMPGE T2,CPOPJ## ;RETURN IF NO MATCH MOVE T1,UNTYPD(T2) ;GET THE DRIVE TYPE CODE JRST CPOPJ1## ;SKIP RETURN UNTYPT: BYTE (16) 022544,010120 ;RA80 BYTE (16) 022544,010121 ;RA81 BYTE (16) 021244,010074 ;RA60 UNTYPL==.-UNTYPT ;LENGTH OF TABLE UNTYPD: EXP TY.R80## ;DRIVE TYPE CODES RETURNED TO AUTCON EXP TY.R81## ;... EXP TY.R60## ;... SUBTTL DRIVER DISPATCH - NODE ONLINE ;HERE WHEN A NODE HAS COME ONLINE, EITHER FOR THE FIRST TIME OR ;AFTER IT HAS DROPPED OFF-LINE. ;CALL: ; T2/ PBI ; PUSHJ P,RAXONL ;RETURN: ; CPOPJ ALWAYS RAXONL: MOVE P2,T2 ;COPY PBI TO SOMEWHERE SAFE BLCAL. (SC.RPB##,) ;READ THE CONFIGURATION DATA FOR THIS NODE POPJ P, ;CAN'T DO IT, IGNORE THE ONLINE LDB T2,[POINT PKSID,.RPDPC(T1),PKPID] ;GET TYPE OF NODE PUSH P,T2 ;SAVE IT A MOMENT MOVE T2,T1 ;COPY ADDRESS TO PROPER AC MOVEI T1,.RPLEN ;LENGTH OF BLOCK PUSHJ P,GIVSWS## ;RETURN THE BLOCK TO THE FREE POOL POP P,T1 ;RESTORE NODE TYPE CAIE T1,ID.HSC ;IS IT AN HSC? POPJ P, ;NO, DON'T CONNECT TO IT PUSHJ P,MSCGCI## ;GET A CONNECT TABLE INDEX POPJ P, ;NONE AVAILABLE, IGNORE THE ONLINE HRRZ P4,T1 ;SAVE THE CTI IN A PERMANENT AC XMOVEI T1,RAXDDT ;GET ADDRESS OF DRIVER DISPATCH TABLE MOVEM T1,MSCDDT##(P4) ;STORE FOR MSCCOM MOVX T1,DT.IRC ;INDICATE WE ARE RELOADING IORM T1,MSCFLG##(P4) ;... BLCAL. (SC.CON##,<<.,OURDNM>,<.,YURDNM>,P2,[DCREDT],[DCREDT],<.,MSCINT##>,P4,[0],[HSCBFN],[DGNUM]>) STOPCD CPOPJ##,DEBUG,CSF, ;++CONNECT TO MSCP SERVER FAILED POPJ P, ;RETURN AND WAIT FOR CONNECT RESPONSE SUBTTL THE END RAXDIE::STOPCD .,STOP,RAX, ;++ RAXKON IS MISERABLE RAXEND::!END