Merge branch 'master' into can-usb1
authorppisa <pisa@cmp.felk.cvut.cz>
Sat, 1 Nov 2008 12:40:35 +0000 (13:40 +0100)
committerppisa <pisa@cmp.felk.cvut.cz>
Sat, 1 Nov 2008 12:40:35 +0000 (13:40 +0100)
The changes between LinCAN 0.3.3 version and current master head are propagated
into "can-usb1" branch.

Conflicts:

lincan/include/kthread.h
lincan/include/main.h
lincan/src/Makefile.omk
lincan/src/bfadcan.c
lincan/src/boardlist.c
lincan/src/finish.c
lincan/src/kthread.c
lincan/src/main.c
lincan/src/modparms.c
lincan/src/proc.c
lincan/src/setup.c

84 files changed:
lincan/CREDITS
lincan/Makefile
lincan/Makefile.omk
lincan/README
lincan/include/aim104.h
lincan/include/c_can.h
lincan/include/can.h
lincan/include/can_sysdep.h
lincan/include/canmsg.h
lincan/include/cc_can104.h
lincan/include/eb8245.h
lincan/include/gensja1000io.h [new file with mode: 0644]
lincan/include/hcan2.h [new file with mode: 0644]
lincan/include/hms30c7202_can.h
lincan/include/ipci165.h
lincan/include/kthread.h
lincan/include/m437.h
lincan/include/main.h
lincan/include/msmcan.h
lincan/include/ns_dev_can.h
lincan/include/nsi.h
lincan/include/nsi_canpci.h
lincan/include/oscar.h
lincan/include/pc-i03.h
lincan/include/pcan_dongle.h
lincan/include/pccan.h
lincan/include/pcccan.h
lincan/include/pcm3680.h
lincan/include/pikronisa.h
lincan/include/pip.h
lincan/include/sh7760.h [new file with mode: 0644]
lincan/include/smartcan.h
lincan/include/ssv.h
lincan/include/template.h
lincan/include/tscan1.h
lincan/src/Makefile
lincan/src/Makefile.omk
lincan/src/Makefile.std
lincan/src/adlink7841.c
lincan/src/aim104.c
lincan/src/bfadcan.c
lincan/src/boardlist.c
lincan/src/c_can.c
lincan/src/c_can_irq.c
lincan/src/cc_can104.c
lincan/src/eb8245.c
lincan/src/ems_cpcpci.c
lincan/src/esdpci200.c [new file with mode: 0644]
lincan/src/gensja1000io.c [new file with mode: 0644]
lincan/src/hcan2.c [new file with mode: 0644]
lincan/src/hms30c7202_can.c
lincan/src/i82527.c
lincan/src/ipci165.c
lincan/src/kthread.c
lincan/src/kv_pcican.c
lincan/src/m437.c
lincan/src/main.c
lincan/src/modparms.c
lincan/src/msmcan.c
lincan/src/ns_dev_can.c
lincan/src/nsi.c
lincan/src/nsi_canpci.c
lincan/src/open.c
lincan/src/oscar.c
lincan/src/pc_i03.c
lincan/src/pcan_dongle.c
lincan/src/pcan_pci.c [new file with mode: 0644]
lincan/src/pccan.c
lincan/src/pcccan.c
lincan/src/pcm3680.c
lincan/src/pikronisa.c
lincan/src/pimx1.c
lincan/src/pip.c
lincan/src/proc.c
lincan/src/setup.c
lincan/src/sh7760.c [new file with mode: 0644]
lincan/src/sja1000.c
lincan/src/smartcan.c
lincan/src/ssv.c
lincan/src/sysdep_lnx.c
lincan/src/template.c
lincan/src/tscan1.c
lincan/src/unican.c
lincan/utils/Makefile

index e16a913..66b123f 100644 (file)
@@ -41,6 +41,10 @@ Ronald Gomes, Technologic Systems
 http://www.embeddedarm.com/
        contributed support for TS-CAN1 and TS-7KV
 
+Manuel Bessler, m.bessler@gmx.net
+http://projects.varxec.net/can_pci-200
+       contributed support for ESD Electronics CAN/PCI-200 card
+
 ========================================
 List of companies and subjects
 who donated hardware to LinCAN project
index f595272..b22a357 100644 (file)
@@ -1,14 +1,14 @@
 # Generic directory or leaf node makefile for OCERA make framework
 
 ifndef MAKERULES_DIR
-MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
 endif
 
 ifeq ($(MAKERULES_DIR),)
 all : default
 .DEFAULT::
        @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
-else   
+else
 include $(MAKERULES_DIR)/Makefile.rules
 endif
 
index d43b19d..f268924 100644 (file)
@@ -1,2 +1,2 @@
-SUBDIRS = src utils
+SUBDIRS = src
 
index 00f8768..faf2677 100644 (file)
@@ -251,6 +251,7 @@ The hw argument can be one of:
 - pcm3680, for the PCM-3680 PC/104 card by Advantech
 - m437, for the M436 PC/104 card by SECO
 - bfadcan for sja1000 CAN embedded card made by BFAD GmbH
+- gensja1000io for many sja1000 I/O mapped cards (PCAN-PC/104 for example).
 - pikronisa for ISA memory mapped sja1000 CAN card made by PiKRON Ltd.
 - pimx1 for MX1_DIS1 extension board for PiMX1 ARM based BCC
 - msmcan for MICROSPACE IO space indexed i82527
@@ -266,6 +267,8 @@ The hw argument can be one of:
 - tscan1 for Technologic Systems' TS-CAN1 single SJA1000 based board
 - ts7kv for Technologic Systems' TS-7KV Multi-function board with SJA1000
    both these cards require CONFIG_OC_LINCAN_CARD_tscan1=y
+- pcan_pci for PEAK System PCAN-PCI single, double or quad SJA1000 based board
+- esdpci200 for the CAN/PCI-200 card by ESD Electronics board
 - template, for yet unsupported hardware (you need to edit src/template.c)
 - virtual, CAN channel for testing of software and driver without CAN hardware
 
@@ -276,7 +279,7 @@ options can be one of:
 - extended=[1|0], configures the driver to use extended message format.
 - pelican=[1|0], configures the driver to set the CAN chips into pelican mode.
 - baudrate=<nr>, sets the baudrate of the device(s)
-- clock_freq=<nr>, the frequency of the CAN quartz
+- clockfreq=<nr>, the frequency of the CAN quartz
 - stdmask=<nr>, sets the standard mask of the device
 - extmask=<nr>, sets the extended mask of the device
 - mo15mask=<nr>, sets the mask for message object 15 (i82527 only)
index 0426441..f65074c 100644 (file)
@@ -13,7 +13,7 @@ int aim104_reset(struct candevice_t *candev);
 int aim104_init_hw_data(struct candevice_t *candev);
 int aim104_init_chip_data(struct candevice_t *candev, int chipnr);
 int aim104_init_obj_data(struct canchip_t *chip, int objnr);
-void aim104_write_register(unsigned data, unsigned long address);
-unsigned aim104_read_register(unsigned long address);
+void aim104_write_register(unsigned data, can_ioptr_t address);
+unsigned aim104_read_register(can_ioptr_t address);
 int aim104_program_irq(struct candevice_t *candev);
 
index f5d9d10..5a189b3 100644 (file)
@@ -14,7 +14,7 @@
  */
 extern inline void c_can_write_reg_w(const struct canchip_t *pchip, u16 data, unsigned reg)
 {
-       u32 address = pchip->chip_base_addr + reg;
+       can_ioptr_t address = pchip->chip_base_addr + reg;
     #ifndef CONFIG_OC_LINCAN_DYNAMICIO
        writew(data,address);
     #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
@@ -24,7 +24,7 @@ extern inline void c_can_write_reg_w(const struct canchip_t *pchip, u16 data, un
 
 extern inline u16 c_can_read_reg_w(const struct canchip_t *pchip, unsigned reg)
 {
-       u32 address = pchip->chip_base_addr + reg;
+       can_ioptr_t address = pchip->chip_base_addr + reg;
     #ifndef CONFIG_OC_LINCAN_DYNAMICIO
        return readw(address);
     #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
index b3b265c..8ff57ea 100644 (file)
@@ -18,6 +18,7 @@
 
 #else /* __KERNEL__ */
 
+#include <inttypes.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
index 5d57f5c..1009689 100644 (file)
   #define CAN_IRQ_HANDLED IRQ_HANDLED
   #define CAN_IRQ_RETVAL  IRQ_RETVAL
 #endif /* <=2.5.67 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+  #define CAN_IRQ_HANDLER_ARGS(irq_number, dev_id) \
+               int irq_number, void *dev_id, struct pt_regs *regs
+#else /* < 2.6.19 */
+  #define CAN_IRQ_HANDLER_ARGS(irq_number, dev_id) \
+               int irq_number, void *dev_id
+#endif /* < 2.6.19 */
 #else /*CAN_WITH_RTL*/
   typedef int can_irqreturn_t;
   #define CAN_IRQ_NONE        0
   #define CAN_IRQ_HANDLED     1
   #define CAN_IRQ_RETVAL(x)   ((x) != 0)
+  #define CAN_IRQ_HANDLER_ARGS(irq_number, dev_id) \
+               int irq_number, void *dev_id, struct pt_regs *regs
 #endif /*CAN_WITH_RTL*/
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,33))
   #define del_timer_sync del_timer
 #endif /* <2.4.0 */
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+   typedef unsigned long can_ioptr_t;
+   #define can_ioptr2ulong(ioaddr) ((unsigned long)(ioaddr))
+   #define can_ulong2ioptr(addr)   ((unsigned long)(addr))
+   #define can_inb(ioaddr) inb(ioaddr)
+   #define can_outb(data,ioaddr) outb(data,ioaddr)
+   #define can_inw(ioaddr) inb(ioaddr)
+   #define can_outw(data,ioaddr) outb(data,ioaddr)
+   #define can_inl(ioaddr) inb(ioaddr)
+   #define can_outl(data,ioaddr) outb(data,ioaddr)
+#else /* >=2.6.9 */
+   typedef void __iomem * can_ioptr_t;
+   #define can_ioptr2ulong(ioaddr) ((unsigned long __force)(ioaddr))
+   #define can_ulong2ioptr(addr)   ((can_ioptr_t)(addr))
+   #define can_inb(ioaddr) inb(can_ioptr2ulong(ioaddr))
+   #define can_outb(data,ioaddr) outb(data,can_ioptr2ulong(ioaddr))
+   #define can_inw(ioaddr) inb(can_ioptr2ulong(ioaddr))
+   #define can_outw(data,ioaddr) outb(data,can_ioptr2ulong(ioaddr))
+   #define can_inl(ioaddr) inb(can_ioptr2ulong(ioaddr))
+   #define can_outl(data,ioaddr) outb(data,can_ioptr2ulong(ioaddr))
+#endif
+
+#define can_readb  readb
+#define can_writeb writeb
+#define can_readw  readw
+#define can_writew writew
+#define can_readl  readl
+#define can_writel writel
+
+#define can_ioport2ioptr can_ulong2ioptr
+
 #ifdef __HAVE_ARCH_CMPXCHG
   #define CAN_HAVE_ARCH_CMPXCHG
 #endif
 #define CAN_DEFINE_SPINLOCK        DEFINE_SPINLOCK
 #endif /*DEFINE_SPINLOCK*/
 
-#if defined(CONFIG_PREEMPT) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+#if !defined(CONFIG_PREEMPT_RT) && ( defined(CONFIG_PREEMPT) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) )
 #define can_preempt_disable        preempt_disable
 #define can_preempt_enable         preempt_enable
 #else /*CONFIG_PREEMPT*/
index 779f68c..0738fc9 100644 (file)
@@ -16,6 +16,7 @@
 
 #else /* __KERNEL__ */
 
+#include <inttypes.h>
 #include <sys/time.h>
 #include <sys/types.h>
 
index 722746a..b3e5b10 100644 (file)
@@ -13,7 +13,7 @@ int cc104_reset(struct candevice_t *candev);
 int cc104_init_hw_data(struct candevice_t *candev);
 int cc104_init_chip_data(struct candevice_t *candev, int chipnr);
 int cc104_init_obj_data(struct canchip_t *chip, int objnr);
-void cc104_write_register(unsigned data, unsigned long address);
-unsigned cc104_read_register(unsigned long address);
+void cc104_write_register(unsigned data, can_ioptr_t address);
+unsigned cc104_read_register(can_ioptr_t address);
 int cc104_program_irq(struct candevice_t *candev);
 
index f076f38..ccb17dc 100644 (file)
@@ -17,5 +17,5 @@ int eb8245_init_hw_data(struct candevice_t *candev);
 int eb8245_init_chip_data(struct candevice_t *candev, int chipnr);
 int eb8245_init_obj_data(struct canchip_t *chip, int objnr);
 int eb8245_program_irq(struct candevice_t *candev);
-void eb8245_write_register(unsigned data, unsigned long address);
-unsigned eb8245_read_register(unsigned long address);
+void eb8245_write_register(unsigned data, can_ioptr_t address);
+unsigned eb8245_read_register(can_ioptr_t address);
diff --git a/lincan/include/gensja1000io.h b/lincan/include/gensja1000io.h
new file mode 100644 (file)
index 0000000..947992c
--- /dev/null
@@ -0,0 +1,22 @@
+/* gensja1000io.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Added by Pavel Pisa pisa@cmp.felk.cvut.cz
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3  17 Jun 2004
+ *
+ * Support for PiKRON Ltd ISA CAN card using 
+ * memory mapped SJA1000 controller
+ */
+
+int gensja1000io_request_io(struct candevice_t *candev);
+int gensja1000io_release_io(struct candevice_t *candev);
+int gensja1000io_reset(struct candevice_t *candev); 
+int gensja1000io_init_hw_data(struct candevice_t *candev);
+int gensja1000io_init_chip_data(struct candevice_t *candev, int chipnr);
+int gensja1000io_init_obj_data(struct canchip_t *chip, int objnr);
+int gensja1000io_program_irq(struct candevice_t *candev);
+void gensja1000io_write_register(unsigned data, can_ioptr_t address);
+unsigned gensja1000io_read_register(can_ioptr_t address);
+
diff --git a/lincan/include/hcan2.h b/lincan/include/hcan2.h
new file mode 100644 (file)
index 0000000..22c1458
--- /dev/null
@@ -0,0 +1,194 @@
+/* hcan2.h
+* Header file for the Linux CAN-bus driver.
+* This software is released under the GPL-License.
+*/
+
+int hcan2_chip_config(struct canchip_t *chip);
+int hcan2_enable_configuration(struct canchip_t *chip);
+int hcan2_disable_configuration(struct canchip_t *chip);
+
+int hcan2_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,      int sampl_pt, int flags);
+int hcan2_set_btregs(struct canchip_t *chip, unsigned short btr0, unsigned short btr1);
+
+int hcan2_start_chip(struct canchip_t *chip);
+int hcan2_stop_chip(struct canchip_t *chip);
+int hcan2_attach_to_chip(struct canchip_t *chip);
+int hcan2_release_chip(struct canchip_t *chip);
+
+int hcan2_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask);
+int hcan2_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask);
+int hcan2_message15_mask(int irq, struct canchip_t *chip);
+
+int hcan2_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
+int hcan2_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg);
+int hcan2_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg);
+int hcan2_remote_request(struct canchip_t *chip, struct msgobj_t *obj);
+
+int hcan2_irq_handler(int irq, struct canchip_t *chip);
+int hcan2_irq_accept(int irq, struct canchip_t *chip);
+int hcan2_config_irqs(struct canchip_t *chip, short irqs);
+
+int hcan2_clear_objects(struct canchip_t *chip);
+int hcan2_check_tx_stat(struct canchip_t *chip);
+int hcan2_check_MB_tx_stat(struct canchip_t *chip, struct msgobj_t *obj);
+int hcan2_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj);
+int hcan2_filtch_rq(struct canchip_t *chip, struct msgobj_t * obj);
+
+int hcan2_register(struct chipspecops_t *chipspecops);
+int hcan2_fill_chipspecops(struct canchip_t *chip);
+
+int hcan2_reset_chip(struct canchip_t *chip);
+
+
+extern inline void can_write_reg_w(const struct canchip_t *pchip, uint16_t data, unsigned reg)
+{
+       can_ioptr_t address = pchip->chip_base_addr + reg;
+    #ifndef CONFIG_OC_LINCAN_DYNAMICIO
+       writew(data,address);
+    #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
+       pchip->write_register(data, address);
+    #endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
+}
+
+extern inline uint16_t can_read_reg_w(const struct canchip_t *pchip, unsigned reg)
+{
+       can_ioptr_t address = pchip->chip_base_addr + reg;
+    #ifndef CONFIG_OC_LINCAN_DYNAMICIO
+       return readw(address);
+    #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
+       return pchip->read_register(address);
+    #endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
+}
+
+
+/* BasicCAN mode address map */
+#define HCAN2_MCR                0x00000000    /* Master control register */
+#define HCAN2_GSR                0x00000002    /* General status register */
+#define HCAN2_BCR1               0x00000004    /* Bit configuration register 1 */
+#define HCAN2_BCR0               0x00000006    /* Bit configuration register 0 */
+#define HCAN2_IRR                0x00000008    /* Interrupt request register */
+#define HCAN2_IMR                0x0000000a    /* Interrupt mask register */
+#define HCAN2_TECREC     0x0000000c    /* 15:8 Transmit error counter 7:0 Receive error counter */
+#define HCAN2_TXPR1              0x00000020    /* Transmit pending request register 1 */
+#define HCAN2_TXPR0              0x00000022    /* Transmit pending request register 0 */
+#define HCAN2_TXCR1              0x00000028    /* Transmit cancel register 1 */
+#define HCAN2_TXCR0              0x0000002a    /* Transmit cancel register 0 */
+#define HCAN2_TXACK1     0x00000030    /* Transmit acknowledge register 1 */
+#define HCAN2_TXACK0     0x00000032    /* Transmit acknowledge register 0 */
+#define HCAN2_ABACK1     0x00000038    /* Abort acknowledge register 1 */
+#define HCAN2_ABACK0     0x0000003a    /* Abort acknowledge register 0 */
+#define HCAN2_RXPR1              0x00000040    /* Receive data frame pending register 1 */
+#define HCAN2_RXPR0              0x00000042    /* Receive data frame pending register 0 */
+#define HCAN2_RFPR1              0x00000048    /* Remote frame request pending register 1 */
+#define HCAN2_RFPR0              0x0000004a    /* Remote frame request pending register 0 */
+#define HCAN2_MBIMR1     0x00000050    /* Mailbox interrupt mask register 1 */
+#define HCAN2_MBIMR0     0x00000052    /* Mailbox interrupt mask register 0 */
+#define HCAN2_UMSR1              0x00000058    /* Unread message status register 1 */
+#define HCAN2_UMSR0              0x0000005a    /* Unread message status register 0 */
+#define HCAN2_TCNTR              0x00000080    /* Timer counter register */
+#define HCAN2_TCR                0x00000082    /* Timer control register */
+#define HCAN2_TCMR               0x00000084    /* Timer Compare Match register */
+#define HCAN2_TDCR               0x00000086
+#define HCAN2_LOSR               0x00000088
+#define HCAN2_ICR1               0x0000008e
+#define HCAN2_TCMR0              0x00000090    /* Timer compare match register */
+#define HCAN2_TCMR1              0x00000092
+#define HCAN2_TCMR2              0x00000094
+#define HCAN2_CCR                0x00000096
+#define HCAN2_CMAX               0x00000098
+#define HCAN2_TMR                0x0000009a
+
+/* BaudRate minimal and maximal TSEG values */
+#define TSEG_MIN       8
+#define        TSEG_MAX        25
+#define TSEG1_MIN      4
+#define        TSEG1_MAX       16
+#define TSEG2_MIN      2
+#define        TSEG2_MAX       8
+
+enum hcan2_mcr {
+       /* bits 15 to 8 are used for test mode */
+       HCAN2_MCR_AWAKE = 1 << 7,               /* Auto Wake Mode */
+       HCAN2_MCR_SLEEP = 1 << 5,               /* Sleep Mode */
+       HCAN2_MCR_TXP   = 1 << 2,               /* Transmition Priority 0-message ID number priority, 1-mailbox number piority*/
+       HCAN2_MCR_HALT  = 1 << 1,               /* Halt Request */
+       HCAN2_MCR_RESET = 1 << 0,               /* Reset Request */
+};
+
+enum hcan2_gsr {
+       HCAN2_GSR_EPS   = 1 << 5,               /* Error Passive Status */
+       HCAN2_GSR_HSS   = 1 << 4,               /* Halt/Sleep Status */
+       HCAN2_GSR_RESET = 1 << 3,               /* Reset Status */
+       HCAN2_GSR_TXC   = 1 << 2,               /* Message Transmission Complete Flag */
+       HCAN2_GSR_TXRXW = 1 << 1,               /* Transmit/Receive Warning Flag */
+       HCAN2_GSR_BOFF  = 1 << 0,               /* Buss Off Flag */
+};
+
+/* IRR and IMR register */
+enum hcan2_irr {
+       HCAN2_IRR_TCMI  = 1 << 14,              /* Time Compare Match Register */
+       HCAN2_IRR_TOI   = 1 << 13,              /* Time Overrun Interrupt */
+       HCAN2_IRR_WUBA  = 1 << 12,              /* Wake-up on Bus Activity */
+       HCAN2_IRR_MOOI  = 1 << 9,               /* Message Overrun/Overwrite Interrupt Flag */
+       HCAN2_IRR_MBEI  = 1 << 8,               /* Messagebox Empty Interrupt Flag */
+       HCAN2_IRR_OF    = 1 << 7,               /* Overload Frame */
+       HCAN2_IRR_BOI   = 1 << 6,               /* Bus Off Interrupt Flag */
+       HCAN2_IRR_EPI   = 1 << 5,               /* Error Passive Interrupt Flag */
+       HCAN2_IRR_ROWI  = 1 << 4,               /* Receive Overload Warning Interrupt Flag */
+       HCAN2_IRR_TOWI  = 1 << 3,               /* Transmit Overload Warining Interrupt Flag */
+       HCAN2_IRR_RFRI  = 1 << 2,               /* Remote Frame Request Interrupt Flag */
+       HCAN2_IRR_DFRI  = 1 << 1,               /* Data Frame Received Interrupt Flag */
+       HCAN2_IRR_RHSI  = 1 << 0,               /* Reset/Halt/Sleep Interrupt Flag */
+};
+
+/* Message box 0-31 */
+#define HCAN2_MB0                0x00000100    /* RECEIVE ONLY */
+#define HCAN2_MB_OFFSET          0x00000020
+
+/* Message box structure offsets */
+#define HCAN2_MB_CTRL0 0x00000000      /* Control 0 */
+#define HCAN2_MB_CTRL1 0x00000002      /* Control 1 */
+#define HCAN2_MB_CTRL2 0x00000004      /* Control 2 */
+#define HCAN2_MB_TSTP  0x00000006      /* Time stamp */
+#define HCAN2_MB_DATA0 0x00000009      /* Data 0 */ 
+#define HCAN2_MB_DATA1 0x00000008      /* Data 1 */
+#define HCAN2_MB_DATA2 0x0000000b      /* Data 2 */
+#define HCAN2_MB_DATA3 0x0000000a      /* Data 3 */
+#define HCAN2_MB_DATA4 0x0000000d      /* Data 4 */
+#define HCAN2_MB_DATA5 0x0000000c      /* Data 5 */
+#define HCAN2_MB_DATA6 0x0000000f      /* Data 6 */
+#define HCAN2_MB_DATA7 0x0000000e      /* Data 7 */
+#define HCAN2_MB_MASK  0x00000010      /* Acceptance filter mask 4 bytes */
+
+/* Control register 0 */
+enum hcan2_mb_ctrl0{
+       HCAN2_MBCT0_STDID       = 0x7ff0,       /* STD ID */
+       HCAN2_MBCT0_RTR = 0x0008,       /* Remote transmition request 0-DataFrame 1-RemoteFrame */
+       HCAN2_MBCT0_IDE = 0x0004,       /* Identifier extension 0-Standard 1-Extended */
+       HCAN2_MBCT0_EXTID       = 0x0003        /* EXTID 17:16 */
+};
+
+/* Control register 1 */
+/* whole register is EXTD ID 15:0 */
+
+/* Control register 2 */
+enum hcan2_mb_ctrl2{
+       HCAN2_MBCT2_NMC         = 1<<13,        /* New message control */
+       HCAN2_MBCT2_ATX         = 1<<12,        /* Automatic transmition of data frame */
+       HCAN2_MBCT2_DART        = 1<<11,        /* Disable automatic re-transmition */
+       HCAN2_MBCT2_MBC         = 7<<8,         /* Mailbox configuration */
+       HCAN2_MBCT2_CBE         = 1<<5,         /* CAN bus error */
+       HCAN2_MBCT2_DLC         = 0xf           /* Data length code */
+};
+
+/* MessageBox modes */
+enum hcan2_mb_mode{
+       HCAN2_MBMOD_TXDR                = 0,    /* Transmit Data and Remote Frame */
+       HCAN2_MBMOD_TXDR_RXR    = 1,    /* Transmit Data and Remote Frame, Receive Remote Frame */
+       HCAN2_MBMOD_RXDR                = 2,    /* Receive Data and Remote Frame */
+       HCAN2_MBMOD_RXD                 = 3,    /* Receive Data Frame */
+       HCAN2_MBMOD_TXR_RXDR    = 4,    /* Transmit Remote Frame, Receive Data and Remove Frame */
+       HCAN2_MBMOD_TXR_RXD             = 5,    /* Transmit Remote Frame, Receive Data Frame */
+       /* 6 is not used and prohibited */
+       HCAN2_MBMOD_INNACTIVE   = 7,    /* Mailboc Innactive */
+};
index 9b4704e..520f0ec 100644 (file)
@@ -17,8 +17,8 @@ int hms30c7202_init_chip_data(struct candevice_t *candev, int chipnr);
 int hms30c7202_request_io(struct candevice_t *candev);\r
 int hms30c7202_release_io(struct candevice_t *candev);\r
 int hms30c7202_reset(  struct candevice_t *candev);\r
-void hms30c7202_write_register(unsigned data, unsigned long address);\r
-unsigned hms30c7202_read_register(unsigned long address);\r
+void hms30c7202_write_register(unsigned data, can_ioptr_t address);\r
+unsigned hms30c7202_read_register(can_ioptr_t address);\r
 \r
 \r
 \r
index 7f50484..4a3f354 100644 (file)
@@ -6,6 +6,7 @@
  * Version lincan-0.3  17 Jun 2004
  */ 
 
+#include "../include/can_sysdep.h"
 #include "../include/kthread.h"
 
 /* PCI device identification */
 
 /* BCI queue info */
 struct bci_queue_t {
-  int           idx;                       /* points to the active record in buffer */
-  unsigned long addr;                      /* start address of the message queue    */
+  int         idx;                         /* points to the active record in buffer */
+  can_ioptr_t addr;                        /* start address of the message queue    */
 };
 
 /* ipci165 chip data */
index 559bdd1..395b04b 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef _KTHREAD_H
 #define _KTHREAD_H
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
-       #include <linux/config.h>
-#endif
 #include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+#include <linux/config.h>
+#endif
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
   #include <linux/tqueue.h>
   #define tasklet_struct tq_struct
-#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
-  #include <linux/devfs_fs_kernel.h>
+#else
+  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+    #include <linux/devfs_fs_kernel.h>
+  #endif
 #endif
 
 #include <linux/wait.h>
 #include <linux/interrupt.h>
 
 #include <asm/unistd.h>
-#include <asm/semaphore.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
+  #include <asm/semaphore.h>
+#else
+  #include <linux/semaphore.h>
+#endif
 
 /* a structure to store all information we need
    for our thread */
index 351e3a3..f8a317f 100644 (file)
@@ -15,7 +15,7 @@ int m437_reset(struct candevice_t *candev);
 int m437_init_hw_data(struct candevice_t *candev);
 int m437_init_chip_data(struct candevice_t *candev, int chipnr);
 int m437_init_obj_data(struct canchip_t *chip, int objnr);
-void m437_write_register(unsigned data, unsigned long address);
-unsigned m437_read_register(unsigned long address);
+void m437_write_register(unsigned data, can_ioptr_t address);
+unsigned m437_read_register(can_ioptr_t address);
 int m437_program_irq(struct candevice_t *candev);
 int m437_register(struct hwspecops_t *hwspecops);
index c85288e..f360dcf 100644 (file)
 #include "./can_queue.h"
 
 #ifdef CAN_DEBUG
-       #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "can.o (debug): " fmt,\
+       #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,\
        ##args)
 #else
        #define DEBUGMSG(fmt,args...)
 #endif
 
-#define CANMSG(fmt,args...) can_printk(KERN_ERR "can.o: " fmt,##args)
+#define CANMSG(fmt,args...) can_printk(KERN_ERR "lincan: " fmt,##args)
 
 
 extern can_spinlock_t canuser_manipulation_lock;
@@ -75,7 +75,8 @@ struct candevice_t {
        int candev_idx;                 /* board index in canhardware_t.candevice[] */
        unsigned long io_addr;          /* IO/physical MEM address */
        unsigned long res_addr;         /* optional reset register port */
-       unsigned long dev_base_addr;    /* CPU translated IO/virtual MEM address */
+       can_ioptr_t dev_base_addr;      /* CPU translated IO/virtual MEM address */
+       can_ioptr_t aux_base_addr;      /* CPU translated IO/virtual MEM address */
        unsigned int flags;
        int nr_all_chips;
        int nr_82527_chips;
@@ -154,13 +155,13 @@ struct canchip_t {
        char *chip_type;
        int chip_idx;   /* chip index in candevice_t.chip[] */
        int chip_irq;
-       unsigned long chip_base_addr;
+       can_ioptr_t chip_base_addr;
        unsigned int flags;
        long clock; /* Chip clock in Hz */
        long baudrate;
 
-       void (*write_register)(unsigned data,unsigned long address);
-       unsigned (*read_register)(unsigned long address);
+       void (*write_register)(unsigned data, can_ioptr_t address);
+       unsigned (*read_register)(can_ioptr_t address);
 
        void *chip_data;
 
@@ -214,7 +215,7 @@ struct canchip_t {
  *              that reuse same object for TX
  */
 struct msgobj_t {
-       unsigned long obj_base_addr;
+       can_ioptr_t obj_base_addr;
        unsigned int minor;     /* associated device minor number  */
        unsigned int object;    /* object number in canchip_t +1 for debug printk */
        unsigned long obj_flags;
@@ -298,8 +299,8 @@ struct hwspecops_t {
        int (*init_chip_data)(struct candevice_t *candev, int chipnr);
        int (*init_obj_data)(struct canchip_t *chip, int objnr);
        int (*program_irq)(struct candevice_t *candev);
-       void (*write_register)(unsigned data,unsigned long address);
-       unsigned (*read_register)(unsigned long address);
+       void (*write_register)(unsigned data, can_ioptr_t address);
+       unsigned (*read_register)(can_ioptr_t address);
 };
 
 /**
@@ -379,9 +380,10 @@ extern int major;
 extern int minor[MAX_TOT_CHIPS];
 extern int extended;
 extern int baudrate[MAX_TOT_CHIPS];
-extern char *hw[MAX_HW_CARDS];
 extern int irq[MAX_IRQ];
+extern char *hw[MAX_HW_CARDS];
 extern unsigned long io[MAX_HW_CARDS];
+extern long clockfreq[MAX_HW_CARDS];
 extern int processlocal;
 
 extern struct canhardware_t *hardware_p;
@@ -392,43 +394,43 @@ extern struct mem_addr *mem_head;
 
 
 #if defined(CONFIG_OC_LINCAN_PORTIO_ONLY)
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned address)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
 {
-       outb(data, chip->chip_base_addr+address);
+       can_outb(data, chip->chip_base_addr+reg_offs);
 }
-extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned address)
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
 {
-       return inb(chip->chip_base_addr+address);
+       return can_inb(chip->chip_base_addr+reg_offs);
 }
 extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned char data, unsigned address)
+                               unsigned char data, unsigned reg_offs)
 {
-       outb(data, obj->obj_base_addr+address);
+       can_outb(data, obj->obj_base_addr+reg_offs);
 }
 extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned address)
+                               unsigned reg_offs)
 {
-       return inb(obj->obj_base_addr+address);
+       return can_inb(obj->obj_base_addr+reg_offs);
 }
 
 #elif defined(CONFIG_OC_LINCAN_MEMIO_ONLY)
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned address)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
 {
-       writeb(data, chip->chip_base_addr+address);
+       can_writeb(data, chip->chip_base_addr+reg_offs);
 }
-extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned address)
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
 {
-       return readb(chip->chip_base_addr+address);
+       return can_readb(chip->chip_base_addr+reg_offs);
 }
 extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned char data, unsigned address)
+                               unsigned char data, unsigned reg_offs)
 {
-       writeb(data, obj->obj_base_addr+address);
+       can_writeb(data, obj->obj_base_addr+reg_offs);
 }
 extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned address)
+                               unsigned reg_offs)
 {
-       return readb(obj->obj_base_addr+address);
+       return can_readb(obj->obj_base_addr+reg_offs);
 }
 
 #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
@@ -436,42 +438,42 @@ extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struc
 #define CONFIG_OC_LINCAN_DYNAMICIO
 #endif
 
-/* Inline function to write to the hardware registers. The argument address is
- * relative to the memory map of the chip and not the absolute memory address.
+/* Inline function to write to the hardware registers. The argument reg_offs is
+ * relative to the memory map of the chip and not the absolute memory reg_offs.
  */
-extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned address)
+extern inline void can_write_reg(const struct canchip_t *chip, unsigned char data, unsigned reg_offs)
 {
-       unsigned long address_to_write;
-       address_to_write = chip->chip_base_addr+address;
+       can_ioptr_t address_to_write;
+       address_to_write = chip->chip_base_addr+reg_offs;
        chip->write_register(data, address_to_write);
 }
 
-extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned address)
+extern inline unsigned can_read_reg(const struct canchip_t *chip, unsigned reg_offs)
 {
-       unsigned long address_to_read;
-       address_to_read = chip->chip_base_addr+address;
+       can_ioptr_t address_to_read;
+       address_to_read = chip->chip_base_addr+reg_offs;
        return chip->read_register(address_to_read);
 }
 
 extern inline void canobj_write_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned char data, unsigned address)
+                               unsigned char data, unsigned reg_offs)
 {
-       unsigned long address_to_write;
-       address_to_write = obj->obj_base_addr+address;
+       can_ioptr_t address_to_write;
+       address_to_write = obj->obj_base_addr+reg_offs;
        chip->write_register(data, address_to_write);
 }
 
 extern inline unsigned canobj_read_reg(const struct canchip_t *chip, const struct msgobj_t *obj,
-                               unsigned address)
+                               unsigned reg_offs)
 {
-       unsigned long address_to_read;
-       address_to_read = obj->obj_base_addr+address;
+       can_ioptr_t address_to_read;
+       address_to_read = obj->obj_base_addr+reg_offs;
        return chip->read_register(address_to_read);
 }
 
 #endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
 
-int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base);
+int can_base_addr_fixup(struct candevice_t *candev, can_ioptr_t new_base);
 int can_request_io_region(unsigned long start, unsigned long n, const char *name);
 void can_release_io_region(unsigned long start, unsigned long n);
 int can_request_mem_region(unsigned long start, unsigned long n, const char *name);
index 9f5b387..5364809 100644 (file)
@@ -13,7 +13,7 @@ int msmcan_reset(struct candevice_t *candev);
 int msmcan_init_hw_data(struct candevice_t *candev);
 int msmcan_init_chip_data(struct candevice_t *candev, int chipnr);
 int msmcan_init_obj_data(struct canchip_t *chip, int objnr);
-void msmcan_write_register(unsigned data, unsigned long address);
-unsigned msmcan_read_register(unsigned long address);
+void msmcan_write_register(unsigned data, can_ioptr_t address);
+unsigned msmcan_read_register(can_ioptr_t address);
 int msmcan_program_irq(struct candevice_t *candev);
 
