]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/include/main.h
CAN driver infrastructure redesign to LinCAN-0.2 version
[lincan.git] / lincan / include / main.h
index c811d8719bdd1be28ac7b38c5baecc336fef1c84..81f1818c5d2c0689504759faa27c5a9baa8211cb 100644 (file)
@@ -1,16 +1,20 @@
 /* main.h
  * Header file for the Linux CAN-bus 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 0.7  6 Aug 2001
+ * Version lincan-0.2  9 Jul 2003
  */
 
+#include <asm/io.h>
 #include <linux/fs.h>
 #include <linux/version.h>
 #include <linux/wait.h>
-#include <asm/io.h>
+#include <linux/interrupt.h>
 #include "./can.h"
 #include "./constants.h"
+#include "./can_queue.h"
 
 #ifdef CAN_DEBUG
        #define DEBUGMSG(fmt,args...) printk(KERN_ERR "can.o (debug): " fmt,\
        (minor(file->f_dentry->d_inode->i_rdev))
 #endif /* Linux kernel > 2.5.7 */
 
-#define MSG_OFFSET(object) ((object)*0x10)
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && !defined(IRQ_RETVAL))
+   typedef void irqreturn_t;
+   #define IRQ_NONE
+   #define IRQ_HANDLED
+   #define IRQ_RETVAL(x)
+#endif /* <=2.5.67 */
 
 struct canhardware_t {
        int nr_boards;
@@ -42,14 +51,17 @@ struct canhardware_t {
 };
 
 struct candevice_t {
-       char *hwname;
-       unsigned long io_addr;
-       unsigned long res_addr;
+       char *hwname;                   /* text board type */
+       int candev_idx;                 /* board index in canhardware_t.candevice[] */
+       unsigned long io_addr;          /* IO/physical MEM address */
+       unsigned long res_addr;         /* optional seset register port */
+       unsigned long dev_base_addr;    /* CPU translated IO/virtual MEM address */
        unsigned int flags;
 
        /* Hardware chip configuration. In case of multiple chips *chip
         * is the first in an array of chip_t structures.
         */
+       int nr_all_chips;
        int nr_82527_chips;
        int nr_sja1000_chips;
        struct chip_t *chip[MAX_HW_CHIPS];
@@ -61,11 +73,20 @@ struct candevice_t {
 
 struct chip_t {
        char *chip_type;
+       int chip_idx;   /* chip index in candevice_t.chip[] */
        int chip_irq;
        unsigned long chip_base_addr;
        unsigned int flags;
        int clock; // Chip clock in Hz
 
+       /* This is copy of the chip->hostdevice->hwspecops->read_register
+        * and the chip->hostdevice->hwspecops->write_register.
+        * The pointers were added for performance reasons, and are initialized
+        * by init_chip_struct() from values given by hardware specific init_hwspecops().
+        */
+       void (*write_register)(unsigned char data,unsigned long address);
+       unsigned (*read_register)(unsigned long address);
+
        /* sja_cdr_reg holds hardware specific options for the Clock Divider
         * register. Options defined in the sja1000.h file:
         * CDR_CLKOUT_MASK, CDR_CLK_OFF, CDR_RXINPEN, CDR_CBP, CDR_PELICAN
@@ -98,30 +119,49 @@ struct chip_t {
        struct chipspecops_t *chipspecops;
 
        struct candevice_t *hostdevice;
+       
+       int max_objects;        /* 1 for sja1000, 15 for */
 };
 
 struct msgobj_t {
        unsigned long obj_base_addr;
-       unsigned int minor;
-       unsigned int object;
-       unsigned int flags; 
+       unsigned int minor;     /* associated device minor number  */
+       unsigned int object;    /* object number in chip_t +1 for debug printk */
+       unsigned long flags; 
        int ret;
 
-       struct canfifo_t *fifo;
+       struct canque_ends_t *qends;
+       struct canque_edge_t *tx_qedge;
+       struct canque_slot_t *tx_slot;
+       struct canmsg_t rx_msg;
 
        struct chip_t *hostchip;
+
+       atomic_t obj_used;
+       struct list_head obj_users;
+};
+
+#define CAN_USER_MAGIC 0x05402033
+
+struct canuser_t {
+       struct list_head peers;
+       struct canque_ends_t *qends;
+        struct file *file;      /* back ptr to file */
+       struct msgobj_t *msgobj;
+       struct canque_edge_t *rx_edge0; /* simplifies IOCTL */
+       int magic;
 };
 
 struct hwspecops_t {
-       int (*request_io)(unsigned long io_addr);
-       int (*release_io)(unsigned long io_addr);
-       int (*reset)(int card);
-       int (*init_hw_data)(int card);
-       int (*init_chip_data)(int card, int chipnr);
-       int (*init_obj_data)(int chipnr, int objnr);
+       int (*request_io)(struct candevice_t *candev);
+       int (*release_io)(struct candevice_t *candev);
+       int (*reset)(struct candevice_t *candev);
+       int (*init_hw_data)(struct candevice_t *candev);
+       int (*init_chip_data)(struct candevice_t *candev, int chipnr);
+       int (*init_obj_data)(struct chip_t *chip, int objnr);
+       int (*program_irq)(struct candevice_t *candev);
        void (*write_register)(unsigned char data,unsigned long address);
        unsigned (*read_register)(unsigned long address);
-       int (*program_irq)(int card);
 };
 
 struct chipspecops_t {
@@ -143,13 +183,14 @@ struct chipspecops_t {
                                                        struct canmsg_t *msg);
        int (*remote_request)(struct chip_t *chip, struct msgobj_t *obj);
        int (*check_tx_stat)(struct chip_t *chip);
+       int (*wakeup_tx)(struct chip_t *chip, struct msgobj_t *obj);
        int (*enable_configuration)(struct chip_t *chip);
        int (*disable_configuration)(struct chip_t *chip);
        int (*set_btregs)(struct chip_t *chip, unsigned short btr0, 
                                                        unsigned short btr1);
        int (*start_chip)(struct chip_t *chip);
        int (*stop_chip)(struct chip_t *chip);
-       void (*irq_handler)(int irq, void *dev_id, struct pt_regs *regs);
+       irqreturn_t (*irq_handler)(int irq, void *dev_id, struct pt_regs *regs);
 };
 
 struct mem_addr {
@@ -157,45 +198,6 @@ struct mem_addr {
        struct mem_addr *next;
 };
 
-/* Structure for the drivers main input and output buffers. The readq, writeq
- * entries are the wait queues for the driver to sleep on in case of blocking
- * read/write calls. buf_rx_entry and buf_tx_entry are pointers to the input and
- * output buffers. The buffers are dynamically allocated. The tx_readp,
- * tx_writep, rx_readp and rx_writep pointers are the various read/write 
- * pointers used when reading or writing the input and output buffers. The 
- * rx/tx_size entries are the dynamically allocated input and output buffer size
- * The rx/tx_in_progress entries are used to determine whether the device is 
- * already set up for transmission.
- */
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0))
-struct canfifo_t {
-       struct wait_queue *readq, *writeq; 
-       struct canmsg_t *buf_tx_entry;
-       struct canmsg_t *buf_rx_entry; 
-       struct canmsg_t *tx_readp;
-       struct canmsg_t *rx_writep;
-       struct canmsg_t *tx_writep;
-       struct canmsg_t *rx_readp;
-       int rx_size, tx_size;
-       volatile int rx_in_progress, tx_in_progress;
-       /*int head, tail;*/ /* removed */
-};
-#else
-struct canfifo_t {
-       struct __wait_queue_head readq;
-       struct __wait_queue_head writeq;
-       struct canmsg_t *buf_tx_entry;
-       struct canmsg_t *buf_rx_entry; 
-       struct canmsg_t *tx_readp;
-       struct canmsg_t *rx_writep;
-       struct canmsg_t *tx_writep;
-       struct canmsg_t *rx_readp;
-       int rx_size, tx_size;
-       volatile int rx_in_progress, tx_in_progress;
-       /*int head, tail;*/ /* removed */
-};
-#endif
-
 /* Structure for the RTR queue */
 struct rtr_id {
        unsigned long id;
@@ -217,7 +219,6 @@ extern int irq[MAX_IRQ];
 extern unsigned long io[MAX_HW_CARDS];
 
 extern struct canhardware_t *hardware_p;
-extern struct candevice_t *candevices_p[MAX_HW_CARDS];
 extern struct chip_t *chips_p[MAX_TOT_CHIPS];
 extern struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
 
@@ -226,31 +227,37 @@ extern struct mem_addr *mem_head;
 /* 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.
  */
-extern inline void can_write_reg(const struct chip_t *chip, unsigned char data, unsigned short address)
+extern inline void can_write_reg(const struct chip_t *chip, unsigned char data, unsigned address)
 {
-       unsigned short segment_number;
        unsigned long address_to_write;
-
        address_to_write = chip->chip_base_addr+address;
+       chip->write_register(data, address_to_write);
+}
 
-       if ( (chip->flags & SEGMENTED) != 0) {
-               segment_number = (unsigned short)(address >> 6);
-               address_to_write += SPACING * segment_number;
-       }
+extern inline unsigned can_read_reg(const struct chip_t *chip, unsigned address)
+{
+       unsigned long address_to_read;
+       address_to_read = chip->chip_base_addr+address;
+       return chip->read_register(address_to_read);
+}
 
-       chip->hostdevice->hwspecops->write_register(data, address_to_write);
+extern inline void canobj_write_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned char data, unsigned address)
+{
+       unsigned long address_to_write;
+       address_to_write = obj->obj_base_addr+address;
+       chip->write_register(data, address_to_write);
 }
 
-extern inline unsigned can_read_reg(const struct chip_t *chip, unsigned short address)
+extern inline unsigned canobj_read_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned address)
 {
-       unsigned short segment_number;
        unsigned long address_to_read;
+       address_to_read = obj->obj_base_addr+address;
+       return chip->read_register(address_to_read);
+}
 
-       address_to_read = chip->chip_base_addr+address;
+int can_base_addr_fixup(struct candevice_t *candev, unsigned long 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);
 
-       if ( (chip->flags & SEGMENTED) != 0) {
-               segment_number = (unsigned short)(address >> 6);
-               address_to_read += SPACING * segment_number;
-       }
-       return chip->hostdevice->hwspecops->read_register(address_to_read);
-}