/*
 * Nasty compatibility functions that don't need to go into the
 * mainline kernel.
 */

#include <linux/smp_lock.h>

#if ((LINUX_VERSION_CODE >= 0x2020f) && (LINUX_VERSION_CODE < 0x20300))
#define SERIAL_HAVE_POLL_WAIT
#endif

#if (LINUX_VERSION_CODE < 131343)  /* 2.1.15 -- XX get correct version */
#define __init
#endif

#if (LINUX_VERSION_CODE < 0x02030F) /*2.3.15-- XX get correct version  */
#define __exit
#endif
	
#if (LINUX_VERSION_CODE < 0x20000)
typedef dev_t kdev_t;
#endif

#if (LINUX_VERSION_CODE < 0x02017E)
static signed long schedule_timeout(signed long timeout)
{
	unsigned long expire;

	expire = timeout + jiffies;

	current->timeout = jiffies + timeout;
	schedule();

	timeout = expire - jiffies;
	return timeout < 0 ? 0 : timeout;
}
#endif

#ifndef time_after
#define time_after(a,b)		((long)(b) - (long)(a) < 0)
#endif

#if (LINUX_VERSION_CODE < 0x020100)
static inline int irq_cannonicalize(int irq)
{
	return ((irq == 2) ? 9 : irq);
}
#endif

#if (LINUX_VERSION_CODE < 131336)
static int copy_from_user(void *to, const void *from_user, unsigned long len)
{
	int	error;

	error = verify_area(VERIFY_READ, from_user, len);
	if (error)
		return len;
	memcpy_fromfs(to, from_user, len);
	return 0;
}

static int copy_to_user(void *to_user, const void *from, unsigned long len)
{
	int	error;
	
	error = verify_area(VERIFY_WRITE, to_user, len);
	if (error)
		return len;
	memcpy_tofs(to_user, from, len);
	return 0;
}

static inline int signal_pending(struct task_struct *p)
{
	return (p->signal & (~p->blocked != 0));
}

#endif

/* XXX This was added sometime between 2.2 and 2.3  When? */
#if (LINUX_VERSION_CODE < 0x020300)
static inline int pci_enable_device(struct pci_dev *dev)
{
	return 0;
}
#endif


#if (LINUX_VERSION_CODE < 131394) /* 2.1.66 */
#define test_and_clear_bit(x,y)		clear_bit(x,y)

static inline void remove_bh(int nr)
{
	bh_base[nr] = NULL;
	bh_mask &= ~(1 << nr);
}
#endif

#ifndef set_current_state
#define set_current_state(state_value)			\
	do { current->state = state_value; } while (0)
#endif

#ifndef DECLARE_WAITQUEUE
#define DECLARE_WAITQUEUE(wait, current) \
	struct wait_queue wait = { current, NULL }
#define init_waitqueue_head(head)	init_waitqueue(head)
#endif

#ifndef CAP_SYS_ADMIN
#define capable(x)	(suser())
#endif
	
#if (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
#define get_zeroed_page(x)	get_free_page(x)
#endif

/* Deal with the interface change in 2.3.23 */
#if defined(CONFIG_SERIAL_CONSOLE) && (LINUX_VERSION_CODE < 0x020317)
void __init serial_console_init_real(void);
long __init serial_console_init(long kmem_start, long kmem_end)
{
	serial_console_init_real();
	return kmem_start;
}

#define serial_console_init	serial_console_init_real

#endif

#ifndef pci_for_each_dev
#define pci_for_each_dev(dev) for (dev=pci_devices;dev;dev=dev->next)

/*
 * New kernels define dev->subsystem_vendor and dev->subsystem device,
 * which we don't have.  So we have to play some games...
 */
	static u16 compat__tmp;

#define pci_get_subvendor(dev) (pci_read_config_word(dev, \
		PCI_SUBSYSTEM_VENDOR_ID, &compat__tmp), compat__tmp)
#define pci_get_subdevice(dev) (pci_read_config_word(dev, \
		PCI_SUBSYSTEM_ID, &compat__tmp), compat__tmp)

#endif

#ifndef PCI_NUM_RESOURCES
#define IS_PCI_REGION_IOPORT(dev, r) (((dev)->base_address[(r)] & \
				       PCI_BASE_ADDRESS_SPACE))
#define pci_resource_start(dev, r) ((dev)->base_address[(r)] & \
	(IS_PCI_REGION_IOPORT(dev, r) ? PCI_BASE_ADDRESS_IO_MASK : \
	 PCI_BASE_ADDRESS_MEM_MASK))
/* Too hard to figure out, so we just return a minimum size. */
#define pci_resource_len(dev, r) 8
#endif	

#ifndef DEVICE_COUNT_IRQ
#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq)

