00001
00002
00003
00004 #include "E12.h"
00005 #include "E12fops.h"
00006 #include "sE12.h"
00007 #include "../includes/E12user.h"
00008 #include <linux/vmalloc.h>
00009 #include <linux/mm.h>
00010 #include <linux/slab.h>
00011
00012
00013
00014
00015 struct file_operations E12fops={
00016 open: E12_Open,
00017 read: E12_Read,
00018 write: E12_Write,
00019 ioctl: E12_Ioctl,
00020 fasync: E12_fasync,
00021 release: E12_Release,
00022 };
00023
00024
00025 static int AllocDevice(E12_device *device)
00026 {
00027 request_region(device->address,E12_IOSIZE,device->devicename);
00028 request_irq(device->IRQ, E12_Interrupt, 0, device->devicename, device);
00029 return 0;
00030 }
00031
00032 static int DeallocDevice(E12_device *device)
00033 {
00034 if(device->valid!=TRUE)
00035 return -1;
00036
00037 if(device->IRQ!=UNSET)
00038 free_irq(device->IRQ,device);
00039
00040 if(device->address!=UNSET)
00041 release_region(device->address,E12_IOSIZE);
00042 return 0;
00043 }
00044
00045
00046 int E12_Open (struct inode *inode, struct file *filp)
00047 {
00048 int minor = NUM(inode->i_rdev);
00049 extern E12_device Global_E12device[E12MAXBOARDS];
00050 E12_device *device;
00051
00052 if(minor>=E12MAXBOARDS)
00053 {
00054 GENDEBUG("invalid board number\n");
00055 return -ENODEV;
00056 }
00057
00058
00059 MOD_INC_USE_COUNT;
00060
00061
00062 GENDEBUG("device memory allocated\n");
00063
00064 device = &Global_E12device[minor];
00065
00066 filp->private_data = device;
00067
00068 if(device->valid==TRUE)
00069 AllocDevice(device);
00070
00071 GENDEBUG(E12NAME"device %x opened\n",minor);
00072 return 0;
00073 }
00074
00075 int E12_Ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
00076 {
00077 E12_device *device = filp->private_data;
00078 E12_config_struct config;
00079 u8 identity;
00080 isodata data;
00081
00082 switch(cmd)
00083 {
00084 case E12_CONFIG:
00085
00086 DeallocDevice(device);
00087 if(access_ok(VERIFY_READ,(void *)arg,sizeof(E12_config_struct)))
00088 copy_from_user(&config,(E12_config_struct *)arg,sizeof(E12_config_struct));
00089 else
00090 {
00091 E12MESSAGE("couldn't copy 37E12 config structure from user space\n");
00092 return -1;
00093 }
00094
00095
00096 if(0>check_region(config.address,E12_IOSIZE))
00097 {
00098 E12MESSAGE("IO address %x not available\n",config.address);
00099 return -1;
00100 }
00101
00102 request_region(config.address,E12_IOSIZE,device->devicename);
00103 device->address = config.address;
00104
00105 IDENT_CHECK(device,identity);
00106
00107 if(identity!=PLDR1_IDENT)
00108 {
00109 E12MESSAGE("37e12 device not found at %x\n",config.address);
00110 release_region(device->address,E12_IOSIZE);
00111 device->address = UNSET;
00112 return -1;
00113 }
00114
00115 IODEBUG("37e12 found at address %x\n",device->address);
00116
00117 if(0>request_irq(config.IRQ, E12_Interrupt, 0, device->devicename, device))
00118 {
00119 E12MESSAGE("IRQ %u not available\n",config.IRQ);
00120 return -1;
00121 }
00122
00123 device->IRQ = config.IRQ;
00124
00125 if(config.IRQedge)
00126 device->IRQedge = RISING_EDGE;
00127 else
00128 device->IRQedge = FALLING_EDGE;
00129
00130 device->valid = TRUE;
00131
00132
00133 IRQ_EDGE_INIT(device);
00134 return 0;
00135
00136 case ISO_DIG_OUT:
00137 if(device->valid!=TRUE)
00138 {
00139 E12MESSAGE("invalid device configuration\n");
00140 return -ENODEV;
00141 }
00142 if(access_ok(VERIFY_READ,(void *)arg,sizeof(isodata)))
00143 copy_from_user(&data,(isodata *)arg,sizeof(isodata));
00144 else
00145 {
00146 E12MESSAGE("couldn't copy 37E12 ISO data from user space\n");
00147 return -1;
00148 }
00149 ISO_OUT(device,data);
00150 return 0;
00151
00152
00153 case ISO_DIG_IN:
00154 if(device->valid!=TRUE)
00155 {
00156 E12MESSAGE("invalid device configuration\n");
00157 return -ENODEV;
00158 }
00159 ISO_IN(device,data);
00160 if(access_ok(VERIFY_READ,(void *)arg,sizeof(isodata)))
00161 copy_to_user((isodata *)arg,&data,sizeof(isodata));
00162 else
00163 {
00164 E12MESSAGE("couldn't copy 37E12 ISO data to user space\n");
00165 return -1;
00166 }
00167 return 0;
00168 }
00169 IODEBUG("invalid command\n");
00170 return -1;
00171 }
00172
00173
00174 ssize_t E12_Write(struct file *filp, const char *buff, size_t count, loff_t *offp)
00175 {
00176 E12_device *device = filp->private_data;
00177 u8 *data;
00178 int bytenum;
00179
00180 if(device->valid!=TRUE)
00181 {
00182 E12MESSAGE("invalid device configuration\n");
00183 return -ENODEV;
00184 }
00185 IODEBUG("writing data\n");
00186
00187 data = vmalloc(count);
00188 disable_irq(device->IRQ);
00189
00190 copy_from_user(data,buff,count);
00191
00192 WRITE_MODE(device);
00193
00194 for(bytenum=0;bytenum<count;bytenum++)
00195 {
00196 WAIT_FOR_IRQ_HIGH(device);
00197
00198 BUSOUT(device,data[bytenum]);
00199
00200 DTACK_ON(device);
00201
00202 WAIT_FOR_IRQ_LOW(device);
00203
00204 if(bytenum<(count-1))
00205 DTACK_OFF(device);
00206
00207 }
00208
00209 enable_irq(device->IRQ);
00210 READ_MODE(device);
00211 DTACK_OFF(device);
00212 vfree(data);
00213 IODEBUG("wrote %u bytes\n",bytenum);\
00214 return bytenum;
00215 }
00216
00217 ssize_t E12_Read(struct file *filp, char *buff, size_t count, loff_t *offp)
00218 {
00219 E12_device *device = filp->private_data;
00220 char *data;
00221 int bytenum;
00222 u8 bitnine=0;
00223
00224 IODEBUG("E12_Read\n");
00225
00226 if(device->valid!=TRUE)
00227 {
00228 E12MESSAGE("invalid device configuration\n");
00229 return -ENODEV;
00230 }
00231 rmb();
00232 if(MIRQ_LOW(device))
00233 {
00234 IODEBUG("Transfer not pending\n");
00235
00236 if(filp->f_flags & O_NONBLOCK)
00237 return 0;
00238
00239 IODEBUG("device is in blocking mode, sleeping\n");
00240 rmb();
00241
00242 if(wait_event_interruptible(device->readqueue, MIRQ_HIGH(device))==-ERESTARTSYS){
00243 E12MESSAGE("37e12 read killed while waiting for data");
00244 return 0;
00245 }
00246
00247 rmb();
00248 IODEBUG("device awoken\n");
00249 }
00250
00251 disable_irq(device->IRQ);
00252 data = vmalloc(count);
00253
00254 for(bytenum=0;bytenum<count;bytenum++)
00255 {
00256 DTACK_ON(device);
00257
00258 WAIT_FOR_IRQ_LOW(device);
00259
00260 DATA_PORT(device,data[bytenum]);
00261 IODEBUG(" %c",data[bytenum]);
00262 BIT_NINE_READ(device,bitnine);
00263
00264
00265
00266 if(bitnine)
00267 {
00268 IODEBUG("transfer completed - bit nine set\n");
00269 enable_irq(device->IRQ);
00270 copy_to_user(buff,data,(bytenum+1));
00271 vfree(data);
00272 DTACK_OFF(device);
00273 return(bytenum+1);
00274 }
00275
00276 if(bytenum<(count-1))
00277 {
00278 DTACK_OFF(device);
00279 WAIT_FOR_IRQ_HIGH(device);
00280 }
00281
00282 }
00283 IODEBUG("transfer completed - buffer filled\n");
00284 enable_irq(device->IRQ);
00285 copy_to_user(buff,data,bytenum);
00286 vfree(data);
00287 DTACK_OFF(device);
00288 IODEBUG("returned %u bytes\n",bytenum);
00289 return bytenum;
00290 }
00291
00292
00293 int E12_fasync(int fd, struct file *filp, int mode)
00294 {
00295 E12_device *device = filp->private_data;
00296 IODEBUG("fasync call\n");
00297
00298 if(device==NULL)
00299 {
00300 GENDEBUG("NULL device, async failed\n");
00301 return -1;
00302 }
00303
00304 return(fasync_helper(fd, filp, mode, &device->dataready));
00305 }
00306
00307
00308
00309 int E12_Release(struct inode *inode, struct file *filp)
00310 {
00311 E12_device *device = filp->private_data;
00312 int minor = device->num;
00313 DeallocDevice(device);
00314 E12_fasync(-1,filp,0);
00315 GENDEBUG(E12NAME"-%u device closed\n",minor);
00316 MOD_DEC_USE_COUNT;
00317 return SUCCESS;
00318 }
00319
00320
00321
00322
00323
00324
00325