This source file includes following definitions.
- lp_reset
- lp_char
- lp_write
- lp_read
- lp_lseek
- lp_open
- lp_release
- lp_init
1
2
3
4
5
6
7
8
9
10
11 #include <linux/sched.h>
12 #define __LP_C__
13 #include <linux/lp.h>
14
15 static int lp_reset(int minor)
16 {
17 int testvalue;
18
19
20 outb(0, LP_B(minor)+2);
21 for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
22 ;
23 outb(LP_PSELECP | LP_PINITP, LP_B(minor)+2);
24 return LP_S(minor);
25 }
26
27 static int lp_char(char lpchar, int minor)
28 {
29 int retval = 0;
30 unsigned long count = 0;
31
32 outb(lpchar, LP_B(minor));
33 do {
34 retval = LP_S(minor);
35 schedule();
36 count ++;
37 } while(!(retval & LP_PBUSY) && count < LP_TIMEOUT);
38 if (count == LP_TIMEOUT) {
39 printk("lp%d timeout\n\r", minor);
40 return 0;
41 }
42
43 outb(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_B( minor ) + 2 ));
44
45 outb(( LP_PSELECP | LP_PINITP ), ( LP_B( minor ) + 2 ));
46
47 return LP_S(minor);
48 }
49
50 static int lp_write(struct inode * inode, struct file * file, char * buf, int count)
51 {
52 int retval;
53 unsigned int minor = MINOR(inode->i_rdev);
54 char c, *temp = buf;
55
56 temp = buf;
57 while (count > 0) {
58 c = get_fs_byte(temp++);
59 retval = lp_char(c, minor);
60 count--;
61 if (retval & LP_POUTPA) {
62 LP_F(minor) |= LP_NOPA;
63 return temp-buf?temp-buf:-ENOSPC;
64 } else
65 LP_F(minor) &= ~LP_NOPA;
66
67 if (!(retval & LP_PSELECD)) {
68 LP_F(minor) &= ~LP_SELEC;
69 return temp-buf?temp-buf:-EFAULT;
70 } else
71 LP_F(minor) &= ~LP_SELEC;
72
73
74 if (!(retval & LP_PERRORP)) {
75 LP_F(minor) |= LP_ERR;
76 return temp-buf?temp-buf:-EIO;
77 } else
78 LP_F(minor) &= ~LP_SELEC;
79 }
80 return temp-buf;
81 }
82
83 static int lp_read(struct inode * inode, struct file * file, char * buf, int count)
84 {
85 return -EINVAL;
86 }
87
88 static int lp_lseek(struct inode * inode, struct file * file, off_t offset, int origin)
89 {
90 return -EINVAL;
91 }
92
93 static int lp_open(struct inode * inode, struct file * file)
94 {
95 unsigned int minor = MINOR(inode->i_rdev);
96
97 if (minor >= LP_NO)
98 return -ENODEV;
99 if ((LP_F(minor) & LP_EXIST) == 0)
100 return -ENODEV;
101 if (LP_F(minor) & LP_BUSY)
102 return -EBUSY;
103 LP_F(minor) |= LP_BUSY;
104 return 0;
105 }
106
107 static void lp_release(struct inode * inode, struct file * file)
108 {
109 unsigned int minor = MINOR(inode->i_rdev);
110
111 LP_F(minor) &= ~LP_BUSY;
112 }
113
114 static struct file_operations lp_fops = {
115 lp_lseek,
116 lp_read,
117 lp_write,
118 NULL,
119 NULL,
120 NULL,
121 lp_open,
122 lp_release
123 };
124
125 void lp_init(void)
126 {
127 int offset = 0;
128 unsigned int testvalue = 0;
129 int count = 0;
130
131 chrdev_fops[6] = &lp_fops;
132
133 for (offset = 0; offset < LP_NO; offset++) {
134
135 outb( LP_DUMMY, LP_B(offset));
136 for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
137 ;
138 testvalue = inb(LP_B(offset));
139 if (testvalue != 255) {
140 LP_F(offset) |= LP_EXIST;
141 lp_reset(offset);
142 printk("lp_init: lp%d exists (%d)\n", offset, testvalue);
143 count++;
144 }
145 }
146 if (count == 0)
147 printk("lp_init: no lp devices found\n");
148 }