Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
1 #include "asm/fhd_user.h"
2 #define MAJOR_NR FHD_MAJOR
3 #include "linux/blk.h"
4 #include "linux/blkdev.h"
5 #include "linux/hdreg.h"
6 #include "linux/init.h"
7 #include "asm/segment.h"
8 #include "asm/uaccess.h"
9 #include "user_util.h"
10 #include "kern_util.h"
11
12 static int fhd_open(struct inode * inode, struct file * filp);
13 static int fhd_release(struct inode * inode, struct file * file);
14 static int fhd_ioctl(struct inode * inode, struct file * file,
15 unsigned int cmd, unsigned long arg);
16
17 static struct block_device_operations fhd_blops = {
18 open: fhd_open,
19 release: fhd_release,
20 ioctl: fhd_ioctl,
21 };
22
23 #define MAX_DEV (8)
24
25 static struct {
26 char *file;
27 int fd;
28 int size;
29 } fhd_dev[MAX_DEV] = { { "root_fs", -1, 0 },
30 [ 1 ... MAX_DEV - 1 ] = { NULL, -1, -1 } };
31
32 static int blk_sizes[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = 512 };
33
34 static int fhd_setup(char *str)
35 {
36 int n;
37
38 n = *str++;
39 if(n < ''){
40 printk("fhd_setup : index out of range\n");
41 return(1);
42 }
43 n -= '';
44 if(n >= MAX_DEV){
45 printk("fhd_setup : index out of range\n");
46 return(1);
47 }
48 if(*str++ != '='){
49 printk("fhd_setup : Expected '='\n");
50 return(1);
51 }
52 fhd_dev[n].file = str;
53 return(1);
54 }
55
56 __setup("fhd", fhd_setup);
57
58 int fhd_init(void)
59 {
60 int i;
61
62 if (register_blkdev(MAJOR_NR, "fhd", &fhd_blops)) {
63 printk("fhd: unable to get major %d\n",MAJOR_NR);
64 return -1;
65 }
66 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
67 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
68 blksize_size[MAJOR_NR] = blk_sizes;
69 for(i=0;i<MAX_DEV;i++){
70 if(fhd_dev[i].file == NULL) continue;
71 if((fhd_dev[i].fd = open_fhd_fs(fhd_dev[i].file)) == -1){
72 printk("fhd%d: Can't open \"%s\"\n", i,
73 fhd_dev[i].file);
74 }
75 fhd_dev[i].size = file_size(fhd_dev[i].file);
76 }
77 return 0;
78 }
79
80 __initcall(fhd_init);
81
82 static int fhd_open(struct inode * inode, struct file * filp)
83 {
84 int target;
85
86 target = DEVICE_NR(inode->i_rdev);
87 if(target > MAX_DEV)
88 return -ENODEV;
89 if(fhd_dev[target].file == NULL)
90 return -ENODEV;
91 return(0);
92 }
93
94 static int fhd_release(struct inode * inode, struct file * file)
95 {
96 return(0);
97 }
98
99 DECLARE_MUTEX(fhd_sem);
100
101 static void do_fhd_request(request_queue_t * q)
102 {
103 int block, nsect, dev;
104
105 if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE) return;
106 INIT_REQUEST;
107 while(!QUEUE_EMPTY){
108 block = CURRENT->sector;
109 nsect = CURRENT->current_nr_sectors;
110 dev = MINOR(CURRENT->rq_dev);
111 if (CURRENT->cmd == READ) {
112 down(&fhd_sem);
113 if(lseek_fhd_fs(fhd_dev[dev].fd, block << 9) == -1){
114 printk("Error seeking in do_fhd_request\n");
115 end_request(0);
116 }
117 else if(read_fhd_fs(fhd_dev[dev].fd, CURRENT->buffer, nsect << 9) == -1){
118 printk("Error reading in do_fhd_request\n");
119 end_request(0);
120 }
121 else {
122 CURRENT->sector += nsect;
123 CURRENT->buffer += nsect << 9;
124 CURRENT->errors = 0;
125 CURRENT->nr_sectors -= nsect;
126 CURRENT->current_nr_sectors = 0;
127 end_request(1);
128 }
129 up(&fhd_sem);
130 }
131 else if (CURRENT->cmd == WRITE) {
132 down(&fhd_sem);
133 if(lseek_fhd_fs(fhd_dev[dev].fd, block << 9) == -1){
134 printk("Error seeking in do_fhd_request\n");
135 end_request(0);
136 }
137 else if(write_fhd_fs(fhd_dev[dev].fd, CURRENT->buffer,
138 nsect << 9) == -1){
139 printk("Error reading in do_fhd_request\n");
140 end_request(0);
141 }
142 else {
143 CURRENT->sector += nsect;
144 CURRENT->buffer += nsect << 9;
145 CURRENT->errors = 0;
146 CURRENT->nr_sectors -= nsect;
147 CURRENT->current_nr_sectors = 0;
148 end_request(1);
149 }
150 up(&fhd_sem);
151 }
152 }
153 }
154
155 static int fhd_ioctl(struct inode * inode, struct file * file,
156 unsigned int cmd, unsigned long arg)
157 {
158 struct hd_geometry *loc = (struct hd_geometry *) arg;
159 int dev, err;
160
161 if ((!inode) || !(inode->i_rdev))
162 return -EINVAL;
163 dev = DEVICE_NR(inode->i_rdev);
164 if (dev > MAX_DEV)
165 return -EINVAL;
166 switch (cmd) {
167 case HDIO_GETGEO:
168 KERN_UNTESTED();
169 if (!loc) return -EINVAL;
170 err = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
171 if (err)
172 return err;
173 KERN_UNTESTED();
174 return 0;
175 case BLKRASET:
176 KERN_UNTESTED();
177 if(!suser()) return -EACCES;
178 if(arg > 0xff) return -EINVAL;
179 read_ahead[MAJOR(inode->i_rdev)] = arg;
180 return 0;
181 case BLKRAGET:
182 KERN_UNTESTED();
183 if (!arg) return -EINVAL;
184 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
185 if (err)
186 return err;
187 return 0;
188 case BLKGETSIZE: /* Return device size */
189 if (!arg) return -EINVAL;
190 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
191 if (err)
192 return err;
193 put_user(fhd_dev[dev].size >> 9, (long *) arg);
194 return 0;
195 case BLKFLSBUF:
196 KERN_UNTESTED();
197 if(!suser()) return -EACCES;
198 return 0;
199
200 case BLKRRPART: /* Re-read partition tables */
201 KERN_UNTESTED();
202 return 0; /* revalidate_hddisk(inode->i_rdev, 1); */
203
204 case HDIO_SET_UNMASKINTR:
205 KERN_UNTESTED();
206 if (!suser()) return -EACCES;
207 if ((arg > 1) || (MINOR(inode->i_rdev) & 0x3F))
208 return -EINVAL;
209 return 0;
210
211 case HDIO_GET_UNMASKINTR:
212 KERN_UNTESTED();
213 if (!arg) return -EINVAL;
214 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
215 if (err)
216 return err;
217 return 0;
218
219 case HDIO_GET_MULTCOUNT:
220 KERN_UNTESTED();
221 if (!arg) return -EINVAL;
222 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
223 if (err)
224 return err;
225 return 0;
226
227 case HDIO_SET_MULTCOUNT:
228 KERN_UNTESTED();
229 if (!suser()) return -EACCES;
230 if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
231 return 0;
232
233 case HDIO_GET_IDENTITY:
234 KERN_UNTESTED();
235 if (!arg) return -EINVAL;
236 return 0;
237
238 default:
239 return -EINVAL;
240 }
241 }
242
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.