Specifications
Sample Driver Written in C
B.1 LRDRIVER Example
*
* Environment:
*
* Kernel mode, system context, device IPL, device lock held.
*/
static int lr$send_char_dev (LR_UCB *ucb) {
int device_data; /* Data from or for CRAM */
char *sys_datap; /* Pointer to next byte in buffer packet */
/* Set the Port Control Register.
* Set the INIT_OFF bit to disable the "INIT" signal. Set the IRQ_EN bit
* to enable interrupts. Assure that the STROBE bit is clear so that we
* can cause a 0-to-1 transition after loading the data register. Assure
* that the DIR_READ bit is clear since we are doing writes to the data
* register. Note byte-lane shift if ISA option.
*/
if (ucb->ucb$l_lr_combo)
device_data = LPC_M_INIT_OFF | LPC_M_IRQ_EN;
else
device_data = (LPC_M_INIT_OFF | LPC_M_IRQ_EN) << 16;
ucb->ucb$ps_cram_lcw->cram$q_wdata = device_data;
ioc$cram_io (ucb->ucb$ps_cram_lcw);
/* Read the port status register. Note byte-lane shift if ISA option. */
ioc$cram_io (ucb->ucb$ps_cram_lps);
device_data = ucb->ucb$ps_cram_lps->cram$q_rdata;
if ( ! ucb->ucb$l_lr_combo) device_data >>= 8;
/* If the device is not ready to accept a character, then do not attempt
* to send it. Return an error status.
*/
if ( ((LPS *) &device_data)->lps_paperout || /* paper out */
! ((LPS *) &device_data)->lps_ok || /* not ok, i.e. error */
! ((LPS *) &device_data)->lps_online || /* not online */
! ((LPS *) &device_data)->lps_ready ) /* not ready */
return SS$_DEVOFFLINE;
/* The device is ready. Load the data byte. Update ucb$l_svapte to
* point to the next byte and decrement the count of bytes lef in
* ucb$l_bcnt. Note that no byte-lane shift is necessary for this register.
*/
sys_datap = (char *) ucb->ucb$r_ucb.ucb$l_svapte;
device_data = *sys_datap++;
ucb->ucb$r_ucb.ucb$l_svapte = (void *) sys_datap;
ucb->ucb$r_ucb.ucb$l_bcnt--;
ucb->ucb$ps_cram_lwd->cram$q_wdata = device_data;
ioc$cram_io (ucb->ucb$ps_cram_lwd);
/* Latch the data byte to the printer.
* Set the STROBE bit in the port control register to latch the data to
* the printer. INIT_OFF and IRQ_EN were set earlier and are kept set.
* DIR_READ is kept clear. Note byte-lane shift if ISA option.
*/
if (ucb->ucb$l_lr_combo)
device_data = LPC_M_INIT_OFF | LPC_M_IRQ_EN | LPC_M_STROBE;
else
device_data = (LPC_M_INIT_OFF | LPC_M_IRQ_EN | LPC_M_STROBE) << 16;
ucb->ucb$ps_cram_lcw->cram$q_wdata = device_data;
ioc$cram_io (ucb->ucb$ps_cram_lcw);
/* Data byte sent. Return success. */
return SS$_NORMAL;
}
B–17










