X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/97078fff5202521b758c9081d75580880417a123..11132ea490f9e860744ee4f851c67e7fb4444231:/lincan/include/main.h diff --git a/lincan/include/main.h b/lincan/include/main.h index c811d87..81f1818 100644 --- a/lincan/include/main.h +++ b/lincan/include/main.h @@ -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 #include #include #include -#include +#include #include "./can.h" #include "./constants.h" +#include "./can_queue.h" #ifdef CAN_DEBUG #define DEBUGMSG(fmt,args...) printk(KERN_ERR "can.o (debug): " fmt,\ @@ -32,7 +36,12 @@ (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); -}