Commit 64d9fb0c authored by Cesar Prados's avatar Cesar Prados

update VME Master driver

parent d9cd2a64
[submodule "drv"]
path = drv
url = git@github.com:GSI-CS-CO/kernel_modules.git
Subproject commit ce3cf1da1b98175b04c3e685b155fc153926790f
if it doesn't compile try:
- installing libc6-dev-i386
ifneq ($(CONFIG_VME_BUS),m)
ifneq ($(CONFIG_VME_BUS),y)
SUBDIRS = driver include lib drvrtest test pylib test_vetar
endif
endif
all: $(SUBDIRS:=-all)
clean: $(SUBDIRS:=-clean)
install: driver-install
%-all:
$(MAKE) -C $* all
%-clean:
$(MAKE) -C $* clean
%-install:
$(MAKE) -C $* install
Work in progress...
* Make sure all windows mapping are removed at module remove time
do it in vme_window_remove. - OK
* Add a vme_release_mapping() function - OK
* Check with Julian if we want a strict CES driver emulation - OK
* Fix mapping creation desc pci address - OK
* Fix module unload BUG - OK
* At module unload: remove all the mappings - OK
* At file close remove all mappings for the task - OK
* Round up VME address and size to a 64K boundary at window creation - OK
* Implement mmap - OK
* Add CES vme_intset() and vme_intclr() functions - OK
* Write CES emulation user library - OK in vmelib
* Should that lib provides vme_intset() and vme_intclr()? - NO OK
* Write misc library (bus error check, byte swapping, ...) - OK in vmelib
* Implement DMA handling in driver - no need for driver API - OK
* Implement DMA support userspace library - OK
* In vme_dma_exit() try an abort after a wait_event_interruptible_timeout() - OK
00:00.0 Host bridge: Intel Corporation Mobile 945GME Express Memory Controller Hub (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Mobile 945GME Express Integrated Graphics Controller (rev 03)
00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 2 (rev 02)
00:1c.4 PCI bridge: Intel Corporation 82801GR/GH/GHM (ICH7 Family) PCI Express Port 5 (rev 02)
00:1c.5 PCI bridge: Intel Corporation 82801GR/GH/GHM (ICH7 Family) PCI Express Port 6 (rev 02)
00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #1 (rev 02)
00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2)
00:1f.0 ISA bridge: Intel Corporation 82801GHM (ICH7-M DH) LPC Interface Bridge (rev 02)
00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE Controller (rev 02)
00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 02)
01:00.0 PCI bridge: Tundra Semiconductor Corp. Unknown device 8114 (rev 02)
02:07.0 Network controller: VMIC Unknown device 5565 (rev 01)
03:00.0 PCI bridge: Tundra Semiconductor Corp. Unknown device 8114 (rev 02)
04:0c.0 Bridge: Tundra Semiconductor Corp. Tsi148 [Tempe] (rev 01)
05:00.0 Serial controller: Oxford Semiconductor Ltd Unknown device c120
06:00.0 Ethernet controller: Intel Corporation 82573L Gigabit Ethernet Controller
-[00]-+-00.0 Host Bridge
|
+-02.0 VGA controller
|
+-1c.0-+ PCI Bridge PCIe port 1
| |
| +- [01-02]-+ Bus 1 - subordinate 2
| |
| +- 00.0-+ PCI bridge (TSI 384)
| |
| +- [02]-+ Bus 2
| |
| +- 07.0 VMIC Network controller
|
+-1c.1-+ PCI Bridge PCIe port 2
| |
| +- [03-04]-+ Bus 3 - subordinate 4
| |
| +- 00.0-+ PCI bridge (TSI 384)
| |
| +- [04]-+ Bus 4
| |
| +- 0c.0 VME bridge (TSI148)
|
+-1c.4-+ PCI Bridge PCIe port 5
| |
| +- [05]-+ Bus 5
| |
| +- 00.0 Serial controller (Oxford)
|
+-1c.5-+ PCI Bridge PCIe port 6
| |
| +- [06]-+ Bus 6
| |
| +- 00.0 Ethernet controller (82573L)
|
+-1d.0 USB Controller
|
+-1d.7 USB Controller
|
+-1e.0-+ PCI Bridge
| |
| +- [07]- Bus 7
|
+-1f.0 ISA bridge
|
+-1f.1 IDE interface
|
+-1f.3 SMBus
This diff is collapsed.
*.o
*.ko
*.cmd
*.mod.c
Module.symvers
modules.order
.tmp_versions
obj-m += vmebus.o
vmebus-objs := tsi148.o vme_bridge.o vme_cesif.o vme_dma.o vme_irq.o vme_misc.o vme_window.o
# KVER=2.6.24.7-rt21
# KVER=2.6.24.7-rt27
# KVER=2.6.29.4-rt15
# KVER=2.6.31.6-rt19
# KVER32 ?= 3.2.33-rt50
# KVER64 ?= 3.2.33-rt50.66.el6rt.x86_64
KERNELVER ?= `uname -r`
KERNELDIR ?= /lib/modules/$(KERNELVER)/build
CFLAGS=-g -Wall
all: driver
driver: modules
modules:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules
install:
$(MAKE) -C $(KERNELDIR) M=`pwd` INSTALL_MOD_PATH=$(STAGING) modules_install
clean:
rm -f *.o *.a *.so $(TESTS)
rm -f *.mod.c .*.cmd
rm -rf L866 L865 L864 ppc .tmp_versions
rm -f *.ko
rm -f Module.symvers modules.order
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* vme_bridge.h - PCI-VME bridge driver definitions
*
* Copyright (c) 2009 Sebastien Dugue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
/*
* This file provides the data structures and definitions internal to the
* driver.
*/
#ifndef _VME_BRIDGE_H
#define _VME_BRIDGE_H
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include "tsi148.h"
#include "vmebus.h"
#define PFX "VME Bridge: "
#define DRV_MODULE_NAME "vmebus"
#define DRV_MODULE_VERSION "1.4"
#define DRV_MODULE_RELDATE "May, 19 2010"
/*
* We just keep the last VME error caught, protecting it with a spinlock.
* A new VME bus error overwrites it.
* This is very simple yet good enough for most (sane) purposes.
* A linked list of handlers is kept for async notification of bus errors.
*/
struct vme_verr {
spinlock_t lock;
struct vme_bus_error_desc desc;
struct list_head h_list;
};
struct vme_bridge_device {
int rev; /* chip revision */
int irq; /* chip interrupt */
int slot; /* the VME slot we're in */
int syscon; /* syscon status */
struct tsi148_chip *regs;
struct pci_dev *pdev;
struct vme_verr verr;
};
/**
* struct vme_berr_handler - VME bus error handler descriptor
* @h_list: handler's list entry
* @offset: VME Bus error descriptor (Initial address + Address Modifier)
* @size: Size of the VME address range of interest
* @func: Handler function
*/
struct vme_berr_handler {
struct list_head h_list;
struct vme_bus_error error;
size_t size;
vme_berr_handler_t func;
};
extern struct vme_bridge_device *vme_bridge;
extern struct resource *vmepcimem;
extern void *crg_base;
extern unsigned int vme_report_bus_errors;
/* Use the standard VME Major */
#define VME_MAJOR 221
/*
* Define our own minor numbers
* If a device get added, do not forget to update devlist[] in vme_bridge.c
*/
#define VME_MINOR_MWINDOW 0
#define VME_MINOR_DMA 1
#define VME_MINOR_CTL 3
#define VME_MINOR_REGS 4
#define VME_MINOR_NR VME_MINOR_LM + 1
/* Devices access rules */
#define DEV_RW 1 /* Device implements read/write */
struct dev_entry {
unsigned int minor;
char *name;
unsigned int flags;
struct file_operations *fops;
};
extern const struct dev_entry devlist[];
/* Prototypes */
/* vme_irq.c */
extern void account_dma_interrupt(int);
extern irqreturn_t vme_bridge_interrupt(int, void *);
extern int vme_enable_interrupts(unsigned int);
extern int vme_disable_interrupts(unsigned int);
/* vme_window.c */
extern int vme_window_release(struct inode *, struct file *);
extern long vme_window_ioctl(struct file *, unsigned int, unsigned long);
extern int vme_window_mmap(struct file *, struct vm_area_struct *);
extern void __devinit vme_window_init(void);
extern void __devexit vme_window_exit(void);
/* vme_dma.c */
extern void handle_dma_interrupt(int);
extern long vme_dma_ioctl(struct file *, unsigned int, unsigned long);
extern int __devinit vme_dma_init(void);
extern void __devexit vme_dma_exit(void);
/* vme_misc.c */
extern ssize_t vme_misc_read(struct file *, char *, size_t, loff_t *);
extern ssize_t vme_misc_write(struct file *, const char *, size_t, loff_t *);
extern long vme_misc_ioctl(struct file *, unsigned int, unsigned long);
extern int vme_bus_error_check(int clear);
extern int vme_bus_error_check_clear(struct vme_bus_error *);
/* Procfs stuff grouped here for comodity */
#ifdef CONFIG_PROC_FS
extern int vme_interrupts_proc_show(char *page, char **start, off_t off,
int count, int *eof, void *data);
extern int vme_irq_proc_show(char *page, char **start, off_t off,
int count, int *eof, void *data);
extern int vme_window_proc_show(char *page, char **start, off_t off,
int count, int *eof, void *data);
#endif /* CONFIG_PROC_FS */
#endif /* _VME_BRIDGE_H */
/*
* vme_cesif - Emulation for the LynxOS CES driver
*
* Copyright (c) 2009 Sebastien Dugue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
/*
* This file provides emulation for the find_controller(), return_controller(),
* vme_intset() and vme_intclr() interfaces of the LynxOS CES driver.
*/
#define DEBUG
#include <linux/device.h>
#include "vmebus.h"
#include "vme_bridge.h"
/**
* find_controller() - Maps a VME address space into the PCI address space
* @vmeaddr: VME physical start address of the mapping
* @len: Window size (must be a multiple of 64k)
* @am: VME address modifier
* @offset: Offset in the mapping for read access test (Not used)
* @size: Data width
* @param: VME mapping parameters
*
* This function is an emulation of the CES driver functionality on LynxOS.
*
* The CES function interface does not give all the needed VME parameters, so
* the following choices were made and may have to be tweaked.
*
* - if read prefetch is enabled the the prefetch size is set to 2 cache lines
* - the VME address and size are automatically aligned on 64k if needed
* - the VME address is limited to 32 bits
*
* The kernel allocated mapping descriptor address (cookie) is stored in
* the pdparam_master sgmin field for use by return_controller().
*
* @return virtual address of the mapping - if success.
* @return -1 - on failure.
*/
unsigned long find_controller(unsigned long vmeaddr, unsigned long len,
unsigned long am, unsigned long offset,
unsigned long size, struct pdparam_master *param)
{
struct vme_mapping *desc;
int rc = 0;
/* Allocate our mapping descriptor */
if ((desc = kzalloc(sizeof(struct vme_mapping), GFP_KERNEL)) == NULL) {
printk(KERN_ERR PFX "%s - "
"Failed to allocate mapping descriptor\n", __func__);
return -1;
}
/* Now fill it with the parameters we got */
if (param->rdpref) {
desc->read_prefetch_enabled = 1;
desc->read_prefetch_size = VME_PREFETCH_2;
}
switch (size) {
case 2:
desc->data_width = VME_D16;
break;
case 4:
desc->data_width = VME_D32;
break;
default:
printk(KERN_ERR PFX "%s - Unsupported data width %ld\n",
__func__, size);
rc = -1;
goto out_free;
break;
}
desc->am = am;
desc->bcast_select = 0;
/*
* Note: no rounding up/down for size and address at this point,
* since that's taken care of when creating the window (if any).
*/
desc->sizel = len;
desc->sizeu = 0;
desc->vme_addrl = vmeaddr;
desc->vme_addru = 0;
/*
* Now we're all set up, just call the mapping function. We force
* window creation if no existing mapping can be found.
*/
if ((rc = vme_find_mapping(desc, 1))) {
printk(KERN_ERR PFX "%s - "
"Failed (rc is %d) to find a mapping "
"for VME addr: %.8lx Size:%8lx AM: %.2lx\n",
__func__, rc, vmeaddr, len, am);
rc = -1;
goto out_free;
}
printk(KERN_DEBUG PFX "%s - "
"Mapping found, VME addr: %.8lx "
"Size:%.8lx AM: %.2lx mapped at %p\n",
__func__, vmeaddr, len, am, desc->kernel_va);
return (unsigned long)desc->kernel_va;
out_free:
kfree(desc);
return rc;
}
EXPORT_SYMBOL_GPL(find_controller);
/**
* @brief Release a VME mapping
*
* @param logaddr - CPU logical address returned by @ref find_controller()
* @param len - size of the mapped window in bytes.
*
* This function is an emulation of the CES driver functionality on LynxOS.
*
* @return 0 - on success.
* @return -1 - if fails.
*/
unsigned long return_controller(unsigned logaddr, unsigned len)
{
struct vme_mapping *desc = find_vme_mapping_from_addr(logaddr);
int err;
if (!desc) {
printk(KERN_ERR PFX "%s - mapping not found @ 0x%x",
__func__, logaddr);
return -1;
}
err = vme_release_mapping(desc, 1);
if (!err)
return 0;
printk(KERN_ERR PFX "%s - failed to remove mapping @ 0x%x (err=%d)\n",
__func__, logaddr, err);
return -1;
}
EXPORT_SYMBOL_GPL(return_controller);
/**
* vme_intset() - Install an interrupt handler for the given vector
* @vec: Interrupt vector
* @handler: Handler function
* @arg: Handler argument
* @sav: Unused
*
* This function is an emulation of the CES driver functionality on LynxOS.
*
* Returns 0 on success, or a standard kernel error
*/
int vme_intset(int vec, int (*handler)(void *), void *arg, void *sav)
{
return vme_request_irq(vec, handler, arg, NULL);
}
EXPORT_SYMBOL_GPL(vme_intset);
/**
* vme_intclr() - Uninstall the interrupt handler for the given vector
* @vec: Interrupt vector
* @sav: Unused
*
* This function is an emulation of the CES driver functionality on LynxOS.
*
* Returns 0 on success, or a standard kernel error
*/
int vme_intclr(int vec, void *sav)
{
return vme_free_irq(vec);
}
EXPORT_SYMBOL_GPL(vme_intclr);
This diff is collapsed.
/*
* vme_dma.h -
*
* Copyright (c) 2009 Sebastien Dugue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef _VME_DMA_H
#define _VME_DMA_H
#include "vmebus.h"
/**
* struct dma_channel - Internal data structure representing a DMA channel
* @busy: Busy flag
* @num: Channel number
* @desc: DMA transfer descriptor currently used
* @chained: Chained (1) / Direct (0) transfer
* @sgl: Scatter gather list of userspace pages for the transfer
* @sg_pages: Number of pages in the scatter gather list
* @sg_mapped: Number of pages mapped onto the PCI bus
* @hw_desc: List of hardware descriptors
* @wait: Wait queue for the DMA channel
*
* Note: concurrent access to all the DMA channels is protected by a
* per-bridge mutex.
*/
struct dma_channel {
unsigned int busy;
unsigned int num;
struct vme_dma desc;
int chained;
struct scatterlist *sgl;
int sg_pages;
int sg_mapped;
struct list_head hw_desc_list;
wait_queue_head_t wait;
};
/**
* struct hw_desc_entry - Hardware descriptor
* @list: Descriptors list
* @va: Virtual address of the descriptor
* @phys: Bus address of the descriptor
*
* This data structure is used internally to keep track of the hardware
* descriptors that are allocated in order to free them when the transfer
* is done.
*/
struct hw_desc_entry {
struct list_head list;
void *va;
dma_addr_t phys;
};
#endif /* _VME_DMA_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
*.o
*.ko
*.cmd
*.mod.c
Module.symvers
modules.order
.tmp_versions
obj-m += ctr_pps_irq.o
obj-m += ctr_multi_irq.o
obj-m += loopirq.o
obj-m += vmemon.o
obj-m += test.o
# This is useful if cross-compiling. Taken from kernel Makefile (CC changed)
#AS =$(CROSS_COMPILE)as
#LD =$(CROSS_COMPILE)ld
#CC =$(CROSS_COMPILE)gcc
#CPP =$(CC) -E
#AR =$(CROSS_COMPILE)ar
#NM =$(CROSS_COMPILE)nm
#STRIP =$(CROSS_COMPILE)strip
#OBJCOPY =$(CROSS_COMPILE)objcopy
#OBJDUMP =$(CROSS_COMPILE)objdump
KERNELVER ?= `uname -r`
KERNELDIR ?= /lib/modules/$(KERNELVER)/build
ifneq ($(KERNELRELEASE),)
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all: vmedriver modules
vmedriver:
cp ../driver/Module.symvers .
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# libvmebus.h and vmebus.h are symlinks generated by make
libvmebus.h
vmebus.h
#include ../common.mk
#include /acc/src/dsc/co/Make.auto
all: clean
ln -s ../driver/vmebus.h vmebus.h
ln -s ../driver/libvmebus.h libvmebus.h
.PHONY: all clean deliver
clean:
rm -f vmebus.h libvmebus.h
$(RM) $(BAKS)
deliver: all
@ umask 0002; \
if [ ! -d $(INSTDIR) ]; then \
echo "Creating $(INSTDIR)"; \
mkdir -p $(INSTDIR); \
fi; \
echo "Copying vmebus.h and libvmebus.h to $(INSTDIR)"; \
dsc_install vmebus.h libvmebus.h $(INSTDIR)
libvmebus.a
libvmebus.so
*.o
EXTSO = .so
EXTLIB = .a
OBJFILES = libvmebus.o
DRIVER_NAME = vmebus
FINAL_DEST = ./
RANLIB = ranlib
INCDIRS= -I../driver
CFLAGS = ${INCDIRS}
CFLAGS += -fPIC
all:lib$(DRIVER_NAME)$(EXTSO) lib$(DRIVER_NAME)$(EXTLIB)
# Rules to build .a library
lib$(DRIVER_NAME)$(EXTLIB): lib$(DRIVER_NAME)$(EXTLIB)($(OBJFILES))
$(RANLIB) $@
lib$(DRIVER_NAME)$(EXTSO): $(OBJFILES)
$(CC) -shared -Wl,-export-dynamic -Wl,-soname,$(@:%.so=%.so) -o $@ $(OBJFILES)
clean:
rm -f $(OBJFILES) *.a *.so
This diff is collapsed.
This diff is collapsed.
libvmebus.a
libvmebus.so
*.o
CFLAGS += -I../driver -O0 -m32
CC = gcc
all: libvmebus.a libvmebus.so
libvmebus.a: libvmebus.o
ar r $@ $^
libvmebus.so: libvmebus.o
$(CC) -m32 -shared $^ -o $@
install:
install -D libvmebus.a libvmebus.so /usr/lib/
clean:
rm -f *.o *.a *.so
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment