www.pudn.com > libscsi.rar > libscsi.h



/*
 *Mega SCSI IOCTL Parameter and Structure Definition
 */

#ifndef _LIB_MEGA_SCSI_H_
#define _LIB_MEGA_SCSI_H_
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "m_defs.h"
#include "scsiio.h"
#include "scsi_all.h"
#include "scsi_disk.h"
#include "raid.h"

/*
 * Mega SCSI Low Level Parameter and Structure Definition
 */

/*
 * Commands and states for mailbox based controllers
 */

#define FC_NEW_CONFIG		0xA1
#define NC_SUBOP_PRODUCT_INFO	0x0E
#define NC_SUBOP_ENQUIRY3	0x0F
#define ENQ3_GET_SOLICITED_FULL	0x02
#define OP_DCMD_READ_CONFIG	0x04
#define NEW_READ_CONFIG_8LD	0x67
#define READ_CONFIG_8LD		0x07


/*
 * Command for random deletion of logical drives
 */
#define	FC_DEL_LOGDRV		0xA4

/*
 * BIOS commands
 */
#define IS_BIOS_ENABLED		0x62
#define GET_BIOS		0x01
#define CHNL_CLASS		0xA9
#define GET_CHNL_CLASS		0x00
#define SET_CHNL_CLASS		0x01
#define CH_RAID			0x01
#define CH_SCSI			0x00
#define BIOS_PVT_DATA		0x40
#define GET_BIOS_PVT_DATA	0x00

/*
 * Module battery status
 */
#define BATTERY_MODULE_MISSING		0x01
#define BATTERY_LOW_VOLTAGE		0x02
#define BATTERY_TEMP_HIGH		0x04
#define BATTERY_PACK_MISSING		0x08
#define BATTERY_CHARGE_MASK		0x30
#define BATTERY_CHARGE_DONE		0x00
#define BATTERY_CHARGE_INPROG		0x10
#define BATTERY_CHARGE_FAIL		0x20
#define BATTERY_CYCLES_EXCEEDED		0x40

/*
 * Physical drive states.
 */
#define PDRV_UNCNF	0
#define PDRV_ONLINE	3
#define PDRV_FAILED	4
#define PDRV_RBLD	5
#define PDRV_HOTSPARE	6


/*
 * Raid logical drive states.
 */
#define RDRV_OFFLINE	0
#define RDRV_DEGRADED	1
#define RDRV_OPTIMAL	2
#define RDRV_DELETED	3

/*
 * Read, write and cache policies
 */
#define NO_READ_AHEAD		0
#define READ_AHEAD		1
#define ADAP_READ_AHEAD		2
#define WRMODE_WRITE_THRU	0
#define WRMODE_WRITE_BACK	1
#define CACHED_IO		0
#define DIRECT_IO		1

#define MAX_LOGICAL_DRIVES_8LD		8
#define MAX_LOGICAL_DRIVES_40LD		40
#define FC_MAX_PHYSICAL_DEVICES		256
#define MAX_MBOX_CHANNELS		5
#define MAX_MBOX_TARGET			15
#define MBOX_MAX_PHYSICAL_DRIVES	MAX_MBOX_CHANNELS*MAX_MBOX_TARGET
#define MAX_ROW_SIZE_40LD		32
#define MAX_ROW_SIZE_8LD		8
#define SPAN_DEPTH_8_SPANS		8
#define SPAN_DEPTH_4_SPANS		4
#define MAX_REQ_SENSE_LEN		0x20

#define	BIG_MAX_PDRIVES	(256)
#define	BIG_MAX_LDRIVES	40
#define	BIG_MAX_SPANDEPTH	8
#define	BIG_MAX_DEVDEPTH	32



/**
 * struct mbox_t - Driver and f/w handshake structure.
 * @cmd		: firmware command
 * @cmdid	: command id
 * @numsectors	: number of sectors to be transferred
 * @lba		: Logical Block Address on LD
 * @xferaddr	: DMA address for data transfer
 * @logdrv	: logical drive number
 * @numsge	: number of scatter gather elements in sg list
 * @resvd	: reserved
 * @busy	: f/w busy, must wait to issue more commands.
 * @numstatus	: number of commands completed.
 * @status	: status of the commands completed
 * @completed	: array of completed command ids.
 * @poll	: poll and ack sequence
 * @ack		: poll and ack sequence
 *
 * The central handshake structure between the driver and the firmware. This
 * structure must be allocated by the driver and aligned at 8-byte boundary.
 */
#define MBOX_MAX_FIRMWARE_STATUS	46
typedef struct {
	unsigned char		cmd;
	unsigned char		cmdid;
	unsigned short	numsectors;
	unsigned int	lba;
	unsigned int	xferaddr;
	unsigned char		logdrv;
	unsigned char		numsge;
	unsigned char		resvd;
	unsigned char		busy;
	unsigned char		numstatus;
	unsigned char		status;
	unsigned char		completed[MBOX_MAX_FIRMWARE_STATUS];
	unsigned char		poll;
	unsigned char		ack;
} __attribute__ ((packed)) mbox_t;


/**
 * mbox64_t - 64-bit extension for the mailbox
 * @segment_lo	: the low 32-bits of the address of the scatter-gather list
 * @segment_hi	: the upper 32-bits of the address of the scatter-gather list
 * @mbox	: 32-bit mailbox, whose xferadder field must be set to
 *		0xFFFFFFFF
 *
 * This is the extension of the 32-bit mailbox to be able to perform DMA
 * beyond 4GB address range.
 */
typedef struct {
	unsigned int	xferaddr_lo;
	unsigned int	xferaddr_hi;
	mbox_t		mbox32;
} __attribute__ ((packed)) mbox64_t;

/*
 * mailbox structure used for internal commands
 */
typedef struct {
	unsigned char	cmd;
	unsigned char	cmdid;
	unsigned char	opcode;
	unsigned char	subopcode;
	unsigned int	lba;
	unsigned int	xferaddr;
	unsigned char	logdrv;
	unsigned char	rsvd[3];
	unsigned char	numstatus;
	unsigned char	status;
} __attribute__ ((packed)) int_mbox_t;

/**
 * mraid_passthru_t - passthru structure to issue commands to physical devices
 * @timeout		: command timeout, 0=6sec, 1=60sec, 2=10min, 3=3hr
 * @ars			: set if ARS required after check condition
 * @islogical		: set if command meant for logical devices
 * @logdrv		: logical drive number if command for LD
 * @channel		: Channel on which physical device is located
 * @target		: SCSI target of the device
 * @queuetag		: unused
 * @queueaction		: unused
 * @cdb			: SCSI CDB
 * @cdblen		: length of the CDB
 * @reqsenselen		: amount of request sense data to be returned
 * @reqsensearea	: Sense information buffer
 * @numsge		: number of scatter-gather elements in the sg list
 * @scsistatus		: SCSI status of the command completed.
 * @dataxferaddr	: DMA data transfer address
 * @dataxferlen		: amount of the data to be transferred.
 */
