3 * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
5 * The original version was derived from linux/fs/proc/net.c,
6 * which is Copyright (C) 1991, 1992 Linus Torvalds.
7 * Much has been rewritten, but some of the code still remains.
9 * /proc/scsi directory handling functions
11 * last change: 95/07/04
13 * Initial version: March '95
14 * 95/05/15 Added subdirectories for each driver and show every
15 * registered HBA as a single file.
16 * 95/05/30 Added rudimentary write support for parameter passing
17 * 95/07/04 Fixed bugs in directory handling
18 * 95/09/13 Update to support the new proc-dir tree
20 * TODO: Improve support to write to the driver files
21 * Add some more comments
23 #include <linux/errno.h>
24 #include <linux/sched.h>
25 #include <linux/proc_fs.h>
26 #include <linux/stat.h>
29 #include <asm/uaccess.h>
31 /* forward references */
32 static ssize_t
proc_readscsi(struct file
* file
, char * buf
,
33 size_t count
, loff_t
*ppos
);
34 static ssize_t
proc_writescsi(struct file
* file
, const char * buf
,
35 size_t count
, loff_t
*ppos
);
36 static long long proc_scsilseek(struct file
*, long long, int);
38 extern void build_proc_dir_hba_entries(uint
);
40 /* the *_get_info() functions are in the respective scsi driver code */
41 int (* dispatch_scsi_info_ptr
) (int ino
, char *buffer
, char **start
,
42 off_t offset
, int length
, int inout
) = 0;
44 static struct file_operations proc_scsi_operations
= {
45 proc_scsilseek
, /* lseek */
46 proc_readscsi
, /* read */
47 proc_writescsi
, /* write */
48 proc_readdir
, /* readdir */
52 NULL
, /* no special open code */
54 NULL
, /* no special release code */
55 NULL
/* can't fsync */
59 * proc directories can do almost nothing..
61 struct inode_operations proc_scsi_inode_operations
= {
62 &proc_scsi_operations
, /* default scsi directory file-ops */
64 proc_lookup
, /* lookup */
73 NULL
, /* follow_link */
81 int get_not_present_info(char *buffer
, char **start
, off_t offset
, int length
)
86 pos
= len
= sprintf(buffer
,
87 "No low-level scsi modules are currently present\n");
93 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
94 len
-= (offset
- begin
);
101 #define PROC_BLOCK_SIZE (3*1024) /* 4K page size, but our output routines
102 * use some slack for overruns
105 static ssize_t
proc_readscsi(struct file
* file
, char * buf
,
106 size_t count
, loff_t
*ppos
)
108 struct inode
* inode
= file
->f_dentry
->d_inode
;
110 ssize_t bytes
= count
;
116 if (!(page
= (char *) __get_free_page(GFP_KERNEL
)))
121 if(bytes
> PROC_BLOCK_SIZE
)
122 thistime
= PROC_BLOCK_SIZE
;
124 if(dispatch_scsi_info_ptr
)
125 length
= dispatch_scsi_info_ptr(inode
->i_ino
, page
, &start
,
128 length
= get_not_present_info(page
, &start
, *ppos
, thistime
);
130 free_page((ulong
) page
);
135 * We have been given a non page aligned block of
136 * the data we asked for + a bit. We have been given
137 * the start pointer and we know the length..
144 copy_to_user(buf
+ copied
, start
, length
);
145 *ppos
+= length
; /* Move down the file */
149 if(length
< thistime
)
150 break; /* End of file */
154 free_page((ulong
) page
);
159 static ssize_t
proc_writescsi(struct file
* file
, const char * buf
,
160 size_t count
, loff_t
*ppos
)
162 struct inode
* inode
= file
->f_dentry
->d_inode
;
166 if(count
> PROC_BLOCK_SIZE
) {
170 if(dispatch_scsi_info_ptr
!= NULL
) {
171 if (!(page
= (char *) __get_free_page(GFP_KERNEL
)))
173 copy_from_user(page
, buf
, count
);
174 ret
= dispatch_scsi_info_ptr(inode
->i_ino
, page
, 0, 0, count
, 1);
176 return(-ENOPKG
); /* Nothing here */
178 free_page((ulong
) page
);
183 static long long proc_scsilseek(struct file
* file
, long long offset
, int orig
)
187 file
->f_pos
= offset
;
190 file
->f_pos
+= offset
;
200 * Overrides for Emacs so that we almost follow Linus's tabbing style.
201 * Emacs will notice this stuff at the end of the file and automatically
202 * adjust the settings for this buffer only. This must remain at the end
204 * ---------------------------------------------------------------------------
207 * c-brace-imaginary-offset: 0
209 * c-argdecl-indent: 4
211 * c-continued-statement-offset: 4
212 * c-continued-brace-offset: 0
213 * indent-tabs-mode: nil