85 * (request_region, ...) |
85 * (request_region, ...) |
86 */ |
86 */ |
87 #include <linux/ioport.h> |
87 #include <linux/ioport.h> |
88 |
88 |
89 #include <linux/fs.h> |
89 #include <linux/fs.h> |
|
90 #include <linux/proc_fs.h> |
90 #include <linux/sched.h> |
91 #include <linux/sched.h> |
91 #include <linux/interrupt.h> |
92 #include <linux/interrupt.h> |
92 #include <linux/pci.h> |
93 #include <linux/pci.h> |
93 #include <linux/slab.h> |
94 #include <linux/slab.h> |
94 #include <asm/io.h> |
95 #include <asm/io.h> |
171 static int me8100_int_occur(me8100_int_occur_type *, me8100_info_t *); |
172 static int me8100_int_occur(me8100_int_occur_type *, me8100_info_t *); |
172 static int me8100_setup_icsr(unsigned char *, me8100_info_t *); |
173 static int me8100_setup_icsr(unsigned char *, me8100_info_t *); |
173 static int me8100_read_icsr(unsigned char *, me8100_info_t *); |
174 static int me8100_read_icsr(unsigned char *, me8100_info_t *); |
174 static int me8100_get_board_info(me8100_info_t *, me8100_info_t *); |
175 static int me8100_get_board_info(me8100_info_t *, me8100_info_t *); |
175 static int me8100_get_int_count(me8100_int_occur_type *, me8100_info_t *); |
176 static int me8100_get_int_count(me8100_int_occur_type *, me8100_info_t *); |
|
177 static int me8100_read_proc(char*, char**, off_t, int, int*, void*); |
176 |
178 |
177 static inline int DEVICE(int i) { return i & 0x0f; } |
179 static inline int DEVICE(int i) { return i & 0x0f; } |
178 static inline int SUBDEVICE(int i) { return (i >> 4) - 1; } |
180 static inline int SUBDEVICE(int i) { return (i >> 4) - 1; } |
179 |
181 |
180 |
182 |
219 * On success the return value is 0, else is failure. |
221 * On success the return value is 0, else is failure. |
220 *-------------------------------------------------------------------------- |
222 *-------------------------------------------------------------------------- |
221 * Author: GG |
223 * Author: GG |
222 * Modification: |
224 * Modification: |
223 */ |
225 */ |
|
226 int init_module(void){ |
224 #ifdef CONFIG_PCI |
227 #ifdef CONFIG_PCI |
225 int init_module(void){ |
|
226 int result; |
228 int result; |
227 unsigned short board_count = 0; |
229 unsigned short board_count = 0; |
228 unsigned short sort_count; |
230 unsigned short sort_count; |
229 struct pci_dev *pci_dev_ptr = NULL; |
231 struct pci_dev *pci_dev_ptr = NULL; |
230 |
232 |
231 PDEBUG("init_module() is executed\n"); |
233 PDEBUG("init_module() is executed\n"); |
232 |
234 |
233 /* Set the board context to 0 */ |
235 /* Set the board context to 0 */ |
234 memset(&info_vec, 0, sizeof(info_vec)); |
236 memset(&info_vec, 0, sizeof(info_vec)); |
235 |
237 |
236 if (pci_present()){ |
238 if (pci_present()) { |
237 /* Search for ME8100_A boards */ |
239 /* Search for ME8100_A boards */ |
238 for(sort_count = 0; |
240 for(sort_count = 0; |
239 sort_count < ME8100_MAX_DEVICES; |
241 sort_count < ME8100_MAX_DEVICES; |
240 sort_count++, board_count++){ |
242 sort_count++, board_count++){ |
241 pci_dev_ptr = pci_find_device(PCI_VENDOR_ID_MEILHAUS, |
243 pci_dev_ptr = pci_find_device(PCI_VENDOR_ID_MEILHAUS, |
291 */ |
293 */ |
292 result = register_chrdev(major, ME8100_NAME, &me8100_file_operations); |
294 result = register_chrdev(major, ME8100_NAME, &me8100_file_operations); |
293 if (result < 0){ |
295 if (result < 0){ |
294 printk(KERN_ERR"ME8100:init_module():Can't get major no\n"); |
296 printk(KERN_ERR"ME8100:init_module():Can't get major no\n"); |
295 return result; |
297 return result; |
296 } |
298 } else { |
297 else{ |
299 /* Finally successful. */ |
298 major = result; |
300 major = result; |
299 PDEBUG("init_module():Major = %d\n", major); |
301 PDEBUG("init_module():Major = %d\n", major); |
|
302 |
|
303 create_proc_read_entry("me8100", 0, NULL, me8100_read_proc, NULL); |
300 } |
304 } |
301 } |
305 } |
302 else{ |
306 else{ |
303 printk(KERN_ERR"ME8100:init_module():No PCI-BIOS present !\n"); |
307 printk(KERN_ERR"ME8100:init_module():No PCI-BIOS present !\n"); |
304 return -ENODEV; |
308 return -ENODEV; |
305 } |
309 } |
306 return 0; |
310 return 0; |
|
311 #else |
|
312 return -ENODEV |
|
313 #endif |
307 } |
314 } |
308 #else |
|
309 return -ENODEV |
|
310 #endif |
|
311 |
315 |
312 |
316 |
313 |
317 |
314 /* |
318 /* |
315 * Routine: |
319 * Routine: |
2131 if ((icsr & icsr_mask[i]) == icsr_mask[i]) { |
2135 if ((icsr & icsr_mask[i]) == icsr_mask[i]) { |
2132 me8100_subinfo_t *subinfo = &info->subinfo[i]; |
2136 me8100_subinfo_t *subinfo = &info->subinfo[i]; |
2133 |
2137 |
2134 PDEBUG("==> Interrupt for subdevice %d\n", i); |
2138 PDEBUG("==> Interrupt for subdevice %d\n", i); |
2135 |
2139 |
|
2140 /* Remember the the time the interrupt was seen. This is used |
|
2141 * later from read() to decide if it has to wait for further |
|
2142 * bytes on the input port. */ |
2136 subinfo->int_seen = jiffies; |
2143 subinfo->int_seen = jiffies; |
2137 ++subinfo->int_count; |
2144 ++subinfo->int_count; |
2138 |
2145 |
|
2146 /* Read the word and store it for later read(). Then |
|
2147 * perform a "dummy" read to re-enable the IRQ line */ |
2139 subinfo->int_di = inw(subinfo->regbase + ME8100_INT_DI_REG); |
2148 subinfo->int_di = inw(subinfo->regbase + ME8100_INT_DI_REG); |
2140 inw(subinfo->regbase + ME8100_RES_INT_REG); // dummy read |
2149 inw(subinfo->regbase + ME8100_RES_INT_REG); |
2141 |
2150 |
2142 PDEBUG("==> read: 0x%04x\n", subinfo->int_di); |
2151 PDEBUG("==> read: 0x%04x\n", subinfo->int_di); |
|
2152 |
|
2153 /* Now wake up all sleeping processes and send the |
|
2154 * interrupt (SIGIO) signal to all asked for. */ |
2143 wake_up_interruptible(&subinfo->readq); |
2155 wake_up_interruptible(&subinfo->readq); |
2144 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2156 if (subinfo->fasync_ptr) kill_fasync(&subinfo->fasync_ptr, SIGIO, POLL_IN); |
2145 } |
2157 } |
2146 } |
2158 } |
2147 |
2159 |
2184 if(major){ |
2196 if(major){ |
2185 err = unregister_chrdev(major, ME8100_NAME); |
2197 err = unregister_chrdev(major, ME8100_NAME); |
2186 if(err) |
2198 if(err) |
2187 printk(KERN_WARNING"ME8100:cleanup_module():cannot unregister major\n"); |
2199 printk(KERN_WARNING"ME8100:cleanup_module():cannot unregister major\n"); |
2188 } |
2200 } |
|
2201 |
|
2202 remove_proc_entry("me8100", NULL); |
2189 } |
2203 } |
2190 |
2204 |
2191 /* Reading: we do only read (at most) one word (an usigned short) and return immediatly, |
2205 /* Reading: we do only read (at most) one word (an usigned short) and return immediatly, |
2192 * thus passing the responsibility for reading a bunch of words back to the caller. |
2206 * thus passing the responsibility for reading a bunch of words back to the caller. |
2193 * This seems to be ok, since it's not expected to read more than one word at once |
2207 * This seems to be ok, since it's not expected to read more than one word at once |
2212 |
2226 |
2213 if (len == 0) return 0; /* do we really need this check? */ |
2227 if (len == 0) return 0; /* do we really need this check? */ |
2214 if (len < 0) return -EINVAL; /* do we really need this check? */ |
2228 if (len < 0) return -EINVAL; /* do we really need this check? */ |
2215 |
2229 |
2216 /* If the time we did the last read operation is more recent than the |
2230 /* If the time we did the last read operation is more recent than the |
2217 * last interupt, we have to go to sleep (or return -EAGAIN in non blockin |
2231 * last interupt, we have to go to sleep (or return -EAGAIN in non blocking |
2218 * mode). Then, if we're awoken, we return the value that triggered the |
2232 * mode). Then, if we're awoken, we return the value that triggered the |
2219 * interrupt. (If awoken from a signal, we return -ERESTARTSYS.) |
2233 * interrupt. (If awoken from a signal, we return -ERESTARTSYS.) |
2220 * |
2234 * |
2221 * If we haven't read any data since the last irq occured, we return |
2235 * If we haven't read any data since the last irq occured, we return |
2222 * the current(!) value visible on the port! |
2236 * the current(!) value visible on the port! |
2230 |
2244 |
2231 if (wait_event_interruptible(subinfo->readq, (priv->last_read != subinfo->int_seen))) |
2245 if (wait_event_interruptible(subinfo->readq, (priv->last_read != subinfo->int_seen))) |
2232 return -ERESTARTSYS; |
2246 return -ERESTARTSYS; |
2233 val = subinfo->int_di; |
2247 val = subinfo->int_di; |
2234 |
2248 |
2235 } else val = inw(subinfo->regbase + ME8100_DI_REG); |
2249 } else val = subinfo->int_di = inw(subinfo->regbase + ME8100_DI_REG); |
2236 |
|
2237 PDEBUG("me8100_read: val=0x%04x\n", val); |
|
2238 |
2250 |
2239 /* Remember the time of the last interrupt we've seen. (It might be |
2251 /* Remember the time of the last interrupt we've seen. (It might be |
2240 * 0 if there was no interrupt yet. This doesn't hurt, since the next |
2252 * 0 if there was no interrupt yet. This doesn't hurt, since the next |
2241 * read will see this (see above) and will wait until an irq raises.) |
2253 * read will see this (see above) and will wait until an irq raises.) |
2242 */ |
2254 */ |
2243 priv->last_read = subinfo->int_seen; |
2255 priv->last_read = subinfo->int_seen; |
|
2256 |
|
2257 |
|
2258 PDEBUG("me8100_read: val=0x%04x\n", val); |
2244 |
2259 |
2245 /* Return at most 2 byte, but check if the read want's them both! */ |
2260 /* Return at most 2 byte, but check if the read want's them both! */ |
2246 if (len >= sizeof(val)) { |
2261 if (len >= sizeof(val)) { |
2247 err = put_user(val, (unsigned short*) buffer); |
2262 err = put_user(val, (unsigned short*) buffer); |
2248 len = sizeof(val); |
2263 len = sizeof(val); |
2300 if (priv->last_read >= subinfo->int_seen) return 0; |
2315 if (priv->last_read >= subinfo->int_seen) return 0; |
2301 return POLLIN | POLLRDNORM; |
2316 return POLLIN | POLLRDNORM; |
2302 |
2317 |
2303 } |
2318 } |
2304 |
2319 |
|
2320 int me8100_read_proc(char *buffer, char **start, off_t offset, int count, int *eof, void *data) |
|
2321 { |
|
2322 int len = 0; |
|
2323 len += sprintf(buffer + len, "Version: $Id$\n"); |
|
2324 *eof = 1; |
|
2325 return len; |
|
2326 } |
|
2327 |
2305 /* |
2328 /* |
2306 vim:sts=2 sw=2 aw ai sm: |
2329 vim:sts=2 sw=2 aw ai sm: |
2307 */ |
2330 */ |
2308 |
2331 |