typedef struct {
	unsigned char		timeout		:3;
	unsigned char		ars		:1;
	unsigned char		reserved	:3;
	unsigned char		islogical	:1;
	unsigned char		logdrv;
	unsigned char		channel;
	unsigned char		target;
	unsigned char		queuetag;
	unsigned char		queueaction;
	unsigned char		cdb[10];
	unsigned char		cdblen;
	unsigned char		reqsenselen;
	unsigned char		reqsensearea[MAX_REQ_SENSE_LEN];
	unsigned char		numsge;
	unsigned char		scsistatus;
	unsigned int	dataxferaddr;
	unsigned int	dataxferlen;
} __attribute__ ((packed)) mraid_passthru_t;

typedef struct {

	unsigned int		dataxferaddr_lo;
	unsigned int		dataxferaddr_hi;
	mraid_passthru_t	pthruint32_t;

} __attribute__ ((packed)) megascsi_passthru64_t;

/**
 * mraid_epassthru_t - passthru structure to issue commands to physical devices
 * @timeout		: command timeout, 0=6sec, 1=60sec, 2=10min, 3=3hr
 * @ars			: set if ARS required after check condition
 * @rsvd1		: reserved field
 * @cd_rom		: (?)
 * @rsvd2		: reserved field
 * @islogical		: set if command meant for logical devices
 * @logdrv		: logical drive number if command for LD
 * @channel		: Channel on which physical device is located
 * @target		: SCSI target of the device
 * @queuetag		: unused
 * @queueaction		: unused
 * @cdblen		: length of the CDB
 * @rsvd3		: reserved field
 * @cdb			: SCSI CDB
 * @numsge		: number of scatter-gather elements in the sg list
 * @status		: SCSI status of the command completed.
 * @reqsenselen		: amount of request sense data to be returned
 * @reqsensearea	: Sense information buffer
 * @rsvd4		: reserved field
 * @dataxferaddr	: DMA data transfer address
 * @dataxferlen		: amount of the data to be transferred.
 */
typedef struct {
	unsigned char		timeout		:3;
	unsigned char		ars		:1;
	unsigned char		rsvd1		:1;
	unsigned char		cd_rom		:1;
	unsigned char		rsvd2		:1;
	unsigned char		islogical	:1;
	unsigned char		logdrv;
	unsigned char		channel;
	unsigned char		target;
	unsigned char		queuetag;
	unsigned char		queueaction;
	unsigned char		cdblen;
	unsigned char		rsvd3;
	unsigned char		cdb[16];
	unsigned char		numsge;
	unsigned char		status;
	unsigned char		reqsenselen;
	unsigned char		reqsensearea[MAX_REQ_SENSE_LEN];
	unsigned char		rsvd4;
	unsigned int	dataxferaddr;
	unsigned int	dataxferlen;
} __attribute__ ((packed)) mraid_epassthru_t;


/**
 * mraid_pinfo_t - product info, static information about the controller
 * @data_size		: current size in bytes (not including resvd)
 * @config_signature	: Current value is 0x00282008
 * @fw_version		: Firmware version
 * @bios_version	: version of the BIOS
 * @product_name	: Name given to the controller
 * @max_commands	: Maximum concurrent commands supported
 * @nchannels		: Number of SCSI Channels detected
 * @fc_loop_present	: Number of Fibre Loops detected
 * @mem_type		: EDO, FPM, SDRAM etc
 * @signature		:
 * @dram_size		: In terms of MB
 * @subsysid		: device PCI subsystem ID
 * @subsysvid		: device PCI subsystem vendor ID
 * @notify_counters	:
 * @pad1k		: 135 + 889 resvd = 1024 total size
 *
 * This structures holds the information about the controller which is not
 * expected to change dynamically.
 *
 * The current value of config signature is 0x00282008:
 * 0x28 = MAX_LOGICAL_DRIVES,
 * 0x20 = Number of stripes and
 * 0x08 = Number of spans
 */
typedef struct {
	unsigned int	data_size;
	unsigned int	config_signature;
	unsigned char		fw_version[16];
	unsigned char		bios_version[16];
	unsigned char		product_name[80];
	unsigned char		max_commands;
	unsigned char		nchannels;
	unsigned char		fc_loop_present;
	unsigned char		mem_type;
	unsigned int	signature;
	unsigned short	dram_size;
	unsigned short	subsysid;
	unsigned short	subsysvid;
	unsigned char		notify_counters;
	unsigned char		pad1k[889];
} __attribute__ ((packed)) mraid_pinfo_t;


/**
 * mraid_notify_t - the notification structure
 * @global_counter		: Any change increments this counter
 * @param_counter		: Indicates any params changed
 * @param_id			: Param modified - defined below
 * @param_val			: New val of last param modified
 * @write_config_counter	: write config occurred
 * @write_config_rsvd		:
 * @ldrv_op_counter		: Indicates ldrv op started/completed
 * @ldrv_opid			: ldrv num
 * @ldrv_opcmd			: ldrv operation - defined below
 * @ldrv_opstatus		: status of the operation
 * @ldrv_state_counter		: Indicates change of ldrv state
 * @ldrv_state_id		: ldrv num
 * @ldrv_state_new		: New state
 * @ldrv_state_old		: old state
 * @pdrv_state_counter		: Indicates change of ldrv state
 * @pdrv_state_id		: pdrv id
 * @pdrv_state_new		: New state
 * @pdrv_state_old		: old state
 * @pdrv_fmt_counter		: Indicates pdrv format started/over
 * @pdrv_fmt_id			: pdrv id
 * @pdrv_fmt_val		: format started/over
 * @pdrv_fmt_rsvd		:
 * @targ_xfer_counter		: Indicates SCSI-2 Xfer rate change
 * @targ_xfer_id		: pdrv Id
 * @targ_xfer_val		: new Xfer params of last pdrv
 * @targ_xfer_rsvd		:
 * @fcloop_id_chg_counter	: Indicates loopid changed
 * @fcloopid_pdrvid		: pdrv id
 * @fcloop_id0			: loopid on fc loop 0
 * @fcloop_id1			: loopid on fc loop 1
 * @fcloop_state_counter	: Indicates loop state changed
 * @fcloop_state0		: state of fc loop 0
 * @fcloop_state1		: state of fc loop 1
 * @fcloop_state_rsvd		:
 */
typedef struct {
	unsigned int	global_counter;
	unsigned char		param_counter;
	unsigned char		param_id;
	unsigned short	param_val;
	unsigned char		write_config_counter;
	unsigned char		write_config_rsvd[3];
	unsigned char		ldrv_op_counter;
	unsigned char		ldrv_opid;
	unsigned char		ldrv_opcmd;
	unsigned char		ldrv_opstatus;
	unsigned char		ldrv_state_counter;
	unsigned char		ldrv_state_id;
	unsigned char		ldrv_state_new;
	unsigned char		ldrv_state_old;
	unsigned char		pdrv_state_counter;
	unsigned char		pdrv_state_id;
	unsigned char		pdrv_state_new;
	unsigned char		pdrv_state_old;
	unsigned char		pdrv_fmt_counter;
	unsigned char		pdrv_fmt_id;
	unsigned char		pdrv_fmt_val;
	unsigned char		pdrv_fmt_rsvd;
	unsigned char		targ_xfer_counter;
	unsigned char		targ_xfer_id;
	unsigned char		targ_xfer_val;
	unsigned char		targ_xfer_rsvd;
	unsigned char		fcloop_id_chg_counter;
	unsigned char		fcloopid_pdrvid;
	unsigned char		fcloop_id0;
	unsigned char		fcloop_id1;
	unsigned char		fcloop_state_counter;
	unsigned char		fcloop_state0;
	unsigned char		fcloop_state1;
	unsigned char		fcloop_state_rsvd;
} __attribute__ ((packed)) mraid_notify_t;


