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