index 79be115..2e928d2 100644 (file)
@@ -20,8 +20,8 @@ int ns_dev_init_chip_data(struct candevice_t *candev, int chipnr);
 int ns_dev_request_io(struct candevice_t *candev);
 int ns_dev_release_io(struct candevice_t *candev);
 int ns_dev_reset(struct candevice_t *candev);
-void ns_dev_write_register(unsigned data, unsigned long address);
-unsigned ns_dev_read_register(unsigned long address);
+void ns_dev_write_register(unsigned data, can_ioptr_t address);
+unsigned ns_dev_read_register(can_ioptr_t address);
 
 int ns_dev_init_obj_data(struct canchip_t *chip, int objnr);
 int ns_dev_program_irq(struct candevice_t *candev);
index c48e4ef..45cf660 100644 (file)
@@ -13,7 +13,7 @@ int nsi_reset(struct candevice_t *candev);
 int nsi_init_hw_data(struct candevice_t *candev);
 int nsi_init_chip_data(struct candevice_t *candev, int chipnr);
 int nsi_init_obj_data(struct canchip_t *chip, int objnr);
-void nsi_write_register(unsigned data, unsigned long address);
-unsigned nsi_read_register(unsigned long address);
+void nsi_write_register(unsigned data, can_ioptr_t address);
+unsigned nsi_read_register(can_ioptr_t address);
 int nsi_program_irq(struct candevice_t *candev);
 
index d59f927..f268172 100644 (file)
@@ -13,7 +13,7 @@ int nsi_canpci_reset(struct candevice_t *candev);
 int nsi_canpci_init_hw_data(struct candevice_t *candev);
 int nsi_canpci_init_chip_data(struct candevice_t *candev, int chipnr);
 int nsi_canpci_init_obj_data(struct canchip_t *chip, int objnr);
-void nsi_canpci_write_register(unsigned data, unsigned long address);
-unsigned nsi_canpci_read_register(unsigned long address);
+void nsi_canpci_write_register(unsigned data, can_ioptr_t address);
+unsigned nsi_canpci_read_register(can_ioptr_t address);
 int nsi_canpci_program_irq(struct candevice_t *candev);
 
index 50cca0c..9560017 100644 (file)
@@ -13,7 +13,7 @@ int oscar_reset(struct candevice_t *candev);
 int oscar_init_hw_data(struct candevice_t *candev);
 int oscar_init_chip_data(struct candevice_t *candev, int chipnr);
 int oscar_init_obj_data(struct canchip_t *chip, int objnr);
-void oscar_write_register(unsigned data, unsigned long address);
-unsigned oscar_read_register(unsigned long address);
+void oscar_write_register(unsigned data, can_ioptr_t address);
+unsigned oscar_read_register(can_ioptr_t address);
 int oscar_program_irq(struct candevice_t *candev);
 
index 0e8ec4f..589e042 100644 (file)
@@ -13,7 +13,7 @@ int pci03_reset(struct candevice_t *candev);
 int pci03_init_hw_data(struct candevice_t *candev);
 int pci03_init_chip_data(struct candevice_t *candev, int chipnr);
 int pci03_init_obj_data(struct canchip_t *chip, int objnr);
-void pci03_write_register(unsigned data, unsigned long address);
-unsigned pci03_read_register(unsigned long address);
+void pci03_write_register(unsigned data, can_ioptr_t address);
+unsigned pci03_read_register(can_ioptr_t address);
 int pci03_program_irq(struct candevice_t *candev);
 
index ca5a14d..b9c07eb 100644 (file)
@@ -96,8 +96,8 @@ int pcan_dongle_reset(struct candevice_t *candev);
 int pcan_dongle_init_hw_data(struct candevice_t *candev);
 int pcan_dongle_init_chip_data(struct candevice_t *candev, int chipnr);
 int pcan_dongle_init_obj_data(struct canchip_t *chip, int objnr);
-void pcan_dongle_write_register(unsigned data, unsigned long address);
-unsigned pcan_dongle_read_register(unsigned long address);
+void pcan_dongle_write_register(unsigned data, can_ioptr_t address);
+unsigned pcan_dongle_read_register(can_ioptr_t address);
 int pcan_dongle_program_irq(struct candevice_t *candev);
 
 #endif // __PCAN_DONGLE_H__
index 918e7cd..35006c9 100644 (file)
@@ -19,8 +19,8 @@ int pccanq_reset(struct candevice_t *candev);
 int pccan_init_hw_data(struct candevice_t *candev);
 int pccan_init_chip_data(struct candevice_t *candev, int chipnr);
 int pccan_init_obj_data(struct canchip_t *chip, int objnr);
-void pccan_write_register(unsigned data, unsigned long address);
-unsigned pccan_read_register(unsigned long address);
+void pccan_write_register(unsigned data, can_ioptr_t address);
+unsigned pccan_read_register(can_ioptr_t address);
 int pccan_program_irq(struct candevice_t *candev);
 
 
index 50039c1..183186b 100644 (file)
@@ -13,7 +13,7 @@ int pcccan_reset(struct candevice_t *candev);
 int pcccan_init_hw_data(struct candevice_t *candev);
 int pcccan_init_chip_data(struct candevice_t *candev, int chipnr);
 int pcccan_init_obj_data(struct canchip_t *chip, int objnr);
-void pcccan_write_register(unsigned data, unsigned long address);
-unsigned pcccan_read_register(unsigned long address);
+void pcccan_write_register(unsigned data, can_ioptr_t address);
+unsigned pcccan_read_register(can_ioptr_t address);
 int pcccan_program_irq(struct candevice_t *candev);
 
index d97cbd2..45b665c 100644 (file)
@@ -13,7 +13,7 @@ int pcm3680_reset(struct candevice_t *candev);
 int pcm3680_init_hw_data(struct candevice_t *candev);
 int pcm3680_init_chip_data(struct candevice_t *candev, int chipnr);
 int pcm3680_init_obj_data(struct canchip_t *chip, int objnr);
-void pcm3680_write_register(unsigned data, unsigned long address);
-unsigned pcm3680_read_register(unsigned long address);
+void pcm3680_write_register(unsigned data, can_ioptr_t address);
+unsigned pcm3680_read_register(can_ioptr_t address);
 int pcm3680_program_irq(struct candevice_t *candev);
 
index a6ba399..292c46e 100644 (file)
@@ -17,6 +17,6 @@ int pikronisa_init_hw_data(struct candevice_t *candev);
 int pikronisa_init_chip_data(struct candevice_t *candev, int chipnr);
 int pikronisa_init_obj_data(struct canchip_t *chip, int objnr);
 int pikronisa_program_irq(struct candevice_t *candev);
-void pikronisa_write_register(unsigned data, unsigned long address);
-unsigned pikronisa_read_register(unsigned long address);
+void pikronisa_write_register(unsigned data, can_ioptr_t address);
+unsigned pikronisa_read_register(can_ioptr_t address);
 
index 5feddfe..93dcefa 100644 (file)
@@ -15,7 +15,7 @@ int pip_reset(struct candevice_t *candev);
 int pip_init_hw_data(struct candevice_t *candev);
 int pip_init_chip_data(struct candevice_t *candev, int chipnr);
 int pip_init_obj_data(struct canchip_t *chip, int objnr);
-void pip_write_register(unsigned data, unsigned long address);
-unsigned pip_read_register(unsigned long address);
+void pip_write_register(unsigned data, can_ioptr_t address);
+unsigned pip_read_register(can_ioptr_t address);
 int pip_program_irq(struct candevice_t *candev);
 
diff --git a/lincan/include/sh7760.h b/lincan/include/sh7760.h
new file mode 100644 (file)
index 0000000..914d848
--- /dev/null
@@ -0,0 +1,29 @@
+/* sh7760.h
+ * Header file for the Linux CAN-bus driver.
+ * This software is released under the GPL-License.
+ */
+
+#define NR_82527       0
+#define NR_SJA1000     0
+#define NR_ALL         2
+
+#define SH7760_CAN_IRQ                 56
+#define SH7760_CAN_CHIP_OFFSET 0x10000
+#define SH7760_CAN_CLOCK       33333330          /* 33.3 MHz */
+
+#define IO_RANGE               0x10000
+
+/* static CAN_DEFINE_SPINLOCK(sh7760_port_lock); */
+
+
+
+int sh7760_request_io(struct candevice_t *candev);
+int sh7760_release_io(struct candevice_t *candev);
+int sh7760_reset(struct candevice_t *candev); 
+int sh7760_init_hw_data(struct candevice_t *candev);
+int sh7760_init_chip_data(struct candevice_t *candev, int chipnr);
+int sh7760_init_obj_data(struct canchip_t *chip, int objnr);
+int sh7760_program_irq(struct candevice_t *candev);
+void sh7760_write_register(unsigned data, can_ioptr_t address);
+unsigned sh7760_read_register(can_ioptr_t address);
+
index 58c0d42..11887be 100644 (file)
@@ -13,6 +13,6 @@ int smartcan_reset(struct candevice_t *candev);
 int smartcan_init_hw_data(struct candevice_t *candev);
 int smartcan_init_chip_data(struct candevice_t *candev, int chipnr);
 int smartcan_init_obj_data(struct canchip_t *chip, int objnr);
-void smartcan_write_register(unsigned data, unsigned long address);
-unsigned smartcan_read_register(unsigned long address);
+void smartcan_write_register(unsigned data, can_ioptr_t address);
+unsigned smartcan_read_register(can_ioptr_t address);
 
index 6395782..2bab005 100644 (file)
@@ -11,7 +11,7 @@ int ssv_reset(struct candevice_t *candev);
 int ssv_init_hw_data(struct candevice_t *candev);
 int ssv_init_chip_data(struct candevice_t *candev, int chipnr);
 int ssv_init_obj_data(struct canchip_t *chip, int objnr);
-void ssv_write_register(unsigned data, unsigned long address);
-unsigned ssv_read_register(unsigned long address);
+void ssv_write_register(unsigned data, can_ioptr_t address);
+unsigned ssv_read_register(can_ioptr_t address);
 int ssv_program_irq(struct candevice_t *candev);
 
index 88f162c..3963dc3 100644 (file)
@@ -13,7 +13,7 @@ int template_reset(struct candevice_t *candev);
 int template_init_hw_data(struct candevice_t *candev);
 int template_init_chip_data(struct candevice_t *candev, int chipnr);
 int template_init_obj_data(struct canchip_t *chip, int objnr);
-void template_write_register(unsigned data, unsigned long address);
-unsigned template_read_register(unsigned long address);
+void template_write_register(unsigned data, can_ioptr_t address);
+unsigned template_read_register(can_ioptr_t address);
 int template_program_irq(struct candevice_t *candev);
 
index 97efdb6..427b387 100644 (file)
@@ -58,8 +58,8 @@ int tscan1_reset(struct candevice_t *candev);
 int tscan1_init_hw_data(struct candevice_t *candev);
 int tscan1_init_chip_data(struct candevice_t *candev, int chipnr);
 int tscan1_init_obj_data(struct canchip_t *chip, int objnr);
-void tscan1_write_register(unsigned data, unsigned long address);
-unsigned tscan1_read_register(unsigned long address);
+void tscan1_write_register(unsigned data, can_ioptr_t address);
+unsigned tscan1_read_register(can_ioptr_t address);
 int tscan1_program_irq(struct candevice_t *candev);
 
 unsigned long tscan1_getmappedaddr(unsigned long address);
index f595272..b22a357 100644 (file)
@@ -1,14 +1,14 @@
 # Generic directory or leaf node makefile for OCERA make framework
 
 ifndef MAKERULES_DIR
-MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
 endif
 
 ifeq ($(MAKERULES_DIR),)
 all : default
 .DEFAULT::
        @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
-else   
+else
 include $(MAKERULES_DIR)/Makefile.rules
 endif
 
index fd53820..72d2811 100644 (file)
@@ -1,8 +1,8 @@
 lincan_cards_NAMES = pip pccan smartcan nsi cc_can104 ems_cpcpci \
-               pc_i03 pcm3680 aim104 m437 pcccan ssv bfadcan pikronisa eb8245 \
-               kv_pcican msmcan oscar adlink7841 unican virtual template usbcan
+               pc_i03 pcm3680 aim104 m437 pcccan ssv bfadcan gensja1000io pikronisa eb8245 \
+               kv_pcican msmcan oscar adlink7841 pcan_pci esdpci200 unican usbcan virtual template
 
-lincan_morecards_NAMES = hms30c7202_can ns_dev_can ipci165 pimx1 tscan1 nsi_canpci
+lincan_morecards_NAMES = hms30c7202_can ns_dev_can ipci165 pimx1 tscan1 nsi_canpci sh7760
 
 default_CONFIG = CONFIG_OC_LINCAN=y CONFIG_OC_LINCANRTL=n CONFIG_OC_LINCANVME=n
 default_CONFIG += CONFIG_OC_LINCAN_PORTIO_ONLY=n CONFIG_OC_LINCAN_MEMIO_ONLY=n
@@ -21,7 +21,7 @@ ifeq ($(CONFIG_OC_LINCAN),y)
 rtlinux_INCLUDES = -I $(srcdir)/../include -I .
 kernel_INCLUDES = -I $(srcdir)/../include -I .
 #kernel_INCLUDES += -DCAN_DEBUG
-kernel_INCLUDES += -DWITH_DEVFS_FS -DKBUILD_MODNAME
+kernel_INCLUDES += -DWITH_DEVFS_FS
 
 lincan_cards_SOURCES = $(lincan_cards_SELECTED:%=%.c)
 
@@ -33,6 +33,10 @@ ifeq ($(CONFIG_OC_LINCAN_CARD_ipci165),y)
 lincan_cards_SOURCES += ipci165_fw.c kthread.c
 endif
 
+ifeq ($(CONFIG_OC_LINCAN_CARD_sh7760),y)
+lincan_cards_SOURCES += sh7760.c
+endif
+
 ifeq ($(CONFIG_OC_LINCAN_CARD_usbcan),y)
 lincan_cards_SOURCES += kthread.c
 endif
@@ -57,7 +61,7 @@ endif #CONFIG_OC_LINCANRTL
 
 lincan_SOURCES = can_queue.c can_quekern.c main.c modparms.c \
                devcommon.c setup.c finish.c irq.c sysdep_lnx.c boardlist.c \
-               sja1000p.c sja1000.c i82527.c  \
+               sja1000p.c sja1000.c i82527.c hcan2.c \
                open.c close.c read.c write.c ioctl.c select.c fasync.c \
                proc.c ioctl_query.c ioctl_remote.c \
                $(lincan_cards_SOURCES) $(lincan_rtl_SOURCES)
index b71ca95..2087c6c 100644 (file)
@@ -48,6 +48,7 @@ endif
 #KERNEL_LOCATION=/usr/src/linux-2.2.19
 #KERNEL_LOCATION=/usr/src/linux-2.2.22
 #KERNEL_LOCATION=/usr/src/linux-2.6.0
+#KERNEL_LOCATION=/usr/src/linux-2.6.18-rc4/_build/arm
 #KERNEL_LOCATION=/home/cvs/ocera/ocera-build/kernel/linux
 
 
@@ -63,7 +64,8 @@ endif
 SUPPORTED_CARDS = pip pccan smartcan nsi cc_can104 \
                  pc_i03 pcm3680 aim104 m437 pcccan ssv \
                  bfadcan pikronisa kv_pcican msmcan virtual template \
-                 unican unican_cl2 ems_cpcpci adlink7841 oscar
+                 unican unican_cl2 ems_cpcpci adlink7841 oscar \
+                 pcan_pci esdpci200
 #                hms30c7202_can c_can c_can_irq tscan1
 #                pcan_dongle
 
@@ -97,6 +99,13 @@ CONFIG_SHELL = TOPDIR=$(TOPDIR)
 KERNEL_VERSION := $(shell awk -F\" '/REL/ {print $$2}' \
        $(KERNEL_LOCATION)/include/linux/version.h | awk -F\- '{print $$1}')
 
+ifeq ($(KERNEL_VERSION),)
+KERNEL_VERSION=$(shell grep UTS_RELEASE ${KERNEL_LOCATION}/include/linux/utsrelease.h | \
+                 sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+endif
+
+#$(warning KERNEL_VERSION = $(KERNEL_VERSION))
+
 PROC_FS := $(shell awk -F\  '/PROC_FS/ {print $$3}' \
        $(KERNEL_LOCATION)/include/linux/autoconf.h)
 
index 59107d4..248f480 100644 (file)
@@ -95,14 +95,14 @@ int adlink7841_release_io(struct candevice_t *candev)
 }
 
 
-void adlink7841_write_register(unsigned data, unsigned long address)
+void adlink7841_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address); 
+       can_outb(data,address); 
 }
 
-unsigned adlink7841_read_register(unsigned long address)
+unsigned adlink7841_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 int adlink7841_reset(struct candevice_t *candev)
@@ -194,7 +194,7 @@ int adlink7841_init_chip_data(struct candevice_t *candev, int chipnr)
 
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
        candev->chip[chipnr]->chip_base_addr=
-                       candev->io_addr+chipnr*ADLINK7841_BYTES_PER_CIRCUIT;
+                       can_ioport2ioptr(candev->io_addr+chipnr*ADLINK7841_BYTES_PER_CIRCUIT);
        candev->chip[chipnr]->flags = 0;
        candev->chip[chipnr]->int_cpu_reg = 0;
        candev->chip[chipnr]->int_clk_reg = 0;
index 485186b..015a793 100644 (file)
@@ -161,7 +161,7 @@ int aim104_init_hw_data(struct candevice_t *candev)
 int aim104_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        sja1000_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->flags = 0;
        candev->chip[chipnr]->sja_cdr_reg = 0x08;
@@ -223,9 +223,9 @@ int aim104_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void aim104_write_register(unsigned data, unsigned long address)
+void aim104_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address);
+       can_outb(data,address);
 }
 
 /**
@@ -238,9 +238,9 @@ void aim104_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned aim104_read_register(unsigned long address)
+unsigned aim104_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 /* !!! Don't change this function !!! */
index 5270bd1..0f08359 100644 (file)
 #define __NO_VERSION__
 #include <linux/module.h>
 
-long clock_freq;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-MODULE_PARM(clock_freq,"i");
-#else
-module_param(clock_freq,int,0);
-#endif
+#define CAN_BFAD_CLOCKFREQ 20000000
 
 /* cli and sti are not allowed in 2.5.5x SMP kernels */
 #ifdef WINDOWED_ACCESS
@@ -46,8 +41,8 @@ static CAN_DEFINE_SPINLOCK(bfadcan_win_lock);
 #define IO_RANGE 0x100
 #endif
 
-unsigned bfadcan_read_register(unsigned long address);
-void bfadcan_write_register(unsigned data, unsigned long address);
+unsigned bfadcan_read_register(can_ioptr_t address);
+void bfadcan_write_register(unsigned data, can_ioptr_t address);
 
 
 /**
@@ -200,17 +195,18 @@ int bfadcan_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        unsigned int id1, id2;
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
-       candev->chip[chipnr]->clock = clock_freq;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
+       if(candev->chip[chipnr]->clock<=0)
+               candev->chip[chipnr]->clock = CAN_BFAD_CLOCKFREQ;
        candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
        candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
-       id1 = inb(0xe284);
-       id2 = inb(0xe285);
+       id1 = can_inb(0xe284);
+       id2 = can_inb(0xe285);
 
 
        CANMSG("can driver ver lincan-0.3, at %04lx, CPLD v%d.%d.%d.%d\n",
-                                       candev->chip[chipnr]->chip_base_addr,
-                                                       id1>>4, id1&0x0f, id2>>4, id2&0x0f);
+                       can_ioptr2ulong(candev->chip[chipnr]->chip_base_addr),
+                       id1>>4, id1&0x0f, id2>>4, id2&0x0f);
 
 
        return 0;
@@ -268,16 +264,16 @@ int bfadcan_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/bfadcan.c
  */
-void bfadcan_write_register(unsigned data, unsigned long address)
+void bfadcan_write_register(unsigned data, can_ioptr_t address)
 {
 #ifdef WINDOWED_ACCESS
        can_spin_irqflags_t flags;
        can_spin_lock_irqsave(&bfadcan_win_lock,flags);
-       outb(address&0x00ff,0x200);
-       outb(data, 0x201);
+       can_outb(can_ioptr2ulong(address)&0x00ff,0x200);
+       can_outb(data, 0x201);
        can_spin_unlock_irqrestore(&bfadcan_win_lock,flags);
 #else
-       outb(data,address);
+       can_outb(data,address);
 #endif
 }
 
@@ -291,18 +287,18 @@ void bfadcan_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/bfadcan.c
  */
-unsigned bfadcan_read_register(unsigned long address)
+unsigned bfadcan_read_register(can_ioptr_t address)
 {
 #ifdef WINDOWED_ACCESS
        can_spin_irqflags_t flags;
        int ret;
        can_spin_lock_irqsave(&bfadcan_win_lock,flags);
-       outb(address&0x00ff,0x200);
-       ret = inb(0x201);
+       can_outb(can_ioptr2ulong(address)&0x00ff,0x200);
+       ret = can_inb(0x201);
        can_spin_unlock_irqrestore(&bfadcan_win_lock,flags);
        return ret;
 #else
-       return inb(address);
+       return can_inb(address);
 #endif
 }
 
index 6caf3a2..0c2696a 100644 (file)
@@ -30,6 +30,7 @@ extern int pcccan_register(struct hwspecops_t *hwspecops);
 extern int ssv_register(struct hwspecops_t *hwspecops);
 extern int bfadcan_register(struct hwspecops_t *hwspecops);
 extern int pikronisa_register(struct hwspecops_t *hwspecops);
+extern int gensja1000io_register(struct hwspecops_t *hwspecops);
 extern int pimx1_register(struct hwspecops_t *hwspecops);
 extern int msmcan_register(struct hwspecops_t *hwspecops);
 extern int unican_register(struct hwspecops_t *hwspecops);
@@ -45,6 +46,9 @@ extern int ns_dev_register(struct hwspecops_t *hwspecops);
 extern int hms30c7202_register(struct hwspecops_t *hwspecops);
 extern int nsi_canpci_register(struct hwspecops_t *hwspecops);
 extern int usbcan_register(struct hwspecops_t *hwspecops);