/**
 * mraid_inquiry3_t - enquiry for device information
 *
 * @data_size		: current size in bytes (not including resvd)
 * @notify		:
 * @notify_rsvd		:
 * @rebuild_rate	: rebuild rate (0% - 100%)
 * @cache_flush_int	: cache flush interval in seconds
 * @sense_alert		:
 * @drive_insert_count	: drive insertion count
 * @battery_status	:
 * @num_ldrv		: no. of Log Drives configured
 * @recon_state		: state of reconstruct
 * @ldrv_op_status	: logdrv Status
 * @ldrv_size		: size of each log drv
 * @ldrv_prop		:
 * @ldrv_state		: state of log drives
 * @pdrv_state		: state of phys drvs.
 * @pdrv_format		:
 * @targ_xfer		: phys device transfer rate
 * @pad1k		: 761 + 263reserved = 1024 bytes total size
 */
#define MAX_NOTIFY_SIZE		0x80
#define CUR_NOTIFY_SIZE		sizeof(mraid_notify_t)

typedef struct {
	unsigned int	data_size;

	mraid_notify_t	notify;

	unsigned char		notify_rsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE];

	unsigned char		rebuild_rate;
	unsigned char		cache_flush_int;
	unsigned char		sense_alert;
	unsigned char		drive_insert_count;

	unsigned char		battery_status;
	unsigned char		num_ldrv;
	unsigned char		recon_state[MAX_LOGICAL_DRIVES_40LD / 8];
	unsigned short	ldrv_op_status[MAX_LOGICAL_DRIVES_40LD / 8];

	unsigned int	ldrv_size[MAX_LOGICAL_DRIVES_40LD];
	unsigned char		ldrv_prop[MAX_LOGICAL_DRIVES_40LD];
	unsigned char		ldrv_state[MAX_LOGICAL_DRIVES_40LD];
	unsigned char		pdrv_state[FC_MAX_PHYSICAL_DEVICES];
	unsigned short	pdrv_format[FC_MAX_PHYSICAL_DEVICES / 16];

	unsigned char		targ_xfer[80];
	unsigned char		pad1k[263];
} __attribute__ ((packed)) mraid_inquiry3_t;


/**
 * mraid_adapinfo_t - information about the adapter
 * @max_commands		: max concurrent commands supported
 * @rebuild_rate		: rebuild rate - 0% thru 100%
 * @max_targ_per_chan		: max targ per channel
 * @nchannels			: number of channels on HBA
 * @fw_version			: firmware version
 * @age_of_flash		: number of times FW has been flashed
 * @chip_set_value		: contents of 0xC0000832
 * @dram_size			: in MB
 * @cache_flush_interval	: in seconds
 * @bios_version		:
 * @board_type			:
 * @sense_alert			:
 * @write_config_count		: increase with every configuration change
 * @drive_inserted_count	: increase with every drive inserted
 * @inserted_drive		: channel:Id of inserted drive
 * @battery_status		: bit 0: battery module missing
 *				bit 1: VBAD
 *				bit 2: temprature high
 *				bit 3: battery pack missing
 *				bit 4,5:
 *					00 - charge complete
 *					01 - fast charge in progress
 *					10 - fast charge fail
 *					11 - undefined
 *				bit 6: counter > 1000
 *				bit 7: Undefined
 * @dec_fault_bus_info		:
 */
typedef struct {
	unsigned char		max_commands;
	unsigned char		rebuild_rate;
	unsigned char		max_targ_per_chan;
	unsigned char		nchannels;
	unsigned char		fw_version[4];
	unsigned short	age_of_flash;
	unsigned char		chip_set_value;
	unsigned char		dram_size;
	unsigned char		cache_flush_interval;
	unsigned char		bios_version[4];
	unsigned char		board_type;
	unsigned char		sense_alert;
	unsigned char		write_config_count;
	unsigned char		battery_status;
	unsigned char		dec_fault_bus_info;
} __attribute__ ((packed)) mraid_adapinfo_t;


/**
 * mraid_ldrv_info_t - information about the logical drives
 * @nldrv	: Number of logical drives configured
 * @rsvd	:
 * @size	: size of each logical drive
 * @prop	:
 * @state	: state of each logical drive
 */
typedef struct {
	unsigned char		nldrv;
	unsigned char		rsvd[3];
	unsigned int	size[MAX_LOGICAL_DRIVES_8LD];
	unsigned char		prop[MAX_LOGICAL_DRIVES_8LD];
	unsigned char		state[MAX_LOGICAL_DRIVES_8LD];
} __attribute__ ((packed)) mraid_ldrv_info_t;


/**
 * mraid_pdrv_info_t - information about the physical drives
 * @pdrv_state	: state of each physical drive
 */
typedef struct {
	unsigned char		pdrv_state[MBOX_MAX_PHYSICAL_DRIVES];
	unsigned char		rsvd;
} __attribute__ ((packed)) mraid_pdrv_info_t;


/**
 * mraid_inquiry_t - RAID inquiry, mailbox command 0x05
 * @mraid_adapinfo_t	: adapter information
 * @mraid_ldrv_info_t	: logical drives information
 * @mraid_pdrv_info_t	: physical drives information
 */
typedef struct {
	mraid_adapinfo_t	adapter_info;
	mraid_ldrv_info_t	logdrv_info;
	mraid_pdrv_info_t	pdrv_info;
} __attribute__ ((packed)) mraid_inquiry_t;


/**
 * mraid_extinq_t - RAID extended inquiry, mailbox command 0x04
 *
 * @raid_inq		: raid inquiry
 * @phys_drv_format	:
 * @stack_attn		:
 * @modem_status	:
 * @rsvd		:
 */
typedef struct {
	mraid_inquiry_t	raid_inq;
	unsigned short	phys_drv_format[MAX_MBOX_CHANNELS];
	unsigned char		stack_attn;
	unsigned char		modem_status;
	unsigned char		rsvd[2];
} __attribute__ ((packed)) mraid_extinq_t;


/**
 * adap_device_t - device information
 * @channel	: channel fpor the device
 * @target	: target ID of the device
 */
typedef struct {
	unsigned char		channel;
	unsigned char		target;
}__attribute__ ((packed)) adap_device_t;


/**
 * adap_span_40ld_t - 40LD span
 * @start_blk	: starting block
 * @num_blks	: number of blocks
 */
typedef struct {
	unsigned int	start_blk;
	unsigned int	num_blks;
	adap_device_t	device[MAX_ROW_SIZE_40LD];
}__attribute__ ((packed)) adap_span_40ld_t;


/**
 * adap_span_8ld_t - 8LD span
 * @start_blk	: starting block
 * @num_blks	: number of blocks
 */
typedef struct {
	unsigned int	start_blk;
	unsigned int	num_blks;
	adap_device_t	device[MAX_ROW_SIZE_8LD];
}__attribute__ ((packed)) adap_span_8ld_t;


