This source file includes following definitions.
- get_not_present_info
- proc_readscsi
- proc_writescsi
- proc_scsilseek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/autoconf.h>
24 #include <asm/segment.h>
25 #include <linux/errno.h>
26 #include <linux/sched.h>
27 #include <linux/proc_fs.h>
28 #include <linux/stat.h>
29 #include <linux/config.h>
30 #include <linux/mm.h>
31
32
33 static int proc_readscsi(struct inode * inode, struct file * file,
34 char * buf, int count);
35 static int proc_writescsi(struct inode * inode, struct file * file,
36 const char * buf, int count);
37 static int proc_scsilseek(struct inode *, struct file *, off_t, int);
38
39 extern void build_proc_dir_hba_entries(uint);
40
41
42 extern int (* dispatch_scsi_info_ptr)(int, char *, char **, off_t, int, int);
43
44
45 static struct file_operations proc_scsi_operations = {
46 proc_scsilseek,
47 proc_readscsi,
48 proc_writescsi,
49 proc_readdir,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 NULL
56 };
57
58
59
60
61 struct inode_operations proc_scsi_inode_operations = {
62 &proc_scsi_operations,
63 NULL,
64 proc_lookup,
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 NULL,
70 NULL,
71 NULL,
72 NULL,
73 NULL,
74 NULL,
75 NULL,
76 NULL
77 };
78
79 int get_not_present_info(char *buffer, char **start, off_t offset, int length)
80 {
81 int len, pos, begin;
82
83 begin = 0;
84 pos = len = sprintf(buffer,
85 "No low-level scsi modules are currently present\n");
86 if(pos < offset) {
87 len = 0;
88 begin = pos;
89 }
90
91 *start = buffer + (offset - begin);
92 len -= (offset - begin);
93 if(len > length)
94 len = length;
95
96 return(len);
97 }
98
99 #define PROC_BLOCK_SIZE (3*1024)
100
101
102
103 static int proc_readscsi(struct inode * inode, struct file * file,
104 char * buf, int count)
105 {
106 int length;
107 int bytes = count;
108 int copied = 0;
109 int thistime;
110 char * page;
111 char * start;
112
113 if (count < -1)
114 return(-EINVAL);
115
116
117 if (!(page = (char *) __get_free_page(GFP_KERNEL)))
118 return(-ENOMEM);
119
120 while(bytes > 0 || count == -1) {
121 thistime = bytes;
122 if(bytes > PROC_BLOCK_SIZE || count == -1)
123 thistime = PROC_BLOCK_SIZE;
124
125 if(dispatch_scsi_info_ptr)
126 length = dispatch_scsi_info_ptr(inode->i_ino, page, &start,
127 file->f_pos, thistime, 0);
128 else
129 length = get_not_present_info(page, &start, file->f_pos, thistime);
130 if(length < 0) {
131 free_page((ulong) page);
132 return(length);
133 }
134
135
136
137
138
139
140 if (length <= 0)
141 break;
142
143
144
145
146 if (count != -1)
147 memcpy_tofs(buf + copied, start, length);
148 file->f_pos += length;
149 bytes -= length;
150 copied += length;
151
152 if(length < thistime)
153 break;
154
155 }
156
157 free_page((ulong) page);
158 return(copied);
159 }
160
161
162 static int proc_writescsi(struct inode * inode, struct file * file,
163 const char * buf, int count)
164 {
165 int ret = 0;
166 char * page;
167
168 if(count > PROC_BLOCK_SIZE) {
169 return(-EOVERFLOW);
170 }
171
172 if(dispatch_scsi_info_ptr != NULL) {
173 if (!(page = (char *) __get_free_page(GFP_KERNEL)))
174 return(-ENOMEM);
175 memcpy_fromfs(page, buf, count);
176 ret = dispatch_scsi_info_ptr(inode->i_ino, page, 0, 0, count, 1);
177 } else
178 return(-ENOPKG);
179
180 free_page((ulong) page);
181 return(ret);
182 }
183
184
185 static int proc_scsilseek(struct inode * inode, struct file * file,
186 off_t offset, int orig)
187 {
188 switch (orig) {
189 case 0:
190 file->f_pos = offset;
191 return(file->f_pos);
192 case 1:
193 file->f_pos += offset;
194 return(file->f_pos);
195 case 2:
196 if (offset)
197 return(-EINVAL);
198 proc_readscsi(inode, file, 0, -1);
199 return(file->f_pos);
200 default:
201 return(-EINVAL);
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222