Specifications
Sample Driver Written in C
B.1 LRDRIVER Example
/* If this is not a "pass all" request, then interpret the $QIO P4
* carriage control parameter. Adjust the required system buffer packet
* size by the prefix and suffix counts plus room of data expansion.
* Currently, the only expansion possible is an extra CR in the prefix
* and suffix characters if "new line" was specified.
*/
if ( ! pass_all ) {
irp->irp$l_iost2 = irp->irp$l_qio_p4;
exe_std$carriage (irp);
sys_buflen += ((CARCON *) &irp->irp$b_carcon)->prefix_count +
((CARCON *) &irp->irp$b_carcon)->suffix_count +
DATA_EXPND_CUSHION;
}
/* Allocate a system buffer for the data in the user buffer. If this
* fails then abort the I/O request and return back to the FDT dispatcher
* in the $QIO system service. Otherwise, set irp$l_svapte to point to
* the packet, irp$l_boff to contain the number of bytes charged, and
* sys_datap to point to the first free data byte in the buffer packet.
*/
status = exe_std$debit_bytcnt_alo (sys_buflen, pcb,
&sys_buflen, (void **) &sys_bufp);
if ( ! $VMS_STATUS_SUCCESS(status) ) {
return ( call_abortio (irp, pcb, (UCB *)ucb, status) );
}
irp->irp$l_svapte = (void *) sys_bufp;
irp->irp$l_boff = sys_buflen;
sys_datap = (char *) sys_bufp + sizeof(SYSBUF_HDR);
/* If this is a "pass all" request, then simply copy the user supplied
* data into the system buffer. Otherwise, process prefix and postfix
* carriage control in addition to the user buffer data.
*/
if ( pass_all ) {
memcpy (sys_datap, qio_bufp, qio_buflen);
irp->irp$l_bcnt = qio_buflen;
} else {
char carcon_char;
int carcon_count;
irp->irp$l_bcnt = 0;
/* Expand the prefix carriage control into the allocated system
* buffer. If the carriage control count is non-zero and the
* carriage control character is 0, this means "new line." Output
* an initial CR, then the counted number of LFs.
*/
carcon_count = ((CARCON *) &irp->irp$b_carcon)->prefix_count;
if (carcon_count != 0) {
carcon_char = ((CARCON *) &irp->irp$b_carcon)->prefix_char;
if (carcon_char == 0) {
*sys_datap++ = CR;
irp->irp$l_bcnt++;
carcon_char = LF;
}
irp->irp$l_bcnt += carcon_count;
for ( ; carcon_count > 0 ; carcon_count--) {
*sys_datap++ = carcon_char;
}
}
/* Copy the user data into the system buffer */
memcpy (sys_datap, qio_bufp, qio_buflen);
irp->irp$l_bcnt += qio_buflen;
sys_datap += qio_buflen;
B–14