/**
 * logdrv_param_t - logical drives parameters
 *
 * @span_depth	: total number of spans
 * @level	: RAID level
 * @read_ahead	: read ahead, no read ahead, adaptive read ahead
 * @stripe_sz	: encoded stripe size
 * @status	: status of the logical drive
 * @write_mode	: write mode, write_through/write_back
 * @direct_io	: direct io or through cache
 * @row_size	: number of stripes in a row
 */
typedef struct {
	unsigned char		span_depth;
	unsigned char		level;
	unsigned char		read_ahead;
	unsigned char		stripe_sz;
	unsigned char		status;
	unsigned char		write_mode;
	unsigned char		direct_io;
	unsigned char		row_size;
} __attribute__ ((packed)) logdrv_param_t;


/**
 * logdrv_40ld_t - logical drive definition for 40LD controllers
 * @lparam	: logical drives parameters
 * @span	: span
 */
typedef struct {
	logdrv_param_t		lparam;
	adap_span_40ld_t	span[SPAN_DEPTH_8_SPANS];
}__attribute__ ((packed)) logdrv_40ld_t;


/**
 * logdrv_8ld_span8_t - logical drive definition for 8LD controllers
 * @lparam	: logical drives parameters
 * @span	: span
 *
 * 8-LD logical drive with upto 8 spans
 */
typedef struct {
	logdrv_param_t	lparam;
	adap_span_8ld_t	span[SPAN_DEPTH_8_SPANS];
}__attribute__ ((packed)) logdrv_8ld_span8_t;


/**
 * logdrv_8ld_span4_t - logical drive definition for 8LD controllers
 * @lparam	: logical drives parameters
 * @span	: span
 *
 * 8-LD logical drive with upto 4 spans
 */
typedef struct {
	logdrv_param_t	lparam;
	adap_span_8ld_t	span[SPAN_DEPTH_4_SPANS];
}__attribute__ ((packed)) logdrv_8ld_span4_t;


/**
 * phys_drive_t - physical device information
 * @type	: Type of the device
 * @cur_status	: current status of the device
 * @tag_depth	: Level of tagging
 * @sync_neg	: sync negotiation - ENABLE or DISBALE
 * @size	: configurable size in terms of 512 byte
 */
typedef struct {
	unsigned char		type;
	unsigned char		cur_status;
	unsigned char		tag_depth;
	unsigned char		sync_neg;
	unsigned int	size;
}__attribute__ ((packed)) phys_drive_t;


/**
 * disk_array_40ld_t - disk array for 40LD controllers
 * @numldrv	: number of logical drives
 * @resvd	:
 * @ldrv	: logical drives information
 * @pdrv	: physical drives information
 */
typedef struct {
	unsigned char		numldrv;
	unsigned char		resvd[3];
	logdrv_40ld_t	ldrv[MAX_LOGICAL_DRIVES_40LD];
	phys_drive_t	pdrv[MBOX_MAX_PHYSICAL_DRIVES];
}__attribute__ ((packed)) disk_array_40ld_t;


/**
 * disk_array_8ld_span8_t - disk array for 8LD controllers
 * @numldrv	: number of logical drives
 * @resvd	:
 * @ldrv	: logical drives information
 * @pdrv	: physical drives information
 *
 * Disk array for 8LD logical drives with upto 8 spans
 */
typedef struct {
	unsigned char			numldrv;
	unsigned char			resvd[3];
	logdrv_8ld_span8_t	ldrv[MAX_LOGICAL_DRIVES_8LD];
	phys_drive_t		pdrv[MBOX_MAX_PHYSICAL_DRIVES];
}__attribute__ ((packed)) disk_array_8ld_span8_t;


/**
 * disk_array_8ld_span4_t - disk array for 8LD controllers
 * @numldrv	: number of logical drives
 * @resvd	:
 * @ldrv	: logical drives information
 * @pdrv	: physical drives information
 *
 * Disk array for 8LD logical drives with upto 4 spans
 */
typedef struct {
	unsigned char			numldrv;
	unsigned char			resvd[3];
	logdrv_8ld_span4_t	ldrv[MAX_LOGICAL_DRIVES_8LD];
	phys_drive_t		pdrv[MBOX_MAX_PHYSICAL_DRIVES];
}__attribute__ ((packed)) disk_array_8ld_span4_t;


/**
 * private_bios_data - bios private data for boot devices
 * @geometry	: bits 0-3 - BIOS geometry, 0x0001 - 1GB, 0x0010 - 2GB,
 *		0x1000 - 8GB, Others values are invalid
 * @unused	: bits 4-7 are unused
 * @boot_drv	: logical drive set as boot drive, 0..7 - for 8LD cards,
 * 		0..39 - for 40LD cards
 * @cksum	: 0-(sum of first 13 bytes of this structure)
 */
struct private_bios_data {
	unsigned char		geometry	:4;
	unsigned char		unused		:4;
	unsigned char		boot_drv;
	unsigned char		rsvd[12];
	unsigned short	cksum;
} __attribute__ ((packed));


/**
 * mbox_sgl64 - 64-bit scatter list for mailbox based controllers
 * @address     : address of the buffer
 * @length      : data transfer length
 */
typedef struct {
        unsigned long long        address;
        unsigned int        length;
} __attribute__ ((packed)) mbox_sgl64;


/**
 * mbox_sgl32 - 32-bit scatter list for mailbox based controllers
 * @address	: address of the buffer
 * @length	: data transfer length
 */
typedef struct {
	unsigned int	address;
	unsigned int	length;
} __attribute__ ((packed)) mbox_sgl32;


#define MEGASCSI_MAX_CHANNEL		4

#define	MEGASCSI_MAX_PDRIVES		(75)
#define	MEGASCSI_MAX_LDRIVES		8
#define	MEGASCSI_MAX_SPANDEPTH	4
#define	MEGASCSI_MAX_DEVDEPTH	8
#define	MEGASCSI_MAX_TARGET		16

#define	MEGASCSI_BIG_MAX_PDRIVES	(256)
#define	MEGASCSI_BIG_MAX_LDRIVES	40
#define	MEGASCSI_BIG_MAX_SPANDEPTH	8
#define	MEGASCSI_BIG_MAX_DEVDEPTH	32

#define	MEGASCSI_MAXCMDS	126	/* theoretical limit is 250 */
#define	MEGASCSI_SECTOR_SIZE	512
#define	MEGASCSI_MAXOFFSETS	26
#define	MEGASCSI_SGEPERCMD	32		/* to prevent page boundary crossing */
#define MEGASCSI_MAX_BUSYWAIT 10		/* wait up to 10 usecs */
#define MEGASCSI_MAX_POLLWAIT 1000000	/* wait up to 1000 000 usecs */
 
#define	MEGASCSI_MAXFER	(MEGASCSI_MAXOFFSETS * PAGE_SIZE)

