~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/arch/um/drivers/fhd.c

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.