/*
 * cistpl.h v1.13: 1995/04/20 20:47:07 (David Hinds)
 */

#ifndef _LINUX_CISTPL_H
#define _LINUX_CISTPL_H

#define CISTPL_NULL		0x00
#define CISTPL_DEVICE		0x01
#define CISTPL_CHECKSUM		0x10
#define CISTPL_LONGLINK_A	0x11
#define CISTPL_LONGLINK_C	0x12
#define CISTPL_LINKTARGET	0x13
#define CISTPL_NO_LINK		0x14
#define CISTPL_VERS_1		0x15
#define CISTPL_ALTSTR		0x16
#define CISTPL_DEVICE_A		0x17
#define CISTPL_JEDEC_C		0x18
#define CISTPL_JEDEC_A		0x19
#define CISTPL_CONFIG		0x1a
#define CISTPL_CFTABLE_ENTRY	0x1b
#define CISTPL_DEVICE_OC	0x1c
#define CISTPL_DEVICE_OA	0x1d
#define CISTPL_DEVICE_GEO	0x1e
#define CISTPL_DEVICE_GEO_A	0x1f
#define CISTPL_MANFID		0x20
#define CISTPL_FUNCID		0x21
#define CISTPL_FUNCE		0x22
#define CISTPL_SWIL		0x23
#define CISTPL_END		0xff
/* Layer 2 tuples */
#define CISTPL_VERS_2		0x40
#define CISTPL_FORMAT		0x41
#define CISTPL_GEOMETRY		0x42
#define CISTPL_BYTEORDER	0x43
#define CISTPL_DATE		0x44
#define CISTPL_BATTERY		0x45
/* Layer 3 tuples */
#define CISTPL_ORG		0x46

typedef struct cistpl_longlink_t {
    u_long	addr;
} cistpl_longlink_t;

typedef struct cistpl_checksum_t {
    u_short	addr;
    u_short	len;
    u_char	sum;
} cistpl_checksum_t;

#define CISTPL_MAX_ALTSTR_STRINGS	4

typedef struct cistpl_altstr_t {
    int		ns;
    int		ofs[CISTPL_MAX_ALTSTR_STRINGS];
    char	str[254];
} cistpl_altstr_t;

#define CISTPL_DTYPE_NULL	0x00
#define CISTPL_DTYPE_ROM	0x01
#define CISTPL_DTYPE_OTPROM	0x02
#define CISTPL_DTYPE_EPROM	0x03
#define CISTPL_DTYPE_EEPROM	0x04
#define CISTPL_DTYPE_FLASH	0x05
#define CISTPL_DTYPE_SRAM	0x06
#define CISTPL_DTYPE_DRAM	0x07
#define CISTPL_DTYPE_FUNCSPEC	0x0d
#define CISTPL_DTYPE_EXTEND	0x0e

#define CISTPL_MAX_DEVICES	4

typedef struct cistpl_device_t {
    int		ndev;
    struct device_info {
	u_char 	type;
	u_char	wp;
	u_long	speed;
	u_long	size;
    } dev[CISTPL_MAX_DEVICES];
} cistpl_device_t;

#define CISTPL_DEVICE_MWAIT	0x01
#define CISTPL_DEVICE_3VCC	0x02

typedef struct cistpl_device_o_t {
    u_char		flags;
    cistpl_device_t	device;
} cistpl_device_o_t;

#define CISTPL_VERS_1_MAX_PROD_STRINGS	4

typedef struct cistpl_vers_1_t {
    u_char	major;
    u_char	minor;
    int		ns;
    int		ofs[CISTPL_VERS_1_MAX_PROD_STRINGS];
    char	str[254];
} cistpl_vers_1_t;

typedef struct cistpl_jedec_t {
    int		nid;
    struct jedec_id {
	u_char	mfr;
	u_char	info;
    } id[CISTPL_MAX_DEVICES];
} cistpl_jedec_t;

typedef struct cistpl_manfid_t {
    u_short	manf;
    u_short	card;
} cistpl_manfid_t;

#define CISTPL_FUNCID_MULTI	0x00
#define CISTPL_FUNCID_MEMORY	0x01
#define CISTPL_FUNCID_SERIAL	0x02
#define CISTPL_FUNCID_PARALLEL	0x03
#define CISTPL_FUNCID_FIXED	0x04
#define CISTPL_FUNCID_VIDEO	0x05
#define CISTPL_FUNCID_NETWORK	0x06
#define CISTPL_FUNCID_AIMS	0x07

#define CISTPL_SYSINIT_POST	0x01
#define CISTPL_SYSINIT_ROM	0x02

typedef struct cistpl_funcid_t {
    u_char	func;
    u_char	sysinit;
} cistpl_funcid_t;

typedef struct cistpl_config_t {
    u_char	last_idx;
    u_long	base;
    u_long	rmask[4];
    u_char	subtuples;
} cistpl_config_t;

/* These are bits in the 'present' field, and indices in 'param' */
#define CISTPL_POWER_VNOM	0
#define CISTPL_POWER_VMIN	1
#define CISTPL_POWER_VMAX	2
#define CISTPL_POWER_ISTATIC	3
#define CISTPL_POWER_IAVG	4
#define CISTPL_POWER_IPEAK	5
#define CISTPL_POWER_IDOWN	6