/* commands */
#define	MEGASCSI_PASSTHRU	0x03	/* pass scsi cdb to the device */
#define	MEGASCSI_EINQUIRY	0x04	/* extended inquiry */
#define	MEGASCSI_INQUIRY	0x05	/* inquiry */
#define	MEGASCSI_CHSTATE	0x06	/* pad[0] -- state */
#define		MEGASCSI_STATE_ON	3
#define		MEGASCSI_STATE_FAIL	4
#define		MEGASCSI_STATE_SPARE	6
#define	MEGASCSI_RCONFIG	0x07	/* read configuration up to 4 spans */
#define	MEGASCSI_REBUILDPD	0x08	/* rebuild physical drive */
#define	MEGASCSI_EINQUIRY3	0x0c
#define	MEGASCSI_SPEAKER	0x51	/* speaker control */
#define		MEGASCSI_SPKR_OFF	0
#define		MEGASCSI_SPKR_ON	1
#define		MEGASCSI_SPKR_SHUT	2
#define		MEGASCSI_SPKR_GVAL	3
#define		MEGASCSI_SPKR_TEST	4

#define	MEGASCSI_NEWCFG	0x99
#define	MEGASCSI_NEWOP	0xa0
#define	MEGASCSI_FCOP	0xa1
#define		MEGASCSI_FC_RDCONF	0x04
#define		MEGASCSI_FC_RDFCONF	0x05
#define		MEGASCSI_FC_PRODINF	0x0e
#define		MEGASCSI_FC_EINQ3	0x0f
#define		MEGASCSI_FC_EINQ4	0x1f
#define			MEGASCSI_FC_EINQ3_SOLICITED_NOTIFY	0x01
#define			MEGASCSI_FC_EINQ3_SOLICITED_FULL	0x02
#define			MEGASCSI_FC_EINQ3_UNSOLICITED	0x03



/* command structures */
#pragma pack(1)
struct megascsi_iocmd {
	unsigned char	acc_cmd;
	unsigned char	acc_id;
	union {
#define	acc_mbox	_._megascsi_mbox
		struct {
			unsigned short	amb_nsect;
			unsigned int	amb_lba;
			unsigned int	amb_data;
			unsigned char	amb_ldn;	/* logical drive no */
			unsigned char	amb_nsge;
			unsigned char	amb_reserved;
		} _megascsi_mbox;

#define	acc_io		_._megascsi_io
		struct {
			unsigned char	aio_channel;
			unsigned char	aio_param;
			unsigned char	aio_pad[4];
			unsigned int	aio_data;
			unsigned char	aio_pad1[3];
		} _megascsi_io;

#define	acc_passthru	_._megascsi_passru
		struct {
			unsigned short	apt_dummy0;
			unsigned int	apt_dummy1;
			unsigned int	apt_data;
			unsigned char	apt_dummy2;
			unsigned char	apt_dummy3;
			unsigned char	apt_reserved;
		} _megascsi_passru;

#define	acc_ldrv	_._megascsi_ldrv
		struct {
			unsigned short	ald_dummy0;
			unsigned int	ald_dummy1;
			unsigned int	ald_data;
			unsigned char	ald_ldrv;
			unsigned char	ald_dummy2;
			unsigned char	ald_reserved;
		} _megascsi_ldrv;
	} _;
	unsigned char	acc_busy;
	unsigned char	acc_nstat;
	unsigned char	acc_status;
#define	MEGASCSI_MAXSTATACK	0x2e
	unsigned char	acc_cmplidl[MEGASCSI_MAXSTATACK];
	unsigned char	acc_poll;
	unsigned char	acc_ack;
	unsigned char	acc_pad[0x3e];	/* pad to 128 bytes */
};

struct megascsi_sgent {
	unsigned int	asg_addr;
	unsigned int	asg_len;
};

struct megascsi_iocmd64 {
	unsigned char	acc_cmd;
	unsigned char	acc_id;
	union {
		struct {
			unsigned short	amb_nsect;
			unsigned int	amb_lba;
			unsigned int	amb_reserved1;
			unsigned char	amb_ldn;	/* logical drive no */
			unsigned char	amb_nsge;	/* high bit == 1 */
			unsigned char	amb_reserved;
		} _megascsi_mbox;

		struct {
			unsigned char	aio_channel;
			unsigned char	aio_param;
			unsigned char	aio_pad[4];
			unsigned int	aio_data;
			unsigned char	aio_pad1[3];
		} _megascsi_io;

		struct {
			unsigned short	apt_dummy0;
			unsigned int	apt_dummy1;
			unsigned int	apt_data;
			unsigned char	apt_dummy2;
			unsigned char	apt_dummy3;
			unsigned char	apt_reserved;
		} _megascsi_passru;

		struct {
			unsigned short	ald_dummy0;
			unsigned int	ald_dummy1;
			unsigned int	ald_data;
			unsigned char	ald_ldrv;
			unsigned char	ald_dummy2;
			unsigned char	ald_reserved;
		} _megascsi_ldrv;
	} _;
	unsigned char	acc_busy;
	unsigned int	acc_data_l;
	unsigned int	acc_data_h;
	unsigned int	acc_reserved;
	unsigned char	acc_nstat;
	unsigned char	acc_status;
	unsigned char	acc_cmplidl[MEGASCSI_MAXSTATACK];
	unsigned char	acc_poll;
	unsigned char	acc_ack;
	unsigned char	acc_pad[0x32];	/* pad to 128 bytes */
};

struct megascsi_sgent64 {
	unsigned int	asg_addr_l;
	unsigned int	asg_addr_h;
	unsigned int	asg_len;
};

struct megascsi_passthrough {
	unsigned char	apt_param;
#define	MEGASCSI_PTPARAM(t,a,l)	(((l) << 7) | (((a) & 1) << 3) | ((t) & 3))
#define	MEGASCSI_TIMEOUT_6	0
#define	MEGASCSI_TIMEOUT_60	1
#define	MEGASCSI_TIMEOUT_10m	2
#define	MEGASCSI_TIMEOUT_3h	3
	unsigned char	apt_ldn;
	unsigned char	apt_channel;
	unsigned char	apt_target;
	unsigned char	apt_qtag;
	unsigned char	apt_qact;
#define	MEGASCSI_MAX_CDB	10
	unsigned char	apt_cdb[MEGASCSI_MAX_CDB];
	unsigned char	apt_ncdb;
	unsigned char	apt_nsense;
#define	MEGASCSI_MAX_SENSE	32
	unsigned char	apt_sense[MEGASCSI_MAX_SENSE];
	unsigned char	apt_nsg;
	unsigned char	apt_scsistat;
	unsigned int	apt_data;
	unsigned int	apt_datalen;
};

struct megascsi_inquiry {
	unsigned char	ain_maxcmd;
	unsigned char	ain_rbldrate;	/* rebuild rate %% */
	unsigned char	ain_targets;	/* max targets per channel */
	unsigned char	ain_channels;
	unsigned char	ain_fwver[4];
	unsigned short	ain_flashage;
	unsigned char	ain_chipset;	/* parity generation policy */
	unsigned char	ain_ramsize;
	unsigned char	ain_flushintv;
	unsigned char	ain_biosver[4];
	unsigned char	ain_brdtype;
	unsigned char	ain_scsisensealert;
	unsigned char	ain_wrcfgcnt;	/* write config count */
	unsigned char	ain_drvinscnt;	/* drive insertion count */
	unsigned char	ain_insdrv;	/* inserted drive */
	unsigned char	ain_battery;	/* battery status */
	unsigned char	ain_reserved;

	unsigned char	ain_nlogdrv;
	unsigned char	ain_reserved1[3];
	unsigned int	ain_ldsize[MEGASCSI_MAX_LDRIVES];
	unsigned char	ain_ldprop[MEGASCSI_MAX_LDRIVES];
	unsigned char	ain_ldstat[MEGASCSI_MAX_LDRIVES];

