www.pudn.com > 422.rar > main.h


/* main.h
 * Header file for the Linux serial-bus driver.
 * Written by wang songyue--bupt   email: wsy5228@sina.com
 * This software is released under the GPL-License.
 * Version 0.1  28 oct 2005
 */

#include 
#include 
#include 
#include 
#include "./serial.h"
#include "./constants.h"

#ifdef CAN_DEBUG
	#define DEBUGMSG(fmt,args...) printk(KERN_ERR "serial.o: " fmt,##args)
#else
	#define DEBUGMSG(fmt,args...)
#endif

#define CANMSG(fmt,args...) printk(KERN_ERR "serial.o: " fmt,##args)

#define MINOR_NR \
	(MINOR(file->f_dentry->d_inode->i_rdev))

#define MSG_OFFSET(object) ((object)*0x10)

unsigned int tts_io_addr;

struct canhardware_t {
	int nr_boards;
	struct rtr_id *rtr_queue;
	spinlock_t rtr_lock;
	struct candevice_t *candevice[MAX_HW_CARDS];
};

struct candevice_t {
	char *hwname;
	unsigned long io_addr;
	unsigned long res_addr;
	unsigned int flags;

	/* Hardware chip configuration. In case of multiple chips *chip
	 * is the first in an array of chip_t structures.
	 */
	//int nr_82527_chips;
	int nr_16c554_chips;
	struct chip_t *chip[MAX_HW_CHIPS];

	struct hwspecops_t *hwspecops;

	struct canhardware_t *hosthardware_p;
};

struct chip_t {
	char *chip_type;
	int chip_irq;
	unsigned long chip_base_addr;
	unsigned int flags;
	int clock; // Chip clock in Hz

	/* 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
	 *
	 * sja_ocr_reg holds hardware specific options for the Output Control
	 * register. Options defined in the sja1000.h file:
	 * OCR_MODE_BIPHASE, OCR_MODE_TEST, OCR_MODE_NORMAL, OCR_MODE_CLOCK,
	 * OCR_TX0_LH, OCR_TX1_ZZ.
	 *
	 * 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.
	 *
	 * 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.
	 *
	 * 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.
	 */
	unsigned short c554_ier_reg; // 16c554 only!
	unsigned short c554_fcr_reg; // 16c554  only!
//	unsigned short int_cpu_reg; // intel 82527 only!
//	unsigned short int_clk_reg; // intel 82527 only!
//	unsigned short int_bus_reg; // intel 82527 only!

	struct msgobj_t *msgobj[MAX_MSGOBJS];

	struct chipspecops_t *chipspecops;

	struct candevice_t *hostdevice;
};

struct msgobj_t {
	unsigned long obj_base_addr;
	unsigned int minor;
	unsigned int object;
	unsigned int flags; 
	int ret;

	struct canfifo_t *fifo;

	struct chip_t *hostchip;
};

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);
	void (*write_register)(unsigned char data,unsigned long address);
	unsigned (*read_register)(unsigned long address);
	int (*program_irq)(int card);
};

struct chipspecops_t {
	int (*chip_config)(struct chip_t *chip);
	int (*baud_rate)(struct chip_t *chip, int rate, int clock, int sjw,
						int sampl_pt, int flags);
	int (*standard_mask)(struct chip_t *chip, unsigned short code, 
							unsigned short mask);
	int (*extended_mask)(struct chip_t *chip, unsigned long code, 
							unsigned long mask);
	int (*message15_mask)(struct chip_t *chip, unsigned long code, 
							unsigned long mask);
	int (*clear_objects)(struct chip_t *chip);
	int (*config_irqs)(struct chip_t *chip, short irqs);
	int (*pre_read_config)(struct chip_t *chip, struct msgobj_t *obj);
	int (*pre_write_config)(struct chip_t *chip, struct msgobj_t *obj,
							struct serialmsg_t *msg);
	int (*send_msg)(struct chip_t *chip, struct msgobj_t *obj,
							struct serialmsg_t *msg);
	int (*remote_request)(struct chip_t *chip, struct msgobj_t *obj);
	int (*check_tx_stat)(struct chip_t *chip);
	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);
};

struct mem_addr {
	void *address;
	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,2,19))
struct canfifo_t {
	struct wait_queue *readq, *writeq; 
	struct serialmsg_t *buf_tx_entry;
	struct serialmsg_t *buf_rx_entry; 
	struct serialmsg_t *tx_readp;
	struct serialmsg_t *rx_writep;
	struct serialmsg_t *tx_writep;
	struct serialmsg_t *rx_readp;
	int rx_size, tx_size;
	volatile int rx_in_progress, tx_in_progress;
	int head, tail; //TEMP!!!
};
#else
struct canfifo_t {
	struct __wait_queue_head readq;
	struct __wait_queue_head writeq;
	struct serialmsg_t *buf_tx_entry;
	struct serialmsg_t *buf_rx_entry; 
	struct serialmsg_t *tx_readp;
	struct serialmsg_t *rx_writep;
	struct serialmsg_t *tx_writep;
	struct serialmsg_t *rx_readp;
	int rx_size, tx_size;
	volatile int rx_in_progress, tx_in_progress;
	int head, tail; //TEMP!!!
};
#endif

/* Structure for the RTR queue */
struct rtr_id {
	unsigned long id;
	struct serialmsg_t *rtr_message;
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))
	struct wait_queue *rtr_wq;
#else
	struct __wait_queue_head rtr_wq;
#endif
	struct rtr_id *next;
};

extern int major;
extern int minor[MAX_TOT_CHIPS];
extern int extended;
extern int baudrate;
extern char *hw[MAX_HW_CARDS];
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];

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 serial_write_reg(struct chip_t *chip, unsigned char data, unsigned short address)
{
	unsigned short segment_number;
	unsigned long address_to_write;

	address_to_write = address;

	if ( (chip->flags & SEGMENTED) != 0) {
		segment_number = (unsigned short)(address >> 6);
		address_to_write += SPACING * segment_number;
	}

	chip->hostdevice->hwspecops->write_register(data, address_to_write);

}

extern inline unsigned serial_read_reg(struct chip_t *chip, unsigned short address)
{
	unsigned short segment_number;
	unsigned long address_to_read;

	address_to_read = address;

	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);
}