+extern int pcan_pci_register(struct hwspecops_t *hwspecops);
+extern int esdpci200_register(struct hwspecops_t *hwspecops);
+extern int sh7760_register(struct hwspecops_t *hwspecops);
 
 const struct boardtype_t can_boardtypes[]={
     #ifdef CONFIG_OC_LINCAN_CARD_template
@@ -109,6 +113,9 @@ const struct boardtype_t can_boardtypes[]={
     #ifdef CONFIG_OC_LINCAN_CARD_pikronisa
        {"pikronisa", pikronisa_register, 1},
     #endif
+    #ifdef CONFIG_OC_LINCAN_CARD_gensja1000io
+       {"gensja1000io", gensja1000io_register, 1},
+    #endif
     #ifdef CONFIG_OC_LINCAN_CARD_pimx1
        {"pimx1", pimx1_register, 0},
     #endif
@@ -136,6 +143,9 @@ const struct boardtype_t can_boardtypes[]={
     #if defined(CONFIG_OC_LINCAN_CARD_adlink7841)
        {"adlink7841", adlink7841_register, 0},
     #endif
+    #if defined(CONFIG_OC_LINCAN_CARD_esdpci200)
+       {"esdpci200", esdpci200_register, 0},
+    #endif
     #if defined(CONFIG_OC_LINCAN_CARD_tscan1)
        {"tscan1", tscan1_register, 1},
        {"ts7kv",  ts7kv_register, 1},
@@ -143,12 +153,18 @@ const struct boardtype_t can_boardtypes[]={
     #if defined(CONFIG_OC_LINCAN_CARD_ns_dev_can)
        {"ns_dev", ns_dev_register, 1},
     #endif
+    #if defined(CONFIG_OC_LINCAN_CARD_sh7760)
+       {"sh7760", sh7760_register, 2},
+    #endif
     #if defined(CONFIG_OC_LINCAN_CARD_hms30c7202_can)
        {"hms30c7202", hms30c7202_register, 1},
     #endif
     #if defined(CONFIG_OC_LINCAN_CARD_nsi_canpci)&&defined(CAN_ENABLE_PCI_SUPPORT)
        {"nsicanpci", nsi_canpci_register, 1},
     #endif
+    #if defined(CONFIG_OC_LINCAN_CARD_pcan_pci)&&defined(CAN_ENABLE_PCI_SUPPORT)
+       {"pcan_pci", pcan_pci_register, 0},
+    #endif
     #if defined(CONFIG_OC_LINCAN_CARD_usbcan)
        {"usbcan", usbcan_register, 0},
     #endif
index 9929467..cddac82 100644 (file)
@@ -96,10 +96,10 @@ int c_can_chip_config(struct canchip_t *pchip)
                return -1;
 
        if (pchip->baudrate == 0)
-               pchip->baudrate = 1000;
+               pchip->baudrate = 1000000;
 
        if (c_can_baud_rate
-           (pchip, pchip->baudrate * 1000, pchip->clock, 0, 75, 0)) {
+           (pchip, pchip->baudrate, pchip->clock, 0, 75, 0)) {
                CANMSG("Error configuring baud rate\n");
                return -ENODEV;
        }
@@ -143,8 +143,8 @@ int c_can_if1_busycheck(struct canchip_t *pchip)
        unsigned short comreg = 0;
 
        comreg = c_can_read_reg_w(pchip, CCIF1CR);
-       while ((comreg & IFXCR_BUSY) && (i <= 10)) {
-               udelay(100);    //100 microseconds
+       while ((comreg & IFXCR_BUSY) && (i <= 100)) {
+               udelay(1);      //1 microseconds
                i++;
                comreg = c_can_read_reg_w(pchip, CCIF1CR);
        }
@@ -167,8 +167,8 @@ int c_can_if2_busycheck(struct canchip_t *pchip)
        unsigned short comreg = 0;
 
        comreg = c_can_read_reg_w(pchip, CCIF2CR);
-       while ((comreg & IFXCR_BUSY) && (i <= 10)) {
-               udelay(100);    //100 microseconds
+       while ((comreg & IFXCR_BUSY) && (i <= 100)) {
+               udelay(1);      //1 microseconds
                i++;
                comreg = c_can_read_reg_w(pchip, CCIF2CR);
        }
@@ -296,6 +296,11 @@ int c_can_mask(struct msgobj_t *pmsgobj, u32 mask, u16 usedirbit)
        if (c_can_if1_busycheck(pmsgobj->hostchip))
                return -ENODEV;
 
+       //set indication, that mask is used
+       tempreg = c_can_read_reg_w(pmsgobj->hostchip, CCIF1DMC);
+       c_can_write_reg_w(pmsgobj->hostchip, tempreg | IFXMC_UMASK,
+               CCIF1DMC);
+
        //writing acceptance mask for extended or standart mode
        if (can_msgobj_test_fl(pmsgobj, RX_MODE_EXT)) {
                if (usedirbit)
@@ -317,6 +322,7 @@ int c_can_mask(struct msgobj_t *pmsgobj, u32 mask, u16 usedirbit)
                                          ((mask << 2) & 0x1FFC), CCIF1M2);
                c_can_write_reg_w(pmsgobj->hostchip, 0, CCIF1M1);
        }
+
        //seting Message Valid Bit to one
        tempreg = c_can_read_reg_w(pmsgobj->hostchip, CCIF1A2);
        c_can_write_reg_w(pmsgobj->hostchip, tempreg | IFXARB2_MVAL, CCIF1A2);
index 4ba6042..8672b4e 100644 (file)
@@ -458,6 +458,7 @@ int c_can_irq_handler(int irq, struct canchip_t *pchip)
                                if (c_can_if1_busycheck(pchip)) ;
                                if (c_can_read_reg_w(pchip, CCIF1A2) &
                                    IFXARB2_DIR) {
+                                       DEBUGMSG("c_can_irq_write_handler idxobj=%d, msgid=%d\n",idxobj,msgid);
                                        spin_unlock(&c_can_if1lock);
                                        c_can_irq_write_handler(pchip, idxobj);
 
index 2dafc3d..15819a3 100644 (file)
@@ -140,7 +140,7 @@ int cc104_init_hw_data(struct candevice_t *candev)
 int cc104_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        sja1000_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->flags = 0;
        candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
@@ -202,9 +202,9 @@ int cc104_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void cc104_write_register(unsigned data, unsigned long address)
+void cc104_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address);
+       can_outb(data,address);
 }
 
 /**
@@ -217,9 +217,9 @@ void cc104_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned cc104_read_register(unsigned long address)
+unsigned cc104_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 /* !!! Don't change this function !!! */
index b871305..ff1f1c5 100644 (file)
  */
 int eb8245_request_io(struct candevice_t *candev)
 {
-        int remap_addr;
+        can_ioptr_t remap_addr;
        
        if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - eb8245")) {
                CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
                return -ENODEV;
        }
-       if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
                can_release_mem_region(candev->io_addr,IO_RANGE);
                return -ENODEV;
@@ -241,11 +241,11 @@ int eb8245_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/eb8245.c
  */
-void eb8245_write_register(unsigned data, unsigned long address)
+void eb8245_write_register(unsigned data, can_ioptr_t address)
 {
        /*DEBUGMSG("eb8245_write_register: addr=0x%lx data=0x%x",
                address,data);*/
-       writeb(data,address);
+       can_writeb(data,address);
 }
 
 /**
@@ -258,9 +258,9 @@ void eb8245_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/eb8245.c
  */
-unsigned eb8245_read_register(unsigned long address)
+unsigned eb8245_read_register(can_ioptr_t address)
 {
-       return readb(address);
+       return can_readb(address);
 }
 
 /* !!! Don't change this function !!! */
index d20e281..ffbf76a 100644 (file)
@@ -71,13 +71,13 @@ The board configuration is probably following:
 void ems_cpcpci_disconnect_irq(struct candevice_t *candev)
 {
        /* Disable interrupts from card */
-       writel(0, candev->dev_base_addr + PITA2_ICR);
+       can_writel(0, candev->aux_base_addr + PITA2_ICR);
 }
 
 void ems_cpcpci_connect_irq(struct candevice_t *candev)
 {
        /* Enable interrupts from card */
-       writel(PITA2_ICR_INT0_En, candev->dev_base_addr + PITA2_ICR);
+       can_writel(PITA2_ICR_INT0_En, candev->aux_base_addr + PITA2_ICR);
 }
 
 
@@ -103,20 +103,21 @@ int ems_cpcpci_request_io(struct candevice_t *candev)
     #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
 
        pita2_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
-       if (!(candev->dev_base_addr = (long) ioremap(pita2_addr, 
+       if (!(candev->aux_base_addr = ioremap(pita2_addr, 
              pci_resource_len(candev->sysdevptr.pcidev,0)))) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", pita2_addr);
                goto error_ioremap_pita2;
        }
 
        io_addr=pci_resource_start(candev->sysdevptr.pcidev,1);;
-       if (!(candev->io_addr = (long) ioremap(io_addr,
+       if (!(candev->dev_base_addr = ioremap(io_addr,
              pci_resource_len(candev->sysdevptr.pcidev,1)))) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", io_addr);
                goto error_ioremap_io;
        }
 
-       candev->res_addr=candev->io_addr;
+       candev->io_addr=io_addr;
+       candev->res_addr=pita2_addr;
        
        /* 
         * this is redundant with chip initialization, but remap address 
@@ -125,21 +126,21 @@ int ems_cpcpci_request_io(struct candevice_t *candev)
        for(i=0;i<candev->nr_all_chips;i++) {
                struct canchip_t *chip=candev->chip[i];
                if(!chip) continue;
-               chip->chip_base_addr = candev->io_addr+
+               chip->chip_base_addr = candev->dev_base_addr+
                        0x400 + i*EMS_CPCPCI_BYTES_PER_CIRCUIT;
                if(!chip->msgobj[0]) continue;
                chip->msgobj[0]->obj_base_addr=chip->chip_base_addr;
        }
 
        /* Configure PITA-2 parallel interface */
-       writel(PITA2_MISC_CONFIG, candev->dev_base_addr + PITA2_MISC);
+       can_writel(PITA2_MISC_CONFIG, candev->aux_base_addr + PITA2_MISC);
 
        ems_cpcpci_disconnect_irq(candev);
 
        return 0;
 
     error_ioremap_io:
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->aux_base_addr);
     error_ioremap_pita2:
     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
        pci_release_region(candev->sysdevptr.pcidev, 1);
@@ -156,8 +157,8 @@ int ems_cpcpci_release_io(struct candevice_t *candev)
 {
        ems_cpcpci_disconnect_irq(candev);
 
-       iounmap((void*)candev->io_addr);
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
+       iounmap(candev->aux_base_addr);
     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
        pci_release_region(candev->sysdevptr.pcidev, 1);
        pci_release_region(candev->sysdevptr.pcidev, 0);
@@ -169,18 +170,18 @@ int ems_cpcpci_release_io(struct candevice_t *candev)
 }
 
 
-void ems_cpcpci_write_register(unsigned data, unsigned long address)
+void ems_cpcpci_write_register(unsigned data, can_ioptr_t address)
 {
-       address += ((address&(EMS_CPCPCI_BYTES_PER_CIRCUIT-1))
-                           *(EMS_CPCPCI_BYTES_PER_REG-1));
-       writeb(data,address); 
+       address += ((can_ioptr2ulong(address)&(EMS_CPCPCI_BYTES_PER_CIRCUIT-1))
+                                            *(EMS_CPCPCI_BYTES_PER_REG-1));
+       can_writeb(data,address); 
 }
 
-unsigned ems_cpcpci_read_register(unsigned long address)
+unsigned ems_cpcpci_read_register(can_ioptr_t address)
 {
-       address += ((address&(EMS_CPCPCI_BYTES_PER_CIRCUIT-1))
-                           *(EMS_CPCPCI_BYTES_PER_REG-1));
-       return readb(address);
+       address += ((can_ioptr2ulong(address)&(EMS_CPCPCI_BYTES_PER_CIRCUIT-1))
+                                            *(EMS_CPCPCI_BYTES_PER_REG-1));
+       return can_readb(address);
 }
 
 int ems_cpcpci_irq_handler(int irq, struct canchip_t *chip)
@@ -191,12 +192,12 @@ int ems_cpcpci_irq_handler(int irq, struct canchip_t *chip)
        unsigned long icr;
        int test_irq_again;
 
-       icr=readl(candev->dev_base_addr + PITA2_ICR);
+       icr=can_readl(candev->aux_base_addr + PITA2_ICR);
        if(!(icr & PITA2_ICR_INT0)) return CANCHIP_IRQ_NONE;
        
        /* correct way to handle interrupts from all chips connected to the one PITA-2 */
        do {
-               writel(PITA2_ICR_INT0_En | PITA2_ICR_INT0, candev->dev_base_addr + PITA2_ICR);
+               can_writel(PITA2_ICR_INT0_En | PITA2_ICR_INT0, candev->aux_base_addr + PITA2_ICR);
                test_irq_again=0;
                for(i=0;i<candev->nr_all_chips;i++){
                        chip=candev->chip[i];
@@ -205,7 +206,7 @@ int ems_cpcpci_irq_handler(int irq, struct canchip_t *chip)
                        if(sja1000p_irq_handler(irq, chip))
                                test_irq_again=1;
                }
-               icr=readl(candev->dev_base_addr + PITA2_ICR);
+               icr=can_readl(candev->aux_base_addr + PITA2_ICR);
        } while((icr & PITA2_ICR_INT0)||test_irq_again);
        return CANCHIP_IRQ_HANDLED;
 }
@@ -282,9 +283,9 @@ int ems_cpcpci_init_hw_data(struct candevice_t *candev)
        if(ems_cpcpci_request_io(candev)<0)
                return -ENODEV;
 
-       /*** candev->dev_base_addr=pci_resource_start(pcidev,0); ***/
+       /*** candev->aux_base_addr=pci_resource_start(pcidev,0); ***/
        /* some control registers */
-       /*** candev->io_addr=pci_resource_start(pcidev,1); ***/
+       /*** candev->dev_base_addr=pci_resource_start(pcidev,1); ***/
        /* 0 more EMS control registers
          * 0x400 the first SJA1000
          * 0x600 the second SJA1000
@@ -295,9 +296,9 @@ int ems_cpcpci_init_hw_data(struct candevice_t *candev)
        
        for(l=0,i=0;i<4;i++){
                l<<=8;
-               l|=readb(candev->io_addr + i*4);
+               l|=can_readb(candev->dev_base_addr + i*4);
        }
-       i=readb(candev->io_addr + i*5);
+       i=can_readb(candev->dev_base_addr + i*5);
        
        CANMSG("EMS CPC-PCI check value %04lx, ID %d\n", l, i);
        
@@ -328,7 +329,7 @@ int ems_cpcpci_init_chip_data(struct candevice_t *candev, int chipnr)
 
        candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
 
-       candev->chip[chipnr]->chip_base_addr = candev->io_addr+
+       candev->chip[chipnr]->chip_base_addr = candev->dev_base_addr+
                        0x400 + chipnr*EMS_CPCPCI_BYTES_PER_CIRCUIT;
        candev->chip[chipnr]->flags = 0;
        candev->chip[chipnr]->int_cpu_reg = 0;
diff --git a/lincan/src/esdpci200.c b/lincan/src/esdpci200.c
new file mode 100644 (file)
index 0000000..1b62e7e
--- /dev/null
@@ -0,0 +1,374 @@
+/* esdpci200.c - support for ESD Electronics' CAN/PCI-200 cards
+ * Linux CAN-bus device driver.
+ * The card support was added by Manuel Bessler <m.bessler@gmx.net>
+ * Based on adlink7841.c and nsi_canpci.c
+ * This software is released under the GPL-License.
+ * Version lincan-0.3.3
+ */ 
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/sja1000p.h"
+
+#ifdef CAN_ENABLE_PCI_SUPPORT
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
+       #define ioread32        can_readl
+       #define iowrite32       can_writel
+       #define ioread8         can_readb
+       #define iowrite8        can_writeb
+       #define wmb()
+       #define rmb()
+#else
+#endif
+
+#define ESDPCI200_PCI_VENDOR_ID        0x10B5
+#define ESDPCI200_PCI_PRODUCT_ID       0x9050
+
+/* PCI to local bus bridge PLX9052 */
+
+#define PLX9052_INTCSR 0x4c    /* interrupt control register */
+#define PLX9052_CNTRL  0x50    /* control register, for software reset */
+
+/* The ESD PCI/200 uses (per default) just LINTi1 (Local Interrupt 1)
+ * on the PLX. This means that both CAN channels' (SJA1000's) /INT pins 
+ * are OR'ed to the LINTi1 pin (actually ANDed in the 74HC08 since both
+ * the SJA1000's /INT pins and the LINTi1 pin are active low).
+ *
+ * The board does have an option to route the 2nd channel to LINTi2,
+ * apparently just one or two resistors need to be added.
+ *
+ * LINTi2 is floating per default, so don't set its interrupt enable flag 
+ * 'PLX9052_INTCSR_LI2EN', it'll just interrupt all the time.
+ */
+#define PLX9052_INTCSR_LI1EN 0x00000001 /* Local Interrupt 1 enable */
+#define PLX9052_INTCSR_LI1S  0x00000004 /* Local Interrupt 1 status */
+#define PLX9052_INTCSR_LI2EN 0x00000008 /* Local Interrupt 2 enable */
+#define PLX9052_INTCSR_LI2S  0x00000020 /* Local Interrupt 2 status */
+#define PLX9052_INTCSR_PIEN  0x00000040 /* PCI Interrupt enable */
+
+#define PLX9052_CNTRL_SWRESET 0x40000000 /* PCI Adapter Software Reset to Local Bus */
+
+#define IO_RANGE 0x100
+
+// Standard value: Pushpull  (OCTP1|OCTN1|OCPOL1|OCTP0|OCTN0|OCM1)
+#define ESDPCI200_OCR_DEFAULT_STD 0xFA
+/* Setting the OCR register to 0xFA is a good idea. 
+   This means  normal output mode , push-pull and the correct polarity. */
+
+
+void esdpci200_pci_soft_reset(struct candevice_t *candev)
+{
+       unsigned long reg_reset;
+       reg_reset = inl( candev->res_addr+PLX9052_CNTRL);
+       reg_reset &= ~(PLX9052_CNTRL_SWRESET);
+       rmb();
+       /* PCI Adapter Software Reset plus reset local bus */
+       outl( (reg_reset | PLX9052_CNTRL_SWRESET ), candev->res_addr+PLX9052_CNTRL);
+       wmb();
+       udelay(2500);
+       outl(reg_reset, candev->res_addr+PLX9052_CNTRL);
+       wmb();
+       udelay(2500);
+}
+
+void esdpci200_disconnect_irq(struct candevice_t *candev)
+{
+    /* writing 0x0 into the PLX's INTCSR register disables interrupts */
+       /* 0x0 is also the value in the register after a power-on reset */
+       outl(0x0, candev->res_addr + PLX9052_INTCSR);
+       DEBUGMSG("disabled interrupts on the PLX\n");
+}
+
+void esdpci200_connect_irq(struct candevice_t *candev)
+{
+        /* enable interrupts for the SJA1000's, enable PCI interrupts */
+       outl(   PLX9052_INTCSR_LI1EN | PLX9052_INTCSR_PIEN,
+               candev->res_addr+PLX9052_INTCSR);
+       DEBUGMSG("enabled interrupts on the PLX\n"); 
+}
+
+int esdpci200_irq_handler(int irq, struct canchip_t *chip)
+{
+       int retcode;
+       unsigned long it_reg;
+       struct candevice_t *candev;
+       candev = chip->hostdevice;
+       retcode = CANCHIP_IRQ_NONE;
+       //DEBUGMSG("Starting to handle an IRQ\n");
+       it_reg = inl(candev->res_addr+PLX9052_INTCSR);
+       rmb();
+       if((it_reg & (PLX9052_INTCSR_LI1S | PLX9052_INTCSR_LI1EN) ) 
+               == (PLX9052_INTCSR_LI1S | PLX9052_INTCSR_LI1EN) ) 
+       {       /*interrupt enabled and active */
+               int chipnum;
+               for(chipnum=0; chipnum < candev->nr_sja1000_chips; chipnum++)
+               {
+                       if(sja1000p_irq_handler(irq, candev->chip[chipnum]) == CANCHIP_IRQ_NONE)
+                       { /* since both chips use the same IRQ and the same LINTi on the PLX,
+                            we need manually do 'interrupt sharing' on the boardlevel
+                            by checking all chips one-by-one */
+                               continue;
+                       }
+                       else
+                       {
+                               retcode=CANCHIP_IRQ_HANDLED;
+                       }
+               }
+               if( retcode != CANCHIP_IRQ_HANDLED )
+               {/* None of the chips felt they were responsible for this IRQ... 
+                   so it appears we have problems with the IRQ */
+                       it_reg &= ~(PLX9052_INTCSR_LI1EN);
+                       //Either we have a problem with IRQ malfunctions, or our IRQ is shared with some other device.
+                       //
+                       //not actually disabled, unless outl() below is uncommented
+                       //outl(it_reg,(void*)(candev->res_addr+PLX9052_INTCSR));
+                       //CANMSG("CAN Interrupt disabled due to malfunction\n");
+               }
+       }
+       return retcode;
+}
+
+int esdpci200_request_io(struct candevice_t *candev)
+{
+       struct pci_dev *pcidev = candev->sysdevptr.pcidev;
+       can_ioptr_t remap_addr;
+       unsigned long bar2_addr;
+
+       #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       if(pci_request_region(pcidev, 0, "esdpci200_plx9050") != 0){
+               CANMSG("Request of esdpci200_plx9050 range failed\n");
+               return -ENODEV;
+       }else if(pci_request_region(pcidev, 1, "esdpci200_io") != 0){
+               CANMSG("Request of esdpci200_io range failed\n");
+               pci_release_region(pcidev, 0);
+               return -ENODEV;
+       }else if(pci_request_region(pcidev, 2, "esdpci200_sja") != 0){
+               CANMSG("Request of esdpci200_sja range failed\n");
+               pci_release_region(pcidev, 1);
+               pci_release_region(pcidev, 0);
+               return -ENODEV;
+       }
+       #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       if(pci_request_regions(pcidev, "esdpci200") != 0){
+               CANMSG("Request of esdpci200_plx9050 regions failed\n");
+               return -ENODEV;
+       }
+       #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+
+        /* ioports, PLX local configuration registers */
+       candev->res_addr=pci_resource_start(pcidev,1);
+       /*MEM window for SJA1000 chips*/
+       bar2_addr = pci_resource_start(pcidev,2);
+       candev->io_addr = bar2_addr;
+       if( ! (remap_addr=ioremap(bar2_addr, 
+               pci_resource_len(pcidev,2)))) /*MEM window for SJA1000 chips*/
+       {
+               CANMSG("Unable to access I/O memory at: 0x%lx\n", (unsigned long)bar2_addr);
+               goto ioremap_error;
+       }
+
+       can_base_addr_fixup(candev, remap_addr);
+       CANMSG("esdpci200_sja IO-memory: 0x%lx - 0x%lx (VMA 0x%lx)\n", 
+               (unsigned long) bar2_addr,
+               (unsigned long) bar2_addr + pci_resource_len(pcidev,2) - 1,
+               (long) remap_addr);
+
+       return 0;
+
+    ioremap_error:
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       pci_release_region(pcidev, 2);
+       pci_release_region(pcidev, 1);
+       pci_release_region(pcidev, 0);
+#else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       pci_release_regions(pcidev);
+#endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       return -ENODEV;
+}
+
+int esdpci200_release_io(struct candevice_t *candev)
+{
+       esdpci200_disconnect_irq(candev);
+       esdpci200_pci_soft_reset(candev);
+
+       iounmap(candev->dev_base_addr);
+    #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       pci_release_region(candev->sysdevptr.pcidev, 2);
+       pci_release_region(candev->sysdevptr.pcidev, 1);
+       pci_release_region(candev->sysdevptr.pcidev, 0);
+    #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       pci_release_regions(candev->sysdevptr.pcidev);
+    #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+       return 0;
+}
+
+void esdpci200_write_register(unsigned data, can_ioptr_t address)
+{
+       iowrite8((u8)data,(void*)address);
+       wmb();
+}
+
+unsigned esdpci200_read_register(can_ioptr_t address)
+{
+       return ioread8((void*)address);
+}
+
+int esdpci200_reset(struct candevice_t *candev)
+{
+       int i=0,chip_nr;
+       struct canchip_t *chip;
+       unsigned cdr;
+       DEBUGMSG("Resetting esdpci200 hardware ...\n");
+
+       esdpci200_disconnect_irq(candev);
+       esdpci200_pci_soft_reset(candev);
+
+       for(chip_nr=0;chip_nr<candev->nr_all_chips;chip_nr++){
+               if(!candev->chip[chip_nr]) continue;
+               chip=candev->chip[chip_nr];
+
+               esdpci200_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
+               udelay(1000);
+
+               cdr=esdpci200_read_register(chip->chip_base_addr+SJACDR);
+               esdpci200_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+               esdpci200_write_register(0, chip->chip_base_addr+SJAIER);
+
+               i=20;
+               esdpci200_write_register(0, chip->chip_base_addr+SJAMOD);
+               while (esdpci200_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
+                       if(!i--) return -ENODEV;
+                       udelay(1000);
+                       esdpci200_write_register(0, chip->chip_base_addr+SJAMOD);
+               }
+
+               cdr=esdpci200_read_register(chip->chip_base_addr+SJACDR);
+               esdpci200_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+               esdpci200_write_register(0, chip->chip_base_addr+SJAIER);
+               
+               esdpci200_read_register(chip->chip_base_addr+SJAIR);
+       }
+       
+
+       esdpci200_connect_irq(candev);
+
+       return 0;
+}      
+
+int esdpci200_init_hw_data(struct candevice_t *candev)
+{
+       struct pci_dev *pcidev = NULL;
+
+       do {
+               pcidev = pci_find_device(ESDPCI200_PCI_VENDOR_ID, ESDPCI200_PCI_PRODUCT_ID, pcidev);
+               if(pcidev == NULL) return -ENODEV;
+       } while(can_check_dev_taken(pcidev));
+       
+       if (pci_enable_device (pcidev)){
+               printk(KERN_CRIT "Setup of ESDPCI200 failed\n");
+               return -EIO;
+       }
+       candev->sysdevptr.pcidev=pcidev;
+
+       can_spin_lock_init(&candev->device_lock);
+
+       if(!(pci_resource_flags(pcidev, 0)&IORESOURCE_MEM))
+       {
+          printk(KERN_CRIT "PCI200 region %d is not MEM\n",0);
+          return -EIO;
+       }
+       if(!(pci_resource_flags(pcidev, 1)&IORESOURCE_IO))
+       {
+          printk(KERN_CRIT "PCI200 region %d is not IO\n",1);
+          return -EIO;
+       }
+
+       if(!(pci_resource_flags(pcidev,2)&IORESOURCE_MEM))
+       {
+          printk(KERN_CRIT "PCI200 region %d is not MEM\n",2);
+          return -EIO;
+       }
+
+        /* Reset/control field - used to store port of PLX9052 control region */
+       candev->res_addr = pci_resource_start(pcidev,1);;
+
+       /* Physical address of SJA1000 window, stored for debugging only */
+       candev->io_addr = pci_resource_start(pcidev,2);
+       
+       candev->aux_base_addr=NULL; /* mapped dynamically in esdpci200_request_io() */
+       candev->dev_base_addr=NULL; /* mapped dynamically in esdpci200_request_io() */
+       /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
+
+       candev->nr_82527_chips=0;
+       candev->nr_sja1000_chips=2;
+       candev->nr_all_chips=2;
+
+       return 0;
+}
+
+int esdpci200_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+
+       if(candev->sysdevptr.pcidev==NULL)
+               return -ENODEV; 
+
+       CANMSG("initializing esdpci200 chip operations\n");
+
+
+       sja1000p_fill_chipspecops(candev->chip[chipnr]);
+       candev->chip[chipnr]->chip_base_addr=candev->dev_base_addr + chipnr * IO_RANGE;
+
+       candev->chip[chipnr]->chipspecops->irq_handler=esdpci200_irq_handler;
+
+       candev->chip[chipnr]->flags = 0;
+       candev->chip[chipnr]->int_cpu_reg = 0; /* i82527 specific */
+       candev->chip[chipnr]->int_clk_reg = 0; /* i82527 specific */
+       candev->chip[chipnr]->int_bus_reg = 0; /* i82527 specific */
+       candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF; /* hardware specific options for the Clock Divider register */
+       candev->chip[chipnr]->sja_ocr_reg = ESDPCI200_OCR_DEFAULT_STD; /* hardware specific options for the Output Control register */
+       candev->chip[chipnr]->clock = 16000000;
+       candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
+       candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
+       if( chipnr > 0 ) /* only one IRQ used for both channels.
+                           CHIP_IRQ_CUSTOM req'd for RTAI, since 
+                           registering two handlers for the same IRQ 
+                           returns an error */
+               candev->chip[chipnr]->flags |= CHIP_IRQ_CUSTOM;
+
+       return 0;
+}      
+
+int esdpci200_init_obj_data(struct canchip_t *chip, int objnr)
+{
+       chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
+       return 0;
+}
+
+int esdpci200_program_irq(struct candevice_t *candev)
+{
+
+       return 0;
+}
+
+int esdpci200_register(struct hwspecops_t *hwspecops)
+{
+       hwspecops->request_io = esdpci200_request_io;
+       hwspecops->release_io = esdpci200_release_io;
+       hwspecops->reset = esdpci200_reset;
+       hwspecops->init_hw_data = esdpci200_init_hw_data;
+       hwspecops->init_chip_data = esdpci200_init_chip_data;
+       hwspecops->init_obj_data = esdpci200_init_obj_data;
+       hwspecops->write_register = esdpci200_write_register;
+       hwspecops->read_register = esdpci200_read_register;
+       hwspecops->program_irq = esdpci200_program_irq;
+       return 0;
+}
+
+
+#endif /*CAN_ENABLE_PCI_SUPPORT*/
diff --git a/lincan/src/gensja1000io.c b/lincan/src/gensja1000io.c
new file mode 100644 (file)
index 0000000..8dcf9fb
--- /dev/null
@@ -0,0 +1,270 @@
+/* gensja1000io.c
+ * Linux CAN-bus device driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3  17 Jun 2004
+ */ 
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/gensja1000io.h"
+#include "../include/sja1000p.h"
+
+/*
+ * IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ */
+#define IO_RANGE 0x20
+
+/**
+ * gensja1000io_request_io: - reserve io or memory range for can board
+ * @candev: pointer to candevice/board which asks for io. Field @io_addr
+ *     of @candev is used in most cases to define start of the range
+ *
+ * The function gensja1000io_request_io() is used to reserve the io-memory. If your
+ * hardware uses a dedicated memory range as hardware control registers you
+ * will have to add the code to reserve this memory as well. 
+ * %IO_RANGE is the io-memory range that gets reserved, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_request_io(struct candevice_t *candev)
+{
+       if (!can_request_io_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) {
+               CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
+               return -ENODEV;
+       }else {
+               DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
+       }
+       return 0;
+}
+
+/**
+ * gensja1000io_elease_io - free reserved io memory range
+ * @candev: pointer to candevice/board which releases io
+ *
+ * The function gensja1000io_release_io() is used to free reserved io-memory.
+ * In case you have reserved more io memory, don't forget to free it here.
+ * IO_RANGE is the io-memory range that gets released, please adjust according
+ * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
+ * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
+ * Return Value: The function always returns zero
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_release_io(struct candevice_t *candev)
+{
+       can_release_io_region(candev->io_addr,IO_RANGE);
+
+       return 0;
+}
+
+/**
+ * gensja1000io_reset - hardware reset routine
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function gensja1000io_reset() is used to give a hardware reset. This is 
+ * rather hardware specific so I haven't included example code. Don't forget to 
+ * check the reset status of the chip before returning.
+ * Return Value: The function returns zero on success or %-ENODEV on failure
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_reset(struct candevice_t *candev)
+{
+       int i;
+       struct canchip_t *chip=candev->chip[0];
+       unsigned cdr;
+       
+       gensja1000io_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
+       udelay(1000);
+       
+       cdr=gensja1000io_read_register(chip->chip_base_addr+SJACDR);
+       gensja1000io_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+       gensja1000io_write_register(0, chip->chip_base_addr+SJAIER);
+
+       i=20;
+       gensja1000io_write_register(0, chip->chip_base_addr+SJAMOD);
+       while (gensja1000io_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
+               if(!i--) return -ENODEV;
+               udelay(1000);
+               gensja1000io_write_register(0, chip->chip_base_addr+SJAMOD);
+       }
+
+       cdr=gensja1000io_read_register(chip->chip_base_addr+SJACDR);
+       gensja1000io_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+       gensja1000io_write_register(0, chip->chip_base_addr+SJAIER);
+       
+       return 0;
+}
+
+#define RESET_ADDR 0x0
+#define NR_82527 0
+#define NR_SJA1000 1
+
+/**
+ * gensja1000io_init_hw_data - Initialize hardware cards
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function gensja1000io_init_hw_data() is used to initialize the hardware
+ * structure containing information about the installed CAN-board.
+ * %RESET_ADDR represents the io-address of the hardware reset register.
+ * %NR_82527 represents the number of intel 82527 chips on the board.
+ * %NR_SJA1000 represents the number of philips sja1000 chips on the board.
+ * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
+ * the hardware uses programmable interrupts.
+ * Return Value: The function always returns zero
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_init_hw_data(struct candevice_t *candev) 
+{
+       candev->res_addr=RESET_ADDR;
+       candev->nr_82527_chips=0;
+       candev->nr_sja1000_chips=1;
+       candev->nr_all_chips=1;
+       candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
+
+       return 0;
+}
+
+/**
+ * gensja1000io_init_chip_data - Initialize chips
+ * @candev: Pointer to candevice/board structure
+ * @chipnr: Number of the CAN chip on the hardware card
+ *
+ * The function gensja1000io_init_chip_data() is used to initialize the hardware
+ * structure containing information about the CAN chips.
+ * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
+ * "sja1000".
+ * The @chip_base_addr entry represents the start of the 'official' memory map
+ * of the installed chip. It's likely that this is the same as the @io_addr
+ * argument supplied at module loading time.
+ * The @clock entry holds the chip clock value in Hz.
+ * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
+ * register. Options defined in the %sja1000.h file:
+ * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
+ * The entry @sja_ocr_reg holds hardware specific options for the Output Control
+ * register. Options defined in the %sja1000.h file:
+ * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
+ * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
+ * The entry @int_clk_reg holds hardware specific options for the Clock Out
+ * register. Options defined in the %i82527.h file:
+ * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
+ * The entry @int_bus_reg holds hardware specific options for the Bus 
+ * Configuration register. Options defined in the %i82527.h file:
+ * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
+ * The entry @int_cpu_reg holds hardware specific options for the cpu interface
+ * register. Options defined in the %i82527.h file:
+ * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
+ * Return Value: The function always returns zero
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+       /*sja1000_fill_chipspecops(candev->chip[chipnr]);*/
+       sja1000p_fill_chipspecops(candev->chip[chipnr]);
+
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
+       if(candev->chip[chipnr]->clock<=0)
+       candev->chip[chipnr]->clock = 16000000;
+       candev->chip[chipnr]->int_clk_reg = 0x0;
+       candev->chip[chipnr]->int_bus_reg = 0x0;
+       candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
+       candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
+
+       return 0;
+}
+
+/**
+ * gensja1000io_init_obj_data - Initialize message buffers
+ * @chip: Pointer to chip specific structure
+ * @objnr: Number of the message buffer
+ *
+ * The function gensja1000io_init_obj_data() is used to initialize the hardware
+ * structure containing information about the different message objects on the
+ * CAN chip. In case of the sja1000 there's only one message object but on the
+ * i82527 chip there are 15.
+ * The code below is for a i82527 chip and initializes the object base addresses
+ * The entry @obj_base_addr represents the first memory address of the message 
+ * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
+ * base address.
+ * Unless the hardware uses a segmented memory map, flags can be set zero.
+ * Return Value: The function always returns zero
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_init_obj_data(struct canchip_t *chip, int objnr)
+{
+       chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
+       return 0;
+}
+
+/**
+ * gensja1000io_program_irq - program interrupts
+ * @candev: Pointer to candevice/board structure
+ *
+ * The function gensja1000io_program_irq() is used for hardware that uses 
+ * programmable interrupts. If your hardware doesn't use programmable interrupts
+ * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and 
+ * leave this function unedited. Again this function is hardware specific so 
+ * there's no example code.
+ * Return value: The function returns zero on success or %-ENODEV on failure
+ * File: src/gensja1000io.c
+ */
+int gensja1000io_program_irq(struct candevice_t *candev)
+{
+       return 0;
+}
+
+/**
+ * gensja1000io_write_register - Low level write register routine
+ * @data: data to be written
+ * @address: memory address to write to
+ *
+ * The function gensja1000io_write_register() is used to write to hardware registers
+ * on the CAN chip. You should only have to edit this function if your hardware
+ * uses some specific write process.
+ * Return Value: The function does not return a value
+ * File: src/gensja1000io.c
+ */
+void gensja1000io_write_register(unsigned data, can_ioptr_t address)
+{
+       /*DEBUGMSG("gensja1000io_write_register: addr=0x%lx data=0x%x",
+               address,data);*/
+       can_outb(data,address);
+}
+
+/**
+ * gensja1000io_read_register - Low level read register routine
+ * @address: memory address to read from
+ *
+ * The function gensja1000io_read_register() is used to read from hardware registers
+ * on the CAN chip. You should only have to edit this function if your hardware
+ * uses some specific read process.
+ * Return Value: The function returns the value stored in @address
+ * File: src/gensja1000io.c
+ */
+unsigned gensja1000io_read_register(can_ioptr_t address)
+{
+       return can_inb(address);
+}
+
+/* !!! Don't change this function !!! */
+int gensja1000io_register(struct hwspecops_t *hwspecops)
+{
+       hwspecops->request_io = gensja1000io_request_io;
+       hwspecops->release_io = gensja1000io_release_io;
+       hwspecops->reset = gensja1000io_reset;
+       hwspecops->init_hw_data = gensja1000io_init_hw_data;
+       hwspecops->init_chip_data = gensja1000io_init_chip_data;
+       hwspecops->init_obj_data = gensja1000io_init_obj_data;
+       hwspecops->write_register = gensja1000io_write_register;
+       hwspecops->read_register = gensja1000io_read_register;
+       hwspecops->program_irq = gensja1000io_program_irq;
+       return 0;
+}
diff --git a/lincan/src/hcan2.c b/lincan/src/hcan2.c
new file mode 100644 (file)
index 0000000..e960685
--- /dev/null
@@ -0,0 +1,1065 @@
+/* hcan2.c
+ * Linux CAN-bus device driver.
+ * This software is released under the GPL-License.
+ */
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/hcan2.h"
+
+#define myDEBUG 0
+
+#if myDEBUG
+       #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
+#endif
+
+
+#define MAX_TRANSMIT_WAIT_LOOPS 20
+#define MAX_SETTING_WAIT_LOOPS 25              /* maximal loop count while checking Chip reply to action */
+#define MAX_IRQ_WAIT_LOOPS 25
+
+void hcan2_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj);
+void hcan2_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj);
+
+void hcan2_clear_irq_flags(struct canchip_t *chip);
+void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx);
+
+void hcan2_setup_mbox4write(struct msgobj_t * obj, struct canmsg_t * msg);
+void hcan2_setup_mbox4write_data(struct msgobj_t * obj, struct canmsg_t * msg);
+void hcan2_setup_mbox4read(struct msgobj_t * obj);
+
+void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2);
+
+int hcan2_compare_msg(struct msgobj_t * obj, struct canmsg_t * msg);
+void hcan2_notifyRXends(struct msgobj_t * obj, int what);
+/* Enable folowing IRQs
+ * HCAN2_IRR_DFRI = Data Frame Received Interrupt Flag
+ * HCAN2_IRR_MBEI = Mailbox Empty Interrupt Flag
+ *
+ * and Errors:
+ * Bus Off, Error Passive, Message Overrun/Overwrite
+ */
+uint16_t IRQs = ~(HCAN2_IRR_DFRI + HCAN2_IRR_MBEI + HCAN2_IRR_BOI + HCAN2_IRR_EPI + HCAN2_IRR_MOOI);
+/* 1 - mask interrupt, 0 - interrupt not masked */
+
+int hcan2_chip_config(struct canchip_t *chip)
+{
+       DEBUGMSG("Configuring chip...\n");
+       
+       if (hcan2_enable_configuration(chip))
+               return -ENODEV;
+
+       if (!chip->baudrate)
+               chip->baudrate=1000000;
+       if (hcan2_baud_rate(chip, chip->baudrate,chip->clock,0,75,0))
+               return -ENODEV;
+
+       hcan2_config_irqs(chip, IRQs);
+
+       if (hcan2_disable_configuration(chip))
+               return -ENODEV;
+
+/*     DEBUGMSG("Chip configured\n"); */
+       return 0;
+}
+
+int hcan2_enable_configuration(struct canchip_t *chip)
+{
+       int i = 0;
+       uint16_t gsr;
+
+       DEBUGMSG("Enabling configuration...\n");
+
+       /* Disable interrupt */
+       can_disable_irq(chip->chip_irq);
+
+       /* Halt mode - disable CAN activity after completing current operation */
+       gsr = can_read_reg_w(chip, HCAN2_GSR);
+       if (gsr & (HCAN2_GSR_BOFF | HCAN2_GSR_RESET))   /* chip is already in config mode */
+               return 0;
+
+       can_write_reg_w(chip, HCAN2_MCR_HALT, HCAN2_MCR);
+
+       /* Waits until chip enters Halt mode - finishes current  TX/RX operation */
+       gsr = can_read_reg_w(chip, HCAN2_GSR);
+       while ( !(gsr & HCAN2_GSR_HSS) && ((i++) <= MAX_SETTING_WAIT_LOOPS) ) {
+               udelay(200);
+               gsr = can_read_reg_w(chip, HCAN2_GSR);
+       }
+
+       if (i >= MAX_SETTING_WAIT_LOOPS) {
+               CANMSG("Error entering HALT mode (enable configuration) \n");
+               can_enable_irq(chip->chip_irq);
+               return -ENODEV;
+       }
+
+/*     DEBUGMSG("Configuration mode is ENABLED\n"); */
+       return 0;
+}
+
+int hcan2_disable_configuration(struct canchip_t *chip)
+{
+       int i = 0;
+       uint16_t gsr, mcr;
+
+       DEBUGMSG("Disabling configuration mode...\n");
+
+       /* Halt mode - disable CAN activity after completing current operation */
+       mcr = can_read_reg_w(chip, HCAN2_MCR);
+       gsr = can_read_reg_w(chip, HCAN2_GSR);
+
+       /* if configuration already disabled */
+       if (!(gsr & HCAN2_GSR_HSS) && !(mcr & HCAN2_MCR_HALT))
+           return 0;
+
+       can_write_reg_w(chip, mcr & ~HCAN2_MCR_HALT, HCAN2_MCR);
+
+       /* Waits until chip leaves Halt mode */
+       gsr = can_read_reg_w(chip, HCAN2_GSR);
+       while ( (gsr & HCAN2_GSR_BOFF) && ((i++) <= MAX_SETTING_WAIT_LOOPS) ) {
+               udelay(200);
+               gsr = can_read_reg_w(chip, HCAN2_GSR);
+       }
+
+       if (i >= MAX_SETTING_WAIT_LOOPS) {
+               CANMSG("Error leaving HALT mode (enable configuration) \n");
+               return -ENODEV;
+       }
+
+       /* Enable interrupt */
+       can_enable_irq(chip->chip_irq);
+
+/*     DEBUGMSG("Configuration mode is DISABLED\n"); */
+       return 0;
+}
+
+/* ********************************************* */
+int hcan2_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags)
+{
+       /* Set communication parameters.
+        * param rate baud rate in Hz
+        * param clock frequency of hcan2 clock in Hz (on sh7760 most probably 27.5MHz)
+        * param sjw synchronization jump width (0-3) prescaled clock cycles
+        * param sampl_pt sample point in % (0-100) sets (TSEG1 + 1)/(TSEG1 + TSEG2 + 1) ration
+        * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP
+        */
+
+
+       /* rate = clock / ((tseg1 + tseg2 + 1) * brp ) */
+
+       int best_error = 1000000000, error;
+       int best_tseg = 0, best_brp = 0, best_rate = 0, brp = 0;
+       int tseg, tseg1 = 0, tseg2 = 0;         /* tseg = TSEG1 + TSEG2 + 1*/
+       uint16_t bcr0 = 0, bcr1 = 0;
+
+       DEBUGMSG("Seting Baud rate...\n");
+
+       for (tseg = TSEG_MIN; tseg <= TSEG_MAX; tseg++)
+       {
+               brp = 10 * clock/(tseg * rate);
+               brp = brp % 10 > 4 ? brp / 10 + 1: brp / 10;    /* round */
+
+               if (brp == 0 || brp > 256)
+                       continue;
+
+               error = rate - clock/(brp * tseg);
+               if (error < 0)
+                       error = -error;
+               if (error <= best_error) {
+                       best_error = error;
+                       best_tseg = tseg;
+                       best_brp = brp;
+                       best_rate = clock/(brp * tseg);
+               }
+       }
+
+       tseg2 = best_tseg - (sampl_pt * best_tseg)/100;
+       if (tseg2 < TSEG2_MIN)          /* tseg2 <= sjw +1 , TSEG2_MIN = 4 */
+               tseg2 = TSEG2_MIN;
+       if (tseg2 > TSEG2_MAX)
+               tseg2 = TSEG2_MAX;
+       tseg1 = best_tseg - tseg2 - 1;
+       if (tseg1 > TSEG1_MAX) {
+               tseg1 = TSEG1_MAX;
+               tseg2 = best_tseg - tseg1 - 1;
+       }
+
+       if (best_error && (rate/best_error < 10)) {
+               CANMSG("baud rate %d is not possible with %d Hz clock\n",
+                       rate, clock);
+               CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
+                       best_rate, best_brp, best_tseg, tseg1, tseg2);
+               return -EINVAL;
+       }
+
+       DEBUGMSG("Setting %d bps.\n", best_rate);
+/*     DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
+               best_brp, best_tseg, tseg1, tseg2,
+               (100 * tseg1 / best_tseg));
+*/
+       /*
+        * EG   = 0b0   - Resynchronization at falling edge
+        * BSP  = 0b00  - bit sampling at one point (end of TSEG1)
+        */
+
+       bcr1 = (((tseg1 - 1) & 0x000f) << 12) + (((tseg2 - 1) & 0x0007) << 8) + ((sjw & 0x0003) << 4);
+       bcr0 = (best_brp - 1) & 0x00ff;
+
+       hcan2_set_btregs(chip, bcr0, bcr1);     
+
+       hcan2_disable_configuration(chip);
+
+/*     DEBUGMSG("Baud rate set successfully\n"); */
+       return 0;
+}
+
+int hcan2_set_btregs(struct canchip_t *chip, unsigned short bcr0, unsigned short bcr1)
+{
+/*     DEBUGMSG("Seting BCR0 and BCR1.\n"); */
+
+       /* masks words to correct format */
+       bcr0 &= 0x00ff;
+       bcr1 &= 0xf733;
+
+       can_write_reg_w(chip, bcr1, HCAN2_BCR1);
+       can_write_reg_w(chip, bcr0, HCAN2_BCR0);
+       
+/*     DEBUGMSG("BCR0 and BCR1 successfully set.\n"); */
+       return 0;
+}
+
+/* ********************************************* */
+int hcan2_start_chip(struct canchip_t *chip)
+{
+/*     DEBUGMSG("Starting chip %d...\n", chip->chip_idx); */
+
+       /* Stop chip turns chip to HALT mode - traffic on CAN bus is ignored after completing curent operation.
+        * Start chip only turn chip back from HALT state - using disable_config
+        */
+       hcan2_disable_configuration(chip);
+
+       DEBUGMSG("Chip [%d] started\n", chip->chip_idx);
+       return 0;
+}
+
+int hcan2_stop_chip(struct canchip_t *chip)
+{
+/*     DEBUGMSG("Stopping chip %d...\n", chip->chip_idx); */
+
+       /* Stop chip turns chip to HALT mode - traffic on CAN bus is ignored after completing curent operation.
+        * - using enable_config
+        */
+       hcan2_enable_configuration(chip);
+
+       DEBUGMSG("Chip [%d] stopped\n", chip->chip_idx);
+       return 0;
+}
+
+int hcan2_attach_to_chip(struct canchip_t *chip)
+{
+/*     DEBUGMSG("Attaching to chip %d.\n", chip->chip_idx); */
+       
+       /* initialize chip */   
+
+       if (hcan2_enable_configuration(chip))
+               return -ENODEV;
+
+       /* Clear all Mailboxes */
+       if (hcan2_clear_objects(chip))
+               return -ENODEV;
+
+       /* set Baudrate and Interrupts */
+       if (hcan2_chip_config(chip))
+               return -ENODEV;
+
+       if (hcan2_disable_configuration(chip))
+               return -ENODEV;
+
+       /* Enable interrupt */
+       can_enable_irq(chip->chip_irq);
+       can_enable_irq(chip->chip_irq);
+
+       CANMSG("Successfully attached to chip [%02d].\n", chip->chip_idx);
+       return 0;
+}
+
+int hcan2_release_chip(struct canchip_t *chip)
+{
+       hcan2_stop_chip(chip);
+       can_disable_irq(chip->chip_irq);
+       
+       hcan2_clear_objects(chip);
+       
+       DEBUGMSG("Chip released [%02d]\n", chip->chip_idx);
+       return 0;
+}
+
+/* ********************************************* */
+int hcan2_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask)
+{
+       uint16_t ctrl0, lafm0;
+       struct msgobj_t * obj;
+       int obj_idx = (int) (chip->chip_data);
+
+       if (code & 0x1ffff800)  
+           return hcan2_extended_mask(chip, code, mask);
+
+       
+       if (obj_idx > 0 && obj_idx <= 32)
+           obj = chip->msgobj[obj_idx - 1];
+       else
+           return -ENODEV;
+
+       chip->chip_data = (void*)0;     /* reset mbox number */
+
+
+       ctrl0 = ((code & 0x07ff) << 4);
+       lafm0 = ((mask & 0x07ff) << 4);
+       lafm0 |= 0x0003;                /* ignore Ext ID 17:16  */
+       
+       can_write_reg_w(chip, ctrl0, (int) obj->obj_base_addr + HCAN2_MB_CTRL0);
+       can_write_reg_w(chip, 0x0000, (int) obj->obj_base_addr + HCAN2_MB_CTRL1);
+       can_write_reg_w(chip, lafm0, (int) obj->obj_base_addr + HCAN2_MB_MASK);
+       can_write_reg_w(chip, 0xffff, (int) obj->obj_base_addr + HCAN2_MB_MASK + 2);
+
+       DEBUGMSG("MB%02d: Set standard_mask [id:0x%04x, m:0x%04x]\n", obj_idx, code, lafm0);
+       return 0;
+}
+
+int hcan2_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
+{
+       uint16_t ctrl0, ctrl1, lafm0, lafm1;
+
+       struct msgobj_t * obj;
+
+       int obj_idx = (int) (chip->chip_data);
+       
+       if (obj_idx > 0 && obj_idx <= 32)
+           obj = chip->msgobj[obj_idx - 1];
+       else
+           return -ENODEV;
+
+       chip->chip_data = (void*)0; /* reset mbox number */
+
+       ctrl0 = ((code & 0x1ffc0000) >> 14);
+       ctrl0 |=((code & 0x00030000) >> 16);
+       ctrl0 |= HCAN2_MBCT0_IDE;       /* set IDE flag */
+       ctrl1 =  (code & 0x0000ffff);
+
+       lafm0 = ((mask & 0x1ffc0000) >> 14);
+       lafm0 |=((mask & 0x00030000) >> 16);
+       lafm1 =  (mask & 0x0000ffff);
+       
+       can_write_reg_w(chip, ctrl0, (int) obj->obj_base_addr + HCAN2_MB_CTRL0);
+       can_write_reg_w(chip, ctrl1, (int) obj->obj_base_addr + HCAN2_MB_CTRL1);
+       can_write_reg_w(chip, lafm0, (int) obj->obj_base_addr + HCAN2_MB_MASK);
+       can_write_reg_w(chip, lafm1, (int) obj->obj_base_addr + HCAN2_MB_MASK + 2);
+       
+       DEBUGMSG("MB%02d: Set extended_mask [id:0x%08x, m:0x%08x]\n", obj_idx, (uint32_t)code, (uint32_t)mask);
+    
+        return 0;
+}
+
+/* ********************************************* */
+int hcan2_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       DEBUGMSG("Pre read config\n");
+
+       hcan2_enable_configuration(chip);
+
+       /* clears mailbox and setup LFA to accept all Exted Messages */
+       hcan2_setup_mbox4read(obj);
+       
+       hcan2_disable_configuration(chip);
+
+       return 0;
+}
+
+int hcan2_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
+{
+       DEBUGMSG("Pre write config\n");
+
+       /* change Mailbox header only if neccessary */  
+       /* otherwise change only data */
+       if (hcan2_compare_msg(obj, msg))
+       {
+               if (hcan2_enable_configuration(chip))
+                       return -ENODEV;
+       
+               hcan2_setup_mbox4write(obj, msg);
+               
+               if (hcan2_disable_configuration(chip))
+                       return -ENODEV;
+       }
+       else
+               hcan2_setup_mbox4write_data(obj, msg);
+
+       return 0;
+}
+
+int hcan2_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
+{
+       unsigned obj_bit;
+       int b_addr = ((obj->object - 1) / 16) * (-2); 
+
+       obj_bit = (1 << ((obj->object - 1) % 16));
+       
+/*     CANMSG("Sending message [obj: %d]\n", obj->object - 1); */
+
+       can_write_reg_w(chip, obj_bit, b_addr + HCAN2_TXPR0);
+
+/*     CANMSG("Message sent [obj: %d]\n", obj->object - 1); */
+       return 0;
+}
+
+int hcan2_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       CANMSG("hcan2_remote_request not implemented\n");
+       return -ENOSYS;
+}
+
+/* ********************************************* */
+int hcan2_irq_handler(int irq, struct canchip_t *chip)
+{
+       uint16_t irq_reg, idx;
+       short loop_cnt = MAX_IRQ_WAIT_LOOPS;
+       uint32_t rxdf, txdf;
+
+/*
+       HCAN2_IRR_TCMI  - Time Compare Match Register
+       HCAN2_IRR_TOI   - Time Overrun Interrupt
+       HCAN2_IRR_WUBA  - Wake-up on Bus Activity
+       HCAN2_IRR_MOOI  - Message Overrun/Overwrite Interrupt Flag
+       HCAN2_IRR_MBEI  - Messagebox Empty Interrupt Flag
+       HCAN2_IRR_OF    - Overload Frame
+       HCAN2_IRR_BOI   - Bus Off Interrupt Flag
+       HCAN2_IRR_EPI   - Error Passive Interrupt Flag
+       HCAN2_IRR_ROWI  - Receive Overload Warning Interrupt Flag
+       HCAN2_IRR_TOWI  - Transmit Overload Warining Interrupt Flag
+       HCAN2_IRR_RFRI  - Remote Frame Request Interrupt Flag
+       HCAN2_IRR_DFRI  - Data Frame Received Interrupt Flag
+       HCAN2_IRR_RHSI  - Reset/Halt/Sleep Interrupt Flag */
+
+       irq_reg = can_read_reg_w(chip, HCAN2_IRR);
+       DEBUGMSG("irq: %d, chip base addr: 0x%08x\n", irq, (uint32_t)chip->chip_base_addr);
+       DEBUGMSG("IRQ Handler: HCAN2_IRR: 0x%04x\n", irq_reg); //*/
+
+       do {
+
+               if(!loop_cnt--) {
+                       CANMSG("hcan2_irq_handler IRQ %d stuck\n", irq);
+                       return CANCHIP_IRQ_STUCK;
+               }
+
+               /* Received message */
+               if (irq_reg & HCAN2_IRR_DFRI)
+               {
+                       rxdf = (can_read_reg_w(chip, HCAN2_RXPR1) << 16) +
+                               can_read_reg_w(chip, HCAN2_RXPR0);
+
+                       while(rxdf) {
+                               DEBUGMSG("Received message [0x%08x]\n", rxdf);
+
+                               /* find the message object */
+                               for (idx = 0; (idx < chip->max_objects) && rxdf; idx++)
+                                       if ((rxdf & (1<<idx))) {
+                                               hcan2_irq_read_handler(chip, chip->msgobj[idx]);
+                                               /* RXPR flag for this msgobj is cleared during irq_read_handler*/
+                                               rxdf &= ~(1 << idx);
+                                       }
+
+
+                               DEBUGMSG("Before reset flags [0x%08x]\n", rxdf);
+                               rxdf = (can_read_reg_w(chip, HCAN2_RXPR1) << 16) +
+                                       can_read_reg_w(chip, HCAN2_RXPR0);
+                       }
+               }
+
+               /* Error: Bus Off */
+               if (irq_reg & HCAN2_IRR_BOI) {
+                       CANMSG("Error: entering BUS OFF state\nstatus register: 0x%02x irq register: 0x%02x\n",
+                               can_read_reg_w(chip, HCAN2_GSR), irq_reg);
+
+                       /* notify all RX/TX ends */
+                       for (idx = 0; idx < chip->max_objects; idx++) {
+                               /* notify TX */
+                               chip->msgobj[idx]->ret=-1;
+                               if(chip->msgobj[idx]->tx_slot)
+                                       canque_notify_inends(chip->msgobj[idx]->tx_qedge,
+                                               CANQUEUE_NOTIFY_ERROR);
+                               /* notify RX */
+                               hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
+                       }
+
+                       /* reset flag - by writing '1' */
+                       can_write_reg_w(chip, HCAN2_IRR_BOI, HCAN2_IRR);
+               }
+
+               /* Warning: Error Passive */
+               if (irq_reg & HCAN2_IRR_EPI) {
+                       uint16_t tecrec;
+                       tecrec = can_read_reg_w(chip, HCAN2_TECREC);
+
+                       CANMSG("Warning: entering ERROR PASSIVE state\nTEC: %d REC: %d\n",
+                               (uint16_t)((tecrec >> 8) & 0x00ff), (uint16_t)(tecrec & 0x00ff));
+                       
+                       /* Show warning only */
+
+                       /* reset flag - by writing '1' */
+                       can_write_reg_w(chip, HCAN2_IRR_EPI, HCAN2_IRR);
+               }
+
+               /* Message Overrun/Overwritten */
+               if (irq_reg & HCAN2_IRR_MOOI) { 
+                       /* put get Unread Message Status Register */
+                       rxdf =  (can_read_reg_w(chip, HCAN2_UMSR1) << 16) + can_read_reg_w(chip, HCAN2_UMSR0);
+
+                       /* find the message object */
+                       for (idx = 0; (idx < chip->max_objects) && !(rxdf & (1<<idx)); idx++) { }
+                       
+                       CANMSG("Error: MESSAGE OVERRUN/OVERWRITTEN [MB: %d]\n",idx);
+                       
+                       /* notify only injured RXqueue-end */
+                       if (idx < chip->max_objects) 
+                               hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
+
+                       /* reset flag */
+                       can_write_reg_w(chip, (1 << (idx % 16)), HCAN2_UMSR0 - 2 * (idx / 16));
+               }
+
+               /* Mailbox empty - after message was sent */
+               if (irq_reg & HCAN2_IRR_MBEI)
+               {
+                   txdf = (can_read_reg_w(chip, HCAN2_TXACK1) << 16) +
+                       can_read_reg_w(chip, HCAN2_TXACK0);
+
+                   /* find the message object */
+                   for (idx = 0; (idx < chip->max_objects) && !(txdf & (1<<idx)); idx++) { }
+
+                   /* realy i got one? */
+                   if (idx >= chip->max_objects) {
+                       /* IRQ is caused by Aborted transmition */
+                       can_write_reg_w(chip, 0xffff, HCAN2_ABACK0);
+                       can_write_reg_w(chip, 0xffff, HCAN2_ABACK1);
+                       return CANCHIP_IRQ_HANDLED;
+                   } 
+
+                   /* Clear TXACK flag */                  
+                   can_write_reg_w(chip, 1 << (idx % 16), HCAN2_TXACK0 - 2 * (idx / 16));
+
+                   /* sends message */     
+                   hcan2_wakeup_tx(chip, chip->msgobj[idx]);
+               }
+
+               irq_reg = can_read_reg_w(chip, HCAN2_IRR);
+       } while(irq_reg & ~IRQs);
+
+       return CANCHIP_IRQ_HANDLED;
+}
+
+int hcan2_irq_accept(int irq, struct canchip_t *chip)
+{
+       CANMSG("hcan2_irq_accept NOT IMPLEMENTED\n");
+       return -ENOSYS;
+}
+
+int hcan2_config_irqs(struct canchip_t *chip, short irqs)
+{
+       hcan2_clear_irq_flags(chip);
+
+       can_write_reg_w(chip, irqs, HCAN2_IMR);
+       
+       /* allow all mailboxes to generate IRQ */
+       can_write_reg_w(chip, 0, HCAN2_MBIMR0);
+       can_write_reg_w(chip, 0, HCAN2_MBIMR1);
+       
+/*     CANMSG("IRQ Mask set [0x%02x]\n", irqs); */
+       return 0;
+}
+
+
+/* ********************************************* */
+int hcan2_clear_objects(struct canchip_t *chip)
+{
+       int i;
+       for (i = 0; i < chip->max_objects; i++)
+               hcan2_clear_mbox(chip, i);
+
+       return 0;
+}
+
+int hcan2_check_tx_stat(struct canchip_t *chip)
+{
+/*     DEBUGMSG("Check TX stat\n"); */
+       /* If Transmition is complete return 0 - no error */
+       if (can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_TXC)
+               return 0;
+       else
+               return 1;
+}
+
+/* Note: this checks TX status of concrete messagebox */
+int hcan2_check_MB_tx_stat(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       /* Transmition is complete return 0 - no error */
+       
+       /* MB1-MB15 are in CANTXPR0 and MB16-MB31 are in CANTXPR1
+          CANTXPR0 = CANTXPR1 + 0x0002
+          MB0 - receive only */
+
+       char id = obj->object - 1;
+       return (can_read_reg_w(chip, HCAN2_TXPR0 - 2 * (id / 16)) & (1 << (id & 0x00ff)));
+}
+
+int hcan2_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       DEBUGMSG("WakeUP TX\n");
+
+       if (obj->object == 1)   /* msgbox 0 cant transmit only receive ! */
+           return -ENODEV;
+    
+       can_preempt_disable();
+       
+       can_msgobj_set_fl(obj,TX_REQUEST);
+       if(!can_msgobj_test_and_set_fl(obj,TX_LOCK) &&
+               !hcan2_check_MB_tx_stat(chip, obj))
+       {       /* enable transmition only if MB is empty */
+               can_msgobj_clear_fl(obj,TX_REQUEST);
+
+               hcan2_irq_write_handler(chip, obj);
+       
+               can_msgobj_clear_fl(obj,TX_LOCK);
+       }
+       else
+               can_msgobj_clear_fl(obj,TX_REQUEST);
+
+
+       can_preempt_enable();
+
+/*     DEBUGMSG("WakeUP TX - END\n"); */
+       return 0;
+}
+
+int hcan2_filtch_rq(struct canchip_t *chip, struct msgobj_t * obj)
+{
+       struct canfilt_t filter;
+
+
+#if myDEBUG
+       int num = canqueue_ends_filt_conjuction(obj->qends, &filter);
+#else
+       canqueue_ends_filt_conjuction(obj->qends, &filter);
+#endif
+
+       /* in structure chip->chip_data is Mailbox number */
+       chip->chip_data = (void*)(obj->object);
+
+       /* HCAN2 uses oposite logic for LAFM: 1-ignore bit, 0-use bit as mask */
+
+       DEBUGMSG("CNT: %d ID: 0x%08x MASK: 0x%08x\n", num, (uint32_t) (filter.id) & 0x1fffffff, (uint32_t) (~filter.mask) & 0x1fffffff);
+
+       if (filter.flags & MSG_EXT)             /* Extended ID */
+               return hcan2_extended_mask(chip, filter.id, ~filter.mask);
+       else                                    /* Standard ID */
+               return hcan2_standard_mask(chip, filter.id, ~filter.mask);
+}
+
+/* ********************************************* */
+void hcan2_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       int i, len;
+       unsigned ctrl0, ctrl2, data;
+       unsigned long flag_addr;
+       uint16_t mb_offset;
+       
+
+       mb_offset = (int ) obj->obj_base_addr;
+
+/*     DEBUGMSG("------IRQ Read Handler\n"); */
+
+       ctrl0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
+       ctrl2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
+
+       obj->rx_msg.length = len = ctrl2 & HCAN2_MBCT2_DLC;
+       obj->rx_msg.flags = (ctrl0 & HCAN2_MBCT0_RTR) ? MSG_RTR : 0;
+       obj->rx_msg.cob = obj->object - 1;
+               
+       /* get ID of received message */
+       if (ctrl0 & HCAN2_MBCT0_IDE)
+       {
+           DEBUGMSG("EXTENDED ID\n");
+           obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID) << (18 - 4);
+           obj->rx_msg.id |= can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
+           obj->rx_msg.id |= ((ctrl0 & HCAN2_MBCT0_EXTID) << 16);
+       }
+       else
+           obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID)>>4;
+
+
+       if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+       for (i = 0; i < len; i++)
+       {
+               /* rcanqueue_ends_filt_conjuctionead 16bit data - two data bytes*/
+               data = can_read_reg_w(chip, (int) obj->obj_base_addr + HCAN2_MB_DATA1 + i);
+               obj->rx_msg.data[i] = (data & 0xff00) >> 8;             // one data byte
+               if (++i < len) obj->rx_msg.data[i] = data & 0x00ff;     // second data byte
+       }
+
+       /* Computes correct offset address of register from MSGBOX_IDX and RTR flag
+        * result is one of these:
+        * HCAN2_RXPR1, HCAN2_RXPR0, HCAN2_RFPR1, HCAN2_RFPR0
+        */
+       flag_addr = HCAN2_RXPR0 - (int)((obj->object - 1) / 16) * 2;
+               
+       /* Reset flag by writing 1 to its position */
+       can_write_reg_w(chip, (1 << ((obj->object - 1) % 16)), flag_addr);
+
+       /* fill CAN message timestamp */
+       can_filltimestamp(&obj->rx_msg.timestamp);
+
+       canque_filter_msg2edges(obj->qends, &obj->rx_msg);
+}
+
+void hcan2_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
+{
+       int cmd;
+
+       if(obj->tx_slot){
+               /* Do local transmitted message distribution if enabled */
+               if (processlocal){
+                       /* fill CAN message timestamp */
+                       can_filltimestamp(&obj->tx_slot->msg.timestamp);
+
+                       obj->tx_slot->msg.flags |= MSG_LOCAL;
+                       canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
+               }
+               /* Free transmitted slot */
+               canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+               obj->tx_slot=NULL;
+       }
+
+       cmd = canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
+       if(cmd < 0)
+               return;
+
+       if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
+               obj->ret = -1;
+               canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
+               canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+               obj->tx_slot = NULL;
+               return;
+       }
+       if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
+               obj->ret = -1;
+               canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
+               canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+               obj->tx_slot = NULL;
+               return;
+       }
+}
+
+/* ********************************************* */
+int hcan2_register(struct chipspecops_t *chipspecops)
+{
+       chipspecops->chip_config = hcan2_chip_config;
+       chipspecops->enable_configuration = hcan2_enable_configuration;
+       chipspecops->disable_configuration = hcan2_disable_configuration;
+
+       chipspecops->baud_rate = hcan2_baud_rate;
+       chipspecops->set_btregs = hcan2_set_btregs;
+
+       chipspecops->start_chip = hcan2_start_chip;
+       chipspecops->stop_chip = hcan2_stop_chip;
+       chipspecops->attach_to_chip = hcan2_attach_to_chip;
+       chipspecops->release_chip = hcan2_release_chip;
+
+       chipspecops->standard_mask = hcan2_standard_mask;
+       chipspecops->extended_mask = hcan2_extended_mask;
+       chipspecops->message15_mask = NULL; /* hcan2_message15_mask; */
+
+       chipspecops->pre_read_config = hcan2_pre_read_config;
+       chipspecops->pre_write_config = hcan2_pre_write_config;
+       chipspecops->send_msg = hcan2_send_msg;
+       chipspecops->remote_request = hcan2_remote_request;
+
+       chipspecops->irq_handler = hcan2_irq_handler;
+       chipspecops->irq_accept = NULL; /* hcan2_irq_accept; */
+       chipspecops->config_irqs = hcan2_config_irqs;
+
+       chipspecops->clear_objects = hcan2_clear_objects;
+       chipspecops->check_tx_stat = hcan2_check_tx_stat;
+       chipspecops->wakeup_tx = hcan2_wakeup_tx;
+       chipspecops->filtch_rq = hcan2_filtch_rq;
+       return 0;
+}
+
+int hcan2_fill_chipspecops(struct canchip_t *chip)
+{
+       chip->chip_type = "hcan2";
+       chip->max_objects = 32;
+       chip->write_register = chip->hostdevice->hwspecops->write_register;
+       chip->read_register = chip->hostdevice->hwspecops->read_register;
+       
+       /*
+       chip->flags;
+       chip->baudrate;
+       chip->msgobj;
+       chip->chip_data;
+       chip->chip_lock;
+
+       chip->sja_cdr_reg;
+       chip->sja_ocr_reg;
+       chip->int_cpu_reg;
+       chip->int_clk_reg;
+       chip->int_bus_reg;
+
+       #ifdef CAN_WITH_RTL
+       chip->worker_thread;
+       chip->pend_flags;
+       #endif
+       */
+
+       hcan2_register(chip->chipspecops);
+       return 0;
+}
+
+
+/* ********************************************* */
+int hcan2_reset_chip(struct canchip_t *chip)
+{
+       /* After reset and reconfig (start_chip) Chip waits for
+        * 11 recessive bits to join CAN bus activity
+        */
+
+       int i; 
+       unsigned gsr_reset;
+
+       DEBUGMSG("Resetting HCAN2 chip %d...\n", chip->chip_idx);
+
+       /* send Reset Request */
+       can_write_reg_w(chip, HCAN2_MCR_RESET, HCAN2_MCR );
+
+       /* Check hardware reset status */ 
+       i = 0;
+       gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
+       while (!(gsr_reset) && ((i++) <= MAX_SETTING_WAIT_LOOPS))
+       {
+               udelay(10000);
+               gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
+       }
+
+       if (i >= MAX_SETTING_WAIT_LOOPS) {
+               CANMSG("Reset status timeout! (enter Reset Mode)\n");
+               return -ENODEV;
+       }
+
+       /* Clear Reset request flag */
+       can_write_reg_w(chip, can_read_reg_w(chip, HCAN2_MCR) & (~HCAN2_MCR_RESET), HCAN2_MCR);
+
+
+       /* Clear Reset Interrupt Flag IRR 0 */
+       can_write_reg_w(chip, HCAN2_IRR_RHSI, HCAN2_IRR);
+
+/*     DEBUGMSG("Chips reset status ok.\n"); */
+
+       return 0;
+}
+
+/* !!! Functions below doesn't call enable/disable chip config !!! */
+/* !!! Usable only in block, where enable/diable config is called explicitly !!! */
+void hcan2_clear_irq_flags(struct canchip_t *chip)
+{
+       uint16_t irr;
+       DEBUGMSG("Clearing IRQ flags...\n");
+       DEBUGMSG("IRR: %04x\n",can_read_reg_w(chip, HCAN2_IRR));
+
+       irr = HCAN2_IRR_TCMI | HCAN2_IRR_TOI | HCAN2_IRR_WUBA |
+               HCAN2_IRR_OF | HCAN2_IRR_BOI | HCAN2_IRR_EPI |
+               HCAN2_IRR_ROWI | HCAN2_IRR_TOWI | HCAN2_IRR_RHSI;
+       can_write_reg_w(chip, irr, HCAN2_IRR);
+
+       /* Other IRQ flags are cleared through other registers - see below */
+
+       /* Meseage Overrun/Overwrite interrupt */
+       can_write_reg_w(chip, 0, HCAN2_UMSR0);
+       can_write_reg_w(chip, 0, HCAN2_UMSR1);
+
+       /* Mailbox Empty Interrupt */
+       can_write_reg_w(chip, 0, HCAN2_TXACK0);
+       can_write_reg_w(chip, 0, HCAN2_TXACK1);
+       can_write_reg_w(chip, 0, HCAN2_ABACK0);
+       can_write_reg_w(chip, 0, HCAN2_ABACK1);
+
+       /* Remote Frame Request Interrupt */
+       can_write_reg_w(chip, 0, HCAN2_RFPR0);
+       can_write_reg_w(chip, 0, HCAN2_RFPR1);
+
+       /* Data Frame Received Interupt Flag */
+       can_write_reg_w(chip, 0, HCAN2_RXPR0);
+       can_write_reg_w(chip, 0, HCAN2_RXPR1);
+
+       DEBUGMSG("clear_irq_flags - OK\n");
+}
+
+void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx)
+{
+       unsigned long mb_start_addr = HCAN2_MB0 + msgobj_idx * HCAN2_MB_OFFSET;
+
+/*     DEBUGMSG("Clearing message object %d\n", msgobj_idx); */
+
+       /* STDID = 0
+        * Standard Identifier format (0)
+        * Data Frame (0)
+        * EXTID{17,16} = 0
+        */
+       can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL0);
+
+       /* EXTID {15:0} = 0 */
+       can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL1);
+
+       /* NMC: overwrite stored message (1)
+        * ATDF: No message is transmited after receiving Remote Frame (0)
+        * DARTX: disable Automatic Retransmition: yes (1)
+        * MBC = 111 - not used: HCAN2_MBCT2_MBC default value correspond to 'Not Used'
+        * CAN Bus error - 0
+        * Data Length = 0
+        */
+       can_write_reg_w(chip, (uint16_t) (HCAN2_MBCT2_NMC | HCAN2_MBCT2_DART | HCAN2_MBCT2_MBC), mb_start_addr + HCAN2_MB_CTRL2);
+
+       /* TimeStamp */
+       can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_TSTP);
+
+       /* Data: all bytes 0xff */
+       can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA0);
+       can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA2);
+       can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA4);
+       can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA6);
+
+       /* Local Acceptance Filter Mask - all bits of STDID and EXTID must match values set in mailbox */
+       can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK);
+       can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK + 2);            /* Mask is 4 bytes */
+
+
+       DEBUGMSG("Mailbox [%d] cleared.\n", msgobj_idx);
+}
+
+void hcan2_setup_mbox4write(struct msgobj_t * obj, struct canmsg_t * msg)
+{
+       int mb_offset;
+       uint16_t ctrl0, ctrl1, ctrl2; 
+
+       struct canchip_t * chip = obj->hostchip;
+
+       DEBUGMSG("Change Header\n");
+
+       mb_offset = (int) obj->obj_base_addr;
+       
+       hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
+
+       can_write_reg_w(chip, ctrl0, mb_offset + HCAN2_MB_CTRL0);
+       can_write_reg_w(chip, ctrl1, mb_offset + HCAN2_MB_CTRL1);       /* set 0 if not using EXT format */
+       can_write_reg_w(chip, ctrl2, mb_offset + HCAN2_MB_CTRL2);
+
+       /* data */
+       hcan2_setup_mbox4write_data(obj, msg);
+}
+
+void hcan2_setup_mbox4write_data(struct msgobj_t * obj, struct canmsg_t * msg)
+{
+       int len,i, mb_offset;
+       uint16_t data; 
+       
+       struct canchip_t * chip = obj->hostchip;
+
+       DEBUGMSG("Change Data\n");
+
+       mb_offset = (int) obj->obj_base_addr;
+       
+       len = msg->length;
+       if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+       
+       for (i = 0; i < len; i+=2)
+       {
+               data = (msg->data[i] << 8) + (i+1 < len ? msg->data[i+1] : 0);
+               can_write_reg_w(chip, data, mb_offset + HCAN2_MB_DATA1 + i);
+       }
+}
+
+void hcan2_setup_mbox4read(struct msgobj_t * obj)
+{
+       struct canchip_t * chip = obj->hostchip;
+    
+       hcan2_clear_mbox(chip, obj->object - 1);
+
+       // in structure chip->chip_data is Mailbox number
+       chip->chip_data = (void*)(obj->object);
+       hcan2_extended_mask(chip, 2048, 0x1fffffff);    /* accept all */
+
+       can_write_reg_w(chip, HCAN2_MBCT2_DART + (HCAN2_MBMOD_RXDR << 8),
+           (int) obj->obj_base_addr + HCAN2_MB_CTRL2);
+}
+
+void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2)
+{
+       uint8_t len;
+       uint32_t id = msg->id;
+
+       len = msg->length;
+       if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+
+       *ctrl0 = (msg->flags & MSG_RTR ? HCAN2_MBCT0_RTR : 0);
+
+       if (msg->flags & MSG_EXT)
+       {
+               /* Extended ID */
+               *ctrl0 |= ((id & 0x1ffc0000) << 14);
+               *ctrl0 |= ((id & 0x00030000) >> 16) | HCAN2_MBCT0_IDE;  /* get bits {17:16} from EXTID */
+               *ctrl1 = (id & 0x0000ffff);
+       }
+       else
+       {
+               /* Standard ID */
+               *ctrl0 |= ((id & 0x01ff) << 4);
+               *ctrl1 = 0;
+       }
+
+       *ctrl2 = HCAN2_MBCT2_DART + HCAN2_MBMOD_TXDR + (len & HCAN2_MBCT2_DLC);
+}
+
+int hcan2_compare_msg(struct msgobj_t * obj, struct canmsg_t * msg)
+{
+       /* Check if mailbox header content change is neccessary */
+       /* Comparing only Control regs */
+       uint16_t ctrl0, ctrl1, ctrl2;
+       uint16_t mb_offset;
+       uint16_t c0,c1,c2;
+       
+       struct canchip_t * chip = obj->hostchip;
+
+       mb_offset = (int) obj->obj_base_addr;
+
+       c0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
+       c1 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
+       c2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
+
+       hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
+
+       /* if using EXT ID conpare also ctrl1 */
+       if (msg->flags & MSG_EXT && ctrl1 ^ c1)
+               return 1;
+               
+
+       DEBUGMSG("C0 0x%04x HW: 0x%04x\n", ctrl0, c0);
+       DEBUGMSG("C1 0x%04x HW: 0x%04x\n", ctrl1, c1);
+       DEBUGMSG("C2 0x%04x HW: 0x%04x\n", ctrl2, c2);
+
+       return ((ctrl0 ^ c0) || (ctrl2 ^ c2));
+}
+
+void hcan2_notifyRXends(struct msgobj_t * obj, int what){
+       struct canque_edge_t * edge;
+       canque_for_each_inedge(obj->qends, edge){
+               canque_notify_outends(edge, what);
+       }
+}
index 1a18904..ff12573 100644 (file)
@@ -47,7 +47,7 @@ int hms30c7202_request_io(struct candevice_t *candev)
                (unsigned long)candev->io_addr );
        }
        
