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