	unsigned char	ain_pdstat[MEGASCSI_MAX_PDRIVES];
	unsigned char	ain_predictivefailure;

	unsigned char	ain_pdfmtinp[MEGASCSI_MAX_PDRIVES];
	unsigned char	ain_reserved2[MEGASCSI_MAX_PDRIVES];

	unsigned int	ain_esize;	/* extended data size */
	unsigned short	ain_ssid;	/* subsystem id */
	unsigned short	ain_ssvid;	/* subsystem vendor id */
	unsigned int	ain_signature;
#define	MEGASCSI_SIGN431	0xfffe0001
#define	MEGASCSI_SIGN438	0xfffd0002
#define	MEGASCSI_SIGN762	0xfffc0003
#define	MEGASCSI_SIGNT5	0xfffb0004
#define	MEGASCSI_SIGN466	0xfffa0005
};

#define MAX_NOTIFY_SIZE	0x80
/* #define CUR_NOTIFY_SIZE (sizeof(struct megascsi_notify)) */
struct megascsi_notify
{
	unsigned int	ano_eventcounter;	/* incremented for changes */

	unsigned char	ano_paramcounter;	/* param change */
	unsigned char	ano_parmegad;		/* param modified */
#define MEGASCSI_PARAM_RBLD_RATE		0x01 /* new rebuild rate */
#define MEGASCSI_PARAM_CACHE_FLUSH_INTERVAL	0x02 /* new cache flush interval */
#define MEGASCSI_PARAM_SENSE_ALERT		0x03 /* pd caused check condition */
#define MEGASCSI_PARAM_DRIVE_INSERTED	0x04 /* pd inserted */
#define MEGASCSI_PARAM_BATTERY_STATUS	0x05 /* battery status */
#define MEGASCSI_PARAM_NVRAM_EVENT_ALERT	0x06 /* NVRAM # of entries */
#define MEGASCSI_PARAM_PATROL_READ_UPDATE	0x07 /* # pd done with patrol read */
#define MEGASCSI_PARAM_PATROL_READ_STATUS	0x08 /* 0 stopped
					      * 2 aborted
					      * 4 started */

	unsigned short	ano_paramval;		/* new val modified param */

	unsigned char	ano_writeconfcounter;	/* write config */
	unsigned char	ano_writeconfrsvd[3];

	unsigned char	ano_ldopcounter;	/* ld op started/completed */
	unsigned char	ano_ldopid;		/* ld modified */
	unsigned char	ano_ldopcmd;		/* ld operation */
#define MEGASCSI_LDCMD_CHKCONSISTANCY	0x01
#define MEGASCSI_LDCMD_INITIALIZE		0x02
#define MEGASCSI_LDCMD_RECONSTRUCTION	0x03
	unsigned char	ano_ldopstatus;		/* status of the operation */
#define MEGASCSI_LDOP_SUCCESS		0x00
#define MEGASCSI_LDOP_FAILED			0x01
#define MEGASCSI_LDOP_ABORTED		0x02
#define MEGASCSI_LDOP_CORRECTED		0x03
#define MEGASCSI_LDOP_STARTED		0x04

	unsigned char	ano_ldstatecounter;	/* change of ld state */
	unsigned char	ano_ldstateid;		/* ld state changed */
	unsigned char	ano_ldstatenew;		/* new state */
	unsigned char	ano_ldstateold;		/* old state */
#define MEGASCSI_RDRV_OFFLINE		0
#define MEGASCSI_RDRV_DEGRADED		1
#define MEGASCSI_RDRV_OPTIMAL		2
#define MEGASCSI_RDRV_DELETED		3

	unsigned char	ano_pdstatecounter;	/* change of pd state */
	unsigned char	ano_pdstateid;		/* pd state changed */
	unsigned char	ano_pdstatenew;		/* new state */
	unsigned char	ano_pdstateold;		/* old state */
#define MEGASCSI_PD_UNCNF			0
#define MEGASCSI_PD_ONLINE			3
#define MEGASCSI_PD_FAILED			4
#define MEGASCSI_PD_RBLD			5
#define MEGASCSI_PD_HOTSPARE			6

	unsigned char	ano_pdfmtcounter;	/* pd format started/over */
	unsigned char	ano_pdfmtid;		/* pd id */
	unsigned char	ano_pdfmtval;		/* format started/over */
#define MEGASCSI_PDFMT_START			0x01
#define MEGASCSI_PDFMT_OVER			0x02
	unsigned char	ano_pdfmtrsvd;

	unsigned char	ano_targxfercounter;	/* SCSI-2 Xfer rate change */
	unsigned char	ano_targxferid;		/* pd that changed  */
	unsigned char	ano_targxferval;	/* new xfer parameters */
	unsigned char	ano_targxferrsvd;

	unsigned char	ano_fclidchgcounter;	/* loop id changed */
	unsigned char	ano_fclidpdid;		/* pd id */
	unsigned char	ano_fclid0;		/* loop id on fc loop 0 */
	unsigned char	ano_fclid1;		/* loop id on fc loop 1 */

	unsigned char	ano_fclstatecounter;	/* loop state changed */
	unsigned char	ano_fclstate0;		/* state of fc loop 0 */
	unsigned char	ano_fclstate1;		/* state of fc loop 1 */
#define MEGASCSI_FCLOOP_FAILED		0
#define MEGASCSI_FCLOOP_ACTIVE		1
#define MEGASCSI_FCLOOP_TRANSIENT		2
	unsigned char	ano_fclstatersvd;
};

struct megascsi_fc_einquiry {
	unsigned int	ain_size;	/* size of this structure */

	/* notify */
	struct	megascsi_notify ain_notify;
	unsigned char	ain_notifyrsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE];

	unsigned char	ain_rbldrate;	/* rebuild rate %% */
	unsigned char	ain_flushintvl;
	unsigned char	ain_sensealert;
	unsigned char	ain_drvinscnt;	/* drive insertion count */
	unsigned char	ain_battery;	/* battery status */

	unsigned char	ain_nlogdrv;
	unsigned char	ain_recon[MEGASCSI_BIG_MAX_LDRIVES / 8];
	unsigned short	ain_stat[MEGASCSI_BIG_MAX_LDRIVES / 8];

	unsigned int	ain_ldsize[MEGASCSI_BIG_MAX_LDRIVES];
	unsigned char	ain_ldprop[MEGASCSI_BIG_MAX_LDRIVES];
	unsigned char	ain_ldstat[MEGASCSI_BIG_MAX_LDRIVES];

	unsigned char	ain_pdstat[MEGASCSI_BIG_MAX_PDRIVES];
	unsigned short	ain_pdfmtinp[MEGASCSI_BIG_MAX_PDRIVES];
	unsigned char	ain_pdrates [80];	/* pdrv xfer rates */
	unsigned char	ain_pad[263];		/* pad to 1k */
};