/*
 * Old kernels don't have ISAPNP support, so they don't have
 * dev->prepare and dev->activate.  Compensate.
 */
#define PREPARE_FUNC(dev)  ((int (*)(struct pci_dev *)) 0)
#define ACTIVATE_FUNC(dev)  ((int (*)(struct pci_dev *)) 0)
#define DEACTIVATE_FUNC(dev)  ((int (*)(struct pci_dev *)) 0)

#endif

#if (LINUX_VERSION_CODE <= 0x2032D)
static void tty_register_devfs  (struct tty_driver *driver, unsigned int flags,
				 unsigned int minor)
{
	return;
}

static void tty_unregister_devfs (struct tty_driver *driver, unsigned minor)
{
	return;
}
#endif

#if (LINUX_VERSION_CODE < 0x020400)
static void del_timer_sync(struct timer_list * timer)
{
	lock_kernel();
	del_timer(timer);
	unlock_kernel();
}
#endif
	

/*
 * Compatibility with the new module_init() code
 */
#ifndef module_init
#ifdef MODULE
#define module_init(x)	int init_module(void) { return x(); }
#define module_exit(x)	void cleanup_module(void) { x(); }
#else
#define module_init(x)	/* nothing */
#define module_exit(x)	/* nothing */
#endif
#endif	/* module_init */


/* New termbits definitions */
#ifndef TIOCM_OUT1
#define TIOCM_OUT1	0x2000
#define TIOCM_OUT2	0x4000
#endif

#ifndef TIOCM_LOOP
#define TIOCM_LOOP	0x8000
#endif

#ifndef TTY_DRIVER_NO_DEVFS
#define TTY_DRIVER_NO_DEVFS 0
#endif

/* Define new-style CPU configs */
#if defined(__i386__) && defined(CPU)
#if CPU == 386 && !defined(CONFIG_M386)
#define CONFIG_M386
#endif
#if CPU == 486 && !defined(CONFIG_M486)
#define CONFIG_M486
#endif
#endif

/*
 * This fakes out compatibility with the new PCI interface
 */
#if (LINUX_VERSION_CODE < 0x020400)

#define __devinit
#define __devinitdata
#define MODULE_DEVICE_TABLE(x,y)	

struct pci_device_id {
	unsigned int vendor, device;	/* Vendor and device ID or PCI_ANY_ID */
	unsigned int subvendor, subdevice;/* Subsystem ID's or PCI_ANY_ID */
	unsigned int class, class_mask;	/* (class,subclass,prog-if) triplet */
	unsigned long driver_data;	/* Data private to the driver */
};
	
