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 #include <linux/lp.h>
6
7
8 static int lp_reset(int minor)
9 {
10 int testvalue;
11
12
13 outb(0, LP_C(minor));
14 for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
15 ;
16 outb(LP_PSELECP | LP_PINITP, LP_C(minor));
17 return LP_S(minor);
18 }
19
20 static int lp_char(char lpchar, int minor)
21 {
22 int retval = 0;
23 unsigned long count = 0;
24
25 outb(lpchar, LP_B(minor));
26 do {
27 retval = LP_S(minor);
28 count ++;
29 if (need_resched)
30 schedule();
31 } while(!(retval & LP_PBUSY) && count < LP_TIME_CHAR);
32
33 if (count == LP_TIME_CHAR) {
34 return 0;
35
36 }
37
38 outb(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor )));
39
40 outb(( LP_PSELECP | LP_PINITP ), ( LP_C( minor )));
41
42 return LP_S(minor);
43 }
44
45 static int lp_write(struct inode * inode, struct file * file, char * buf, int count)
46 {
47 int retval;
48 unsigned int minor = MINOR(inode->i_rdev);
49 unsigned int each_cnt = 0, old_cnt = 0;
50 char c, *temp = buf;
51
52 temp = buf;
53 while (count > 0) {
54 c = get_fs_byte(temp);
55 retval = lp_char(c, minor);
56
57 if (retval) {
58 count--;
59 temp++;
60 }
61
62 if (!retval) {
63 each_cnt = count - old_cnt;
64 old_cnt = count;
65
66
67
68
69
70
71 if (current->signal & ~current->blocked) {
72 return temp-buf?temp-buf:-ERESTARTSYS;
73 }
74 current->state = TASK_INTERRUPTIBLE;
75 current->timeout = jiffies + LP_TIME(minor);
76 schedule();
77 LP_COUNT(minor) = each_cnt;
78
79
80
81
82 if (!(LP_S(minor) & LP_BUSY)) {
83 current->state = TASK_INTERRUPTIBLE;
84 current->timeout = jiffies + LP_TIMEOUT;
85 schedule();
86 if (!(LP_S(minor) & LP_BUSY))
87 printk("lp%d timeout\n\r", minor);
88 }
89 } else {
90 if (retval & LP_POUTPA) {
91 LP_F(minor) |= LP_NOPA;
92 printk("lp%d out of paper\n\r", minor);
93 return temp-buf?temp-buf:-ENOSPC;
94 } else
95 LP_F(minor) &= ~LP_NOPA;
96
97 if (!(retval & LP_PSELECD)) {
98 LP_F(minor) |= LP_SELEC;
99 printk("lp%d off-line\n\r", minor);
100 return temp-buf?temp-buf:-EFAULT;
101 } else
102 LP_F(minor) &= ~LP_SELEC;
103
104
105 if (!(retval & LP_PERRORP)) {
106 LP_F(minor) |= LP_ERR;
107 printk("lp%d on fire\n\r", minor);
108 return temp-buf?temp-buf:-EIO;
109 } else
110 LP_F(minor) &= ~LP_SELEC;
111 }
112 }
113 return temp-buf;
114 }
115
116 static int lp_read(struct inode * inode, struct file * file, char * buf, int count)
117 {
118 return -EINVAL;
119 }
120
121 static int lp_lseek(struct inode * inode, struct file * file, off_t offset, int origin)
122 {
123 return -EINVAL;
124 }
125
126 static int lp_open(struct inode * inode, struct file * file)
127 {
128 unsigned int minor = MINOR(inode->i_rdev);
129
130 if (minor >= LP_NO)
131 return -ENODEV;
132 if ((LP_F(minor) & LP_EXIST) == 0)
133 return -ENODEV;
134 if (LP_F(minor) & LP_BUSY)
135 return -EBUSY;
136 LP_F(minor) |= LP_BUSY;
137 return 0;
138 }
139
140 static void lp_release(struct inode * inode, struct file * file)
141 {
142 unsigned int minor = MINOR(inode->i_rdev);
143
144 LP_F(minor) &= ~LP_BUSY;
145 }
146
147 static struct file_operations lp_fops = {
148 lp_lseek,
149 lp_read,
150 lp_write,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 lp_open,
156 lp_release
157 };
158
159 long lp_init(long kmem_start)
160 {
161 int offset = 0;
162 unsigned int testvalue = 0;
163 int count = 0;
164
165 chrdev_fops[6] = &lp_fops;
166
167 for (offset = 0; offset < LP_NO; offset++) {
168
169 outb( LP_DUMMY, LP_B(offset));
170 for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
171 ;
172 testvalue = inb(LP_B(offset));
173 if (testvalue != 255) {
174 LP_F(offset) |= LP_EXIST;
175 lp_reset(offset);
176 printk("lp_init: lp%d exists (%d)\n", offset, testvalue);
177 count++;
178 }
179 }
180 if (count == 0)
181 printk("lp_init: no lp devices found\n");
182 return kmem_start;
183 }