]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/include/main.h
First part of IRQ handling changes
[lincan.git] / lincan / include / main.h
index b4a0b32a7eb29cf395e357d822fc1f9bb17a17fe..3af24c62bf32ba577ea53235e78d54ca07128779 100644 (file)
@@ -4,7 +4,7 @@
  * 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.2  9 Jul 2003
+ * Version lincan-0.3  17 Jun 2004
  */
 
 #include "./can.h"
@@ -53,6 +53,8 @@ struct canhardware_t {
  * @chip: array of pointers to the chip structures
  * @hwspecops: pointer to board specific operations
  * @hosthardware_p: pointer to the root hardware structure
+ * @sysdevptr: union reserved for pointer to bus specific
+ *     device structure (case @pcidev is used for PCI devices)
  *
  * The structure represent configuration and state of associated board.
  * The driver infrastructure prepares this structure and calls
@@ -85,6 +87,7 @@ struct candevice_t {
        struct canhardware_t *hosthardware_p;
        
        union {
+               void *anydev;
            #ifdef CAN_ENABLE_PCI_SUPPORT
                struct pci_dev *pcidev;
            #endif /*CAN_ENABLE_PCI_SUPPORT*/
@@ -102,8 +105,9 @@ struct candevice_t {
  *     %CHIP_SEGMENTED .. access to the chip is segmented (mainly for i82527 chips)
  * @clock: chip base clock frequency in Hz
  * @baudrate: selected chip baudrate in Hz
- * @write_register: write chip register function copy -
+ * @write_register: write chip register function copy
  * @read_register: read chip register function copy
+ * @chip_data: pointer for optional chip specific data extension
  * @sja_cdr_reg: SJA specific register -
  *     holds hardware specific options for the Clock Divider
  *     register. Options defined in the sja1000.h file:
@@ -129,6 +133,15 @@ struct candevice_t {
  * @chipspecops: pointer to the set of chip specific object filled by init_chip_data() function
  * @hostdevice: pointer to chip hosting board
  * @max_objects: maximal number of communication objects connected to this chip
+ * @chip_lock: reserved for synchronization of the chip supporting routines
+ *     (not used in the current driver version)
+ * @worker_thread: chip worker thread ID (RT-Linux specific field)
+ * @pend_flags: holds information about pending interrupt and tx_wake() operations
+ *     (RT-Linux specific field). Masks values:
+ *     %MSGOBJ_TX_REQUEST .. some of the message objects requires tx_wake() call, 
+ *     %MSGOBJ_IRQ_REQUEST .. chip interrupt processing required
+ *     %MSGOBJ_WORKER_WAKE .. marks, that worker thread should be waked
+ *             for some of above reasons
  *
  * The fields @write_register and @read_register are copied from
  * corresponding fields from @hwspecops structure
@@ -145,9 +158,11 @@ struct chip_t {
        long clock; /* Chip clock in Hz */
        long baudrate;
 
-       void (*write_register)(unsigned char data,unsigned long address);
+       void (*write_register)(unsigned data,unsigned long address);
        unsigned (*read_register)(unsigned long address);
-
+       
+       void *chip_data;
+       
        unsigned short sja_cdr_reg; /* sja1000 only! */
        unsigned short sja_ocr_reg; /* sja1000 only! */
        unsigned short int_cpu_reg; /* intel 82527 only! */
@@ -190,6 +205,12 @@ struct chip_t {
  * @obj_used: counter of users (associated file structures for Linux
  *     userspace clients) of this object
  * @obj_users: list of user structures of type &canuser_t.
+ * @obj_flags: message object specific flags. Masks values:
+ *     %MSGOBJ_TX_REQUEST .. the message object requests TX activation
+ *     %MSGOBJ_TX_LOCK .. some IRQ routine or callback on some CPU 
+ *             is running inside TX activation processing code
+ * @rx_preconfig_id: place to store RX message identifier for some chip types
+ *              that reuse same object for TX
  */
 struct msgobj_t {
        unsigned long obj_base_addr;
@@ -208,6 +229,8 @@ struct msgobj_t {
        struct canmsg_t rx_msg;
 
        struct chip_t *hostchip;
+       unsigned long rx_preconfig_id;
 
        atomic_t obj_used;
        struct list_head obj_users;
@@ -274,7 +297,7 @@ struct hwspecops_t {
        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);
+       void (*write_register)(unsigned data,unsigned long address);
        unsigned (*read_register)(unsigned long address);
 };
 
@@ -293,6 +316,7 @@ struct hwspecops_t {
  * @remote_request: configures message object and asks for RTR message
  * @check_tx_stat: checks state of transmission engine
  * @wakeup_tx: wakeup TX processing
+ * @filtch_rq: optional routine for propagation of outgoing edges filters to HW
  * @enable_configuration: enable chip configuration mode
  * @disable_configuration: disable chip configuration mode
  * @set_btregs: configures bitrate registers
@@ -320,13 +344,14 @@ struct chipspecops_t {
        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 (*filtch_rq)(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);
-       can_irqreturn_t (*irq_handler)(int irq, void *dev_id, struct pt_regs *regs);
+       int (*irq_handler)(int irq, struct chip_t *chip);
 };
 
 struct mem_addr {
@@ -358,6 +383,52 @@ extern struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];
 
 extern struct mem_addr *mem_head;
 
+
+#if defined(CONFIG_OC_LINCAN_PORTIO_ONLY)
+extern inline void can_write_reg(const struct chip_t *chip, unsigned char data, unsigned address)
+{
+       outb(data, chip->chip_base_addr+address);
+}
+extern inline unsigned can_read_reg(const struct chip_t *chip, unsigned address)
+{
+       return inb(chip->chip_base_addr+address);
+}
+extern inline void canobj_write_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned char data, unsigned address)
+{
+       outb(data, obj->obj_base_addr+address);
+}
+extern inline unsigned canobj_read_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned address)
+{
+       return inb(obj->obj_base_addr+address);
+}
+
+#elif defined(CONFIG_OC_LINCAN_MEMIO_ONLY)
+extern inline void can_write_reg(const struct chip_t *chip, unsigned char data, unsigned address)
+{
+       writeb(data, chip->chip_base_addr+address);
+}
+extern inline unsigned can_read_reg(const struct chip_t *chip, unsigned address)
+{
+       return readb(chip->chip_base_addr+address);
+}
+extern inline void canobj_write_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned char data, unsigned address)
+{
+       writeb(data, obj->obj_base_addr+address);
+}
+extern inline unsigned canobj_read_reg(const struct chip_t *chip, const struct msgobj_t *obj,
+                               unsigned address)
+{
+       return readb(obj->obj_base_addr+address);
+}
+
+#else /*CONFIG_OC_LINCAN_DYNAMICIO*/
+#ifndef CONFIG_OC_LINCAN_DYNAMICIO
+#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.
  */
@@ -391,6 +462,8 @@ extern inline unsigned canobj_read_reg(const struct chip_t *chip, const struct m
        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_request_io_region(unsigned long start, unsigned long n, const char *name);
 void can_release_io_region(unsigned long start, unsigned long n);
@@ -405,6 +478,28 @@ struct boardtype_t {
 
 const struct boardtype_t* boardtype_find(const char *str);
 
+int can_check_dev_taken(void *anydev);
+
+#if defined(can_gettimeofday) && defined(CAN_MSG_VERSION_2) && 1
+static inline
+void can_filltimestamp(canmsg_tstamp_t *ptimestamp)
+{
+       can_gettimeofday(ptimestamp);
+}
+#else /* No timestamp support, set field to zero */
+static inline
+void can_filltimestamp(canmsg_tstamp_t *ptimestamp)
+{
+    #ifdef CAN_MSG_VERSION_2
+       ptimestamp->tv_sec = 0;
+       ptimestamp->tv_usec = 0;
+    #else /* CAN_MSG_VERSION_2 */
+       *ptimestamp = 0;
+    #endif /* CAN_MSG_VERSION_2 */
+
+}
+#endif /* End of timestamp source selection */
+
 #ifdef CAN_WITH_RTL
 extern int can_rtl_priority;
 #endif /*CAN_WITH_RTL*/