struct pci_driver {
	struct list_head node;
	char *name;
	const struct pci_device_id *id_table;	/* NULL if wants all devices */
	int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
	void (*remove)(struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
	void (*suspend)(struct pci_dev *dev);	/* Device suspended */
	void (*resume)(struct pci_dev *dev);	/* Device woken up */
};

static inline int pci_module_init(struct pci_driver *driver)
{
	struct pci_dev *dev = NULL;
	  
	pci_for_each_dev(dev) {
		driver->probe(dev, 0);
	}
	return 0;
}

static inline int pci_unregister_driver(struct pci_driver *driver)
{
	return 0;
}

#endif
	
	
/*
 * Some PCI identifiers which might not be in pci.h
 */

#ifndef PCI_VENDOR_ID_V3
#define PCI_VENDOR_ID_V3		0x11b0
#define PCI_DEVICE_ID_V3_V960		0x0001
#define PCI_DEVICE_ID_V3_V350		0x0001
#define PCI_DEVICE_ID_V3_V961		0x0002
#define PCI_DEVICE_ID_V3_V351		0x0002
#endif

#ifndef PCI_VENDOR_ID_SEALEVEL
#define PCI_VENDOR_ID_SEALEVEL		0x135e
#define PCI_DEVICE_ID_SEALEVEL_U530	0x7101
#define PCI_DEVICE_ID_SEALEVEL_UCOMM2	0x7201
#define PCI_DEVICE_ID_SEALEVEL_UCOMM422	0x7402
#define PCI_DEVICE_ID_SEALEVEL_UCOMM232	0x7202
#define PCI_DEVICE_ID_SEALEVEL_COMM4	0x7401
#define PCI_DEVICE_ID_SEALEVEL_COMM8	0x7801
#endif
	
#ifndef PCI_SUBVENDOR_ID_CONNECT_TECH
#define PCI_SUBVENDOR_ID_CONNECT_TECH			0x12c4
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232		0x0001
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232		0x0002
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232		0x0003
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485		0x0004
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4	0x0005
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485		0x0006
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2	0x0007
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485		0x0008
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6	0x0009
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1	0x000A
#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1	0x000B
#endif

#ifndef PCI_SUBVENDOR_ID_KEYSPAN
#define PCI_SUBVENDOR_ID_KEYSPAN 			0x11a9
#define PCI_SUBDEVICE_ID_KEYSPAN_SX2			0x5334
#endif

#ifndef PCI_DEVICE_ID_PLX_GTEK_SERIAL2
#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2	0xa001
#endif

#ifndef PCI_DEVICE_ID_PLX_SPCOM200
#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103
#endif
	
#ifndef PCI_DEVICE_ID_PLX_SPCOM800
#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076
#endif

#ifndef PCI_VENDOR_ID_PLX_ROMULUS
#define PCI_VENDOR_ID_PLX_ROMULUS	0x106a
#endif

#ifndef PCI_DEVICE_ID_PLX_SPCOM800
#define PCI_DEVICE_ID_PLX_SPCOM800	0x1076
#endif

#ifndef PCI_DEVICE_ID_PLX_1077
#define PCI_DEVICE_ID_PLX_1077		0x1077
#endif

#ifndef PCI_VENDOR_ID_TITAN
#define PCI_VENDOR_ID_TITAN		0x14D2
#define PCI_DEVICE_ID_TITAN_100		0xA001
#define PCI_DEVICE_ID_TITAN_200		0xA005
#define PCI_DEVICE_ID_TITAN_400		0xA003
#define PCI_DEVICE_ID_TITAN_800B	0xA004
#endif

#ifndef PCI_VENDOR_ID_PANACOM
#define PCI_VENDOR_ID_PANACOM             0x14d4
#define PCI_DEVICE_ID_PANACOM_QUADMODEM   0x0400
#define PCI_DEVICE_ID_PANACOM_DUALMODEM   0x0402
#endif

#ifndef PCI_SUBVENDOR_ID_CHASE_PCIFAST
#define PCI_SUBVENDOR_ID_CHASE_PCIFAST		0x12E0
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4		0x0031
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8		0x0021
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16	0x0011
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC	0x0041
#define PCI_SUBVENDOR_ID_CHASE_PCIRAS		0x124D
#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4		0xF001
#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8		0xF010
#endif

#ifndef PCI_VENDOR_ID_QUATECH
#define PCI_VENDOR_ID_QUATECH		0x135C
#define PCI_DEVICE_ID_QUATECH_QSC100	0x0010
#define PCI_DEVICE_ID_QUATECH_DSC100	0x0020
#define PCI_DEVICE_ID_QUATECH_DSC200	0x0030
#define PCI_DEVICE_ID_QUATECH_QSC200	0x0040
#define PCI_DEVICE_ID_QUATECH_ESC100D	0x0050
#define PCI_DEVICE_ID_QUATECH_ESC100M	0x0060
#endif

#ifndef PCI_VENDOR_ID_ROCKWELL
#define PCI_VENDOR_ID_ROCKWELL		0x127A
#endif

#ifndef PCI_VENDOR_ID_USR
#define PCI_VENDOR_ID_USR		0x12B9
#endif

#ifndef PCI_SUBDEVICE_ID_SPECIALIX_SPEED4
#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
#endif

#ifndef PCI_VENDOR_ID_OXSEMI
#define PCI_VENDOR_ID_OXSEMI            0x1415
#define PCI_DEVICE_ID_OXSEMI_16PCI954   0x9501
#endif

#ifndef PCI_DEVICE_ID_OXSEMI_16PCI952
#define PCI_DEVICE_ID_OXSEMI_16PCI952	0x950A
#define PCI_DEVICE_ID_OXSEMI_16PCI95N	0x9511
#endif

#ifndef PCI_VENDOR_ID_LAVA
#define PCI_VENDOR_ID_LAVA		0x1407
#endif

#ifndef PCI_DEVICE_ID_LAVA_DSERIAL
#define PCI_DEVICE_ID_LAVA_DSERIAL	0x0100 /* 2x 16550 */
#define PCI_DEVICE_ID_LAVA_QUATRO_A	0x0101 /* 2x 16550, half of 4 port */
#define PCI_DEVICE_ID_LAVA_QUATRO_B	0x0102 /* 2x 16550, half of 4 port */
#define PCI_DEVICE_ID_LAVA_PORT_PLUS	0x0200 /* 2x 16650 */
#define PCI_DEVICE_ID_LAVA_QUAD_A	0x0201 /* 2x 16650, half of 4 port */
#define PCI_DEVICE_ID_LAVA_QUAD_B	0x0202 /* 2x 16650, half of 4 port */
#define PCI_DEVICE_ID_LAVA_SSERIAL	0x0500 /* 1x 16550 */
#define PCI_DEVICE_ID_LAVA_PORT_650	0x0600 /* 1x 16650 */
#endif
	
#ifndef PCI_VENDOR_ID_TIMEDIA
#define PCI_VENDOR_ID_TIMEDIA		0x1409
#define PCI_DEVICE_ID_TIMEDIA_1889	0x7168
#endif 

#ifndef PCI_VENDOR_ID_SIIG
#define PCI_VENDOR_ID_SIIG		0x131f
#endif

#ifndef PCI_DEVICE_ID_SIIG_1S_10x_550
#define PCI_DEVICE_ID_SIIG_1S_10x_550  0x1000
#define PCI_DEVICE_ID_SIIG_1S_10x_650  0x1001
#define PCI_DEVICE_ID_SIIG_1S_10x_850  0x1002
#define PCI_DEVICE_ID_SIIG_2S_10x_550  0x1030
#define PCI_DEVICE_ID_SIIG_2S_10x_650  0x1031
#define PCI_DEVICE_ID_SIIG_2S_10x_850  0x1032
#define PCI_DEVICE_ID_SIIG_4S_10x_550  0x1050
#define PCI_DEVICE_ID_SIIG_4S_10x_650  0x1051
#define PCI_DEVICE_ID_SIIG_4S_10x_850  0x1052
#define PCI_DEVICE_ID_SIIG_1S_20x_550  0x2000
#define PCI_DEVICE_ID_SIIG_1S_20x_650  0x2001
#define PCI_DEVICE_ID_SIIG_1S_20x_850  0x2002
#define PCI_DEVICE_ID_SIIG_2S_20x_550  0x2030
#define PCI_DEVICE_ID_SIIG_2S_20x_650  0x2031
#define PCI_DEVICE_ID_SIIG_2S_20x_850  0x2032
#define PCI_DEVICE_ID_SIIG_4S_20x_550  0x2050
#define PCI_DEVICE_ID_SIIG_4S_20x_650  0x2051
#define PCI_DEVICE_ID_SIIG_4S_20x_850  0x2052
#define PCI_DEVICE_ID_SIIG_1S1P_10x_550	0x1010
#define PCI_DEVICE_ID_SIIG_1S1P_10x_650	0x1011
#define PCI_DEVICE_ID_SIIG_1S1P_10x_850	0x1012
#define PCI_DEVICE_ID_SIIG_2S1P_10x_550	0x1034
#define PCI_DEVICE_ID_SIIG_2S1P_10x_650	0x1035
#define PCI_DEVICE_ID_SIIG_2S1P_10x_850	0x1036
#define PCI_DEVICE_ID_SIIG_2P1S_20x_550	0x2040
#define PCI_DEVICE_ID_SIIG_2P1S_20x_650	0x2041
#define PCI_DEVICE_ID_SIIG_2P1S_20x_850	0x2042
#define PCI_DEVICE_ID_SIIG_1S1P_20x_550	0x2010
#define PCI_DEVICE_ID_SIIG_1S1P_20x_650	0x2011
#define PCI_DEVICE_ID_SIIG_1S1P_20x_850	0x2012
#define PCI_DEVICE_ID_SIIG_2S1P_20x_550	0x2060
#define PCI_DEVICE_ID_SIIG_2S1P_20x_650	0x2061
#define PCI_DEVICE_ID_SIIG_2S1P_20x_850	0x2062
#endif

#ifndef PCI_VENDOR_ID_COMPUTONE
#define PCI_VENDOR_ID_COMPUTONE			0x8e0e
#endif

#ifndef PCI_DEVICE_ID_COMPUTONE_PG
#define PCI_DEVICE_ID_COMPUTONE_PG		0x0302
#define PCI_SUBVENDOR_ID_COMPUTONE		0x8e0e
#define PCI_SUBDEVICE_ID_COMPUTONE_PG4	0x0001
#define PCI_SUBDEVICE_ID_COMPUTONE_PG8	0x0002
#define PCI_SUBDEVICE_ID_COMPUTONE_PG6	0x0003
#endif

#ifndef PCI_DEVICE_ID_ATT_VENUS_MODEM
#define PCI_DEVICE_ID_ATT_VENUS_MODEM	0x480
#endif

#ifndef PCI_VENDOR_ID_MORETON
#define PCI_VENDOR_ID_MORETON		0x15aa
#define PCI_DEVICE_ID_RASTEL_2PORT	0x2000
#endif

#ifndef PCI_DEVICE_ID_DCI_PCCOM8
#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002
#endif

#ifndef PCI_VENDOR_ID_SGI
#define PCI_VENDOR_ID_SGI		0x10a9
#define PCI_DEVICE_ID_SGI_IOC3		0x0003
#endif
