/* Copyright (c) 2002 - 2005 Promise Technology, Inc.  All rights reserved.
 *
 * pdc618_mod.h - defines data structures, constants and scsi template
 *
 */
#ifndef _PDC618_MOD_H
#define _PDC618_MOD_H

#include <linux/version.h>

#define PDCNAME "pdc-ultra"
#define PRODUCT "SATA150"
#define VERSION	"1.00.0.10"

#define MAXADAPTER  0x2

#define ChPAda      0x4
#define DrvPCh      0x2
#define MAXCHANNEL  MAXADAPTER*ChPAda
#define MAXDRIVE    MAXADAPTER*ChPAda*DrvPCh
#define MAXTIMER    MAXADAPTER*ChPAda*2

#define QLENGTH     64
#define MAXSGTABLE  32

#define DID318      0x3318
#define DID375      0x3375
#define DID378      0x3373
#define DID618      0x6626

#define Q_INITIAL   0x1
#define Q_STARTED   0x2
#define Q_POSTED    0x4
#define Q_PENDING   0x8
#define Q_COMPLETED 0x10
#define Q_FINISHED  0x20
#define Q_START_MASK (Q_STARTED | Q_POSTED | Q_PENDING | Q_COMPLETED | Q_FINISHED)

#define LOGATA      0x1
#define LOGATAPI    0x2

/* char device ioctl commands */
#define STIO_GET_ADAPTERCOUNT	0x00004001
#define STIO_GET_ADAPTERTYPE	0x00004002
#define STIO_GET_ADAPTERINFO	0x00004003
#define STIO_FIND_FLASHMEM	0x00004004
#define STIO_ERASE_FLASHMEM	0x00004005
#define STIO_READ_FLASHMEM	0x00004006
#define STIO_WRITE_FLASHMEM	0x00004007

unsigned short PDC618_DEVID[5] = { DID618, DID318, DID375, DID378, 0};

typedef struct _pdc618_adapter pdc618_adapter_t;
typedef struct _pdc618_channel pdc618_channel_t;
typedef struct _pdc618_drive pdc618_drive_t;
typedef struct _pdc618_timer pdc618_timer_t;
typedef struct _pdc618_req pdc618_req_t;
typedef struct _pdc618_info pdc618_info_t;

struct _pdc618_adapter {
	unsigned char 	id;				/* adapter #: 0 ~ 3 */
	unsigned char	present;			/* 1: present */
	unsigned short 	deviceid;			/* adapter deviceid */
	unsigned int 	irq;				/* interrupt */
	unsigned int	base[6];			/* base address */
	unsigned int	range[6];			/* base address range */
	unsigned int 	rombase;
	ADAPTER_CONFIG_INFO	*cam_ada;		/* cam adapter info */
	CAM_INFO	*cam_info;			/* cam info */
	spinlock_t	pdc618_lock;			/* spin lock */
	pdc618_channel_t	*pchannel[ChPAda];

	/* linux only */
	struct pci_dev	*pci_dev;			/* pci structure */
	struct Scsi_Host	*host;			/* scsi host */
} __attribute__ ((packed));

struct _pdc618_channel {
	pdc618_adapter_t	*padapter;
	unsigned char		id;			/* channel id */
	CHNL_CONFIG		*cam_chn;		/* cam channel info */
	pdc618_drive_t		*pdrive[DrvPCh];
} __attribute__ ((packed));

struct _pdc618_drive {
	pdc618_channel_t	*pchannel;
	/* CAM_IDENTIFY_DATA	identify;*/		/* hd identify */
	DEV_CONFIG		*cam_dev;		/* cam device info */
	unsigned char		retries;
} __attribute__ ((packed));

struct _pdc618_timer {					/* timer table */
	struct timer_list timer;			/* timer list */
	int id;
	unsigned char status;				/* timer status */
	void (*callback)(void);				/* my timer callback */
	struct _pdc618_timer *next;
} __attribute__ ((packed));

struct _pdc618_req {
	ATA_TASK cam_task;				/* submit to cam */
	ATA_TASK cam_task2;				/* backup cam_task */
	CAMSG  	 cam_sg[MAXSGTABLE];			/* cam sg table */
	void	 *cmd;					/* for SCpnt */
	unsigned char *buffer;				/* for atapi */
	int	 buffer_size;				/* for atapi */
	int	 stat;
	int	 id;
	struct _pdc618_req *next;
} __attribute__ ((packed));

struct _pdc618_info {					/* proc info */
	char	*buffer;
	int	length;
	int	offset;
	int	position;
} __attribute__ ((packed));

/* structure for char ioctl args */
typedef enum _hardwaretype {
	SATA150 = 0,			/* SATA150 series */
	ULTRA618,			/* ULTRA 618 */
	SATA375,			/* SATA150 TX2plus */
	SATA318,			/* SATA150 TX4 */
	SATA378				/* SATA 378 */
} hardwaretype;

typedef struct _tag_adaptercount {
	unsigned char adaptercount;	/* total adapter count */
} tag_adaptercount_t;

typedef struct _tag_adaptertype {
	unsigned char adapter;		/* adapter index */
	hardwaretype adaptertype;	/* adapter type */
} tag_adaptertype_t;

typedef struct _tag_adapterinfo {
	unsigned char adapter;		/* adapter index */
	unsigned short deviceid;	/* adapter device id */
} tag_adapterinfo_t;

/* flash operation */
typedef struct _tag_flash {
	unsigned char adapter;		/* adapter index */
	unsigned long offset;		/* mem offset */
	unsigned long buffer_size;	/* buffer size of buffer */
	unsigned char *buffer;		/* data buffer */
} tag_flash_t;

#define pdc618 {						\
	next: NULL,						\
	proc_info: pdc618_proc_info,				\
	name: PDCNAME,						\
	detect: pdc618_detect,					\
	release: pdc618_release,				\
	ioctl: pdc618_ioctl,					\
	info: NULL,						\
	command: NULL,						\
	queuecommand: pdc618_queuecommand,			\
	abort: pdc618_scsi_abort,				\
	reset: pdc618_scsi_reset,				\
	eh_abort_handler: pdc618_scsi_eh_abort,			\
	eh_device_reset_handler: pdc618_scsi_eh_device_reset,	\
	eh_host_reset_handler: pdc618_scsi_eh_host_reset,	\
	slave_attach: NULL,					\
	bios_param: pdc618_bios_param,				\
	can_queue: QLENGTH,					\
	this_id: -1,						\
	sg_tablesize: MAXSGTABLE,				\
	cmd_per_lun: 1,						\
	present: 0,						\
	unchecked_isa_dma: 0,					\
	use_clustering: DISABLE_CLUSTERING,			\
	use_new_eh_code: 0,					\
	emulated: 1						\
}

#endif /* end of _PDC618_MOD_H */