#define CISTPL_POWER_HIGHZ_OK	0x01
#define CISTPL_POWER_HIGHZ_REQ	0x02

typedef struct cistpl_power_t {
    u_char	present;
    u_char	flags;
    u_long	param[7];
} cistpl_power_t;

typedef struct cistpl_timing_t {
    u_long	wait, waitscale;
    u_long	ready, rdyscale;
    u_long	reserved, rsvscale;
} cistpl_timing_t;

#define CISTPL_IO_LINES_MASK	0x1f
#define CISTPL_IO_8BIT		0x20
#define CISTPL_IO_16BIT		0x40
#define CISTPL_IO_RANGE		0x80

#define CISTPL_IO_MAX_WIN	16

typedef struct cistpl_io_t {
    u_char	flags;
    int		nwin;
    struct {
	u_long	base;
	u_long	len;
    } win[CISTPL_IO_MAX_WIN];
} cistpl_io_t;

typedef struct cistpl_irq_t {
    u_long	IRQInfo1;
    u_long	IRQInfo2;
} cistpl_irq_t;

#define CISTPL_MEM_MAX_WIN	8

typedef struct cistpl_mem_t {
    u_char	flags;
    u_char	nwin;
    struct {
	u_long	len;
	u_long	card_addr;
	caddr_t	host_addr;
    } win[CISTPL_MEM_MAX_WIN];
} cistpl_mem_t;

#define CISTPL_CFTABLE_DEFAULT		0x01
#define CISTPL_CFTABLE_BVDS		0x02
#define CISTPL_CFTABLE_WP		0x04
#define CISTPL_CFTABLE_RDYBSY		0x08
#define CISTPL_CFTABLE_MWAIT		0x10
#define CISTPL_CFTABLE_AUDIO		0x20
#define CISTPL_CFTABLE_READONLY		0x40
#define CISTPL_CFTABLE_PWRDOWN		0x80

typedef struct cistpl_cftable_entry_t {
    u_char		index;
    u_char		flags;
    u_char		interface;
    cistpl_power_t	vcc, vpp1, vpp2;
    cistpl_timing_t	timing;
    cistpl_io_t		io;
    cistpl_irq_t	irq;
    cistpl_mem_t	mem;
    u_char		subtuples;
} cistpl_cftable_entry_t;

typedef struct cistpl_device_geo_t {
    int		ngeo;
    struct geo {
	u_char		buswidth;
	u_long		erase_block;
	u_long		read_block;
	u_long		write_block;
	u_long		partition;
	u_long		interleave;
    } geo[CISTPL_MAX_DEVICES];
} cistpl_device_geo_t;

typedef struct cistpl_vers_2_t {
    u_char	vers;
    u_char	comply;
    u_short	dindex;
    u_char	vspec8, vspec9;
    u_char	nhdr;
    int		vendor, info;
    char	str[244];
} cistpl_vers_2_t;

typedef struct cistpl_org_t {
    u_char	data_org;
    char	desc[30];
} cistpl_org_t;

#define CISTPL_ORG_FS		0x00
#define CISTPL_ORG_APPSPEC	0x01
#define CISTPL_ORG_XIP		0x02

typedef union cisparse_t {
    cistpl_device_t		device;
    cistpl_checksum_t		checksum;
    cistpl_longlink_t		longlink;
    cistpl_vers_1_t		version_1;
    cistpl_altstr_t		altstr;
    cistpl_jedec_t		jedec;
    cistpl_manfid_t		manfid;
    cistpl_funcid_t		funcid;
    cistpl_config_t		config;
    cistpl_cftable_entry_t	cftable_entry;
    cistpl_device_geo_t		device_geo;
    cistpl_vers_2_t		vers_2;
    cistpl_org_t		org;
} cisparse_t;

typedef struct tuple_t {
    u_long	Attributes;
    cisdata_t 	DesiredTuple;
    u_long	Flags;		/* internal use */
    u_long	LinkOffset;	/* internal use */
    u_long	CISOffset;	/* internal use */
    cisdata_t	TupleCode;
    cisdata_t	TupleLink;
    cisdata_t	TupleOffset;
    cisdata_t	TupleDataMax;
    cisdata_t	TupleDataLen;
    cisdata_t	*TupleData;
} tuple_t;

/* Special cisdata_t value */
#define RETURN_FIRST_TUPLE	0xff

/* Attributes for tuple calls */
#define TUPLE_RETURN_LINK	0x01

/* For ValidateCIS */
typedef struct cisinfo_t {
    u_long	Chains;
} cisinfo_t;

#ifdef IN_CARD_SERVICES

void read_cis_mem(socket_info_t *s, int attr,
		  long addr, long len, u_char *ptr);
void write_cis_mem(socket_info_t *s, int attr,
		   long addr, long len, u_char *ptr);
int setup_cis_mem(socket_info_t *s);

int get_first_tuple(client_handle_t handle, tuple_t *tuple);
int get_next_tuple(client_handle_t handle, tuple_t *tuple);
int get_tuple_data(client_handle_t handle, tuple_t *tuple);
int parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse);
int validate_cis(client_handle_t handle, cisinfo_t *info);

#endif /* IN_CARD_SERVICES */

#endif /* LINUX_CISTPL_H */