-       if (!( candev->dev_base_addr = (long)ioremap( candev->io_addr, IO_RANGE ))) {
+       if (!( candev->dev_base_addr = ioremap( candev->io_addr, IO_RANGE ))) {
                DEBUGMSG( "Failed to map IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx\n",
                        (unsigned long)candev->io_addr,
                        (unsigned long)candev->io_addr + IO_RANGE - 1,
@@ -121,7 +121,7 @@ int hms30c7202_release_io(struct candevice_t *candev)
        candev->chip[0]->chipspecops->stop_chip(candev->chip[0]);
        
        // release I/O memory mapping
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
        
        // Release the memory region
        can_release_mem_region(candev->io_addr, IO_RANGE);
@@ -193,16 +193,16 @@ int hms30c7202_init_hw_data(struct candevice_t *candev)
 /*( struct canchip_t *pchip, u16 chip_nr, u16 startminor, u32 baseaddr, u8 irq )*/
 {
        //      u32 intCntrVAddr = 0;
-       u32 gpioVAddr = 0;
+       can_ioptr_t gpioVAddr = 0;
        u32 tempReg = 0;
        u32 baseaddr=candev->io_addr;
        
-       //      if ( (!( intCntrVAddr = (u32)ioremap( 0x80024000, 0xCD ) ))
-       //              & (! ( gpioVAddr = (u32)ioremap( 0x80023000, 0xAD ) ))) {
+       //      if ( (!( intCntrVAddr = ioremap( 0x80024000, 0xCD ) ))
+       //              & (! ( gpioVAddr = ioremap( 0x80023000, 0xAD ) ))) {
        //              DEBUGMSG("Failed to map Int and GPIO memory\n");
        //              return -EIO;
        //      }
-       if ( ! ( gpioVAddr = (u32)ioremap( 0x80023000, 0xAD ) )) {
+       if ( ! ( gpioVAddr = ioremap( 0x80023000, 0xAD ) )) {
                DEBUGMSG("Failed to map GPIO memory\n");
                return -EIO;
        } else {
@@ -218,48 +218,48 @@ int hms30c7202_init_hw_data(struct candevice_t *candev)
        }
        
        if (baseaddr == 0x8002f000) {
-               //              tempReg = readl(intCntrVAddr);
+               //              tempReg = can_readl(intCntrVAddr);
                //              DEBUGMSG("Read Interrupt Enable Register : 0x%.4lx\n",(long)tempReg);
                //              DEBUGMSG("Trying to activate CAN0 Interrupt (Bit 18)\n");
-               //              writel((tempReg | (1<<18)), intCntrVAddr);
-               //              tempReg = readl(intCntrVAddr);
+               //              can_writel((tempReg | (1<<18)), intCntrVAddr);
+               //              tempReg = can_readl(intCntrVAddr);
                //              DEBUGMSG("Read changed Interrupt Enable Register : 0x%.4lx\n",(long)tempReg);
-               tempReg = readl(gpioVAddr + 0x5C);
+               tempReg = can_readl(gpioVAddr + 0x5C);
                DEBUGMSG("Read GPIO-C Enable Register : 0x%.4lx\n",(long)tempReg);
                DEBUGMSG("Trying to activate CAN0 (Bit 1 = 0 for CANTx0, Bit 2 = 0 for CANRx0,)\n");
-               writel(tempReg & ~0x6, gpioVAddr + 0x5C);
-               tempReg = readl(gpioVAddr + 0x5C);
+               can_writel(tempReg & ~0x6, gpioVAddr + 0x5C);
+               tempReg = can_readl(gpioVAddr + 0x5C);
                DEBUGMSG("Read changed GPIO-C Enable Register : 0x%.4lx\n",(long)tempReg);
-               tempReg = readl(gpioVAddr + 0x44);
+               tempReg = can_readl(gpioVAddr + 0x44);
                DEBUGMSG("Read GPIO-C Direction Register : 0x%.4lx\n",(long)tempReg);
                DEBUGMSG("Trying to set CAN0 directions (Bit 1 = 0 for CANTx0 as OUT, Bit 2 = 1 for CANRx0 as IN,)\n");
-               writel((tempReg & ~0x2) | 0x4, gpioVAddr + 0x44);
-               tempReg = readl(gpioVAddr + 0x44);
+               can_writel((tempReg & ~0x2) | 0x4, gpioVAddr + 0x44);
+               tempReg = can_readl(gpioVAddr + 0x44);
                DEBUGMSG("Read changed GPIO-C Direction Register : 0x%.4lx\n",(long)tempReg);
        }
        else if (baseaddr == 0x80030000) {
-               //              tempReg = readl(intCntrVAddr);
-               //              writel((tempReg | (1<<19)), intCntrVAddr);
-               tempReg = readl(gpioVAddr + 0x9C);
+               //              tempReg = can_readl(intCntrVAddr);
+               //              can_writel((tempReg | (1<<19)), intCntrVAddr);
+               tempReg = can_readl(gpioVAddr + 0x9C);
                DEBUGMSG("Read GPIO-E Enable Register : 0x%.8lx\n",(long)tempReg);
                DEBUGMSG("Trying to activate CAN1 (Bit 22 = 0 for CANRx1, Bit 23 = 0 for CANTx1,)\n");
-               writel(tempReg & 0xFF3FFFFF, gpioVAddr + 0x9C);
-               tempReg = readl(gpioVAddr + 0x9C);
+               can_writel(tempReg & 0xFF3FFFFF, gpioVAddr + 0x9C);
+               tempReg = can_readl(gpioVAddr + 0x9C);
                DEBUGMSG("Read changed GPIO-E Enable Register : 0x%.8lx\n",(long)tempReg);
-               tempReg = readl(gpioVAddr + 0x84);
+               tempReg = can_readl(gpioVAddr + 0x84);
                DEBUGMSG("Read GPIO-E Direction Register : 0x%.8lx\n",(long)tempReg);
                DEBUGMSG("Trying to set CAN1 directions (Bit 22 = 1 for CANRx1 as IN, Bit 23 = 0 for CANTx1 as OUT,)\n");
-               writel((tempReg & ~(1<<23)) | 1<<22, gpioVAddr + 0x84);
-               tempReg = readl(gpioVAddr + 0x84);
+               can_writel((tempReg & ~(1<<23)) | 1<<22, gpioVAddr + 0x84);
+               tempReg = can_readl(gpioVAddr + 0x84);
                DEBUGMSG("Read changed GPIO-E Direction Register : 0x%.8lx\n",(long)tempReg);
        }
 
        //DEBUGMSG("Current Interrupt Status Register (ISR): 0x%4.4lx\n",
-       //                      (long)readl(intCntrVAddr + 4));
+       //                      (long)can_readl(intCntrVAddr + 4));
        //DEBUGMSG("Current Interrupt ID: %d\n",
-       //                      (int)(readl(intCntrVAddr + 0x90) & 0xF));
+       //                      (int)(can_readl(intCntrVAddr + 0x90) & 0xF));
        //      iounmap( (void*)intCntrVAddr);
-       iounmap( (void*)gpioVAddr );
+       iounmap( gpioVAddr );
        //      DEBUGMSG( "Unmapped Interrupt Controller IO-memory: 0x%lx\n",
        //            (unsigned long)intCntrVAddr);
        DEBUGMSG( "Unmapped GPIO IO-memory: 0x%lx\n",
@@ -352,17 +352,18 @@ int hms30c7202_init_obj_data(struct canchip_t *chip, int objnr)
  * File: src/template.c
  */
 
-void hms30c7202_write_register(unsigned data, unsigned long address)
+void hms30c7202_write_register(unsigned data, can_ioptr_t address)
 {
+       unsigned long addr=can_ioptr2ulong(address);
        int i;
        //unsigned long usecs = 1;
 
-       address = ((address & C_CAN_REGOFFS_MASK) << 1) |
-                 (address & ~C_CAN_REGOFFS_MASK);
+       address = can_ulong2ioptr(((addr & C_CAN_REGOFFS_MASK) << 1) |
+                                 (addr & ~C_CAN_REGOFFS_MASK));
        
        //DEBUGMSG("Trying to write 0x%u16x to address 0x%lx\n",data,address);
        
-       writew(data,address);
+       can_writew(data,address);
        //udelay( usecs );
        for (i=0; i<5; i++);
 }
@@ -378,19 +379,20 @@ void hms30c7202_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned hms30c7202_read_register(unsigned long address)
+unsigned hms30c7202_read_register(can_ioptr_t address)
 {
+       unsigned long addr=can_ioptr2ulong(address);
        u16 value, i;
        
-       address = ((address & C_CAN_REGOFFS_MASK) << 1) |
-                 (address & ~C_CAN_REGOFFS_MASK);
+       address = can_ulong2ioptr(((addr & C_CAN_REGOFFS_MASK) << 1) |
+                                 (addr & ~C_CAN_REGOFFS_MASK));
 
        //DEBUGMSG("Trying to read from address 0x%lx :",address);
        
-       value = readw(address);
+       value = can_readw(address);
        //udelay( usecs );
        for (i=0;i<5;i++);
-       value = readw(address);
+       value = can_readw(address);
                //udelay( usecs );
        for (i=0;i<5;i++);
        
index 58aa048..9210ac4 100644 (file)
@@ -596,7 +596,8 @@ void i82527_irq_update_filter(struct canchip_t *chip, struct msgobj_t *obj)
 
                i82527_pre_read_config(chip, obj);
 
-               CANMSG("i82527_irq_update_filter: obj at 0x%08lx\n",obj->obj_base_addr);
+               CANMSG("i82527_irq_update_filter: obj at 0x%08lx\n",
+                       can_ioptr2ulong(obj->obj_base_addr));
        }
 }
 
index 5ca7bc4..2a1f7c4 100644 (file)
 
 #include <ctype.h>
 
-can_irqreturn_t ipci165_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+#ifndef IRQF_SHARED
+#define IRQF_SHARED SA_SHIRQ
+#endif  /*IRQF_SHARED*/
+
+can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id));
 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
                       int sampl_pt, int flags);
 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
@@ -62,9 +66,9 @@ static void ipci165_delay(long msdelay)
  */
 void ipci165_generate_irq(struct candevice_t *candev)
 {
-  unsigned long crm_addr = candev->io_addr;
-  writeb(readb(crm_addr + CRM_UCR) & 0xFB, crm_addr + CRM_UCR);
-  writeb(readb(crm_addr + CRM_UCR) | 0x04, crm_addr + CRM_UCR);
+  can_ioptr_t crm_addr = candev->aux_base_addr;
+  can_writeb(can_readb(crm_addr + CRM_UCR) & 0xFB, crm_addr + CRM_UCR);
+  can_writeb(can_readb(crm_addr + CRM_UCR) | 0x04, crm_addr + CRM_UCR);
 }
 
 /**
@@ -79,7 +83,7 @@ void ipci165_generate_irq(struct candevice_t *candev)
  */
 int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
 {
-  unsigned long dpram_addr = candev->dev_base_addr;
+  can_ioptr_t dpram_addr = candev->dev_base_addr;
 
   DEBUGMSG ("ipci165_bci_command\n");
 
@@ -93,7 +97,7 @@ int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
   can_spin_lock(&candev->device_lock);
 
   // check command buffer status
-  if (readb(dpram_addr + OF_BCI_SYNC) != 0)
+  if (can_readb(dpram_addr + OF_BCI_SYNC) != 0)
   {
     /* something went wrong ... */
     can_spin_unlock(&candev->device_lock);
@@ -102,12 +106,12 @@ int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
   }
 
   // prepare command
-  writeb(cmd, dpram_addr + OF_BCI_CMD);
-  writeb(size + 1, dpram_addr + OF_BCI_NUM);
+  can_writeb(cmd, dpram_addr + OF_BCI_CMD);
+  can_writeb(size + 1, dpram_addr + OF_BCI_NUM);
   memcpy_toio(dpram_addr + OF_BCI_DATA, data, size);
 
   // set flag for firmware
-  writeb(1, dpram_addr + OF_BCI_SYNC);
+  can_writeb(1, dpram_addr + OF_BCI_SYNC);
 
   // generate interrupt to microcontroller
   ipci165_generate_irq (candev);
@@ -127,14 +131,14 @@ int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
  */
 int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
 {
-  unsigned long dpram_addr = candev->dev_base_addr;
+  can_ioptr_t dpram_addr = candev->dev_base_addr;
   char tmp;
   int delay;
 
   DEBUGMSG ("ipci165_bci_response\n");
 
   delay = 1000;
-  while (readb(dpram_addr + OF_BCI_SYNC) != 2)
+  while (can_readb(dpram_addr + OF_BCI_SYNC) != 2)
   {
     /* wait 1 ms */
     /*    ipci165_delay(1); */
@@ -150,13 +154,13 @@ int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
   }
 
   /* we will not copy the command filed, so decrement the size by 1 */
-  tmp = readb(dpram_addr + OF_BCI_NUM) - 1;
+  tmp = can_readb(dpram_addr + OF_BCI_NUM) - 1;
   if (*size > tmp) *size = tmp;
 
-  if (readb(dpram_addr + OF_BCI_CMD) != cmd)
+  if (can_readb(dpram_addr + OF_BCI_CMD) != cmd)
   {
     /* release the buffer */
-    writeb(0, dpram_addr + OF_BCI_SYNC);
+    can_writeb(0, dpram_addr + OF_BCI_SYNC);
     /* unlock the access */
     can_spin_unlock(&candev->device_lock);
 
@@ -166,7 +170,7 @@ int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
   memcpy_fromio(data, dpram_addr + OF_BCI_DATA, *size);
 
   /* release the buffer */
-  writeb(0, dpram_addr + OF_BCI_SYNC);
+  can_writeb(0, dpram_addr + OF_BCI_SYNC);
   /* unlock the access */
   can_spin_unlock(&candev->device_lock);
   return 0;
@@ -206,8 +210,8 @@ int ipci165_restart_can(struct canchip_t *chip)
 
   for (i = 0; i< BCI_QUEUE_SIZE; i++)
   {
-    writeb(BCI_MSG_STATUS_FREE, chip_data->rx_queue.addr + msg_ofs);
-    writeb(BCI_MSG_STATUS_FREE, chip_data->tx_queue.addr + msg_ofs);
+    can_writeb(BCI_MSG_STATUS_FREE, chip_data->rx_queue.addr + msg_ofs);
+    can_writeb(BCI_MSG_STATUS_FREE, chip_data->tx_queue.addr + msg_ofs);
     msg_ofs += BCI_MSG_SIZE;
   }
 
@@ -314,22 +318,22 @@ long ipci165_qfull_latency(struct msgobj_t *obj)
  */
 int ipci165_connect_irq(struct candevice_t *candev)
 {
-  unsigned long crm_addr = candev->io_addr;
+  can_ioptr_t crm_addr = candev->aux_base_addr;
   unsigned char icr;
   DEBUGMSG ("ipci165_connect_irq\n");
 
   /* install interrupt routine */
   if (request_irq(candev->sysdevptr.pcidev->irq,
                   ipci165_irq_handler,
-                  SA_SHIRQ,
+                  IRQF_SHARED,
                   DEVICE_NAME,
                   candev))
     return -ENODEV;
 
   // Enable interrupt to PC
-  writeb(readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
+  can_writeb(can_readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
   udelay (100);
-  icr = readb(crm_addr + CRM_ICR);
+  icr = can_readb(crm_addr + CRM_ICR);
   return 0;
 }
 
@@ -342,14 +346,14 @@ int ipci165_connect_irq(struct candevice_t *candev)
  */
 void ipci165_disconnect_irq(struct candevice_t *candev)
 {
-  unsigned long crm_addr = candev->io_addr;
+  can_ioptr_t crm_addr = candev->aux_base_addr;
   unsigned char icr;
   DEBUGMSG ("ipci165_disconnect_irq\n");
 
   // Enable interrupt to PC
-  writeb(readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
+  can_writeb(can_readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
   udelay (100);
-  icr = readb(crm_addr + CRM_ICR);
+  icr = can_readb(crm_addr + CRM_ICR);
   /* deinstall interrupt routine */
   free_irq(candev->sysdevptr.pcidev->irq, candev);
 }
@@ -607,8 +611,8 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
 {
   struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
   struct bci_queue_t *queue = &(chip_data)->rx_queue;
-  unsigned long       queue_addr = queue->addr;
-  unsigned long       msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
+  can_ioptr_t         queue_addr = queue->addr;
+  can_ioptr_t         msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
 
   int len;
   unsigned char frame_info;
@@ -620,18 +624,18 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
 
   do {
     dump_mem(msg_addr, BCI_MSG_SIZE);
-    if (readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
+    if (can_readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
     {
 #if 0
-      printk("ST(0)=%x, ST(1)=%x\n",readw(chip->chip_base_addr+OF_CAN1_STATUS),
-             readw(chip->chip_base_addr+OF_CAN2_STATUS));
+      printk("ST(0)=%x, ST(1)=%x\n",can_readw(chip->chip_base_addr+OF_CAN1_STATUS),
+             can_readw(chip->chip_base_addr+OF_CAN2_STATUS));
       for (tmp16 = 0 ; tmp16 < BCI_QUEUE_SIZE ; tmp16 ++)
-        printk ("MSG_ST(%i)=%x\n",tmp16,readb(chip->chip_base_addr + OF_CH2_TX_QUEUE + tmp16*BCI_MSG_SIZE + BCI_MSG_STATUS));
+        printk ("MSG_ST(%i)=%x\n",tmp16,can_readb(chip->chip_base_addr + OF_CH2_TX_QUEUE + tmp16*BCI_MSG_SIZE + BCI_MSG_STATUS));
       /* this is a can message */
       DEBUGMSG ("ipci165_irq_read_handler[%i]: message in buffer\n",chip->chip_idx);
 #endif
 
-      frame_info = readb(msg_addr + BCI_MSG_FRAME);
+      frame_info = can_readb(msg_addr + BCI_MSG_FRAME);
       len =  frame_info & 0x0f;
       if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
       obj->rx_msg.length = len;
@@ -639,8 +643,8 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
       obj->rx_msg.cob    = 0;
       obj->rx_msg.timestamp.tv_sec = 0;
       obj->rx_msg.timestamp.tv_usec = 
-          BCI_TIMESTAMP_RES * readl(msg_addr + BCI_MSG_TIMESTAMP);
-      /*  BCI_TIMESTAMP_RES * le32_to_cpu(readl(msg_addr + BCI_MSG_TIMESTAMP)); */
+          BCI_TIMESTAMP_RES * can_readl(msg_addr + BCI_MSG_TIMESTAMP);
+      /*  BCI_TIMESTAMP_RES * le32_to_cpu(can_readl(msg_addr + BCI_MSG_TIMESTAMP)); */
 
       /* fill CAN message timestamp */
       /* can_filltimestamp(&obj->rx_msg.timestamp); */
@@ -650,7 +654,7 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
         /* extended frame - 29 bit identifier */
         obj->rx_msg.flags |= MSG_EXT;
         /* the ID is stored in motorola format (big endian), left justified  */
-        /* obj->rx_msg.id = be32_to_cpu(readl(msg_addr + BCI_MSG_ID) >> 3); */
+        /* obj->rx_msg.id = be32_to_cpu(can_readl(msg_addr + BCI_MSG_ID) >> 3); */
         memcpy_fromio(&tmp32, msg_addr + BCI_MSG_ID, 4);
         obj->rx_msg.id = be32_to_cpu(tmp32 >> 3);
         if (len > 0)
@@ -659,7 +663,7 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
       {
         /* standard frame - 11 bit identifier */
         /* the ID is stored in motorola format (big endian), left justified */
-        /* obj->rx_msg.id = be16_to_cpu(readw(msg_addr + BCI_MSG_ID) >> 5); */
+        /* obj->rx_msg.id = be16_to_cpu(can_readw(msg_addr + BCI_MSG_ID) >> 5); */
         memcpy_fromio(&tmp16, msg_addr + BCI_MSG_ID, 2);
         obj->rx_msg.id = be16_to_cpu(tmp16 >> 5);
         if (len > 0)
@@ -670,7 +674,7 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
     else
     {
       /* this is a status message */
-      status = readw(msg_addr + BCI_MSG_CAN_STATUS);
+      status = can_readw(msg_addr + BCI_MSG_CAN_STATUS);
       DEBUGMSG ("ipci165_irq_read_handler[%i]: CAN status=%04x\n",chip->chip_idx, status);
 
       /* wake up the reset thread if the CAN is in bus off */
@@ -693,10 +697,10 @@ void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
     /* update pointer */
     queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
     /* release the buffer */
-    writeb(BCI_MSG_STATUS_FREE, msg_addr + BCI_MSG_STATUS);
+    can_writeb(BCI_MSG_STATUS_FREE, msg_addr + BCI_MSG_STATUS);
     msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
 
-  } while (readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
+  } while (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
 
 }
 
@@ -713,8 +717,8 @@ void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
 {
   struct ipci165_chip_t *chip_data = ((struct ipci165_chip_t *)chip->chip_data);
   struct bci_queue_t *queue      = &chip_data->tx_queue;
-  unsigned long       queue_addr = queue->addr;
-  unsigned long       msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
+  can_ioptr_t         queue_addr = queue->addr;
+  can_ioptr_t         msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
   struct canque_slot_t *tx_slot;
 
   int len;
@@ -727,7 +731,7 @@ void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
   while ((canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot) >=0))
   {
     if (test_bit(CHIP_FLAG_RESET,&chip_data->flags) ||
-        (readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
+        (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
     {
       canque_again_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
 
@@ -757,9 +761,9 @@ void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
         ((tx_slot->msg.flags & MSG_RTR) ? BCI_MSG_FRAME_RTR : 0) |
         ((tx_slot->msg.flags & MSG_EXT) ? BCI_MSG_FRAME_EXT : 0);
 
-    writeb(BCI_MSG_SIZE - 2, msg_addr + BCI_MSG_NUM);
-    writeb(BCI_MSG_TYPE_CAN, msg_addr + BCI_MSG_TYPE);
-    writeb(frame_info, msg_addr + BCI_MSG_FRAME);
+    can_writeb(BCI_MSG_SIZE - 2, msg_addr + BCI_MSG_NUM);
+    can_writeb(BCI_MSG_TYPE_CAN, msg_addr + BCI_MSG_TYPE);
+    can_writeb(frame_info, msg_addr + BCI_MSG_FRAME);
     if (frame_info & BCI_MSG_FRAME_EXT)
     {
       /* extended frame - 29 bit identifier */
@@ -783,7 +787,7 @@ void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
     /* update pointer */
     queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
     /* mark the buffer as full */
-    writeb(BCI_MSG_STATUS_FULL, msg_addr + BCI_MSG_STATUS);
+    can_writeb(BCI_MSG_STATUS_FULL, msg_addr + BCI_MSG_STATUS);
     /* wake up the controller */
     ipci165_generate_irq(chip->hostdevice);
 
@@ -848,12 +852,12 @@ void ipci165_irq_chip_handler(struct canchip_t *chip)
 
   /* check receive queue for messages */
   queue = &chip_data->rx_queue;
-  if (readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
+  if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
       == BCI_MSG_STATUS_FULL)
     ipci165_irq_read_handler(chip, obj);
 
   queue = &chip_data->tx_queue;
-/*  if (readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
+/*  if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
   == BCI_MSG_STATUS_FREE) */
   {
     can_msgobj_set_fl(obj,TX_REQUEST);
@@ -879,13 +883,13 @@ void ipci165_irq_chip_handler(struct canchip_t *chip)
  * acknowledged and ipci165_irq_chip_handler is called for every channel.
  * File: src/ipci165.c
  */
-can_irqreturn_t ipci165_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id))
 {
   int retval;
   struct candevice_t *candev = (struct candevice_t *)dev_id;
 
-  unsigned long crm_addr   = candev->io_addr;
-  unsigned long ucr1_addr  = crm_addr + CRM_UCR + 1;
+  can_ioptr_t crm_addr   = candev->aux_base_addr;
+  can_ioptr_t ucr1_addr  = crm_addr + CRM_UCR + 1;
   struct canchip_t *chip;
   unsigned char icr;
   int i;
@@ -893,15 +897,15 @@ can_irqreturn_t ipci165_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
   /* DEBUGMSG ("ipci165_irq_handler\n"); */
 
   /* read interrupt control register (byte 0) */
-  icr = readb(crm_addr + CRM_ICR);
+  icr = can_readb(crm_addr + CRM_ICR);
 
   if ((icr & 0x44) == 0x44)
   {
     DEBUGMSG ("ipci165_irq_handler: pending interrupt\n");
 
     /* confirm pending interrupt */
-    writeb(readb(ucr1_addr) | 0x01,  ucr1_addr);
-    writeb(readb(ucr1_addr) & ~0x01, ucr1_addr);
+    can_writeb(can_readb(ucr1_addr) | 0x01,  ucr1_addr);
+    can_writeb(can_readb(ucr1_addr) & ~0x01, ucr1_addr);
 
     /* call interrupt handler for every channel */
     for (i=0 ; i < candev->nr_all_chips ; i++)
@@ -1005,9 +1009,9 @@ int ipci165_release_chip(struct canchip_t *chip)
  */
 int ipci165_request_io(struct candevice_t *candev)
 {
-  unsigned long dpram_addr;
-  unsigned long crm_addr;
-  unsigned long fix_addr;
+  unsigned long dpram_addr; /* physical address before remap for this function */
+  unsigned long crm_addr;   /* physical address before remap for this function */
+  unsigned long fix_addr;   /* physical address before remap for this function */
   int i,j;
 
   DEBUGMSG ("ipci165_request_io\n");
@@ -1029,18 +1033,18 @@ int ipci165_request_io(struct candevice_t *candev)
     {
       CANMSG ("This card was not fixed!\n");
 
-      if (candev->io_addr == 0)
+      if (candev->aux_base_addr == NULL)
       {
         CANMSG ("You have to specify IO address parameter!\n");
         return -EINVAL;
       }
       CANMSG ("Using specified IO address value for the memory [0x%lx]\n",
-              candev->io_addr);
+              can_ioptr2ulong(candev->aux_base_addr));
     }
     else
     {
       CANMSG ("Fixed card. Using of 3 region [0x%lx]\n", fix_addr);
-      candev->io_addr = fix_addr;
+      candev->aux_base_addr = fix_addr;
     }
 
     pci_write_config_dword (candev->sysdevptr.pcidev,
@@ -1058,17 +1062,16 @@ int ipci165_request_io(struct candevice_t *candev)
   {
 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
 
-      if ((candev->dev_base_addr = (long) ioremap(dpram_addr, 
+      if ((candev->dev_base_addr = ioremap(dpram_addr, 
            pci_resource_len(candev->sysdevptr.pcidev,2))))
       {
         DEBUGMSG ("ipci165_request_io: dpram remapped to 0x%lx\n", candev->dev_base_addr);
 
-        if ((candev->io_addr = (long) ioremap(crm_addr, 
+        if ((candev->aux_base_addr = ioremap(crm_addr, 
              pci_resource_len(candev->sysdevptr.pcidev,0))))
         {
-          DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", candev->io_addr);
+          DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", can_ioptr2ulong(candev->aux_base_addr));
           /* all resources has been allocated */
-          candev->res_addr=candev->io_addr;
 
           /* Because of my mapping, I cannot use the
              can_base_addr_fixup(candev, remap_addr) to remap the addresses */
@@ -1082,10 +1085,10 @@ int ipci165_request_io(struct candevice_t *candev)
           return 0;
 
         } else CANMSG("Unable to remap memory at: 0x%lx\n", crm_addr);
-        iounmap((void*)candev->io_addr);
+        iounmap(candev->aux_base_addr);
 
       } else CANMSG("Unable to remap memory at: 0x%lx\n", dpram_addr);
-      iounmap((void*)candev->dev_base_addr);
+      iounmap(candev->dev_base_addr);
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
       pci_release_region(candev->sysdevptr.pcidev, 0);
@@ -1126,8 +1129,8 @@ int ipci165_release_io(struct candevice_t *candev)
   }
 #endif
 
-  iounmap((void*)candev->io_addr);
-  iounmap((void*)candev->dev_base_addr);
+  iounmap(candev->aux_base_addr);
+  iounmap(candev->dev_base_addr);
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
   pci_release_region(candev->sysdevptr.pcidev, 2);
@@ -1148,7 +1151,7 @@ int ipci165_release_io(struct candevice_t *candev)
  */
 int ipci165_download_fw(struct candevice_t *candev)
 {
-  unsigned long dpram_addr = candev->dev_base_addr;
+  can_ioptr_t dpram_addr = candev->dev_base_addr;
   char board_name[BOARD_NAME_LEN+1];
   char hw_version[HW_VERSION_LEN+1];
   char mode[MODE_LEN+1];
@@ -1189,13 +1192,13 @@ int ipci165_download_fw(struct candevice_t *candev)
   while (fwArray->len)
   {
     /* fill buffer */
-    writeb(LD_CMD_DOWNLOAD, dpram_addr + OF_LD_CMD);
-    writeb(fwArray->len, dpram_addr + OF_LD_NUM);
-    writeb(0, dpram_addr + OF_LD_NUM + 1);
+    can_writeb(LD_CMD_DOWNLOAD, dpram_addr + OF_LD_CMD);
+    can_writeb(fwArray->len, dpram_addr + OF_LD_NUM);
+    can_writeb(0, dpram_addr + OF_LD_NUM + 1);
 
-    writel(fwArray->addr, dpram_addr + OF_LD_ADDRESS);
-    /*    writel already performes the cpu_to_le32 conversion by itself   */
-    /*    writel(cpu_to_le32(fwArray->addr), dpram_addr + OF_LD_ADDRESS); */
+    can_writel(fwArray->addr, dpram_addr + OF_LD_ADDRESS);
+    /*    can_writel already performes the cpu_to_le32 conversion by itself   */
+    /*    can_writel(cpu_to_le32(fwArray->addr), dpram_addr + OF_LD_ADDRESS); */
 
     memcpy_toio(dpram_addr + OF_LD_DATA, fwArray->a_data, fwArray->len);
 
@@ -1203,14 +1206,14 @@ int ipci165_download_fw(struct candevice_t *candev)
     dump_mem((void *)(dpram_addr + OF_LD_SYNC), fwArray->len + 8);
 #endif
     /* buffer is prepared, set flag for loader */
-    writeb(1, dpram_addr + OF_LD_SYNC);
+    can_writeb(1, dpram_addr + OF_LD_SYNC);
 
     /* update pointer */
     fwArray++;
 
     /* wait for the loader */
     attempt = 1000;
-    while (readb(dpram_addr + OF_LD_SYNC) != 0)
+    while (can_readb(dpram_addr + OF_LD_SYNC) != 0)
     {
       udelay(100);
       if (--attempt == 0)
@@ -1224,8 +1227,8 @@ int ipci165_download_fw(struct candevice_t *candev)
   CANMSG ("Firmware downladed successfully\n");
 
   /* start the FW */
-  writeb(LD_CMD_START_FW, dpram_addr + OF_LD_CMD);
-  writeb(1, dpram_addr + OF_LD_SYNC);
+  can_writeb(LD_CMD_START_FW, dpram_addr + OF_LD_CMD);
+  can_writeb(1, dpram_addr + OF_LD_SYNC);
   ipci165_delay (500);
 
   return 0;
@@ -1240,7 +1243,7 @@ int ipci165_download_fw(struct candevice_t *candev)
  */
 int ipci165_reset(struct candevice_t *candev)
 {
-  unsigned long crm_addr = candev->io_addr;
+  can_ioptr_t crm_addr = candev->aux_base_addr;
   unsigned long test_data;
   char buffer[BCI_CMD_MAX_LEN];
   int i, size, chips;
@@ -1251,10 +1254,10 @@ int ipci165_reset(struct candevice_t *candev)
   DEBUGMSG ("ipci165_reset: hardware reset\n");
 
   /* reset the HW */
-  ucr = readb(crm_addr + CRM_UCR + 3);
-  writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
+  ucr = can_readb(crm_addr + CRM_UCR + 3);
+  can_writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
   udelay(100);
-  writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
+  can_writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
 
   /* wait a little bit */
   ipci165_delay(200);
index 1dfd253..ae43c30 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/version.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
-       #include <linux/config.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+#include <linux/config.h>
 #endif
 
 #if defined(MODVERSIONS)
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
   #include <linux/tqueue.h>
-#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
-  #include <linux/devfs_fs_kernel.h>
+#else
+  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
+    #include <linux/devfs_fs_kernel.h>
+  #endif
 #endif
 
 #include <linux/wait.h>
 #include <linux/signal.h>
 #include <linux/interrupt.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
+  #include <asm/semaphore.h>
+#else
+  #include <linux/semaphore.h>
+#endif
 
-#include <asm/semaphore.h>
 #include <linux/smp_lock.h>
 
 #include "../include/kthread.h"
@@ -49,7 +55,7 @@ void start_kthread(void (*func)(kthread_t *), kthread_t *kthread)
        in the down operation below until the thread has reached
        the up() operation.
     */
-    init_MUTEX_LOCKED(&kthread->startstop_sem);
+    sema_init(&kthread->startstop_sem, 0);
 
     /* store the function to be executed in the data passed to
        the launcher */
@@ -98,7 +104,7 @@ void stop_kthread(kthread_t *kthread)
        will unlock it. As soon as we see the semaphore
        unlocked, we know that the thread has exited.
     */
-    init_MUTEX_LOCKED(&kthread->startstop_sem);
+    sema_init(&kthread->startstop_sem,0);
 
     /* We need to do a memory barrier here to be sure that
        the flags are visible on all CPUs.
index a3d2000..e01a9eb 100644 (file)
@@ -56,18 +56,18 @@ void kv_pcican_disconnect_irq(struct candevice_t *candev)
 {
        unsigned long tmp;
        /* Disable interrupts from card */
-       tmp = inl(candev->dev_base_addr + S5920_INTCSR);
+       tmp = can_inl(candev->dev_base_addr + S5920_INTCSR);
        tmp &= ~INTCSR_ADDON_INTENABLE_M;
-       outl(tmp, candev->dev_base_addr + S5920_INTCSR);
+       can_outl(tmp, candev->dev_base_addr + S5920_INTCSR);
 }
 
 void kv_pcican_connect_irq(struct candevice_t *candev)
 {
        unsigned long tmp;
        /* Enable interrupts from card */
-       tmp = inl(candev->dev_base_addr + S5920_INTCSR);
+       tmp = can_inl(candev->dev_base_addr + S5920_INTCSR);
        tmp |= INTCSR_ADDON_INTENABLE_M;
-       outl(tmp, candev->dev_base_addr + S5920_INTCSR);
+       can_outl(tmp, candev->dev_base_addr + S5920_INTCSR);
 }
 
 
@@ -121,14 +121,14 @@ int kv_pcican_release_io(struct candevice_t *candev)
 }
 
 
-void kv_pcican_write_register(unsigned data, unsigned long address)
+void kv_pcican_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address); 
+       can_outb(data,address); 
 }
 
-unsigned kv_pcican_read_register(unsigned long address)
+unsigned kv_pcican_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 int kv_pcican_reset(struct candevice_t *candev)
@@ -140,7 +140,7 @@ int kv_pcican_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting kv_pcican hardware ...\n");
 
        /* Assert PTADR# - we're in passive mode so the other bits are not important */
-       outl(0x80808080L, candev->dev_base_addr + S5920_PTCR);
+       can_outl(0x80808080L, candev->dev_base_addr + S5920_PTCR);
 
        kv_pcican_disconnect_irq(candev);
 
index c67b3dd..f72943a 100644 (file)
@@ -5,13 +5,19 @@
  * email:pisa@cmp.felk.cvut.cz
  * This software is released under the GPL-License.
  * Version lincan-0.3  17 Jun 2004
- */ 
+ *
+ * 15 July 2008 updated by Philippe Corbes,  email:philippe.corbes@logibag.com
+ * This driver has been designed to support "Memory (MEM)" mode.
+ * For example: Memory, MEM:0xD0000 => io=0xD0000. 
+ * Configure the card with m437set.com provided by seco before loading driver.
+ * This software is released under the GPL-License.
+ */
 
-/* 
- * Support for the SECO M437 
- * 
+/*
+ * Support for the SECO M437
+ *
  * SECO M437 is a pc104 format, i82527 controller based card
- * produced by SECO http://www.seco.it 
+ * produced by SECO http://www.seco.it
  * This driver uses the Memory Mapped I/O mode, and should be
  * working with all cards supporting this mode.
  *
@@ -36,8 +42,6 @@
 #define IO_RANGE 0x100
 
 
-static long base = 0L; 
-
 /**
  * m437_request_io: - reserve io or memory range for can board
  * @candev: pointer to candevice/board which asks for io. Field @io_addr
@@ -45,7 +49,7 @@ static long base = 0L;
  *
  * The function m437_request_io() is used to reserve the io-memory. If your
  * hardware uses a dedicated memory range as hardware control registers you
- * will have to add the code to reserve this memory as well. 
+ * will have to add the code to reserve this memory as well.
  * %IO_RANGE is the io-memory range that gets reserved, please adjust according
  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
@@ -54,19 +58,36 @@ static long base = 0L;
  */
 int m437_request_io(struct candevice_t *candev)
 {
+       can_ioptr_t remap_addr;
 
        if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) {
-               CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
+               CANMSG("M437 Unable to request IO-memory: 0x%lx\n",candev->io_addr);
                return -ENODEV;
        }
 
-       if ( !( base = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
-               CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
+               CANMSG("M437 Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
                can_release_mem_region(candev->io_addr,IO_RANGE);
                return -ENODEV;
-       
+
+       }
+       CANMSG("M437 Registered IO-memory: 0x%lx - 0x%lx\n",
+               candev->io_addr, candev->io_addr + IO_RANGE - 1);
+       CANMSG("M437 IO-memory: 0x%lx  Remapped to: 0x%lx\n",
+               (unsigned long)candev->io_addr, (unsigned long)remap_addr);
+
+       /* remap the chip and pointers on objects */
+       can_base_addr_fixup(candev, remap_addr);
+
+#ifdef CAN_DEBUG
+       {
+               int objnr;
+               for (objnr=0; objnr<15 ; objnr++) {
+                       DEBUGMSG("M437 Message%d remapped to: 0x%lx\n", objnr+1, candev->chip[0]->msgobj[objnr]->obj_base_addr);
+               }
        }
-       DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
+#endif /*CAN_DEBUG*/
+
        return 0;
 }
 
@@ -84,10 +105,16 @@ int m437_request_io(struct candevice_t *candev)
  */
 int m437_release_io(struct candevice_t *candev)
 {
+       /*
+        * The full board reset is more robust solution
+        * than reset of communication objects
+        * Philippe Corbes, 06 jun 2008
+        */
+#if 0 /* Object reset method */
        unsigned i;
        
         /* disable IRQ generation */
-        m437_write_register(iCTL_CCE, iCTL);
+        m437_write_register(iCTL_CCE, candev->dev_base_addr+iCTL);
 
        /* clear all message objects */
        for (i=1; i<=15; i++) {
@@ -96,24 +123,30 @@ int m437_release_io(struct candevice_t *candev)
                                RXIE_RES | 
                                TXIE_RES | 
                                MVAL_RES, 
-                               i*0x10+iMSGCTL0);
+                               candev->dev_base_addr+i*0x10+iMSGCTL0);
                m437_write_register(
                                NEWD_RES | 
                                MLST_RES | 
                                CPUU_RES | 
                                TXRQ_RES | 
                                RMPD_RES, 
-                               i*0x10+iMSGCTL1);
+                               candev->dev_base_addr+i*0x10+iMSGCTL1);
        }
-       
+
        /* power down i82527 */
-       m437_write_register(iCPU_PWD, iCPU);
-       
+       m437_write_register(iCPU_PWD, candev->dev_base_addr+iCPU);
+
+#else /* Full board reset */
+       m437_reset(candev);
+#endif /* Full board reset */
+
        /* release I/O memory mapping */
-       iounmap((void*)base);
+       iounmap(candev->dev_base_addr);
 
        can_release_mem_region(candev->io_addr,IO_RANGE);
 
+       CANMSG("M437 release - OK\n");
+
        return 0;
 }
 
@@ -121,14 +154,36 @@ int m437_release_io(struct candevice_t *candev)
  * m437_reset - hardware reset routine
  * @candev: Pointer to candevice/board structure
  *
- * The function m437_reset() is used to give a hardware reset. This is 
- * rather hardware specific so I haven't included example code. Don't forget to 
+ * The function m437_reset() is used to give a hardware reset. This is
+ * rather hardware specific so I haven't included example code. Don't forget to
  * check the reset status of the chip before returning.
  * Return Value: The function returns zero on success or %-ENODEV on failure
  * File: src/m437.c
+ * from Philippe Corbes, 08 July 2008
  */
 int m437_reset(struct candevice_t *candev)
 {
+       int i=0;
+
+       DEBUGMSG("Resetting %s hardware ...\n", candev->hwname);
+       for (i = 0 ; i < 10 ; i++) {
+               m437_write_register(0x01,candev->dev_base_addr+candev->res_addr);
+       }
+       m437_write_register(0x0,candev->dev_base_addr+candev->res_addr);
+
+       /* Check hardware reset status */
+       i=0;
+       while ( (m437_read_register(candev->dev_base_addr+iCPU) & iCPU_RST) && (i<=15)) {
+               udelay(20000);
+               i++;
+       }
+       if (i>=15) {
+               CANMSG("M437 Reset status timeout! Please check your hardware.\n");
+               return -ENODEV;
+       }
+       else
+               DEBUGMSG("Chip0 reset status ok.\n");
+
        return 0;
 }
 
@@ -150,13 +205,13 @@ int m437_reset(struct candevice_t *candev)
  * Return Value: The function always returns zero
  * File: src/m437.c
  */
-int m437_init_hw_data(struct candevice_t *candev) 
+int m437_init_hw_data(struct candevice_t *candev)
 {
        DEBUGMSG("m437_init_hw_data()\n");
        candev->res_addr=RESET_ADDR;
        candev->nr_82527_chips=1;
        candev->nr_sja1000_chips=0;
-        candev->nr_all_chips=1;
+       candev->nr_all_chips=1;
        candev->flags &= ~CANDEV_PROGRAMMABLE_IRQ;
        /* The M437 has no programmable IRQ */
 
@@ -186,7 +241,7 @@ int m437_init_hw_data(struct candevice_t *candev)
  * The entry @int_clk_reg holds hardware specific options for the Clock Out
  * register. Options defined in the %i82527.h file:
  * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
- * The entry @int_bus_reg holds hardware specific options for the Bus 
+ * The entry @int_bus_reg holds hardware specific options for the Bus
  * Configuration register. Options defined in the %i82527.h file:
  * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
  * The entry @int_cpu_reg holds hardware specific options for the cpu interface
@@ -198,10 +253,10 @@ int m437_init_hw_data(struct candevice_t *candev)
 int m437_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        i82527_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=candev->dev_base_addr;
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC | iCPU_CEN;
-       candev->chip[chipnr]->int_clk_reg = 
+       candev->chip[chipnr]->int_clk_reg =
                iCLK_CD0 | iCLK_CD1 | iCLK_CD2 | iCLK_SL0 | iCLK_SL1;
        candev->chip[chipnr]->int_bus_reg = iBUS_CBY;
 
@@ -218,7 +273,7 @@ int m437_init_chip_data(struct candevice_t *candev, int chipnr)
  * CAN chip. In case of the sja1000 there's only one message object but on the
  * i82527 chip there are 15.
  * The code below is for a i82527 chip and initializes the object base addresses
- * The entry @obj_base_addr represents the first memory address of the message 
+ * The entry @obj_base_addr represents the first memory address of the message
  * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
  * base address.
  * Unless the hardware uses a segmented memory map, flags can be set zero.
@@ -228,7 +283,7 @@ int m437_init_chip_data(struct candevice_t *candev, int chipnr)
 int m437_init_obj_data(struct canchip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
-       
+
        return 0;
 }
 
@@ -236,16 +291,17 @@ int m437_init_obj_data(struct canchip_t *chip, int objnr)
  * m437_program_irq - program interrupts
  * @candev: Pointer to candevice/board structure
  *
- * The function m437_program_irq() is used for hardware that uses 
+ * The function m437_program_irq() is used for hardware that uses
  * programmable interrupts. If your hardware doesn't use programmable interrupts
- * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and 
- * leave this function unedited. Again this function is hardware specific so 
+ * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
+ * leave this function unedited. Again this function is hardware specific so
  * there's no example code.
  * Return value: The function returns zero on success or %-ENODEV on failure
  * File: src/m437.c
  */
 int m437_program_irq(struct candevice_t *candev)
 {
+       DEBUGMSG("M437 Programmable interrupt is not supported by the hardware!\n");
        return 0;
 }
 
@@ -260,9 +316,10 @@ int m437_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/m437.c
  */
-void m437_write_register(unsigned data, unsigned long address)
+void m437_write_register(unsigned data, can_ioptr_t address)
 {
-       writeb(data,base+address);
+       DEBUGMSG("m437_write_register(@0x%lx=0x%x)\n", address, data);
+       can_writeb(data,address);
 }
 
 /**
@@ -275,9 +332,12 @@ void m437_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/m437.c
  */
-unsigned m437_read_register(unsigned long address)
+unsigned m437_read_register(can_ioptr_t address)
 {
-       return readb(base+address);
+       unsigned data;
+       data = can_readb(address);
+       DEBUGMSG("m437_read_register(@0x%lx=0x%x)\n", address, data);
+       return data;
 }
 
 /* !!! Don't change this function !!! */
index b59160b..b8edf46 100644 (file)
@@ -88,6 +88,7 @@ int baudrate[MAX_TOT_CHIPS];
 char *hw[MAX_HW_CARDS]={NULL,};
 int irq[MAX_IRQ]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
 unsigned long io[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
+long clockfreq[MAX_HW_CARDS];
 int stdmask=0;
 int extmask=0;
 int mo15mask=0;
@@ -98,8 +99,9 @@ unsigned int baudrate_specified;
 unsigned int hw_specified;
 unsigned int irq_specified;
 unsigned int io_specified;
+unsigned int clockfreq_specified;
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12))
 /* Module parameters, some must be supplied at module loading time */
 MODULE_PARM(major,"1i");
 /*MODULE_PARM(minor, "1-" __MODULE_STRING(MAX_TOT_CHIPS)"i");*/
@@ -110,12 +112,13 @@ MODULE_PARM(baudrate, "1-" __MODULE_STRING(MAX_TOT_CHIPS_STR)"i");
 MODULE_PARM(hw, "1-" __MODULE_STRING(MAX_HW_CARDS)"s");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_IRQ)"i");
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
+MODULE_PARM(clockfreq, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
 MODULE_PARM(stdmask, "1i");
 MODULE_PARM(extmask, "1i");
 MODULE_PARM(mo15mask, "1i");
 MODULE_PARM(processlocal, "1i");
 
-#else /* LINUX_VERSION_CODE >= 2,6,0 */
+#else /* LINUX_VERSION_CODE >= 2,6,12 */
 module_param(major, int, 0);
 module_param_array(minor, int, &minor_specified, 0);
 module_param(extended, int, 0);
@@ -123,12 +126,13 @@ module_param(pelican, int, 0);
 module_param_array(baudrate, int, &baudrate_specified, 0);
 module_param_array(hw, charp, &hw_specified, 0);
 module_param_array(irq, int, &irq_specified, 0);
-module_param_array(io, int, &io_specified, 0);
+module_param_array(io, ulong, &io_specified, 0);
+module_param_array(clockfreq, long, &clockfreq_specified, 0);
 module_param(stdmask, int, 0);
 module_param(extmask, int, 0);
 module_param(mo15mask, int, 0);
 module_param(processlocal, int, 0);
-#endif /* LINUX_VERSION_CODE >= 2,6,0 */
+#endif /* LINUX_VERSION_CODE >= 2,6,12 */
 
 MODULE_PARM_DESC(major,"can be used to change default major [" __MODULE_STRING(CAN_MAJOR) "]");
 MODULE_PARM_DESC(minor,"can be used to change default starting minor for each channel");
@@ -139,6 +143,7 @@ MODULE_PARM_DESC(baudrate,"baudrate for each channel in step of 1kHz");
 MODULE_PARM_DESC(hw,"list of boards types to initialize - virtual,pip5,...");
 MODULE_PARM_DESC(irq,"list of iterrupt signal numbers, most ISA has one per chip, no value for PCI or virtual");
 MODULE_PARM_DESC(io,"IO address for each board, use 0 for PCI or virtual");
+MODULE_PARM_DESC(clockfreq,"base board clock source frequency in step of 1kHz");
 MODULE_PARM_DESC(stdmask,"default standard mask for i82527 chips");
 MODULE_PARM_DESC(extmask,"default extended mask for i82527 chips");
 MODULE_PARM_DESC(mo15mask,"mask for communication object 15 of i82527 chips");
@@ -323,8 +328,10 @@ int init_module(void)
         {
            #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0))
                char dev_name[32];
-           #else
+           #elif  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25) /* >= 2.6.15 */
                struct class_device *this_dev;
+           #else
+               struct device *this_dev;
            #endif
                int dev_minor;
                for(i=0;i<MAX_TOT_MSGOBJS;i++) {
@@ -339,14 +346,18 @@ int init_module(void)
                    #else
                      #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14))
                        this_dev=class_device_create(can_class, MKDEV(major, dev_minor), NULL,  "can%d", dev_minor);
-                     #else /* >= 2.6.15 */
+                     #elif  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25) /* >= 2.6.15 */
                        this_dev=class_device_create(can_class, NULL, MKDEV(major, dev_minor), NULL,  "can%d", dev_minor);
-                     #endif /* >= 2.6.15 */
+                     #else /* >= 2.6.26 */
+                       this_dev=device_create_drvdata(can_class, NULL, MKDEV(major, dev_minor), objects_p[i],  "can%d", dev_minor);
+                     #endif /* >= 2.6.26 */
                        if(IS_ERR(this_dev)){
                                CANMSG("problem to create device \"can%d\" in the class \"can\"\n", dev_minor);
+                     #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
                        }else{
                                /*this_dev->class_data=objects_p[i];*/
                                class_set_devdata(this_dev,objects_p[i]);
+                     #endif /* <= 2.6.25 */
                        }
                      #ifdef CONFIG_DEVFS_FS
                        devfs_mk_cdev(MKDEV(major, dev_minor), S_IFCHR | S_IRUGO | S_IWUGO, "can%d", dev_minor);
@@ -392,15 +403,8 @@ int init_module(void)
                canqueue_rtl_done();
                #endif /*CAN_WITH_RTL*/
 
-               #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
                unregister_chrdev(major,DEVICE_NAME);
-               #else /*LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)*/
-               res=unregister_chrdev(major,DEVICE_NAME);
-               if (res<0)
-                       CANMSG("Error unloading CAN driver, error: %d\n",res);
-               else
-                       CANMSG("No CAN devices or driver setup error.\n");
-               #endif /*LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)*/
+               CANMSG("No CAN devices or driver setup error.\n");
 
        register_error:
                if ( can_del_mem_list() )
@@ -507,14 +511,18 @@ struct candevice_t* register_usbdev(const char *hwname,void *devdata,void (*chip
                        #else
                        #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14))
                        this_dev=class_device_create(can_class, MKDEV(major, dev_minor), NULL,  "can%d", dev_minor);
-                       #else /* >= 2.6.15 */
+                       #elif  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25) /* >= 2.6.15 */
                        this_dev=class_device_create(can_class, NULL, MKDEV(major, dev_minor), NULL,  "can%d", dev_minor);
-                       #endif /* >= 2.6.15 */
+                       #else /* >= 2.6.26 */
+                       this_dev=device_create_drvdata(can_class, NULL, MKDEV(major, dev_minor), objects_p[i],  "can%d", dev_minor);
+                       #endif /* >= 2.6.26 */
                        if(IS_ERR(this_dev)){
                                CANMSG("problem to create device \"can%d\" in the class \"can\"\n", dev_minor);
+                     #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
                        }else{
                                /*this_dev->class_data=objects_p[i];*/
                                class_set_devdata(this_dev,objects_p[i]);
+                     #endif /* <= 2.6.25 */
                        }
                        #ifdef CONFIG_DEVFS_FS
                        devfs_mk_cdev(MKDEV(major, dev_minor), S_IFCHR | S_IRUGO | S_IWUGO, "can%d", dev_minor);
@@ -587,7 +595,11 @@ void cleanup_usbdev(struct candevice_t *dev)
                        #ifdef CONFIG_DEVFS_FS
                        devfs_remove("can%d", dev_minor);
                        #endif
+                       #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
                        class_device_destroy(can_class, MKDEV(major, dev_minor));
+                       #else /* >= 2.6.26 */
+                       device_destroy(can_class, MKDEV(major, dev_minor));
+                       #endif /* >= 2.6.26 */
                }
                #endif
        }
@@ -612,7 +624,9 @@ void cleanup_usbdev(struct candevice_t *dev)
 
 void cleanup_module(void)
 {
-       int res=0,i=0;
+#if defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+       int i=0;
+#endif
 
 #if defined(CONFIG_OC_LINCAN_CARD_usbcan)
        usbcan_exit();
@@ -636,7 +650,11 @@ void cleanup_module(void)
                    #ifdef CONFIG_DEVFS_FS
                        devfs_remove("can%d", dev_minor);
                    #endif
+                   #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
                        class_device_destroy(can_class, MKDEV(major, dev_minor));
+                   #else /* >= 2.6.26 */
+                       device_destroy(can_class, MKDEV(major, dev_minor));
+                   #endif /* >= 2.6.26 */
                }
            #endif
                }
@@ -656,11 +674,5 @@ void cleanup_module(void)
        if ( can_del_mem_list() )
                CANMSG("Error deallocating memory\n");
 
-       #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
        unregister_chrdev(major,DEVICE_NAME);
-       #else /*LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)*/
-       res=unregister_chrdev(major,DEVICE_NAME);
-       if (res<0)
-               CANMSG("Error unregistering CAN driver, error: %d\n",res);
-       #endif /*LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)*/
 }
index 3c79a36..c53971f 100644 (file)
@@ -21,7 +21,7 @@ int parse_mod_parms(void)
        if ( (hw[0] == NULL) | (io[0] == -1) ) {
                //CANMSG("You must supply your type of hardware, interrupt numbers and io address.\n");
                CANMSG("Autodetection works only for USB devices, supply your type of hardware for PCI devices \n");
-               CANMSG("Example: # insmod can.o hw=pip5 irq=4 io=0x8000\n");
+               CANMSG("Example: # insmod lincan.ko hw=pip5 irq=4 io=0x8000\n");
                //return -ENODEV;
        }
 
index 9851b5f..b6ebbae 100644 (file)
@@ -61,7 +61,7 @@ int msmcan_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting msmcan hardware ...\n");
        /* we don't use template_write_register because we don't use the two first
           registers of the card but the third in order to make a hard reset */
-       /* outb (1, msmcan_base + candev->res_addr); */
+       /* can_outb (1, msmcan_base + candev->res_addr); */
 
 
        /* terrible MSMCAN reset design - best to comment out */
@@ -128,7 +128,7 @@ int msmcan_init_chip_data(struct candevice_t *candev, int chipnr)
        i82527_fill_chipspecops(candev->chip[chipnr]);
        /* device uses indexed access */
        candev->chip[chipnr]->chip_base_addr=
-           candev->io_addr << 16;
+           can_ioport2ioptr(candev->io_addr << 16);
        candev->chip[chipnr]->clock = 16000000;
        /* The CLKOUT has to be enabled to reset MSMCAN MAX1232 watchdog */
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC | iCPU_CEN;
@@ -172,17 +172,18 @@ int msmcan_program_irq(struct candevice_t *candev)
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific write process.
  */
-void msmcan_write_register(unsigned data, unsigned long address)
+void msmcan_write_register(unsigned data, can_ioptr_t address)
 {
        /* address is combination of base address shifted left by 16 and index */
        can_spin_irqflags_t flags;
+       unsigned long addr=can_ioptr2ulong(address);
 
        /* the msmcan card has two registers, the data register at 0x0
           and the address register at 0x01 */
 
        can_spin_lock_irqsave(&msmcan_port_lock,flags);
-       outb(address & 0xff, (address>>16)+1);
-       outb(data, address>>16); 
+       can_outb(addr & 0xff, (addr>>16)+1);
+       can_outb(data, addr>>16); 
        can_spin_unlock_irqrestore(&msmcan_port_lock,flags);
 }
 
@@ -190,7 +191,7 @@ void msmcan_write_register(unsigned data, unsigned long address)
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific read process.
  */
-unsigned msmcan_read_register(unsigned long address)
+unsigned msmcan_read_register(can_ioptr_t address)
 {
        /* this is the same thing that the function write_register.
           We use the two register, we write the address where we 
@@ -198,11 +199,11 @@ unsigned msmcan_read_register(unsigned long address)
           data */
        unsigned char ret;
        can_spin_irqflags_t flags;
-    
+       unsigned long addr=can_ioptr2ulong(address);
 
        can_spin_lock_irqsave(&msmcan_port_lock,flags);
-       outb(address & 0xff, (address>>16)+1);
-       ret=inb(address>>16); 
+       can_outb(addr & 0xff, (addr>>16)+1);
+       ret=can_inb(addr>>16); 
        can_spin_unlock_irqrestore(&msmcan_port_lock,flags);
        return ret;
 }
index 0fc15c0..4d35965 100644 (file)
@@ -43,7 +43,7 @@ int ns_dev_request_io(struct candevice_t *candev)
                       (unsigned long)candev->io_addr);
        }
 
-       if (!(candev->dev_base_addr = (long)ioremap(candev->io_addr, IO_RANGE))) {
+       if (!(candev->dev_base_addr = ioremap(candev->io_addr, IO_RANGE))) {
                DEBUGMSG
                    ("Failed to map IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx\n",
                     (unsigned long)candev->io_addr,
@@ -76,13 +76,10 @@ int ns_dev_request_io(struct candevice_t *candev)
  */
 int ns_dev_release_io(struct candevice_t *candev)
 {
-       u16 tempReg;
-       int i;
-
        DEBUGMSG("(c%d)ns_dev_release_io (...)\n", candev->chip[0]->chip_idx);
 
        /* Release I/O memory mapping */
-       iounmap((void *)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
 
        /* Release the memory region */
        can_release_mem_region(candev->io_addr, IO_RANGE);
@@ -148,21 +145,21 @@ int ns_dev_reset(struct candevice_t *candev)
  */
 int ns_dev_init_hw_data(struct candevice_t *candev)
 {
-       u32 sys_contVA = 0;
+       can_ioptr_t sys_contVA = NULL;
 
        /* LUCAN : Magic numbers */
-       if (!(sys_contVA = (u32) ioremap(NS9750_PERIPHERAL_BASE_ADDRESS,
+       if (!(sys_contVA = ioremap(NS9750_PERIPHERAL_BASE_ADDRESS,
                                         NS9750_PERIPHERAL_MAP_SIZE))) {
                DEBUGMSG("Failed to map FPGA memory\n");
                return -EIO;
        } else {
                DEBUGMSG("Writing to NS9750 sys cont\n");
-               writel((BUS_WIDTH_16BIT | ACTIVE_LOW_CHIP_SELECT),
+               can_writel((BUS_WIDTH_16BIT | ACTIVE_LOW_CHIP_SELECT),
                       sys_contVA + NS9750_SYSTEM_CONTROLLER_OFFSET);
        }
 
        /* We have finished with this mapping */
-       iounmap((void *)sys_contVA);
+       iounmap(sys_contVA);
 
        candev->nr_82527_chips = 0;
        candev->nr_sja1000_chips = 0;
@@ -236,12 +233,12 @@ int ns_dev_init_obj_data(struct canchip_t *chip, int objnr)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void ns_dev_write_register(unsigned data, unsigned long address)
+void ns_dev_write_register(unsigned data, can_ioptr_t address)
 {
        int i;
        //unsigned long usecs = 1;
 
-       writew(data, address);
+       can_writew(data, address);
        //udelay( usecs );
        for (i = 0; i < 5; i++) ;
 }
@@ -256,14 +253,14 @@ void ns_dev_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned ns_dev_read_register(unsigned long address)
+unsigned ns_dev_read_register(can_ioptr_t address)
 {
        u16 value, i;
 
-       value = readw(address);
+       value = can_readw(address);
        //udelay( usecs );
        for (i = 0; i < 5; i++) ;
-       value = readw(address);
+       value = can_readw(address);
        //udelay( usecs );
        for (i = 0; i < 5; i++) ;
 
index ce9c591..06d38e1 100644 (file)
@@ -64,8 +64,8 @@ int nsi_reset(struct candevice_t *candev)
     DEBUGMSG("Resetting nsi hardware ...\n");
     /* we don't use template_write_register because we don't use the two first
        register of the card but the third in order to make a hard reset */
-    outb (1, nsican_base + candev->res_addr);
-    outb (0, nsican_base + candev->res_addr);
+    can_outb (1, nsican_base + candev->res_addr);
+    can_outb (0, nsican_base + candev->res_addr);
     for (i = 1; i < 1000; i++)
        udelay (1000);
     
@@ -124,7 +124,7 @@ int nsi_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        i82527_fill_chipspecops(candev->chip[chipnr]);
        candev->chip[chipnr]->chip_base_addr=
-           candev->io_addr;
+           can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        nsican_irq=candev->chip[chipnr]->chip_irq;      
         nsican_base=candev->chip[chipnr]->chip_base_addr;
@@ -169,7 +169,7 @@ int nsi_program_irq(struct candevice_t *candev)
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific write process.
  */
-void nsi_write_register(unsigned data, unsigned long address)
+void nsi_write_register(unsigned data, can_ioptr_t address)
 {
     /* address is an absolute address */
 
@@ -178,14 +178,14 @@ void nsi_write_register(unsigned data, unsigned long address)
 
     /* write the relative address on the eight LSB bits 
        and the data on the eight MSB bits in one time */
-    outw(address-nsican_base + (256 * data), nsican_base); 
+    can_outw(address-nsican_base + (256 * data), nsican_base); 
 }
 
 /* The function template_read_register is used to read from hardware registers
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific read process.
  */
-unsigned nsi_read_register(unsigned long address)
+unsigned nsi_read_register(can_ioptr_t address)
 {
     /* this is the same thing that the function write_register.
        We use the two register, we write the address where we 
@@ -195,8 +195,8 @@ unsigned nsi_read_register(unsigned long address)
        can_spin_irqflags_t flags;
     
        can_spin_lock_irqsave(&nsican_port_lock,flags);
-       outb(address-nsican_base, nsican_base);
-       ret=inb(nsican_base+1);
+       can_outb(address-nsican_base, nsican_base);
+       ret=can_inb(nsican_base+1);
        can_spin_unlock_irqrestore(&nsican_port_lock,flags);
        return ret;
 }
index d77b951..97ce2b4 100644 (file)
@@ -23,40 +23,28 @@ extern int mo15mask;
 #include <linux/module.h>
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
-       #define ioread32        readl
-       #define iowrite32       writel
-       #define ioread8         readb
-       #define iowrite8        writeb
-       #define wmb()
-       #define rmb()
+       #define ioread32        can_readl
+       #define iowrite32       can_writel
+       #define ioread8         can_readb
+       #define iowrite8        can_writeb
 #else
 #endif
 
 
 
-#define INT_CONF 0x00000040 /* valeur de config du registre INTCSR du PLX */
+#define INT_CONF 0x00000040    /* value for register INTCSR of PLX */
 #define NSI_VENDOR_ID          0x1637
 #define NSI_CANPCI_DEVICE_ID   0x0001
 
 enum PORT2 { P2_0=1, P2_1=1<<1, P2_2=1<<2, P2_3=1<<3, P2_4=1<<4, P2_5=1<<5, P2_6=1<<6, P2_7=1<<7 };
 
-/* Definition de tous les registres du PLX */
-#define PLX_CNTRL      0x50    /* Regitre de control */
-#define PLX_INTCSR     0x4C    /* Registe pour les interruptions */
-
-/* Horloge en Hz du chip i82527 respecter le tableau suivant: */
-/*   =========================================
- *   | XTAL | SCLK (DSC bit) | MCLK (DMC bit) |
- *   |======|================|================|
- *   | 4MHz |    4MHz (0)    |    4MHz (0)    |    NE PAS OUBLIER DE POSITIONNER LES BITS DSC et DMC EN FONTION
- *   | 8MHz |    8MHz (0)    |    8MHz (0)    |
- *   |10MHz |   10MHz (0)    |    5MHz (1)    |
- *   |12MHz |    6MHZ (1)    |    6MHZ (0)    |
- *   |16MHz |    8MHz (1)    |    8MHz (0)    |
- *   ==========================================  */
+/*PLX register definition */
+#define PLX_CNTRL      0x50    /* Controle register */
+#define PLX_INTCSR     0x4C    /* Interruption controle register */
+
+/* This value define the i82527 clock frequency */
 #define iCLOCK         16000000
 
-static CAN_DEFINE_SPINLOCK(nsicanpci_port_lock);
 
 /* Il faut reserver 4 zones:
  *             BAR0: 128 octets memoire (32bits) pour les registres du PLX9052
@@ -66,23 +54,20 @@ static CAN_DEFINE_SPINLOCK(nsicanpci_port_lock);
  */
 /* Variables globales contenant les @ des IO-Memory apres remap */
 #define NB_VALID_BAR   4
-void* addr_BAR_remap[NB_VALID_BAR]={0,0,0,0};
+
+typedef struct {
+       void* addr_BAR_remap[NB_VALID_BAR];
+}t_CardArray;
 
 void nsi_canpci_connect_irq(struct candevice_t *candev)
 {
-       /* Preparation du registre pour configurer les INT locales 1 et 2 du PLX, INT actif à l'etat Haut */
-//     iowrite32(INT_CONF,(void*)(candev->dev_base_addr+PLX_INTCSR));
-//     wmb();
-//     DEBUGMSG("Interruptions du PLX configurees !!\n");
-
+//Not used
 }
 void nsi_canpci_disconnect_irq(struct candevice_t *candev)
 {
-// Il faut aussi desactiver les interruption du PLX, sous peine de freeze au prochain init_module
-// tout en laissant le bit isa mis a 1
-       iowrite32(0x0,(void*)(candev->dev_base_addr+PLX_INTCSR));
-       wmb();
-       DEBUGMSG("disable interruption du PLX\n");
+//on disconnecting interrupt we need to disable interruption form PLX
+       iowrite32(0x0,(void*)(candev->io_addr+PLX_INTCSR));
+       DEBUGMSG("PLX interrupt disabled\n");
 }
 
 int nsi_canpci_config_irqs(struct canchip_t *chip, short irqs)
@@ -91,7 +76,7 @@ int nsi_canpci_config_irqs(struct canchip_t *chip, short irqs)
        unsigned long it_mask,it_reg;
        struct candevice_t *candev;
        it_mask=0;
-       DEBUGMSG("NSI Interrupt configuration\n");
+       DEBUGMSG("Configuring NSI CANPCI interrupt\n");
        can_write_reg(chip,irqs,iCTL);
        if( (irqs&0x0E)!=0)
        {//At least one interrupt source requested
@@ -105,12 +90,10 @@ int nsi_canpci_config_irqs(struct canchip_t *chip, short irqs)
                        DEBUGMSG("starting interrupt on chip 1\n");
                        it_mask=8;
                }
-               candev=(struct candevice_t *)chip->chip_data;
-               it_reg = ioread32( (void*)(candev->dev_base_addr+PLX_INTCSR));
-               rmb();
+               candev=chip->hostdevice;
+               it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
                it_reg|=it_mask|0x40;
-               iowrite32(it_reg,(void*)(candev->dev_base_addr+PLX_INTCSR));
-               wmb();          
+               iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
        }
        else
        {//No more interrupt source
@@ -124,26 +107,23 @@ int nsi_canpci_config_irqs(struct canchip_t *chip, short irqs)
                        DEBUGMSG("stoping interrupt on chip 1\n");
                        it_mask=8;
                }
-               candev=(struct candevice_t *)chip->chip_data;
-               it_reg = ioread32( (void*)(candev->dev_base_addr+PLX_INTCSR));
-               rmb();
+               candev=chip->hostdevice;
+               it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
                it_reg&=~it_mask;
-               iowrite32(it_reg,(void*)(candev->dev_base_addr+PLX_INTCSR));
-               wmb();                  
+               iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
        }
        return 0;
 }
 
 int nsi_canpci_i82527_chip_config(struct canchip_t *chip)
 {
-       //Normale fonction
        can_write_reg(chip,chip->int_cpu_reg,iCPU); // Configure cpu interface
        can_write_reg(chip,(iCTL_CCE|iCTL_INI),iCTL); // Enable configuration
        i82527_seg_write_reg(chip,chip->int_clk_reg,iCLK); // Set clock out slew rates 
        i82527_seg_write_reg(chip,chip->int_bus_reg,iBUS); /* Bus configuration */
        
-       can_write_reg(chip,P2_2|P2_1,iP2C); // Configure P2_2,P2_1 en sortie
-       can_write_reg(chip,P2_2|P2_1,iP2O); // Positionne P2_2 a 1
+       can_write_reg(chip,P2_2|P2_1,iP2C); // The pin P2_2,P2_1 of the 527 must be set as output
+       can_write_reg(chip,P2_2|P2_1,iP2O); // and P2_2 must be set to 1
        
        can_write_reg(chip,0x00,iSTAT); /* Clear error status register */
 
@@ -210,11 +190,11 @@ int nsi_canpci_start_chip(struct canchip_t *chip)
                DEBUGMSG("starting chip 1\n");
                it_mask=8;
        }
-       candev=(struct candevice_t *)chip->chip_data;
-       it_reg = ioread32( (void*)(candev->dev_base_addr+PLX_INTCSR));
+       candev=chip->hostdevice;
+       it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
        rmb();
        it_reg|=it_mask|0x40;
-       iowrite32(it_reg,(void*)(candev->dev_base_addr+PLX_INTCSR));
+       iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
        wmb();  
        i82527_start_chip(chip);
        return 0;
@@ -235,11 +215,11 @@ int nsi_canpci_stop_chip(struct canchip_t *chip)
                DEBUGMSG("stoping chip 1\n");
                it_mask=8;
        }
-       candev=(struct candevice_t *)chip->chip_data;
-       it_reg = ioread32( (void*)(candev->dev_base_addr+PLX_INTCSR));
+       candev=chip->hostdevice;
+       it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
        rmb();
        it_reg&=~it_mask;
-       iowrite32(it_reg,(void*)(candev->dev_base_addr+PLX_INTCSR));
+       iowrite32(it_reg,(void*)(candev->io_addr+PLX_INTCSR));
        wmb();  
        i82527_stop_chip(chip);
        return 0;
@@ -250,18 +230,18 @@ int nsi_canpci_irq_handler(int irq, struct canchip_t *chip)
        int retcode;
        unsigned long it_reg;
        struct candevice_t *candev;
-       candev=(struct candevice_t *)chip->chip_data;
+       candev=chip->hostdevice;
        retcode = CANCHIP_IRQ_NONE;
-       it_reg = ioread32( (void*)(candev->dev_base_addr+PLX_INTCSR));
+       it_reg = ioread32( (void*)(candev->io_addr+PLX_INTCSR));
        rmb();
        if(chip->chip_idx==0)
        {
                if((it_reg &0x4)!=0) //interrupt active
                {
                        if(i82527_irq_handler(irq,chip)==CANCHIP_IRQ_NONE)
-                       {//soucis avec les IT
+                       {//some trouble with IT
                                it_reg&=~(0x01);
-                               CANMSG("IT du canal0 annulee pour cause de dysonctionnement\n");
+                               CANMSG("Unexcepted interruption from canal0, interruption is canceled\n");
 
                        }else
                        {
@@ -272,12 +252,12 @@ int nsi_canpci_irq_handler(int irq, struct canchip_t *chip)
        }
        else
        {
-               if((it_reg &0x20)!=0) //interrupt active
+               if((it_reg &0x20)!=0) //interrupt is set
                {
                        if(i82527_irq_handler(irq,chip)==CANCHIP_IRQ_NONE)
                        {//soucis avec les IT
                                it_reg&=~(0x08);
-                               CANMSG("IT du canal1 annulee pour cause de dysonctionnement\n");
+                               CANMSG("Unexcepted interruption from canal1, interruption is canceled\n");
                        }else
                        {
                                retcode=CANCHIP_IRQ_HANDLED;
@@ -295,7 +275,7 @@ int nsi_canpci_irq_handler(int irq, struct canchip_t *chip)
 int nsi_canpci_request_io(struct candevice_t *candev)
 {
   (void)candev;
-  if(addr_BAR_remap[0]==NULL)
+  if(candev->dev_base_addr==0)
        return -EIO;  
   return 0;
 }
@@ -307,24 +287,25 @@ int nsi_canpci_release_io(struct candevice_t *candev)
 {
        unsigned long reg_reset;
        struct pci_dev *pcidev = candev->sysdevptr.pcidev;
-       DEBUGMSG("Liberation des io de la carte \n");
+       DEBUGMSG("Releasing board io\n");
        
        nsi_canpci_disconnect_irq(candev);
-       // Recherche du registre de controle du PLX parmi les IO-port du PLX */
-       reg_reset = ioread32( (void*)(candev->dev_base_addr+PLX_CNTRL));
+       // First, set RESET signal to 0
+       reg_reset = ioread32( (void*)(candev->io_addr+PLX_CNTRL));
        reg_reset&=(~(0x40000000));
        rmb();
-       iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->dev_base_addr+PLX_CNTRL)); /* Mise à '1' du bit reset */
+       //Then set it to '1' for reseting the board
+       iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->io_addr+PLX_CNTRL));
        wmb();
-       udelay(2500); /* Reset supérieur a 1ms car necessaire aux i82527 */
-       iowrite32( (reg_reset ),(void*)(candev->dev_base_addr+PLX_CNTRL)); /* Mise à '0' du bit reset */
+       udelay(2500); /* This delay must be greater than 1ms for i82527 */
+       iowrite32( (reg_reset ),(void*)(candev->io_addr+PLX_CNTRL)); //Releasing RESET signal
        wmb();
-       udelay(2500); /* Reset supérieur a 1ms car necessaire aux i82527 */
-       iounmap(addr_BAR_remap[0]);
-       iounmap(addr_BAR_remap[1]);
-       iounmap(addr_BAR_remap[2]);
-       iounmap(addr_BAR_remap[3]);
-  
+       udelay(2500); // Waiting for some additionnal time before writing in the 82527
+       iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]);
+       iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[1]);
+       iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[2]);
+       iounmap(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[3]);
+       kfree((void*)(candev->dev_base_addr));
        pci_release_region(pcidev,0);
        pci_release_region(pcidev,1);
        pci_release_region(pcidev,2);                   
@@ -340,19 +321,20 @@ int nsi_canpci_reset(struct candevice_t *candev)
 {
        unsigned long reg_reset;
        
-       DEBUGMSG("Reset de la carte !!!\n");
-       /* Il faut aussi desactiver les interruption du PLX, sous peine de freeze au prochain init_module */    
+       DEBUGMSG("Board reset !!!\n");
+       // Before reset disconnet interrupt to avoir freeze     
        nsi_canpci_disconnect_irq(candev);
-       // Recherche du registre de controle du PLX parmi les IO-port du PLX */
-       reg_reset = ioread32( (void*)(candev->dev_base_addr+PLX_CNTRL));
+       // First, set RESET signal to 0
+       reg_reset = ioread32( (void*)(candev->io_addr+PLX_CNTRL));
        reg_reset&=(~(0x40000000));
-       iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->dev_base_addr+PLX_CNTRL)); /* Mise à '1' du bit reset */
+       //Then set it to '1' for reseting the board
+       iowrite32( (reg_reset | 0x40000000 ),(void*)(candev->io_addr+PLX_CNTRL));
        wmb();
-       udelay(2500); /* Reset supérieur a 1ms car necessaire aux i82527 */
-       iowrite32(reg_reset,(void*)(candev->dev_base_addr+PLX_CNTRL)); /* Mise à '0' du bit reset */
+       udelay(2500); /* This delay must be greater than 1ms for i82527 */
+       iowrite32(reg_reset,(void*)(candev->io_addr+PLX_CNTRL)); //Releasing RESET signal
        wmb();
-       udelay(2500); /* Attente, pour laisser les composants s'initialiser */  
-       DEBUGMSG("Reset termine !!!\n");
+       udelay(2500); // Waiting for some additionnal time before writing in the 82527
+       DEBUGMSG("Reset done !!!\n");
        
        nsi_canpci_connect_irq(candev);
        return 0;       
@@ -371,7 +353,7 @@ int nsi_canpci_init_hw_data(struct candevice_t *candev)
      {
   struct pci_dev *pcidev = NULL;
 
-  /* recherche de la carte NSI CANPCI sur le bus */
+  /* looking for NSI CANPCI ident on the pci bus*/
   do
   {
     pcidev = pci_find_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID, pcidev);
@@ -449,13 +431,21 @@ int nsi_canpci_init_hw_data(struct candevice_t *candev)
   {
        return -EIO;
   }
+  candev->dev_base_addr=(unsigned long)(kmalloc(sizeof(t_CardArray),GFP_ATOMIC));  
   
-  addr_BAR_remap[0]=ioremap(pci_resource_start(pcidev,0),pci_resource_len(pcidev,0) );
-  addr_BAR_remap[1]=ioremap(pci_resource_start(pcidev,1),pci_resource_len(pcidev,1) );
-  addr_BAR_remap[2]=ioremap(pci_resource_start(pcidev,2),pci_resource_len(pcidev,2) );
-  addr_BAR_remap[3]=ioremap(pci_resource_start(pcidev,3),pci_resource_len(pcidev,3) );
+  if((unsigned long)candev->dev_base_addr==0)
+       return -EIO;
+  //PLX register 
+  ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]=ioremap(pci_resource_start(pcidev,0),pci_resource_len(pcidev,0) );
+  //PLX IO
+  ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[1]=ioremap(pci_resource_start(pcidev,1),pci_resource_len(pcidev,1) );
+  //Chip 0
+  ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[2]=ioremap(pci_resource_start(pcidev,2),pci_resource_len(pcidev,2) );
+  //Chip 1
+  ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[3]=ioremap(pci_resource_start(pcidev,3),pci_resource_len(pcidev,3) );
   
-  candev->dev_base_addr=(unsigned long)(addr_BAR_remap[0]);  
+  //Short acces to plx register
+  candev->io_addr=(unsigned long)(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]);
   return 0;  
 }
 
@@ -480,10 +470,10 @@ int nsi_canpci_init_chip_data(struct candevice_t *candev, int chipnr)
        candev->chip[chipnr]->chipspecops->stop_chip=nsi_canpci_stop_chip;
        candev->chip[chipnr]->chipspecops->config_irqs=nsi_canpci_config_irqs;
        candev->chip[chipnr]->chipspecops->irq_handler=nsi_canpci_irq_handler;
-       candev->chip[chipnr]->chip_data =candev;
+       /*candev->chip[chipnr]->chip_data = NULL;*/
        
-       candev->chip[chipnr]->chip_base_addr= (unsigned long)addr_BAR_remap[chipnr+2];
-       candev->chip[chipnr]->clock = 16000000;
+       candev->chip[chipnr]->chip_base_addr= (unsigned long) (((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[chipnr+2]);
+       candev->chip[chipnr]->clock = iCLOCK;
        candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
        candev->chip[chipnr]->flags=CHIP_IRQ_PCI;
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC+iCPU_CEN;
@@ -527,29 +517,18 @@ int nsi_canpci_program_irq(struct candevice_t *candev)
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific write process.
  */
-void nsi_canpci_write_register(unsigned data, unsigned long address)
+void nsi_canpci_write_register(unsigned data, can_ioptr_t address)
 {
        iowrite8((u8)data,(void*)address);
-       wmb(); /* Assure que la donnee a ete ecrite */
 }
 
 /* The function template_read_register is used to read from hardware registers
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific read process.
  */
-unsigned nsi_canpci_read_register(unsigned long address)
+unsigned nsi_canpci_read_register(can_ioptr_t address)
 {
-    /* this is the same thing that the function write_register.
-       We use the two register, we write the address where we 
-       want to read in a first time. In a second time we read the
-       data */
-       unsigned char ret;
-       can_spin_irqflags_t flags;
-       can_spin_lock_irqsave(&nsicanpci_port_lock,flags);
-       rmb();
-       ret=ioread8((void*)address);
-       can_spin_unlock_irqrestore(&nsicanpci_port_lock,flags);
-       return ret;     
+       return ioread8((void*)address);
 }
 
 
index 45406fc..e471470 100644 (file)
@@ -24,6 +24,7 @@ int can_open(struct inode *inode, struct file *file)
        struct canque_ends_t *qends;
        struct canque_edge_t *edge;
        can_spin_irqflags_t iflags;
+       char openflag;          // Martin Petera: Object already opened
 
        if ( ((obj=objects_p[MINOR_NR]) == NULL) || 
                        ((chip=objects_p[MINOR_NR]->hostchip) == NULL) ) {
@@ -33,6 +34,7 @@ int can_open(struct inode *inode, struct file *file)
 
        atomic_inc(&obj->obj_used);
        DEBUGMSG("Device %d opened %d times.\n", MINOR_NR, atomic_read(&obj->obj_used));
+       openflag = can_msgobj_test_fl(obj,OPENED);      // Martin Petera: store previous status
        can_msgobj_set_fl(obj,OPENED);
 
        if (chip->flags & CHIP_CONFIGURED) 
@@ -42,11 +44,19 @@ int can_open(struct inode *inode, struct file *file)
                        CANMSG("Error configuring chip.\n");
                else
                        chip->flags |= CHIP_CONFIGURED; 
+       } /* End of chip configuration */
+
 
+       /* Martin Petera: Fix for HCAN2
+        * pre_read was called only once -> Opening second MSG object from userspace
+        * didn't call function to configure MSG object for receive.
+        * FIX: Call pre_read once for each MSG object
+        **/
+       if (!openflag) {
                if (chip->chipspecops->pre_read_config(chip,obj)<0)
                        CANMSG("Error initializing chip for receiving\n");
+       }
 
-       } /* End of chip configuration */
 
        canuser = (struct canuser_t *)kmalloc(sizeof(struct canuser_t), GFP_KERNEL);
        if(canuser == NULL) goto no_canuser;
@@ -80,7 +90,7 @@ int can_open(struct inode *inode, struct file *file)
 #endif 
 
        return 0;
-       
+
     no_rx_qedge:
        canque_notify_bothends(edge, CANQUEUE_NOTIFY_DEAD_WANTED);
        canque_edge_decref(edge);
index 798e6ea..0c8c5af 100644 (file)
@@ -83,7 +83,7 @@ int oscar_init_chip_data(struct candevice_t *candev, int chipnr)
     // sja1000_fill_chipspecops(candev->chip[chipnr]);
     sja1000p_fill_chipspecops(candev->chip[chipnr]);
        
-    candev->chip[chipnr]->chip_base_addr = candev->io_addr;
+    candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr);
     candev->chip[chipnr]->clock = 12000000;
     candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP;  // we use an external tranceiver
     candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
@@ -110,14 +110,14 @@ int oscar_program_irq(struct candevice_t *candev)
     return 0;
 }
 
-void oscar_write_register(unsigned data, unsigned long address)
+void oscar_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address);
+       can_outb(data,address);
 }
 
-unsigned oscar_read_register(unsigned long address)
+unsigned oscar_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 /* !!! Don't change this function !!! */
index c724068..def0546 100644 (file)
@@ -230,7 +230,7 @@ int pci03_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/pc-i03.c
  */
-void pci03_write_register(unsigned data, unsigned long address)
+void pci03_write_register(unsigned data, can_ioptr_t address)
 {
        unsigned int *pci03_base_ptr;
        unsigned short address_to_write;
@@ -255,7 +255,7 @@ void pci03_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/pc-i03.c
  */
-unsigned pci03_read_register(unsigned long address)
+unsigned pci03_read_register(can_ioptr_t address)
 {
        unsigned int *pci03_base_ptr;
        unsigned short address_to_read;
index ce94186..d2a8968 100644 (file)
 #define ECR_PORT_SIZE            1  // size of the associated ECR register
 #define DNG_DEFAULT_COUNT        4  // count of defaults for init
 
-typedef void (*PARPORT_IRQ_HANLDER)(int, void *, struct pt_regs *);
+typedef void (*PARPORT_IRQ_HANLDER)(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id));
 
 /****************************************************************************/
 // GLOBALS
@@ -140,13 +140,13 @@ char dongle_type[] = "epp_dongle";
 static void _parport_disable_irq(struct DONGLE_PORT *dng)
 {
   u16 _PC_ = (u16)dng->dwPort + 2;
-  outb(inb(_PC_) & ~0x10, _PC_);
+  can_outb(can_inb(_PC_) & ~0x10, _PC_);
 }
 
 static void _parport_enable_irq(struct DONGLE_PORT *dng)
 {
   u16 _PC_ = (u16)dng->dwPort + 2;
-  outb(inb(_PC_) | 0x10, _PC_);
+  can_outb(can_inb(_PC_) | 0x10, _PC_);
 }
 
 
@@ -157,18 +157,18 @@ static u8 pcan_dongle_sp_readreg(struct DONGLE_PORT *dng, u8 port) // read a reg
   u16 _PB_ = _PA_ + 1;
   u16 _PC_ = _PB_ + 1;
   u8  b0, b1 ;
-  u8  irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable
+  u8  irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable
   can_spin_irqflags_t flags;
 
   can_spin_lock_irqsave(&pcan_lock, flags);
 
-  outb((0x0B ^ 0x0D) | irqEnable, _PC_);
-  outb((port & 0x1F) | 0x80,      _PA_);
-  outb((0x0B ^ 0x0C) | irqEnable, _PC_);
-  b1=nibble_decode[inb(_PB_)>>3];
-  outb(0x40, _PA_);
-  b0=nibble_decode[inb(_PB_)>>3];
-  outb((0x0B ^ 0x0D) | irqEnable, _PC_);
+  can_outb((0x0B ^ 0x0D) | irqEnable, _PC_);
+  can_outb((port & 0x1F) | 0x80,      _PA_);
+  can_outb((0x0B ^ 0x0C) | irqEnable, _PC_);
+  b1=nibble_decode[can_inb(_PB_)>>3];
+  can_outb(0x40, _PA_);
+  b0=nibble_decode[can_inb(_PB_)>>3];
+  can_outb((0x0B ^ 0x0D) | irqEnable, _PC_);
 
   can_spin_unlock_irqrestore(&pcan_lock, flags);
 
@@ -179,16 +179,16 @@ static void pcan_dongle_writereg(struct DONGLE_PORT *dng, u8 port, u8 data) // w
 {
   u16 _PA_ = (u16)dng->dwPort;
   u16 _PC_ = _PA_ + 2;
-  u8  irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable
+  u8  irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable
   can_spin_irqflags_t flags;
 
   can_spin_lock_irqsave(&pcan_lock, flags);
 
-  outb((0x0B ^ 0x0D) | irqEnable, _PC_);
-  outb(port & 0x1F,               _PA_);
-  outb((0x0B ^ 0x0C) | irqEnable, _PC_);
-  outb(data,                      _PA_);
-  outb((0x0B ^ 0x0D) | irqEnable, _PC_);
+  can_outb((0x0B ^ 0x0D) | irqEnable, _PC_);
+  can_outb(port & 0x1F,               _PA_);
+  can_outb((0x0B ^ 0x0C) | irqEnable, _PC_);
+  can_outb(data,                      _PA_);
+  can_outb((0x0B ^ 0x0D) | irqEnable, _PC_);
 
   can_spin_unlock_irqrestore(&pcan_lock, flags);
 }
@@ -199,16 +199,16 @@ static u8 pcan_dongle_epp_readreg(struct DONGLE_PORT *dng, u8 port) // read a re
   u16 _PA_ = (u16)dng->dwPort;
   u16 _PC_ = _PA_ + 2;
   u8  wert;
-  u8  irqEnable = inb(_PC_) & 0x10; // don't influence irqEnable
+  u8  irqEnable = can_inb(_PC_) & 0x10; // don't influence irqEnable
   can_spin_irqflags_t flags;
 
   can_spin_lock_irqsave(&pcan_lock, flags);
 
-  outb((0x0B ^ 0x0F) | irqEnable, _PC_);
-  outb((port & 0x1F) | 0x80,      _PA_);
-  outb((0x0B ^ 0x2E) | irqEnable, _PC_);
-  wert = inb(_PA_);
-  outb((0x0B ^ 0x0F) | irqEnable, _PC_);
+  can_outb((0x0B ^ 0x0F) | irqEnable, _PC_);
+  can_outb((port & 0x1F) | 0x80,      _PA_);
+  can_outb((0x0B ^ 0x2E) | irqEnable, _PC_);
+  wert = can_inb(_PA_);
+  can_outb((0x0B ^ 0x0F) | irqEnable, _PC_);
 
   can_spin_unlock_irqrestore(&pcan_lock, flags);
 
@@ -260,8 +260,8 @@ static void setECR(struct DONGLE_PORT *dng)
 {
        u16 wEcr = dng->wEcr;
 
-       dng->ucOldECRContent = inb(wEcr);
-       outb((dng->ucOldECRContent & 0x1F) | 0x20, wEcr);
+       dng->ucOldECRContent = can_inb(wEcr);
+       can_outb((dng->ucOldECRContent & 0x1F) | 0x20, wEcr);
 
        if (dng->ucOldECRContent == 0xff)
                DEBUGMSG("%s: realy ECP mode configured?\n", DEVICE_NAME);
@@ -271,7 +271,7 @@ static void restoreECR(struct DONGLE_PORT *dng)
 {
   u16 wEcr = dng->wEcr;
 
-  outb(dng->ucOldECRContent, wEcr);
+  can_outb(dng->ucOldECRContent, wEcr);
 
   DEBUGMSG("%s: restore ECR\n", DEVICE_NAME);
 }
@@ -337,8 +337,8 @@ static int pcan_dongle_open(struct DONGLE_PORT *dng)
       wPort    = (u16)dng->dwPort;
          
      // save old port contents
-     dng->ucOldDataContent     = inb(wPort);
-     dng->ucOldControlContent  = inb(wPort + 2);
+     dng->ucOldDataContent     = can_inb(wPort);
+     dng->ucOldControlContent  = can_inb(wPort + 2);
          
      // switch to epp mode if possible
      if (dng->wType == HW_DONGLE_SJA_EPP)
@@ -364,8 +364,8 @@ static int pcan_dongle_release(struct DONGLE_PORT *dng)
     restoreECR(dng);
     
   // restore port state
-  outb(dng->ucOldDataContent, wPort);
-  outb(dng->ucOldControlContent, wPort + 2);
+  can_outb(dng->ucOldDataContent, wPort);
+  can_outb(dng->ucOldControlContent, wPort + 2);
       
   parport_release(dng->pardev);
   
@@ -605,7 +605,7 @@ int pcan_dongle_init_chip_data(struct candevice_t *candev, int chipnr)
 
 
        candev->chip[chipnr]->chip_type=CHIP_TYPE;
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_clk_reg = 0x0;
        candev->chip[chipnr]->int_bus_reg = 0x0;
@@ -679,7 +679,7 @@ int pcan_dongle_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void pcan_dongle_write_register(unsigned data, unsigned long address)
+void pcan_dongle_write_register(unsigned data, can_ioptr_t address)
 {
    address -= dongle_port.chip->chip_base_addr;  // it's in mutiplexed mode
 
@@ -698,7 +698,7 @@ void pcan_dongle_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned pcan_dongle_read_register(unsigned long address)
+unsigned pcan_dongle_read_register(can_ioptr_t address)
 {
    u8 val;
 
diff --git a/lincan/src/pcan_pci.c b/lincan/src/pcan_pci.c
new file mode 100644 (file)
index 0000000..53fb133
--- /dev/null
@@ -0,0 +1,366 @@
+/* pcan_pci.c - support for PEAK System PCAN-PCI cards
+ * Linux CAN-bus device driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3  17 Jun 2004
+ */
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/sja1000p.h"
+
+#ifdef CAN_ENABLE_PCI_SUPPORT
+
+/* This card is based on Infineon's PSB 4600 PITA bridge */
+
+#define PITA_ICR         0x00        /* interrupt control register */
+#define PITA_ICR_STAT    0x00        /*   - status/IRQ pending bits */
+#define PITA_ICR_IEN     0x02        /*   - IRQ enable bits */
+#define PITA_GPIOICR     0x18        /* general purpose IO interface control register */
+#define PITA_MISC        0x1C        /* misc register */
+
+#define PCAN_PCI_CONFIG_PORT_SIZE 0x1000  /* size of the config io-memory */
+#define PCAN_PCI_PORT_SIZE        0x0400  /* size of a channel io-memory */
+
+#define PCAN_PCI_VENDOR_ID     0x001C  /* PCAN-PCI and clones vednor id */
+#define PCAN_PCI_PRODUCT_ID    0x0001  /* PCAN-PCI and clones device ID */
+
+/* Standard value: Pushpull  (OCTP1|OCTN1|OCPOL1|OCTP0|OCTN0|OCM1) */
+#define PCAN_PCI_OCR_DEFAULT_STD 0xFA
+
+#define PCAN_PCI_BYTES_PER_CIRCUIT 0x400
+#define PCAN_PCI_BYTES_PER_REG     4
+
+/* Conversion of the chip index to IRQ register mask */
+static unsigned int pcan_pci_idx2mask[4]={
+       0x0002,
+       0x0001,
+       0x0040,
+       0x0080
+};
+
+void pcan_pci_disconnect_irq(struct candevice_t *candev)
+{
+       u16 w;
+
+       /* disable interrupts sources */
+       w = can_readw(candev->aux_base_addr + PITA_ICR_IEN);
+       can_writew(w & ~0xC3, candev->aux_base_addr + PITA_ICR_IEN);
+}
+
+void pcan_pci_connect_irq(struct candevice_t *candev)
+{
+       u16 w;
+       int i;
+
+       /* clear previous accumulated status */
+       can_writew(0xC3, candev->aux_base_addr + PITA_ICR_STAT);
+
+       /* enable interrupts sources */
+       w = can_readw(candev->aux_base_addr + PITA_ICR_IEN);
+       for(i = 0; i < candev->nr_all_chips; i++)
+               w |= pcan_pci_idx2mask[i];
+       can_writew(w, candev->aux_base_addr + PITA_ICR_IEN);
+}
+
+
+int pcan_pci_request_io(struct candevice_t *candev)
+{
+       unsigned long ctrl_addr;
+       unsigned long io_addr;
+       int i;
+
+    #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       if(pci_request_region(candev->sysdevptr.pcidev, 0, "pcan_pci_ctrl") != 0){
+               CANMSG("Request of pcan_pci_ctrl range failed\n");
+               return -ENODEV;
+       }else if(pci_request_region(candev->sysdevptr.pcidev, 1, "pcan_pci_io") != 0){
+               CANMSG("Request of pcan_pci_io range failed\n");
+               goto error_io;
+       }
+    #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       if(pci_request_regions(candev->sysdevptr.pcidev, "pcan_pci") != 0){
+               CANMSG("Request of pcan_pci_bridge regions failed\n");
+               return -ENODEV;
+       }
+    #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+       ctrl_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
+       if (!(candev->aux_base_addr = ioremap(ctrl_addr,
+             pci_resource_len(candev->sysdevptr.pcidev,0)))) {
+               CANMSG("Unable to access I/O memory at: 0x%lx\n", ctrl_addr);
+               goto error_ioremap_ctrl;
+       }
+
+       io_addr=pci_resource_start(candev->sysdevptr.pcidev,1);;
+       if (!(candev->dev_base_addr = ioremap(io_addr,
+             pci_resource_len(candev->sysdevptr.pcidev,1)))) {
+               CANMSG("Unable to access I/O memory at: 0x%lx\n", io_addr);
+               goto error_ioremap_io;
+       }
+
+       candev->io_addr=io_addr;
+       candev->res_addr=ctrl_addr;
+
+       /*
+        * this is redundant with chip initialization, but remap address
+        * can change when resources are temporarily released
+        */
+       for(i=0;i<candev->nr_all_chips;i++) {
+               struct canchip_t *chip=candev->chip[i];
+               if(!chip) continue;
+               chip->chip_base_addr = candev->dev_base_addr +
+                       i * PCAN_PCI_BYTES_PER_CIRCUIT;
+               if(!chip->msgobj[0]) continue;
+               chip->msgobj[0]->obj_base_addr=chip->chip_base_addr;
+       }
+
+       pcan_pci_disconnect_irq(candev);
+
+       /* Configure PITA */
+       can_writew(0x0005, candev->aux_base_addr + PITA_GPIOICR + 2);   /* set GPIO control register */
+
+       can_writeb(0x00, candev->aux_base_addr + PITA_GPIOICR);         /* enable all channels */
+
+       can_writeb(0x05, candev->aux_base_addr + PITA_MISC + 3);        /* toggle reset */
+       mdelay(5);
+       writeb(0x04, candev->aux_base_addr + PITA_MISC + 3);            /* leave parport mux mode */
+       wmb();
+
+       return 0;
+
+    error_ioremap_io:
+       iounmap(candev->aux_base_addr);
+    error_ioremap_ctrl:
+    #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       pci_release_region(candev->sysdevptr.pcidev, 1);
+    error_io:
+       pci_release_region(candev->sysdevptr.pcidev, 0);
+    #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       pci_release_regions(candev->sysdevptr.pcidev);
+    #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+       return -ENODEV;
+}
+
+int pcan_pci_release_io(struct candevice_t *candev)
+{
+       pcan_pci_disconnect_irq(candev);
+
+       iounmap(candev->dev_base_addr);
+       iounmap(candev->aux_base_addr);
+    #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+       pci_release_region(candev->sysdevptr.pcidev, 1);
+       pci_release_region(candev->sysdevptr.pcidev, 0);
+    #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+       pci_release_regions(candev->sysdevptr.pcidev);
+    #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+       return 0;
+}
+
+void pcan_pci_write_register(unsigned data, can_ioptr_t address)
+{
+       address += ((can_ioptr2ulong(address)&(PCAN_PCI_BYTES_PER_CIRCUIT-1))
+                                            *(PCAN_PCI_BYTES_PER_REG-1));
+       can_writeb(data,address);
+}
+
+unsigned pcan_pci_read_register(can_ioptr_t address)
+{
+       address += ((can_ioptr2ulong(address)&(PCAN_PCI_BYTES_PER_CIRCUIT-1))
+                                            *(PCAN_PCI_BYTES_PER_REG-1));
+       return can_readb(address);
+}
+
+int pcan_pci_irq_handler(int irq, struct canchip_t *chip)
+{
+       struct candevice_t *candev=chip->hostdevice;
+       int ret;
+       unsigned int icr_stat;
+       unsigned int chip_mask = pcan_pci_idx2mask[chip->chip_idx];
+
+       icr_stat = can_readw(candev->aux_base_addr + PITA_ICR_STAT);
+
+       if(!(icr_stat & chip_mask)) return CANCHIP_IRQ_NONE;
+
+       ret = sja1000p_irq_handler(irq, chip);
+
+       can_writew(chip_mask, candev->aux_base_addr + PITA_ICR_STAT);
+
+       return ret;
+}
+
+int pcan_pci_reset(struct candevice_t *candev)
+{
+       int i=0,chip_nr;
+       struct canchip_t *chip;
+       unsigned cdr;
+
+       DEBUGMSG("Resetting pcan_pci hardware ...\n");
+
+       pcan_pci_disconnect_irq(candev);
+
+       for(chip_nr=0;chip_nr<candev->nr_all_chips;chip_nr++){
+               if(!candev->chip[chip_nr]) continue;
+               chip=candev->chip[chip_nr];
+
+               pcan_pci_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
+               udelay(1000);
+
+               cdr=pcan_pci_read_register(chip->chip_base_addr+SJACDR);
+               pcan_pci_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+               pcan_pci_write_register(0, chip->chip_base_addr+SJAIER);
+
+               i=20;
+               pcan_pci_write_register(0, chip->chip_base_addr+SJAMOD);
+               while (pcan_pci_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
+                       if(!i--) return -ENODEV;
+                       udelay(1000);
+                       pcan_pci_write_register(0, chip->chip_base_addr+SJAMOD);
+               }
+
+               cdr=pcan_pci_read_register(chip->chip_base_addr+SJACDR);
+               pcan_pci_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
+
+               pcan_pci_write_register(0, chip->chip_base_addr+SJAIER);
+
+               pcan_pci_read_register(chip->chip_base_addr+SJAIR);
+       }
+
+
+       pcan_pci_connect_irq(candev);
+
+       return 0;
+}
+
+int pcan_pci_init_hw_data(struct candevice_t *candev)
+{
+       struct pci_dev *pcidev = NULL;
+       int i;
+       int nr_chips;
+       u16 subsysid;
+
+       i = 0;
+       do {
+               pcidev = pci_find_device(PCAN_PCI_VENDOR_ID, PCAN_PCI_PRODUCT_ID, pcidev);
+               if(pcidev == NULL) {
+                       printk(KERN_ERR "No unused PCAN_PCI #%d card found\n", i);
+                       return -ENODEV;
+               }
+               i++;
+       } while(can_check_dev_taken(pcidev));
+
+       if (pci_enable_device (pcidev)){
+               printk(KERN_ERR "Enable PCAN_PCI failed\n");
+               return -EIO;
+       }
+       candev->sysdevptr.pcidev=pcidev;
+
+        if(pci_read_config_word(pcidev, 0x2E, &subsysid))
+               goto error_ret;
+
+        if(pci_write_config_word(pcidev, 0x04, 2))
+               goto error_ret;
+
+        if(pci_write_config_word(pcidev, 0x44, 0))
+               goto error_ret;
+
+        wmb();
+
+       for(i=0;i<2;i++){
+               if(!(pci_resource_flags(pcidev,0)&IORESOURCE_MEM)){
+                       printk(KERN_ERR "PCAN_PCI region %d is not memory\n",i);
+                       goto error_ret;
+               }
+       }
+
+       candev->res_addr=pci_resource_start(pcidev,0);  /* Control registers */
+       candev->io_addr=pci_resource_start(pcidev,1);   /* SJA1000 chips are mapped here */
+       candev->dev_base_addr=pci_resource_start(pcidev,1);
+
+       /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
+
+       if(subsysid >= 12)
+               nr_chips = 4;
+       else if(subsysid >= 10)
+               nr_chips = 3;
+       else if(subsysid >= 4)
+               nr_chips = 2;
+       else
+               nr_chips = 1;
+
+       candev->nr_82527_chips=0;
+       candev->nr_sja1000_chips=nr_chips;
+       candev->nr_all_chips=nr_chips;
+
+       printk(KERN_INFO "Found PCAN_PCI device with %d chip(s)\n", nr_chips);
+
+       return 0;
+
+error_ret:
+
+       printk(KERN_CRIT "Setup of PCAN_PCI failed\n");
+       pci_disable_device (pcidev);
+       return -EIO;
+}
+
+int pcan_pci_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+
+       if(candev->sysdevptr.pcidev==NULL)
+               return -ENODEV;
+
+       sja1000p_fill_chipspecops(candev->chip[chipnr]);
+
+       /* special version of the IRQ handler is required for PCAN_PCI board */
+       candev->chip[chipnr]->chipspecops->irq_handler=pcan_pci_irq_handler;
+
+       candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
+
+       candev->chip[chipnr]->chip_base_addr=
+                       can_ioport2ioptr(candev->io_addr+chipnr*PCAN_PCI_BYTES_PER_CIRCUIT);
+       candev->chip[chipnr]->flags = 0;
+       candev->chip[chipnr]->int_cpu_reg = 0;
+       candev->chip[chipnr]->int_clk_reg = 0;
+       candev->chip[chipnr]->int_bus_reg = 0;
+       candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
+       candev->chip[chipnr]->sja_ocr_reg = PCAN_PCI_OCR_DEFAULT_STD;
+       candev->chip[chipnr]->clock = 16000000;
+       candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
+
+       return 0;
+}
+
+int pcan_pci_init_obj_data(struct canchip_t *chip, int objnr)
+{
+       chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
+       return 0;
+}
+
+int pcan_pci_program_irq(struct candevice_t *candev)
+{
+
+       return 0;
+}
+
+int pcan_pci_register(struct hwspecops_t *hwspecops)
+{
+       hwspecops->request_io = pcan_pci_request_io;
+       hwspecops->release_io = pcan_pci_release_io;
+       hwspecops->reset = pcan_pci_reset;
+       hwspecops->init_hw_data = pcan_pci_init_hw_data;
+       hwspecops->init_chip_data = pcan_pci_init_chip_data;
+       hwspecops->init_obj_data = pcan_pci_init_obj_data;
+       hwspecops->write_register = pcan_pci_write_register;
+       hwspecops->read_register = pcan_pci_read_register;
+       hwspecops->program_irq = pcan_pci_program_irq;
+       return 0;
+}
+
+
+#endif /*CAN_ENABLE_PCI_SUPPORT*/
index 4d877c6..289fa84 100644 (file)
@@ -108,14 +108,14 @@ int pccanf_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting pccanf/s hardware ...\n");
        while (i < 1000000) {
                i++;
-               outb(0x00,candev->res_addr);
+               can_outb(0x00,candev->res_addr);
        }
-       outb(0x01,candev->res_addr);
-       outb(0x00,candev->chip[0]->chip_base_addr+SJACR);
+       can_outb(0x01,candev->res_addr);
+       can_outb(0x00,candev->chip[0]->chip_base_addr+SJACR);
 
        /* Check hardware reset status */
        i=0;
-       while ( (inb(candev->chip[0]->chip_base_addr+SJACR) & sjaCR_RR)
+       while ( (can_inb(candev->chip[0]->chip_base_addr+SJACR) & sjaCR_RR)
                                                                 && (i<=15) ) {
                udelay(20000);
                i++;
@@ -138,17 +138,17 @@ int pccand_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting pccan-d hardware ...\n");
        while (i < 1000000) {
                i++;
-               outb(0x00,candev->res_addr);
+               can_outb(0x00,candev->res_addr);
        }
-       outb(0x01,candev->res_addr);
-       outb(0x00,candev->chip[0]->chip_base_addr+SJACR);
-       outb(0x00,candev->chip[1]->chip_base_addr+SJACR);
+       can_outb(0x01,candev->res_addr);
+       can_outb(0x00,candev->chip[0]->chip_base_addr+SJACR);
+       can_outb(0x00,candev->chip[1]->chip_base_addr+SJACR);
 
        /* Check hardware reset status */
        i=0;
        for (chip_nr=0; chip_nr<2; chip_nr++) {
                i=0;
-               while ( (inb(candev->chip[chip_nr]->chip_base_addr +
+               while ( (can_inb(candev->chip[chip_nr]->chip_base_addr +
                                                SJACR) & sjaCR_RR) && (i<=15) ) {
                        udelay(20000);
                        i++;
@@ -174,17 +174,17 @@ int pccanq_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting pccan-q hardware ...\n");
        while (i < 100000) {
                i++;
-               outb(0x00,candev->res_addr);
+               can_outb(0x00,candev->res_addr);
        }
        outb_p(0x01,candev->res_addr);
                
-       outb(0x00,candev->chip[2]->chip_base_addr+SJACR);
-       outb(0x00,candev->chip[3]->chip_base_addr+SJACR);
+       can_outb(0x00,candev->chip[2]->chip_base_addr+SJACR);
+       can_outb(0x00,candev->chip[3]->chip_base_addr+SJACR);
 
        /* Check hardware reset status */
        for (chip_nr=0; chip_nr<2; chip_nr++) {
                i=0;
-               while( (inb(candev->chip[chip_nr]->chip_base_addr +
+               while( (can_inb(candev->chip[chip_nr]->chip_base_addr +
                                                iCPU) & iCPU_RST) && (i<=15) ) {
                        udelay(20000);
                        i++;
@@ -199,7 +199,7 @@ int pccanq_reset(struct candevice_t *candev)
        }
        for (chip_nr=2; chip_nr<4; chip_nr++) {
                i=0;
-               while( (inb(candev->chip[chip_nr]->chip_base_addr +
+               while( (can_inb(candev->chip[chip_nr]->chip_base_addr +
                                                SJACR) & sjaCR_RR) && (i<=15) ) {
                        udelay(20000);
                        i++;
@@ -267,11 +267,11 @@ int pccan_init_chip_data(struct candevice_t *candev, int chipnr)
                        candev->chip[chipnr]->sja_ocr_reg = 
                                                sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;     
                }
-               candev->chip[chipnr]->chip_base_addr=0x1000*chipnr+0x2000+candev->io_addr;
+               candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(0x1000*chipnr+0x2000+candev->io_addr);
        }
        else {
                sja1000_fill_chipspecops(candev->chip[chipnr]);
-               candev->chip[chipnr]->chip_base_addr=0x1000*chipnr+0x4000+candev->io_addr;
+               candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(0x1000*chipnr+0x4000+candev->io_addr);
                candev->chip[chipnr]->flags = 0;
                candev->chip[chipnr]->int_cpu_reg = 0;
                candev->chip[chipnr]->int_clk_reg = 0;
@@ -330,22 +330,22 @@ int pccan_program_irq(struct candevice_t *candev)
                        }
                }
        }
-       outb(irq_reg_value,0x6000+candev->io_addr);
+       can_outb(irq_reg_value,0x6000+candev->io_addr);
        DEBUGMSG("Configured pccan hardware interrupts\n");
-       outb(0x80,0x6000+candev->io_addr+0x02);
+       can_outb(0x80,0x6000+candev->io_addr+0x02);
        DEBUGMSG("Selected pccan on-board 16 MHz oscillator\n");
 
        return 0;
 }
 
-inline void pccan_write_register(unsigned data, unsigned long address)
+inline void pccan_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address); 
+       can_outb(data,address); 
 }
 
-unsigned pccan_read_register(unsigned long address)
+unsigned pccan_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 int pccanf_register(struct hwspecops_t *hwspecops)
index b568912..a8c0b19 100644 (file)
@@ -103,13 +103,13 @@ int pcccan_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting pcccan-1 hardware ...\n");
        while (i < 1000000) {
                i++;
-               outb(0x0,candev->res_addr);
+               can_outb(0x0,candev->res_addr);
        }
 
        /* Check hardware reset status */
        i=0;
-       outb(iCPU,candev->io_addr+0x1);
-       while ( (inb(candev->io_addr+0x2)&0x80) && (i<=15) ) {
+       can_outb(iCPU,candev->io_addr+0x1);
+       while ( (can_inb(candev->io_addr+0x2)&0x80) && (i<=15) ) {
                udelay(20000);
                i++;
        }
@@ -187,7 +187,7 @@ int pcccan_init_hw_data(struct candevice_t *candev)
 int pcccan_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        i82527_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC | iCPU_DMC;
        candev->chip[chipnr]->int_clk_reg = iCLK_SL1 | iCLK_CD0;
@@ -252,12 +252,12 @@ int pcccan_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/pcccan.c
  */
-void pcccan_write_register(unsigned data, unsigned long address)
+void pcccan_write_register(unsigned data, can_ioptr_t address)
 {
        can_spin_irqflags_t flags;
        can_spin_lock_irqsave(&pcccan_port_lock,flags);
-       outb(address - pcccan_base, pcccan_base+1);
-       outb(data, pcccan_base+6);
+       can_outb(address - pcccan_base, pcccan_base+1);
+       can_outb(data, pcccan_base+6);
        can_spin_unlock_irqrestore(&pcccan_port_lock,flags);
 }
 
@@ -271,13 +271,13 @@ void pcccan_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/pcccan.c
  */
-unsigned pcccan_read_register(unsigned long address)
+unsigned pcccan_read_register(can_ioptr_t address)
 {
        unsigned ret;
        can_spin_irqflags_t flags;
        can_spin_lock_irqsave(&pcccan_port_lock,flags);
-       outb(address - pcccan_base, pcccan_base+1);
-       ret=inb(pcccan_base+2);
+       can_outb(address - pcccan_base, pcccan_base+1);
+       ret=can_inb(pcccan_base+2);
        can_spin_unlock_irqrestore(&pcccan_port_lock,flags);
        return ret;
 
index adc4293..b87e7a8 100644 (file)
  */
 int pcm3680_request_io(struct candevice_t *candev)
 {
-        unsigned long remap_addr;
+        can_ioptr_t remap_addr;
        if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pcm3680")) {
                CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
                return -ENODEV;
        }
-       if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
                can_release_mem_region(candev->io_addr,IO_RANGE);
                return -ENODEV;
@@ -172,7 +172,7 @@ int pcm3680_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
        candev->chip[chipnr]->chip_base_addr=
-                       candev->io_addr + 0x200*chipnr;
+                       candev->dev_base_addr + 0x200*chipnr;
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_clk_reg = 0x0;
        candev->chip[chipnr]->int_bus_reg = 0x0;
@@ -235,9 +235,9 @@ int pcm3680_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void pcm3680_write_register(unsigned data, unsigned long address)
+void pcm3680_write_register(unsigned data, can_ioptr_t address)
 {
-       writeb(data,address);
+       can_writeb(data,address);
 }
 
 /**
@@ -250,9 +250,9 @@ void pcm3680_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned pcm3680_read_register(unsigned long address)
+unsigned pcm3680_read_register(can_ioptr_t address)
 {
-       return readb(address);
+       return can_readb(address);
 }
 
 /* !!! Don't change this function !!! */
index fd0f340..2a4fd22 100644 (file)
  */
 int pikronisa_request_io(struct candevice_t *candev)
 {
-        int remap_addr;
+        can_ioptr_t remap_addr;
        
        if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pikronisa")) {
                CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
                return -ENODEV;
        }
-       if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
                can_release_mem_region(candev->io_addr,IO_RANGE);
                return -ENODEV;
@@ -68,7 +68,7 @@ int pikronisa_request_io(struct candevice_t *candev)
 int pikronisa_release_io(struct candevice_t *candev)
 {
        /* release I/O memory mapping */
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
        can_release_mem_region(candev->io_addr,IO_RANGE);
 
        return 0;
@@ -180,7 +180,7 @@ int pikronisa_init_chip_data(struct candevice_t *candev, int chipnr)
        /*sja1000_fill_chipspecops(candev->chip[chipnr]);*/
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
 
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=candev->dev_base_addr;
        candev->chip[chipnr]->clock = 24000000;
        candev->chip[chipnr]->int_clk_reg = 0x0;
        candev->chip[chipnr]->int_bus_reg = 0x0;
@@ -241,11 +241,11 @@ int pikronisa_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/pikronisa.c
  */
-void pikronisa_write_register(unsigned data, unsigned long address)
+void pikronisa_write_register(unsigned data, can_ioptr_t address)
 {
        /*DEBUGMSG("pikronisa_write_register: addr=0x%lx data=0x%x",
                address,data);*/
-       writeb(data,address);
+       can_writeb(data,address);
 }
 
 /**
@@ -258,9 +258,9 @@ void pikronisa_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/pikronisa.c
  */
-unsigned pikronisa_read_register(unsigned long address)
+unsigned pikronisa_read_register(can_ioptr_t address)
 {
-       return readb(address);
+       return can_readb(address);
 }
 
 /* !!! Don't change this function !!! */
index 1c1a303..1cf71e7 100644 (file)
@@ -79,7 +79,7 @@ int pimx1_setup_hardware(struct candevice_t *candev)
  */
 int pimx1_request_io(struct candevice_t *candev)
 {
-        int remap_addr;
+        can_ioptr_t remap_addr;
 
        if(pimx1_setup_hardware(candev)<0){
                CANMSG("PiMX1 board hardware setup failure\n");
@@ -133,11 +133,11 @@ int pimx1_release_io(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/pikronisa.c
  */
-void pimx1_write_register(unsigned data, unsigned long address)
+void pimx1_write_register(unsigned data, can_ioptr_t address)
 {
        /*DEBUGMSG("pimx1_write_register: addr=0x%lx data=0x%x\n",
                address,data);*/
-       writeb(data,address);
+       can_writeb(data,address);
 }
 
 /**
@@ -150,9 +150,9 @@ void pimx1_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/pikronisa.c
  */
-unsigned pimx1_read_register(unsigned long address)
+unsigned pimx1_read_register(can_ioptr_t address)
 {
-       return readb(address);
+       return can_readb(address);
 }
 
 /**
index add0fee..1410288 100644 (file)
@@ -71,13 +71,13 @@ int pip_reset(struct candevice_t *candev)
        DEBUGMSG("Resetting %s hardware ...\n", candev->hwname);
        while (i < 1000000) {
                i++;
-               outb(0x01, candev->res_addr);
+               can_outb(0x01, candev->res_addr);
        }
-       outb(0x0, candev->res_addr);
+       can_outb(0x0, candev->res_addr);
 
        /* Check hardware reset status */
        i = 0;
-       while ((inb(candev->io_addr + iCPU) & iCPU_RST) && (i <= 15)) {
+       while ((can_inb(candev->io_addr + iCPU) & iCPU_RST) && (i <= 15)) {
                udelay(20000);
                i++;
        }
@@ -106,7 +106,7 @@ int pip_init_hw_data(struct candevice_t *candev)
 int pip_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        i82527_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr = candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 8000000;
        candev->chip[chipnr]->int_cpu_reg = 0;
        candev->chip[chipnr]->int_clk_reg = iCLK_SL1;
@@ -131,7 +131,7 @@ int pip_program_irq(struct candevice_t *candev)
        unsigned char can_addr = 0, can_reg = 0;
        DEBUGMSG("pip_program_irq\n");
        /* Reset can controller */
-       outb(0x01, candev->res_addr);
+       can_outb(0x01, candev->res_addr);
        if (strcmp(candev->hwname, "pip5") == 0) {
                irq_mask = PIP5_IRQ_MAP;
        } else if (strcmp(candev->hwname, "pip6") == 0) {
@@ -175,26 +175,26 @@ int pip_program_irq(struct candevice_t *candev)
                        return -ENODEV;
                }
        }
-       can_reg = inb(PIP_CANRES_REG);
+       can_reg = can_inb(PIP_CANRES_REG);
        DEBUGMSG("PIP_CANRES was 0x%x\n", can_reg);
        can_reg = (candev->chip[0]->chip_irq << 4) | can_addr;
        DEBUGMSG("Setting PIP_CANRES_REG to 0x%x\n", can_reg);
-       outb((candev->chip[0]->chip_irq << 4) | can_addr, PIP_CANRES_REG);
+       can_outb((candev->chip[0]->chip_irq << 4) | can_addr, PIP_CANRES_REG);
        /* re-enable the chip */
-       outb(0x00, candev->res_addr);
+       can_outb(0x00, candev->res_addr);
 
        return 0;
 }
 
 
-void pip_write_register(unsigned data, unsigned long address)
+void pip_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data, address);
+       can_outb(data, address);
 }
 
-unsigned pip_read_register(unsigned long address)
+unsigned pip_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 /* !!! Don't change these functions !!! */
index a73f71e..e423b92 100644 (file)
@@ -27,6 +27,12 @@ int remove_object_from_procdir(int chip_nr);
 static int can_proc_readlink(struct proc_dir_entry *ent, char *page);
 #endif
 
+#if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
+#define CAN_PROC_ROOT (&proc_root)
+#else /* >= 2.6.26 */
+#define CAN_PROC_ROOT (NULL)
+#endif /* >= 2.6.26 */
+
 static int cc=0; /* static counter for each CAN chip */
 
 static struct canproc_t can_proc_base;
@@ -156,7 +162,7 @@ int can_init_procdir(void)
        mutex_init(&proc_mutex);
 
        base->can_proc_entry = can_create_proc_entry("can", S_IFDIR | S_IRUGO |
-                                       S_IXUGO, &proc_root);
+                                       S_IXUGO, CAN_PROC_ROOT);
        if (base->can_proc_entry == NULL)
                return -ENODEV;
 
@@ -186,7 +192,7 @@ int can_delete_procdir(void)
        if (remove_channels_from_procdir())
                return -ENODEV;
        /* name: "can" */
-       if (can_remove_proc_entry(base->can_proc_entry, &proc_root))
+       if (can_remove_proc_entry(base->can_proc_entry, CAN_PROC_ROOT))
                return -ENODEV;
 
        return 0;
@@ -211,9 +217,10 @@ static int can_chip_procinfo(char *buf, char **start, off_t offset,
        len += sprintf(buf+len,"type    : %s\n",chip->chip_type);
        len += sprintf(buf+len,"index   : %d\n",chip->chip_idx);
        len += sprintf(buf+len,"irq     : %d\n",chip->chip_irq);
-       len += sprintf(buf+len,"addr    : %lu\n",chip->chip_base_addr);
+       len += sprintf(buf+len,"addr    : %lu\n",
+                       can_ioptr2ulong(chip->chip_base_addr));
        len += sprintf(buf+len,"config  : %s\n",
-                      (chip->flags & CHIP_CONFIGURED) ? "yes":"no");
+                       (chip->flags & CHIP_CONFIGURED) ? "yes":"no");
        len += sprintf(buf+len,"clock   : %ld Hz\n",chip->clock);
        len += sprintf(buf+len,"baud    : %ld\n",chip->baudrate);
        len += sprintf(buf+len,"num obj : %d\n",chip->max_objects);
index 5a4ecb6..cb6550d 100644 (file)
@@ -16,7 +16,7 @@
 
 int init_hwspecops(struct candevice_t *candev, int *irqnum_p);
 int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p);
-int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate);
+int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate, long clock);
 int init_obj_struct(struct candevice_t *candev, struct canchip_t *hostchip, int objnr);
 
 int next_minor=0;
@@ -32,9 +32,9 @@ int next_minor=0;
  * This function is prepared to simplify board specific xxx_request_io() function
  * for memory mapped devices.
  */
-int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base)
+int can_base_addr_fixup(struct candevice_t *candev, can_ioptr_t new_base)
 {
-       unsigned long offs;
+       long offs;
        int i, j;
 
        offs=new_base-candev->dev_base_addr;
@@ -212,6 +212,7 @@ int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
        int chipnr;
        long bd;
        int irqsig=-1;
+       long clock;
 
        candev=(struct candevice_t *)can_checked_malloc(sizeof(struct candevice_t));
        if (candev==NULL)
@@ -227,6 +228,7 @@ int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
        candev->hwname=hw[card];
        candev->io_addr=io[card];
        candev->dev_base_addr=io[card];
+       clock=clockfreq[card];
 
        candev->hwspecops=(struct hwspecops_t *)can_checked_malloc(sizeof(struct hwspecops_t));
        if (candev->hwspecops==NULL)
@@ -249,7 +251,7 @@ int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
                bd=baudrate[*chan_param_idx_p+chipnr];
                if(!bd) bd=baudrate[0];
 
-               if ((ret=init_chip_struct(candev, chipnr, irqsig, bd*1000)))
+               if ((ret=init_chip_struct(candev, chipnr, irqsig, bd*1000, clock*1000)))
                        goto error_chip;
        }
 
@@ -295,6 +297,7 @@ int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
  * @chipnr: index of the chip in the corresponding device/board structure
  * @irq: chip IRQ number or (-1) if not appropriate
  * @baudrate: baudrate in the units of 1Bd
+ * @clock: optional chip base clock frequency in 1Hz step
  *
  * Chip structure is allocated and chip specific operations are filled by
  * call to board specific init_chip_data() which calls chip specific
@@ -303,7 +306,7 @@ int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
  *
  * Return Value: returns negative number in the case of fail
  */
-int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate)
+int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate, long clock)
 {
        struct canchip_t *chip;
        int objnr;
@@ -327,6 +330,7 @@ int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudr
        chip->hostdevice=candev;
        chip->chip_irq=irq;
        chip->baudrate=baudrate;
+       chip->clock=clock;
        chip->flags=0x0;
 
        if(candev->hwspecops->init_chip_data(candev,chipnr)<0)
diff --git a/lincan/src/sh7760.c b/lincan/src/sh7760.c
new file mode 100644 (file)
index 0000000..cc71444
--- /dev/null
@@ -0,0 +1,104 @@
+/* sh7760.c
+* Linux CAN-bus device driver.
+* This software is released under the GPL-License.
+*/ 
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/sh7760.h"
+#include "../include/hcan2.h"
+
+int sh7760_request_io(struct candevice_t *candev)
+{
+       if (!can_request_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE, DEVICE_NAME)) {
+               CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
+               return -ENODEV;
+       }
+
+       DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + candev->nr_all_chips * IO_RANGE - 1);
+       return 0;
+}
+
+int sh7760_release_io(struct candevice_t *candev)
+{
+       can_release_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE);
+
+       return 0;
+}
+
+int sh7760_reset(struct candevice_t *candev)
+{
+       int i; 
+       DEBUGMSG("Resetting HCAN2 chips ...\n");
+
+       for (i = 0; i < candev->nr_all_chips; i++)
+       {
+           /* !!! Assuming this card has ONLY HCAN2 chips !!! */
+           if (hcan2_reset_chip(candev->chip[i])) return -ENODEV;
+       }
+
+       return 0;
+}
+
+int sh7760_init_hw_data(struct candevice_t *candev) 
+{
+       /* candev->res_addr = RESET_ADDR; */
+       candev->nr_82527_chips = NR_82527;
+       candev->nr_sja1000_chips = NR_SJA1000;
+       candev->nr_all_chips = NR_ALL;
+       /* candev->flags |= CANDEV_PROGRAMMABLE_IRQ; */
+
+       return 0;
+}
+int sh7760_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+       hcan2_fill_chipspecops(candev->chip[chipnr]);
+
+       candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr) + chipnr * SH7760_CAN_CHIP_OFFSET; /* one chip with 2 interfaces */
+       candev->chip[chipnr]->clock = SH7760_CAN_CLOCK;
+       candev->chip[chipnr]->chip_irq = SH7760_CAN_IRQ + chipnr;
+       candev->chip[chipnr]->hostdevice = candev;
+
+       return 0;
+}
+
+int sh7760_init_obj_data(struct canchip_t *chip, int objnr)
+{
+       chip->msgobj[objnr]->obj_base_addr = (can_ioptr_t) HCAN2_MB0 + HCAN2_MB_OFFSET * objnr;
+
+       return 0;
+}
+
+int sh7760_program_irq(struct candevice_t *candev)
+{
+       /* sh7760 doesn't use programmable interrupt */ 
+       return 0;
+}
+
+
+void sh7760_write_register(unsigned data, can_ioptr_t address)
+{
+       /* address is an absolute address */
+       writew(data, address);
+}
+
+unsigned sh7760_read_register(can_ioptr_t address)
+{
+       /* address is an absolute address */
+       return readw(address);
+}
+
+int sh7760_register(struct hwspecops_t *hwspecops)
+{
+       hwspecops->request_io = sh7760_request_io;
+       hwspecops->release_io = sh7760_release_io;
+       hwspecops->reset = sh7760_reset;
+       hwspecops->init_hw_data = sh7760_init_hw_data;
+       hwspecops->init_chip_data = sh7760_init_chip_data;
+       hwspecops->init_obj_data = sh7760_init_obj_data;
+       hwspecops->program_irq = sh7760_program_irq;
+       hwspecops->write_register = sh7760_write_register;
+       hwspecops->read_register = sh7760_read_register;
+       return 0;
+}
index 71c7095..de3ab20 100644 (file)
@@ -515,7 +515,7 @@ int sja1000_register(struct chipspecops_t *chipspecops)
        chipspecops->start_chip = sja1000_start_chip;
        chipspecops->stop_chip = sja1000_stop_chip;
        chipspecops->irq_handler = sja1000_irq_handler;
-       chipspecops->irq_handler = NULL;
+       chipspecops->irq_accept = NULL;
        return 0;
 }
 
index a7a990d..f83d8d9 100644 (file)
@@ -41,17 +41,17 @@ int smartcan_reset(struct candevice_t *candev)
        int i=0;
 
        DEBUGMSG("Resetting smartcan hardware ...\n");
-       outb(0x00,candev->res_addr);
+       can_outb(0x00,candev->res_addr);
        while (i < 1000000) {
                i++;
-               outb(0x01,candev->res_addr);
+               can_outb(0x01,candev->res_addr);
        }
-       outb(0x00,candev->res_addr); 
+       can_outb(0x00,candev->res_addr); 
 
        /* Check hardware reset status */
        i=0;
-       outb(candev->io_addr+iCPU,candev->io_addr);
-       while ( (inb(candev->io_addr+1)&0x80) && (i<=15) ) {
+       can_outb(candev->io_addr+iCPU,candev->io_addr);
+       while ( (can_inb(candev->io_addr+1)&0x80) && (i<=15) ) {
                udelay(20000);
                i++;
        }
@@ -79,7 +79,7 @@ int smartcan_init_hw_data(struct candevice_t *candev)
 int smartcan_init_chip_data(struct candevice_t *candev, int chipnr)
 {
        i82527_fill_chipspecops(candev->chip[chipnr]);
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC;
        candev->chip[chipnr]->int_clk_reg = iCLK_SL1;
@@ -100,22 +100,22 @@ int smartcan_init_obj_data(struct canchip_t *chip, int objnr)
 }
 
 
-void smartcan_write_register(unsigned data, unsigned long address)
+void smartcan_write_register(unsigned data, can_ioptr_t address)
 {
        can_spin_irqflags_t flags;
        can_spin_lock_irqsave(&smartcan_port_lock,flags);
-       outb(address-smartcan_base,smartcan_base);
-       outb(data,smartcan_base+1);
+       can_outb(address-smartcan_base,smartcan_base);
+       can_outb(data,smartcan_base+1);
        can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
 }
 
-unsigned smartcan_read_register(unsigned long address)
+unsigned smartcan_read_register(can_ioptr_t address)
 {
        unsigned ret;
        can_spin_irqflags_t flags;
        can_spin_lock_irqsave(&smartcan_port_lock,flags);
-       outb(address-smartcan_base,smartcan_base);
-       ret=inb(smartcan_base+1);
+       can_outb(address-smartcan_base,smartcan_base);
+       ret=can_inb(smartcan_base+1);
        can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
        return ret;
 }
index 45aef4b..17d60ef 100644 (file)
@@ -12,7 +12,7 @@
 #include "../include/i82527.h"
 
 int ssvcan_irq[2]={-1,-1};
-unsigned long ssvcan_base=0x0;
+can_ioptr_t ssvcan_base=0x0;
 
 static CAN_DEFINE_SPINLOCK(ssv_port_lock);
 
@@ -137,7 +137,7 @@ int ssv_init_chip_data(struct candevice_t *candev, int chipnr)
 {
     i82527_fill_chipspecops(candev->chip[chipnr]);
     candev->chip[chipnr]->chip_base_addr=
-       candev->io_addr+0x100*chipnr;
+       can_ioport2ioptr(candev->io_addr+0x100*chipnr);
     candev->chip[chipnr]->clock = 16000000;
     ssvcan_irq[chipnr]=candev->chip[chipnr]->chip_irq;
 
@@ -183,7 +183,7 @@ int ssv_program_irq(struct candevice_t *candev)
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific write process.
  */
-void ssv_write_register(unsigned data, unsigned long address)
+void ssv_write_register(unsigned data, can_ioptr_t address)
 {
     /* address is an absolute address */
 
@@ -193,16 +193,16 @@ void ssv_write_register(unsigned data, unsigned long address)
     /* write the relative address on the eight LSB bits 
      and the data on the eight MSB bits in one time */
     if((address-ssvcan_base)<0x100)
-       outw(address-ssvcan_base + (256 * data), ssvcan_base);
+       can_outw(address-ssvcan_base + (256 * data), ssvcan_base);
     else
-       outw(address-ssvcan_base-0x100 + (256 * data), ssvcan_base+0x02);
+       can_outw(address-ssvcan_base-0x100 + (256 * data), ssvcan_base+0x02);
 }
 
 /* The function template_read_register is used to read from hardware registers
  * on the CAN chip. You should only have to edit this function if your hardware
  * uses some specific read process.
  */
-unsigned ssv_read_register(unsigned long address)
+unsigned ssv_read_register(can_ioptr_t address)
 {
     /* this is the same thing that the function write_register.
        We use the two register, we write the address where we 
@@ -215,15 +215,15 @@ unsigned ssv_read_register(unsigned long address)
     if((address-ssvcan_base)<0x100)
     {
        can_spin_lock_irqsave(&ssv_port_lock,flags);
-       outb(address-ssvcan_base, ssvcan_base);
-       ret=inb(ssvcan_base+1);
+       can_outb(address-ssvcan_base, ssvcan_base);
+       ret=can_inb(ssvcan_base+1);
        can_spin_unlock_irqrestore(&ssv_port_lock,flags);
     }
     else
     {
        can_spin_lock_irqsave(&ssv_port_lock,flags);
-       outb(address-ssvcan_base-0x100, ssvcan_base+0x02);
-       ret=inb(ssvcan_base+1+0x02);
+       can_outb(address-ssvcan_base-0x100, ssvcan_base+0x02);
+       ret=can_inb(ssvcan_base+1+0x02);
        can_spin_unlock_irqrestore(&ssv_port_lock,flags);
     }
 
index 07ef7d0..d01105c 100644 (file)
@@ -20,6 +20,9 @@
  * components/comm/contrib directory. */
 #endif
 
+#ifndef IRQF_SHARED
+#define IRQF_SHARED SA_SHIRQ
+#endif  /*IRQF_SHARED*/
 
 /**
  * can_checked_malloc - memory allocation with registering of requested blocks
@@ -198,12 +201,12 @@ void can_release_mem_region(unsigned long start, unsigned long n)
  * 
  * File: src/setup.c
  */
-can_irqreturn_t can_default_irq_dispatch(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t can_default_irq_dispatch(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id))
 {
        int retval;
        struct canchip_t *chip=(struct canchip_t *)dev_id;
 
-       retval=chip->chipspecops->irq_handler(irq, chip);
+       retval=chip->chipspecops->irq_handler(irq_number, chip);
        return CAN_IRQ_RETVAL(retval);
 }
 
@@ -223,7 +226,7 @@ int can_chip_setup_irq(struct canchip_t *chip)
                return 1;
                        
        if ((chip->flags & CHIP_IRQ_VME) == 0) {
-               if (request_irq(chip->chip_irq,can_default_irq_dispatch,SA_SHIRQ,DEVICE_NAME,chip))
+               if (request_irq(chip->chip_irq,can_default_irq_dispatch,IRQF_SHARED,DEVICE_NAME,chip))
                        return -1;
                else {
                        DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
index d990332..a91d9fd 100644 (file)
@@ -152,7 +152,7 @@ int template_init_chip_data(struct candevice_t *candev, int chipnr)
        /*sja1000_fill_chipspecops(candev->chip[chipnr]);*/
        /*sja1000p_fill_chipspecops(candev->chip[chipnr]);*/
        
-       candev->chip[chipnr]->chip_base_addr=candev->io_addr;
+       candev->chip[chipnr]->chip_base_addr=can_ioport2ioptr(candev->io_addr);
        candev->chip[chipnr]->clock = 16000000;
        candev->chip[chipnr]->int_cpu_reg = iCPU_DSC;
        candev->chip[chipnr]->int_clk_reg = iCLK_SL1;
@@ -216,9 +216,9 @@ int template_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/template.c
  */
-void template_write_register(unsigned data, unsigned long address)
+void template_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data,address);
+       can_outb(data,address);
 }
 
 /**
@@ -231,9 +231,9 @@ void template_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/template.c
  */
-unsigned template_read_register(unsigned long address)
+unsigned template_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
 /* !!! Don't change this function !!! */
index 313f041..dab8584 100644 (file)
 
 static CAN_DEFINE_SPINLOCK(ts7kv_win_lock);
 
-long clock[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
-MODULE_PARM(clock, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
-MODULE_PARM_DESC(clock,"clock frequency for each board in step of 1kHz");
-
-long tscanio[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
-MODULE_PARM(tscanio, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
-MODULE_PARM_DESC(tscanio,"TSCAN CAN controller IO address for each board");
+unsigned long tscanio[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};
+unsigned int tscanio_specified;
 
 #if defined(TS7XXX_IO8_BASE)&&defined(TSXXX_BASE_IO)
 int tsxxx_base=TS7XXX_IO8_BASE+TSXXX_BASE_IO;
@@ -39,10 +34,18 @@ int tsxxx_base=TS7XXX_IO8_BASE;
 #else /*TS7XXX_IO8_BASE*/
 unsigned long tsxxx_base=0;
 #endif /*TS7XXX_IO8_BASE*/
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12))
+MODULE_PARM(tscanio, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");
 MODULE_PARM(tsxxx_base, "1i");
+#else /* LINUX_VERSION_CODE >= 2,6,12 */
+module_param_array(tscanio, int, &tscanio_specified, 0);
+module_param(tsxxx_base, ulong, 0);
+#endif /* LINUX_VERSION_CODE >= 2,6,12 */
+
+MODULE_PARM_DESC(tscanio,"TSCAN CAN controller IO address for each board");
 MODULE_PARM_DESC(tsxxx_base,"The base of the ISA/8-bit IO space for TSxxx CAN peripherals in the system");
 
-unsigned short ts7kv_isused = 0x0;
 
 /**
  * tscan1_request_io: - reserve io or memory range for can board
@@ -133,8 +136,8 @@ int tscan1_request_io(struct candevice_t *candev)
                default:        mode=0x60; break;
        }
 
-       outb(0x00, candev->io_addr+TSCAN1_WIN_REG);
-       outb(mode, candev->io_addr+TSCAN1_MOD_REG);
+       can_outb(0x00, candev->io_addr+TSCAN1_WIN_REG);
+       can_outb(mode, candev->io_addr+TSCAN1_MOD_REG);
 
        return 0;
 }
@@ -174,7 +177,7 @@ int tscan1_release_io(struct candevice_t *candev)
                        can_release_io_region(remap_can_io_addr, TSXXX_CAN_RANGE);
        }
 
-       outb(0x20, candev->io_addr+TSCAN1_MOD_REG);
+       can_outb(0x20, candev->io_addr+TSCAN1_MOD_REG);
 
        can_release_io_region(candev->io_addr, TSXXX_IO_RANGE);
        return 0;
@@ -235,15 +238,15 @@ int tscan1_check_presence(unsigned long remap_io_addr, int *pjmp)
                return -ENODEV;
 
        do {
-               if (inb(remap_io_addr+TSXXX_ID0_REG)!=TSCAN1_ID0 ||
-                       inb(remap_io_addr+TSXXX_ID1_REG)!=TSCAN1_ID1)
+               if (can_inb(remap_io_addr+TSXXX_ID0_REG)!=TSCAN1_ID0 ||
+                       can_inb(remap_io_addr+TSXXX_ID1_REG)!=TSCAN1_ID1)
                        break;
 
-               outb(0x00, remap_io_addr+TSCAN1_WIN_REG);
-               outb(0x20, remap_io_addr+TSCAN1_MOD_REG);
+               can_outb(0x00, remap_io_addr+TSCAN1_WIN_REG);
+               can_outb(0x20, remap_io_addr+TSCAN1_MOD_REG);
 
                if(pjmp)
-                       *pjmp = inb(remap_io_addr+TSCAN1_JMP_REG);
+                       *pjmp = can_inb(remap_io_addr+TSCAN1_JMP_REG);
 
                result = 0;
        } while (0);
@@ -278,7 +281,7 @@ int tscan1_init_hw_data(struct candevice_t *candev)
        io_addr = candev->io_addr;
 
        if(io_addr && (io_addr != (unsigned long)-1)) {
-               remap_io_addr = io_addr = tsxxx_base;
+               remap_io_addr = io_addr + tsxxx_base;
 
                if(tscan1_check_presence(remap_io_addr, &jmp)){
                        CANMSG("No TSCAN1 card found at address 0xlx\n");
@@ -295,7 +298,7 @@ int tscan1_init_hw_data(struct candevice_t *candev)
                        }
 
                        io_addr = TSCAN1_BASE_IO + i*TSXXX_IO_RANGE;
-                       remap_io_addr = io_addr = tsxxx_base;
+                       remap_io_addr = io_addr + tsxxx_base;
 
                        for (j = 0; j < MAX_HW_CARDS; j++) {
                                if(io[j] == io_addr){
@@ -340,12 +343,12 @@ int ts7kv_check_presence(unsigned long remap_io_addr, int *pjmp)
                return -ENODEV;
 
        do {
-               if (inb(remap_io_addr+TSXXX_ID0_REG)!=TS7KV_ID0 ||
-                       inb(remap_io_addr+TSXXX_ID1_REG)!=TS7KV_ID1)
+               if (can_inb(remap_io_addr+TSXXX_ID0_REG)!=TS7KV_ID0 ||
+                       can_inb(remap_io_addr+TSXXX_ID1_REG)!=TS7KV_ID1)
                        break;
 
                if(pjmp)
-                       *pjmp = inb(remap_io_addr+TS7KV_JMP_REG);
+                       *pjmp = can_inb(remap_io_addr+TS7KV_JMP_REG);
 
                result = 0;
        } while (0);
@@ -365,7 +368,7 @@ int ts7kv_init_hw_data(struct candevice_t *candev)
        io_addr = candev->io_addr;
 
        if(io_addr && (io_addr != (unsigned long)-1)) {
-               remap_io_addr = io_addr = tsxxx_base;
+               remap_io_addr = io_addr + tsxxx_base;
 
                if(ts7kv_check_presence(remap_io_addr, &jmp)){
                        CANMSG("No TS7KV card found at address 0xlx\n");
@@ -382,7 +385,7 @@ int ts7kv_init_hw_data(struct candevice_t *candev)
                        }
 
                        io_addr = TS7KV_BASE_IO + i*TSXXX_IO_RANGE;
-                       remap_io_addr = io_addr = tsxxx_base;
+                       remap_io_addr = io_addr + tsxxx_base;
 
                        for (j = 0; j < MAX_HW_CARDS; j++) {
                                if(io[j] == io_addr){
@@ -457,16 +460,10 @@ int ts7kv_init_hw_data(struct candevice_t *candev)
  */
 int tscan1_init_chip_data(struct candevice_t *candev, int chipnr)
 {
-       unsigned long clk;
+       unsigned long default_clk = 16000 * 1000;
        int jmp;
        int irq = -1;
 
-       clk = clock[candev->candev_idx];
-       if(!clk || (clk == -1))
-               clk = 16000 * 1000;
-       else
-               clk *= 1000;
-
        /* unused reset address is used to store jumper setting */
        jmp = candev->res_addr;
 
@@ -483,7 +480,8 @@ int tscan1_init_chip_data(struct candevice_t *candev, int chipnr)
 
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
 
-       candev->chip[chipnr]->clock = clk;
+       if(candev->chip[chipnr]->clock <= 0)
+               candev->chip[chipnr]->clock = default_clk;
        candev->chip[chipnr]->int_clk_reg = 0x0;
        candev->chip[chipnr]->int_bus_reg = 0x0;
        candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
@@ -499,16 +497,10 @@ int tscan1_init_chip_data(struct candevice_t *candev, int chipnr)
 
 int ts7kv_init_chip_data(struct candevice_t *candev, int chipnr)
 {
-       unsigned long clk;
+       unsigned long default_clk = 16000 * 1000;
        int jmp;
        int irq = -1;
 
-       clk = clock[candev->candev_idx];
-       if(!clk || (clk == -1))
-               clk = 24000 * 1000;
-       else
-               clk *= 1000;
-
        /* unused reset address is used to store jumper setting */
        jmp = candev->res_addr;
 
@@ -526,7 +518,8 @@ int ts7kv_init_chip_data(struct candevice_t *candev, int chipnr)
 
        sja1000p_fill_chipspecops(candev->chip[chipnr]);
 
-       candev->chip[chipnr]->clock = clk;
+       if(candev->chip[chipnr]->clock <= 0)
+               candev->chip[chipnr]->clock = default_clk;
        candev->chip[chipnr]->int_clk_reg = 0x0;
        candev->chip[chipnr]->int_bus_reg = 0x0;
        candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
@@ -587,32 +580,33 @@ int tscan1_program_irq(struct candevice_t *candev)
  * Return Value: The function does not return a value
  * File: src/tscan1.c
  */
-void tscan1_write_register(unsigned data, unsigned long address)
+void tscan1_write_register(unsigned data, can_ioptr_t address)
 {
-       outb(data, address);
+       can_outb(data, address);
 }
 
-void ts7kv_write_register(unsigned data, unsigned long address)
+void ts7kv_write_register(unsigned data, can_ioptr_t address)
 {
-       unsigned long base = address & ~0x1f;
+       unsigned long addr=can_ioptr2ulong(address);
+       can_ioptr_t base = can_ulong2ioptr(addr & ~0x1f);
        unsigned char nwin = 0x10;
        unsigned char savewin;
        
        can_spin_irqflags_t flags;
 
-       if((address&0x1f) > 0x1d) {
+       if((addr&0x1f) > 0x1d) {
                nwin++;
                address -= 0x10;
        }
 
        can_spin_lock_irqsave(&ts7kv_win_lock,flags);
-       savewin = inb(base+TS7KV_WIN_REG);
+       savewin = can_inb(base+TS7KV_WIN_REG);
        if(nwin == savewin) {
-               outb(data, address);
+               can_outb(data, address);
        }else{
-               outb(nwin, base+TS7KV_WIN_REG);
-               outb(data, address);
-               outb(savewin, base+TS7KV_WIN_REG);
+               can_outb(nwin, base+TS7KV_WIN_REG);
+               can_outb(data, address);
+               can_outb(savewin, base+TS7KV_WIN_REG);
        }
        can_spin_unlock_irqrestore(&ts7kv_win_lock,flags);
 }
@@ -627,33 +621,34 @@ void ts7kv_write_register(unsigned data, unsigned long address)
  * Return Value: The function returns the value stored in @address
  * File: src/tscan1.c
  */
-unsigned tscan1_read_register(unsigned long address)
+unsigned tscan1_read_register(can_ioptr_t address)
 {
-       return inb(address);
+       return can_inb(address);
 }
 
-unsigned ts7kv_read_register(unsigned long address)
+unsigned ts7kv_read_register(can_ioptr_t address)
 {
-       unsigned long base = address & ~0x1f;
+       unsigned long addr=can_ioptr2ulong(address);
+       can_ioptr_t base = can_ulong2ioptr(addr & ~0x1f);
        unsigned char nwin = 0x10;
        unsigned char savewin;
        unsigned val;
        
        can_spin_irqflags_t flags;
 
-       if((address&0x1f) > 0x1d) {
+       if((addr&0x1f) > 0x1d) {
                nwin++;
                address -= 0x10;
        }
 
        can_spin_lock_irqsave(&ts7kv_win_lock,flags);
-       savewin = inb(base+TS7KV_WIN_REG);
+       savewin = can_inb(base+TS7KV_WIN_REG);
        if(nwin == savewin) {
-               val = inb(address);
+               val = can_inb(address);
        }else{
-               outb(nwin, base+TS7KV_WIN_REG);
-               val = inb(address);
-               outb(savewin, base+TS7KV_WIN_REG);
+               can_outb(nwin, base+TS7KV_WIN_REG);
+               val = can_inb(address);
+               can_outb(savewin, base+TS7KV_WIN_REG);
        }
        can_spin_unlock_irqrestore(&ts7kv_win_lock,flags);
 
index 55cfbd5..7b27ade 100644 (file)
@@ -693,12 +693,12 @@ int unican_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
  */
 int unican_request_io(struct candevice_t *candev)
 {
-        unsigned long remap_addr;
+        can_ioptr_t remap_addr;
        if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - unican")) {
                CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
                return -ENODEV;
        }
-       if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
                can_release_mem_region(candev->io_addr,IO_RANGE);
                return -ENODEV;
@@ -718,7 +718,7 @@ int unican_request_io(struct candevice_t *candev)
  */
 int unican_release_io(struct candevice_t *candev)
 {
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
        can_release_mem_region(candev->io_addr,IO_RANGE);
        return 0;
 }
@@ -812,7 +812,7 @@ int unican_init_chip_data(struct candevice_t *candev, int chipnr)
        chip->int_clk_reg = 0x0;
        chip->int_bus_reg = 0x0;
        chip->max_objects = 1;
-       chip->chip_base_addr=candev->io_addr;
+       chip->chip_base_addr=candev->dev_base_addr;
                        
        CANMSG("initializing unican chip operations\n");
        chip->chipspecops->chip_config=unican_chip_config;
@@ -891,7 +891,7 @@ int unican_register(struct hwspecops_t *hwspecops)
 
 int unican_pci_request_io(struct candevice_t *candev)
 {
-        unsigned long remap_addr;
+        can_ioptr_t remap_addr;
 
     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
        if(pci_request_region(candev->sysdevptr.pcidev, 0, "unican_pci") != 0){
@@ -905,11 +905,10 @@ int unican_pci_request_io(struct candevice_t *candev)
        }
     #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
 
-       candev->dev_base_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
-       candev->io_addr=candev->dev_base_addr;
-       candev->res_addr=candev->dev_base_addr;
+       candev->io_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
+       candev->res_addr=candev->io_addr;
 
-       if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+       if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) {
                CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
            #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
                pci_release_region(candev->sysdevptr.pcidev, 0);
@@ -922,7 +921,8 @@ int unican_pci_request_io(struct candevice_t *candev)
        can_base_addr_fixup(candev, remap_addr);
        DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
        DEBUGMSG("VMA: dev_base_addr: 0x%lx chip_base_addr: 0x%lx\n", 
-               candev->dev_base_addr, candev->chip[0]->chip_base_addr);
+               can_ioptr2ulong(candev->dev_base_addr),
+               can_ioptr2ulong(candev->chip[0]->chip_base_addr));
 
        return 0;
 }
@@ -930,7 +930,7 @@ int unican_pci_request_io(struct candevice_t *candev)
 
 int unican_pci_release_io(struct candevice_t *candev)
 {
-       iounmap((void*)candev->dev_base_addr);
+       iounmap(candev->dev_base_addr);
     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
        pci_release_region(candev->sysdevptr.pcidev, 0);
     #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
@@ -959,9 +959,9 @@ int unican_pci_init_hw_data(struct candevice_t *candev)
                printk(KERN_CRIT "Unican PCI region 0 is not MEM\n");
                return -EIO;
        }
-       candev->dev_base_addr=pci_resource_start(pcidev,0);
-       candev->io_addr=candev->dev_base_addr;
-       candev->res_addr=candev->dev_base_addr;
+       candev->io_addr=pci_resource_start(pcidev,0);
+       candev->res_addr=candev->io_addr;
+       candev->dev_base_addr=NULL;
        
        /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
 
index f595272..b22a357 100644 (file)
@@ -1,14 +1,14 @@
 # Generic directory or leaf node makefile for OCERA make framework
 
 ifndef MAKERULES_DIR
-MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
 endif
 
 ifeq ($(MAKERULES_DIR),)
 all : default
 .DEFAULT::
        @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
-else   
+else
 include $(MAKERULES_DIR)/Makefile.rules
 endif