This source file includes following definitions.
- get_hba_index
- generic_proc_info
- dispatch_scsi_info
- count_templates
- build_proc_dir_hba_entries
- build_proc_dir_entries
- parseFree
- parseInit
- parseOpt
- proc_print_scsidevice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #ifdef MODULE
17
18
19
20
21 #define _SCSI_SYMS_VER_
22 #include <linux/autoconf.h>
23 #include <linux/module.h>
24 #include <linux/version.h>
25 #else
26 #define MOD_INC_USE_COUNT
27 #define MOD_DEC_USE_COUNT
28 #endif
29
30 #include <linux/string.h>
31 #include <linux/mm.h>
32 #include <linux/malloc.h>
33 #include <linux/proc_fs.h>
34 #include <linux/errno.h>
35 #include "../block/blk.h"
36 #include "scsi.h"
37 #include "hosts.h"
38
39 #ifndef TRUE
40 #define TRUE 1
41 #define FALSE 0
42 #endif
43
44 extern struct proc_dir_entry scsi_dir[];
45 extern struct proc_dir_entry scsi_hba_dir[];
46 extern int scsi_proc_info(char *, char **, off_t, int, int, int);
47
48
49 int get_hba_index(int ino)
50 {
51 Scsi_Host_Template *tpnt = scsi_hosts;
52 struct Scsi_Host *hpnt = scsi_hostlist;
53 uint x = 0;
54
55
56
57
58
59
60
61 while (tpnt) {
62 if (ino == tpnt->low_ino)
63 return(x);
64 x += 3;
65 while (hpnt) {
66 if(hpnt->hostt == tpnt)
67 x++;
68 hpnt = hpnt->next;
69 }
70 tpnt = tpnt->next;
71 }
72 return(0);
73 }
74
75
76
77
78 int generic_proc_info(char *buffer, char **start, off_t offset,
79 int length, int inode, int inout)
80 {
81 int len, pos, begin;
82
83 if(inout == TRUE)
84 return(-ENOSYS);
85
86 begin = 0;
87 pos = len = sprintf(buffer,
88 "The driver does not yet support the proc-fs\n");
89 if(pos < offset) {
90 len = 0;
91 begin = pos;
92 }
93
94 *start = buffer + (offset - begin);
95 len -= (offset - begin);
96 if(len > length)
97 len = length;
98
99 return(len);
100 }
101
102
103
104
105 extern int dispatch_scsi_info(int ino, char *buffer, char **start,
106 off_t offset, int length, int func)
107 {
108 struct Scsi_Host *hpnt = scsi_hostlist;
109
110 if(func != 2) {
111 if(ino == PROC_SCSI_SCSI) {
112
113
114
115
116 return(scsi_proc_info(buffer, start, offset, length, 0, func));
117 }
118
119 while(hpnt) {
120 if (ino == (hpnt->host_no + PROC_SCSI_FILE)) {
121 if(hpnt->hostt->proc_info == NULL)
122 return generic_proc_info(buffer, start, offset, length,
123 hpnt->host_no, func);
124 else
125 return(hpnt->hostt->proc_info(buffer, start, offset,
126 length, hpnt->host_no, func));
127 }
128 hpnt = hpnt->next;
129 }
130 return(-EBADF);
131 } else
132 return(get_hba_index(ino));
133 }
134
135 inline uint count_templates(void)
136 {
137 Scsi_Host_Template *tpnt = scsi_hosts;
138 uint x = 0;
139
140 while (tpnt) {
141 tpnt = tpnt->next;
142 x++;
143 }
144 return (x);
145 }
146
147 void build_proc_dir_hba_entries(void)
148 {
149 Scsi_Host_Template *tpnt = scsi_hosts;
150 struct Scsi_Host *hpnt;
151 uint x, y;
152
153
154
155
156
157 static char names[PROC_SCSI_LAST - PROC_SCSI_FILE][4];
158
159 x = y = 0;
160
161 while (tpnt) {
162 scsi_hba_dir[x].low_ino = tpnt->low_ino;
163 scsi_hba_dir[x].namelen = 1;
164 scsi_hba_dir[x++].name = ".";
165 scsi_hba_dir[x].low_ino = PROC_SCSI;
166 scsi_hba_dir[x].namelen = 2;
167 scsi_hba_dir[x++].name = "..";
168
169 hpnt = scsi_hostlist;
170 while (hpnt) {
171 if (tpnt == hpnt->hostt) {
172 scsi_hba_dir[x].low_ino = PROC_SCSI_FILE + hpnt->host_no;
173 scsi_hba_dir[x].namelen = sprintf(names[y],"%d",hpnt->host_no);
174 scsi_hba_dir[x].name = names[y];
175 y++;
176 x++;
177 }
178 hpnt = hpnt->next;
179 }
180
181 scsi_hba_dir[x].low_ino = 0;
182 scsi_hba_dir[x].namelen = 0;
183 scsi_hba_dir[x++].name = NULL;
184 tpnt = tpnt->next;
185 }
186 }
187
188 void build_proc_dir_entries(void)
189 {
190 Scsi_Host_Template *tpnt = scsi_hosts;
191
192 uint newnum;
193 uint x;
194
195 newnum = count_templates();
196
197 scsi_dir[0].low_ino = PROC_SCSI;
198 scsi_dir[0].namelen = 1;
199 scsi_dir[0].name = ".";
200 scsi_dir[1].low_ino = PROC_ROOT_INO;
201 scsi_dir[1].namelen = 2;
202 scsi_dir[1].name = "..";
203 scsi_dir[2].low_ino = PROC_SCSI_SCSI;
204 scsi_dir[2].namelen = 4;
205 scsi_dir[2].name = "scsi";
206
207 for(x = 3; x < newnum + 3; x++, tpnt = tpnt->next) {
208 scsi_dir[x].low_ino = tpnt->low_ino;
209 scsi_dir[x].namelen = strlen(tpnt->procname);
210 scsi_dir[x].name = tpnt->procname;
211 }
212
213 scsi_dir[x].low_ino = 0;
214 scsi_dir[x].namelen = 0;
215 scsi_dir[x].name = NULL;
216
217 build_proc_dir_hba_entries();
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 typedef struct
244 {
245 char *buf,
246 *cmdList,
247 *bufPos,
248 **cmdPos,
249 cmdNum;
250 } parseHandle;
251
252
253 inline int parseFree (parseHandle *handle)
254 {
255 kfree (handle->cmdPos);
256 kfree (handle);
257
258 return(-1);
259 }
260
261
262 parseHandle *parseInit(char *buf, char *cmdList, int cmdNum)
263 {
264 char *ptr;
265 parseHandle *handle;
266
267 if (!buf || !cmdList)
268 return(NULL);
269 if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), 1)) == 0)
270 return(NULL);
271 if ((handle->cmdPos = (char**) kmalloc(sizeof(int), cmdNum)) == 0) {
272 kfree(handle);
273 return(NULL);
274 }
275
276 handle->buf = handle->bufPos = buf;
277 handle->cmdList = cmdList;
278 handle->cmdNum = cmdNum;
279
280 handle->cmdPos[cmdNum = 0] = cmdList;
281 for (ptr = cmdList; *ptr; ptr++) {
282 if(*ptr == ' ') {
283 *ptr++ = 0;
284 handle->cmdPos[++cmdNum] = ptr++;
285 }
286 }
287 return(handle);
288 }
289
290
291 int parseOpt(parseHandle *handle, char **param)
292 {
293 int cmdIndex = 0,
294 cmdLen = 0;
295 char *startPos;
296
297 if (!handle)
298 return(parseFree(handle));
299
300 for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
301 if (!*(handle->bufPos))
302 return(parseFree(handle));
303
304 startPos = handle->bufPos;
305 for (; handle->cmdPos[cmdIndex][cmdLen] && *(handle->bufPos); handle->bufPos++)
306 {
307 for (;;)
308 {
309 if (*(handle->bufPos) == handle->cmdPos[cmdIndex][cmdLen])
310 break;
311 else
312 if (memcmp(startPos, (char*)(handle->cmdPos[++cmdIndex]), cmdLen))
313 return(parseFree(handle));
314
315 if (cmdIndex >= handle->cmdNum)
316 return(parseFree(handle));
317 }
318
319 cmdLen++;
320 }
321
322
323
324 for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
325 *param = handle->bufPos;
326
327 for (; *(handle->bufPos) && *(handle->bufPos) != ' '; handle->bufPos++);
328 *(handle->bufPos++) = 0;
329
330 return(cmdIndex);
331 }
332
333 #define MAX_SCSI_DEVICE_CODE 10
334 const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
335 {
336 "Direct-Access ",
337 "Sequential-Access",
338 "Printer ",
339 "Processor ",
340 "WORM ",
341 "CD-ROM ",
342 "Scanner ",
343 "Optical Device ",
344 "Medium Changer ",
345 "Communications "
346 };
347
348 void proc_print_scsidevice(Scsi_Device *scd, char *buffer, int *size, int len)
349 {
350 int x, y = *size;
351
352 y = sprintf(buffer + len,
353 "Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
354 scd->channel, scd->id, scd->lun);
355 for (x = 0; x < 8; x++) {
356 if (scd->vendor[x] >= 0x20)
357 y += sprintf(buffer + len + y, "%c", scd->vendor[x]);
358 else
359 y += sprintf(buffer + len + y," ");
360 }
361 y += sprintf(buffer + len + y, " Model: ");
362 for (x = 0; x < 16; x++) {
363 if (scd->model[x] >= 0x20)
364 y += sprintf(buffer + len + y, "%c", scd->model[x]);
365 else
366 y += sprintf(buffer + len + y, " ");
367 }
368 y += sprintf(buffer + len + y, " Rev: ");
369 for (x = 0; x < 4; x++) {
370 if (scd->rev[x] >= 0x20)
371 y += sprintf(buffer + len + y, "%c", scd->rev[x]);
372 else
373 y += sprintf(buffer + len + y, " ");
374 }
375 y += sprintf(buffer + len + y, "\n");
376
377 y += sprintf(buffer + len + y, " Type: %s ",
378 scd->type < MAX_SCSI_DEVICE_CODE ?
379 scsi_dev_types[(int)scd->type] : "Unknown " );
380 y += sprintf(buffer + len + y, " ANSI"
381 " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
382 if (scd->scsi_level == 2)
383 y += sprintf(buffer + len + y, " CCS\n");
384 else
385 y += sprintf(buffer + len + y, "\n");
386
387 *size = y;
388 return;
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408