struct megascsi_fc_prodinfo {
	unsigned int	api_size;	/* size of this structure */
	unsigned int	api_config;
	unsigned char	api_fwver[16];
	unsigned char	api_biosver[16];
	unsigned char	api_product[80];
	unsigned char	api_maxcmd;
	unsigned char	api_channels;
	unsigned char	api_fcloops;
	unsigned char	api_memtype;
	unsigned int	api_signature;
	unsigned short	api_ramsize;
	unsigned short	api_ssid;
	unsigned short	api_ssvid;
	unsigned char	api_nnotify;
};

struct megascsi_diskarray {
	unsigned char	ada_nld;
	unsigned char	ada_pad[3];
	struct {
		unsigned char	adl_spandepth;
		unsigned char	adl_raidlvl;
		unsigned char	adl_rdahead;
		unsigned char	adl_stripesz;
		unsigned char	adl_status;
		unsigned char	adl_wrpolicy;
		unsigned char	adl_directio;
		unsigned char	adl_nstripes;
		struct {
			unsigned int	ads_start;
			unsigned int	ads_length;	/* blocks */
			struct {
				unsigned char	add_channel;
				unsigned char	add_target;
			} ads_devs[MEGASCSI_MAX_DEVDEPTH];
		} adl_spans[MEGASCSI_MAX_SPANDEPTH];
	} ada_ldrv[MEGASCSI_MAX_LDRIVES];
	struct {
		unsigned char	adp_type;	/* SCSI device type */
		unsigned char	adp_ostatus;	/* status during config */
		unsigned char	adp_tagdepth;	/* level of tagging */
		unsigned char	adp_sneg;	/* sync negotiation */
		unsigned int	adp_size;
	} ada_pdrv[MEGASCSI_MAX_PDRIVES];
};

struct megascsi_big_diskarray {
	unsigned char	ada_nld;
	unsigned char	ada_pad[3];
#define ald ada_ldrv
	struct {
		unsigned char	adl_spandepth;
		unsigned char	adl_raidlvl;
		unsigned char	adl_rdahead;
		unsigned char	adl_stripesz;
		unsigned char	adl_status;
		unsigned char	adl_wrpolicy;
		unsigned char	adl_directio;
		unsigned char	adl_nstripes;
#define 	asp adl_spans
		struct {
			unsigned int	ads_start;
			unsigned int	ads_length;	/* blocks */
#define 		adv ads_devs
			struct {
				unsigned char	add_channel;
				unsigned char	add_target;
			} ads_devs[MEGASCSI_BIG_MAX_DEVDEPTH];
		} adl_spans[MEGASCSI_BIG_MAX_SPANDEPTH];
	} ada_ldrv[MEGASCSI_BIG_MAX_LDRIVES];
#define apd ada_pdrv
	struct {
		unsigned char	adp_type;	/* SCSI device type */
		unsigned char	adp_ostatus;	/* status during config */
		unsigned char	adp_tagdepth;	/* level of tagging */
		unsigned char	adp_sneg;	/* sync negotiation */
		unsigned int	adp_size;
	} ada_pdrv[MEGASCSI_BIG_MAX_PDRIVES];
};

struct megascsi_scsisense {
	unsigned char	ase_end;
	struct {
		unsigned char	asd_channel;
		unsigned char	asd_target;
		unsigned short	asd_errcode;
		unsigned short	asd_sense;
		unsigned short	asd_addarea1;
		unsigned short	asd_addarea2;
		unsigned short	asd_cmdspec0;
		unsigned short	asd_cmdspec1;
		unsigned short	asd_aadapter_ascq;
	} ase_dump[5];
};

struct megascsi_escsisense {
	unsigned char	ase_end;
	struct {
		unsigned char	asd_channel;
		unsigned char	asd_target;
		unsigned short	asd_errcode;
		unsigned short	asd_sense;
		unsigned short	asd_addarea1;
		unsigned short	asd_addarea2;
		unsigned short	asd_cmdspec0;
		unsigned short	asd_cmdspec1;
		unsigned short	asd_aadapter_ascq;
		unsigned short	asd_extarea;
	} ase_dump[5];
};

struct megascsi_cachestats {
	unsigned int	acs_total;
	unsigned int	acs_hits;
};

struct megascsi_drivehistory {
	struct {
		unsigned char	adh_error;
#define	MEGASCSI_ADHERR_TIMEOUT(e)	((e) & 15)
#define	MEGASCSI_ADHERR_PARITY(e)	(((e) >> 4) & 15)
		unsigned char	adh_throttle;
	} adh_err[3][16];	/* channels * drives */
	unsigned char	adh_failidx;
	struct {
		unsigned char	adh_tag;
#define	MEGASCSI_ADHTAG_CH(t)	((t) & 7)
#define	MEGASCSI_ADHTAG_TARG(t)	(((t) >> 3) & 15)
#define	MEGASCSI_ADHTAG_VALID(t)	((t) & 0x80)
		unsigned char	reason;
#define	MEGASCSI_ADHERR_MEDIA	1
#define	MEGASCSI_ADHERR_NMEDIA	2
#define	MEGASCSI_ADHERR_CMDTMO	3
#define	MEGASCSI_ADHERR_SELTMO	4
#define	MEGASCSI_ADHERR_HAFAIL	5
#define	MEGASCSI_ADHERR_REASSIGN	6
#define	MEGASCSI_ADHERR_CMDFAIL	7
#define	MEGASCSI_ADHERR_OTHER	8

#define	MEGASCSI_FAILHISTORY		10
	} adh_fail[MEGASCSI_FAILHISTORY];
};

struct megascsi_inq_data {
	unsigned char	aid_peri;
	unsigned char	aid_scsitype;
	unsigned char	aid_ver;
	unsigned char	aid_datatrans;
	unsigned char	aid_addlen;
	unsigned char	aid_resv[2];
	unsigned char	aid_scsival;
	unsigned char	aid_vendor[8];
	unsigned char	aid_prod[16];
	unsigned char	aid_prodver[4];
	unsigned char	aid_mederr;
	unsigned char	aid_otherr;
	unsigned char	aid_proctype;

	unsigned char	resv2[20];
};

#pragma pack()


/* mega scsi device definition */
struct megascsi_adapter;

struct device {
	int	dv_unit;		/* device unit number */
	char	dv_xname[16];		/* external name (name + unit) */
	struct	device *dv_parent;	/* pointer to parent device */
	int	dv_flags;		/* misc. flags; see below */
	int	dv_ref;			/* ref count */
};


struct megascsi_rawadapter {
	struct megascsi_adapter *adapter_softc;
	unsigned char	adapter_channel;

	int		adapter_proctarget;	/* ses/safte target id */
	char		adapter_procdev[16];	/* ses/safte device */
};

struct megascsi_adapter {
	struct device	adapter_dev;
	uint	adapter_handle;
	uint	adapter_adapt_no;
/* don't use 0x0001 */
#define MEGASCSI_BROKEN 	0x0002
#define	MEGASCSI_CMDWAIT	0x0004
#define MEGASCSI_QUARTZ	0x0008
	uint	adapter_flags;


	volatile struct megascsi_iocmd *adapter_mbox;
	unsigned int	adapter_mbox_pa;


	int		adapter_timeout;
	/*
	struct timeout	adapter_requeue_tmo;
	struct timeout	adapter_poll_tmo;
	*/
	int		adapter_dis_poll;

