root/kernel/chr_drv/lp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lp_reset
  2. lp_init
  3. lp_char
  4. lp_write

   1 /*
   2  $Header: /usr/src/linux/kernel/chr_drv/lp.c,v 1.9 1992/01/06 16:11:19
   3   james_r_wiegand Exp james_r_wiegand $
   4 */
   5 
   6 #define __LP_C__
   7 #include <linux/lp.h>
   8 
   9 #include <checkpoint.h>
  10 
  11 int lp_reset(int minor)
     /* [previous][next][first][last][top][bottom][index][help] */
  12 {
  13         int testvalue;
  14 
  15         /* reset value */
  16         outb(0, LP_B(minor)+2);
  17         for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
  18                 ;
  19         outb(LP_PSELECP | LP_PINITP, LP_B(minor)+2);
  20         return LP_S(minor);
  21 }
  22 
  23 void lp_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  24 {
  25         int offset = 0;
  26         unsigned int testvalue = 0;
  27         int count = 0;
  28 
  29         /* take on all known port values */
  30         for (offset = 0; offset < LP_NO; offset++) {
  31                 /* write to port & read back to check */
  32                 outb( LP_DUMMY, LP_B(offset));
  33                 for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
  34                         ;
  35                 testvalue = inb(LP_B(offset));
  36                 if (testvalue != 255) {
  37                         LP_F(offset) |= LP_EXIST;
  38                         lp_reset(offset);
  39                         printk("lp_init: lp%d exists (%d)\n", offset, testvalue);
  40                         count++;
  41                 }
  42         }
  43         if (count == 0)
  44                 printk("lp_init: no lp devices found\n");
  45 }
  46 
  47 int lp_char(char lpchar, int minor)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         int retval = 0;
  50         unsigned long count  = 0; 
  51 
  52         outb(lpchar, LP_B(minor));
  53         do {
  54                 retval = LP_S(minor);
  55                 schedule(); 
  56                 count ++;
  57         } while(!(retval & LP_PBUSY) && count < LP_TIMEOUT);
  58         if (count == LP_TIMEOUT) {
  59                 printk("lp%d timeout\n\r", minor);
  60                 return 0;
  61         }
  62   /* control port pr_table[0]+2 take strobe high */
  63         outb(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_B( minor ) + 2 ));
  64   /* take strobe low */
  65         outb(( LP_PSELECP | LP_PINITP ), ( LP_B( minor ) + 2 ));
  66   /* get something meaningful for return value */
  67         return LP_S(minor);
  68 }
  69 
  70 int lp_write(unsigned minor, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         int  retval;
  73         int  loop;
  74         int  tcount;
  75         char c, *temp = buf;
  76 
  77         if (minor > LP_NO - 1)
  78                 return -ENODEV;
  79         if ((LP_F(minor) & LP_EXIST) == 0)
  80                 return -ENODEV;
  81 
  82 /* if we aren't the "owner task", check if the old owner has died... */
  83         if (LP_T(minor) != current->pid && (LP_F(minor) & LP_BUSY)) {
  84                 for(tcount = 0; tcount < NR_TASKS; tcount++) { 
  85                         if (!task[tcount])
  86                                 continue;
  87                         if (task[tcount]->state == TASK_ZOMBIE)
  88                                 continue;
  89                         if (task[tcount]->pid == LP_T(minor)) {
  90                                 tcount = -1;
  91                                 break;
  92                         }
  93                 }
  94                 if (tcount == -1)
  95                         return -EBUSY;
  96         }
  97 
  98         LP_T(minor) = current->pid;
  99         LP_F(minor) |= LP_BUSY;
 100         LP_R(minor) = count;
 101         temp = buf;
 102 
 103         for (loop = 0 ; loop < count ; loop++, temp++) {
 104                 c = get_fs_byte(temp);
 105                 retval = lp_char(c, minor);
 106                 LP_R(minor)--;
 107                 if (retval & LP_POUTPA) {
 108                         LP_F(minor) |= LP_NOPA;
 109                         return loop?loop:-ENOSPC;
 110                 } else
 111                         LP_F(minor) &= ~LP_NOPA;
 112 
 113                 if (!(retval & LP_PSELECD)) {
 114                         LP_F(minor) &= ~LP_SELEC;
 115                         return loop?loop:-EFAULT;
 116                 } else
 117                         LP_F(minor) &= ~LP_SELEC;
 118 
 119     /* not offline or out of paper. on fire? */
 120                 if (!(retval & LP_PERRORP)) {
 121                         LP_F(minor) |= LP_ERR;
 122                         return loop?loop:-EIO;
 123                 } else
 124                         LP_F(minor) &= ~LP_SELEC;
 125         }
 126         return count;
 127 }

/* [previous][next][first][last][top][bottom][index][help] */