/* * lun.c */ /*)LIBRARY */ #ifdef DOCUMENTATION title lun LUN usage for RSX index Lun usage for RSX description These routines where developed because of the need to access devices directly through QIO's under DECUS 'C. The problem at the time, was that we wished to access graphics terminals under 'C, without opening the device as a file [fopen()], because of the large DECUS 'C buffer overheads (I'ts a waste of memory to allocate buffers etc, when you're only accessing the device through a LUN). One solution is to select an arbitory LUN (using magic number generation program), and use this as a constant in the program. The problems with this are : a) Depending upon the program, the 'C run-time library may allocat that same lun to a file you open !! b) Many modules using the same allocation scheme used in the same program, could have conflicting LUNs, and might be hard to get working together, if lun schems don't line up. The obvious solution is to allocate the lun to use from the run-time library's table. Easy solution ? I thought so, so I started reading through code !!! Starting with fopen(), and then going through code for lots of associated modules, I eventually came accross the wanted table. While working out how this table worked ,I descoverd that the number of luns is hard-wired to 20 luns only (another symptom of RSTS). To get the full 32 LUNs available to RSX, You would have to re-build the module [5,5]IOV.MAC, with $$lmax as the new lun table size. Also I found that the lun table for rsx starts at LUN 2, So that stderr is kept from harm to get at this, access it as lun 1. (C run-time librarys won't let you access it). #endif #include "lun.h" /* LUNOPN * Open and assign a device on a LUN, This by-passes the 'C bufferd IO system * therfore not assigning any FILE type structures. The LUN is marked as * used in the LUN table however, so as not to stir up the 'C environment * Returns 0 on error or LUN number * If an error occurs, the lun will be de-allocated */ int lunopn(device) char *device; /* device name to open xxn */ { int devnam; /* 2 character device name */ int devnum; /* device unit number */ int lun; /* lun that we're allocated */ /* Find a LUN to use */ if(!(lun=alolun())) return(0); /* return 0 if no luns left */ /* split up the name into it's componant peices */ if (isalpha(*device) && isalpha(*(device+1))) { devnam=amapiu(device); devnum=atoi(device+2); /* now assign the lun */ if(alun(lun,devnam,devnum)==IS_SUC) { /* we may now need attach to the device */ if(qiow(IO_ATT,lun,LUNEFN,0,0,0) == IS_SUC) { return(lun); } } } /* there's a problem, so de-allocate the lun */ dealun(lun); /* return error code */ return(0); } /* LUNCLS * Close a device opened by lunopn() * returns 0 if successfull or -1 if problem encounted * */ luncls(lun) int lun; /* LUN to close */ { /* detach the lun */ if (qiow(IO_DET,lun,LUNEFN,0,0,0)==IS_SUC) { /* de-allocate the lun */ if(!dealun(lun)) { /* return success code */ return(0); } } /* problem, so return error code */ return(-1); } /* ALOLUN * Find a free LUN in the lun table, and allocate it * Returns the LUN number or 0 on error */ alolun() { int *ltp; /* pointer to lun table */ int lun; /* lun we've got */ int n; /* lun's left to look at */ ltp=$$luns; /* point at lun table */ n=$$nlun; /* how many we're alowed to look at */ /* find a free LUN */ for(lun=2 ; ((n--)&&(ltp!=$$lune)&&(*(ltp))) ; lun++) { ltp++; } /* if there's a free LUN */ if(!(*ltp)) { /* assign lun ... point to srderr for inquisitive people */ *ltp=stderr; /* return the LUn to the caller */ return(lun); } else { return(0); } } /* DEALUN * De-allocate the specified lun, returning it to the LUN table * Returns 0 on OK or -1 on error * */ dealun(lun) int lun; /* lun to de-allocate */ { /* if lun is valid, then de-allocate it and return 0 else return -1 */ if (lun<=$$nlun) { *($$luns+(lun-2))=0; return(0); } return(-1); }