	char	adapter_fwver[16];
	char	adapter_biosver[16];
	int	adapter_maxcmds;
	int	adapter_memory;
	int	adapter_targets;
	int	adapter_channels;
	int	adapter_maxunits;
	int	adapter_nunits;
	struct {
		unsigned char	hd_present;
		unsigned char	hd_is_logdrv;
		unsigned char	hd_heads;
		unsigned char	hd_secs;
		unsigned char	hd_prop;
		unsigned char	hd_stat;
		unsigned int	hd_size;
		char		dev[16];
	} adapter_hdr[MEGASCSI_BIG_MAX_PDRIVES];
	struct megascsi_rawadapter adapter_rawadapters[MEGASCSI_MAX_CHANNEL];
};


/* Mega IOCTL definition*/
#define BUFF_SIZE 4096
#define POLL_TIME 10	/* in secs */

#define DEBUG 1

/**
 * mimd_t	: Old style ioctl packet structure (deprecated)
 *
 * @inlen	:
 * @outlen	:
 * @fca		:
 * @opcode	:
 * @subopcode	:
 * @adapno	:
 * @buffer	:
 * @pad		:
 * @length	:
 * @mbox	:
 * @pthru	:
 * @data	:
 * @pad		:
 *
 * Note		: This structure is DEPRECATED. New applications must use
 *		: uioc_t structure instead. All new hba drivers use the new
 *		: format. If we get this mimd packet, we will convert it into
 *		: new uioc_t format and send it to the hba drivers.
 */

typedef struct mimd {

	unsigned int inlen;
	unsigned int outlen;

	union {
		unsigned char fca[16];
		struct {
			unsigned char opcode;
			unsigned char subopcode;
			unsigned short adapno;
#if BITS_PER_LONG == 32	
			unsigned char *buffer;
			unsigned char pad[4];
#endif 
#if BITS_PER_LONG == 64
			unsigned char *buffer;
#endif
			unsigned int length;
		} __attribute__ ((packed)) fcs;
	} __attribute__ ((packed)) ui;

	unsigned char mbox[18];		/* 16 bytes + 2 status bytes */
	mraid_passthru_t pthru;

#if BITS_PER_LONG == 32
	char *data;		/* buffer <= 4096 for 0x80 commands */
	char pad[4];
#endif
#if BITS_PER_LONG == 64
	char *data;
#endif
} __attribute__ ((packed))mimd_t;

/*
 * Definitions & Declarations needed to use common management module
 */

#define MEGAIOC_MAGIC		'm'
#define MEGAIOCCMD		_IOWR(MEGAIOC_MAGIC, 0, mimd_t)

#define MEGAIOC_QNADAP		'm'	/* Query # of adapters		*/
#define MEGAIOC_QDRVRVER	'e'	/* Query driver version		*/
#define MEGAIOC_QADAPINFO   	'g'	/* Query adapter information	*/

// #define USCSICMD		0x80	/* Linux 2.6.x kernel */
// #define USCSICMD             0xe0	/* Linux 2.4.x kernel */

#define UIOC_RD			0x00001
#define UIOC_WR			0x00002

#define MBOX_CMD		0x00000
#define GET_DRIVER_VER		0x10000
#define GET_N_ADAP		0x20000
#define GET_ADAP_INFO		0x30000
#define GET_CAP			0x40000
#define GET_STATS		0x50000
#define GET_IOCTL_VERSION	0x01

#define EXT_IOCTL_SIGN_SZ	16
#define EXT_IOCTL_SIGN		"$$_EXTD_IOCTL_$$"

#define	MBOX_LEGACY		0x00		/* ioctl has legacy mbox*/
#define MBOX_HPE		0x01		/* ioctl has hpe mbox	*/

#define	APPTYPE_MIMD		0x00		/* old existing apps	*/
#define APPTYPE_UIOC		0x01		/* new apps using uioc	*/

#define IOCTL_ISSUE		0x00000001	/* Issue ioctl		*/
#define IOCTL_ABORT		0x00000002	/* Abort previous ioctl	*/

#define DRVRTYPE_MBOX		0x00000001	/* regular mbox driver	*/
#define DRVRTYPE_HPE		0x00000002	/* new hpe driver	*/

/**
 * struct mraid_hba_info - information about the controller
 *
 * @param pci_vendor_id		: PCI vendor id
 * @param pci_device_id		: PCI device id
 * @param subsystem_vendor_id	: PCI subsystem vendor id
 * @param subsystem_device_id	: PCI subsystem device id
 * @param baseport		: base port of hba memory
 * @param pci_bus		: PCI bus
 * @param pci_dev_fn		: PCI device/function values
 * @param irq			: interrupt vector for the device
 *
 * Extended information of 256 bytes about the controller. Align on the single
 * byte boundary so that 32-bit applications can be run on 64-bit platform
 * drivers withoug re-compilation.
 * NOTE: reduce the number of reserved bytes whenever new field are added, so
 * that total size of the structure remains 256 bytes.
 */
typedef struct mraid_hba_info {

	unsigned short	pci_vendor_id;
	unsigned short	pci_device_id;
	unsigned short	subsys_vendor_id;
	unsigned short	subsys_device_id;

	unsigned long long	baseport;
	unsigned char		pci_bus;
	unsigned char		pci_dev_fn;
	unsigned char		pci_slot;
	unsigned char		irq;

	unsigned int	unique_id;
	unsigned int	host_no;

	unsigned char		num_ldrv;
} __attribute__ ((aligned(256), packed)) mraid_hba_info_t;



/**
 * mcontroller	: adapter info structure for old mimd_t apps
 *
 * @base	: base address
 * @irq		: irq number
 * @numldrv	: number of logical drives
 * @pcibus	: pci bus
 * @pcidev	: pci device
 * @pcifun	: pci function
 * @pciid	: pci id
 * @pcivendor	: vendor id
 * @pcislot	: slot number
 * @uid		: unique id
 */
typedef struct mcontroller {

	unsigned long long	base;
	unsigned char		irq;
	unsigned char		numldrv;
	unsigned char		pcibus;
	unsigned short	pcidev;
	unsigned char		pcifun;
	unsigned short	pciid;
	unsigned short	pcivendor;
	unsigned char		pcislot;
	unsigned int	uid;

} __attribute__ ((packed)) mcontroller_t;


/* Kernel Mode IOCTL Operation Definition*/
int	megascsi_query_adapt(struct megascsi_adapter *);
void megascsi_copyhds(struct megascsi_adapter *scsi_adapter, const unsigned int *sizes,
	const unsigned char *props, const unsigned char *stats);
int megascsi_drv_inq(struct megascsi_adapter *, unsigned char, unsigned char, unsigned char, void *);
int megascsi_mgmt(struct megascsi_adapter *, unsigned char, unsigned char, unsigned char, unsigned char,
    size_t, void *);
int megascsi_ioctl_inq(struct megascsi_adapter *, struct mioc_inq *);
int megascsi_vol(struct megascsi_adapter *, struct mioc_vol *,
    struct megascsi_big_diskarray *);
int megascsi_disk(struct megascsi_adapter *, struct mioc_disk *,
    struct megascsi_big_diskarray *);
int megascsi_ioctl_vol(struct megascsi_adapter *, struct mioc_vol *);
int megascsi_ioctl_disk(struct megascsi_adapter *, struct mioc_disk *);

#endif /* _LIB_MEGA_SCSI_H_ */