/* Private kernel definitions for Linux VME support. * G.Paubert 1997-1999 */ #ifndef _VME_VME_H #define _VME_VME_H #define VME_MAGIC ('V'+'M'+'E') /* Should be 0xE8 */ #include #include /* The VME address modifiers in numerical order. Some are still missing, * namely A40, MD32, and 2eBLT. The official VME nomenclature is quite * confusing, defining different names for address modifiers and corresponding * capabilities, with the following non obvious equivalences: * - A16 <-> SHORT * - A24 <-> STANDARD * - A32 <-> EXTENDED * - A64 <-> LONG * Only the Ann notation will be employed because it seems much clearer, * and the default will be non-privileged data access. */ #define VME_DW_SHIFT 8 #define VME_DW_MASK 0x00000f00 #define VME_DW(x) (((x)<<(VME_DW_SHIFT-3)) & VME_DW_MASK) /* Since 2eBLT makes use of 8 bits of extended address modifier codes, * we leave room in the flags to implement it in the future. */ #define VME_AM_MASK 0x3f000000 #define VME_AM_SHIFT 24 #define VME_AM(x) (((x)<vme_rxx, same for write * and the ones with included barriers would be vme_rawxx, vme_rarxx, * and vme_wawxx. */ #if defined(__powerpc__) #define vme_rar_barrier() __asm__ __volatile__("eieio") #define vme_raw_barrier() __asm__ __volatile__("eieio") #define vme_waw_barrier() __asm__ __volatile__("eieio") #elif defined(__mc68000__) || defined(__i386__) #define vme_rar_barrier() do { } while(0) #define vme_raw_barrier() do { } while(0) #define vme_waw_barrier() do { } while(0) #else #error "VME bus is not supported under Linux for this architecture" #endif #include struct vme_device { struct vme_device *next; struct file_operations * fops; /* These 3 fields are necessary to perform automatic * deallocation when unregistering a device. */ struct vme_region *regions; struct vme_interrupt *interrupts; struct vme_dma *dmalists; char * name; void * private; u_int minor; }; struct vme_interrupt { struct vme_interrupt * next; void (*handler)(struct vme_interrupt *, int, int); struct vme_device *device; void * handler_data; char * name; u_long count; u_int level, vector; u_int flags; /* interrupt attributes */ }; struct vme_region { struct vme_region * next; struct vme_device * device; volatile u_char *kvaddr; u_long phyaddr; u_long base; u_long limit; u_int flags; }; struct vme_dma { struct vme_dma * next; struct vme_dma * queue; /* To queue DMA requests */ struct vme_device * device; void * private; /* Memory pointer to the head of the list */ void (*handler)(struct vme_dma *); void * handler_data; size_t maxfrags; /* Maximum number of scatter/gather fragments */ size_t remlen; long timeout; /* timeout in jiffies */ u_int flags; /* VME_DMA_BUSY and other internal flags */ u32 error; /* Error status: 0, -EIO, -ETIME, ... */ }; /* Set by queue_dmalist and cleared by release_dmalist */ #define VME_DMA_BUSY 0 #define VME_DMA_READY 1 struct vme_dmavec { u_long kvaddr; u_long vme_addr; size_t length; u32 flags; }; #if defined(__powerpc__) /* These functions have been optimized on PPC, a portable version should * be written for other architectures and be exported as a general kernel * service. */ extern long copy_user_io(volatile void *, volatile const void*, u_long); #define copy_io_to_user(d,s,l) copy_user_io(d,s,l) #define copy_user_to_io(d,s,l) copy_user_io(d,s,l) #endif int vme_register_device(struct vme_device *); void vme_unregister_device(struct vme_device *); int vme_register_region(struct vme_device *, struct vme_region *); void vme_unregister_region(struct vme_region *); int vme_request_interrupt(struct vme_device *, struct vme_interrupt *); void vme_free_interrupt(struct vme_interrupt *); /* This interface might still change: although it seems pretty stable now. */ int vme_alloc_dmalist(struct vme_device *, struct vme_dma *, size_t); void vme_free_dmalist(struct vme_dma *); int vme_queue_dmalist(struct vme_dma *, struct vme_dmavec *, size_t); /* This function has to be called in the dma termination handlers. */ extern inline void vme_release_dmalist(struct vme_dma * dma) { clear_bit(VME_DMA_BUSY, &dma->flags); } int vme_safe_access(u_int, u32, u_long, u_long *); int vme_modbits(u_int, u32, u_long, u_int *, u_int); #endif /*!_VME_VME_H*/