2005-04-17 02:20:36 +04:00
# ifndef CCISS_H
# define CCISS_H
# include <linux/genhd.h>
2009-09-17 22:46:58 +04:00
# include <linux/mutex.h>
2005-04-17 02:20:36 +04:00
# include "cciss_cmd.h"
# define NWD_SHIFT 4
# define MAX_PART (1 << NWD_SHIFT)
# define IO_OK 0
# define IO_ERROR 1
2009-06-09 01:05:56 +04:00
# define IO_NEEDS_RETRY 3
2005-04-17 02:20:36 +04:00
2009-06-02 16:48:39 +04:00
# define VENDOR_LEN 8
# define MODEL_LEN 16
# define REV_LEN 4
2005-04-17 02:20:36 +04:00
struct ctlr_info ;
typedef struct ctlr_info ctlr_info_t ;
struct access_method {
void ( * submit_command ) ( ctlr_info_t * h , CommandList_struct * c ) ;
void ( * set_intr_mask ) ( ctlr_info_t * h , unsigned long val ) ;
unsigned long ( * fifo_full ) ( ctlr_info_t * h ) ;
unsigned long ( * intr_pending ) ( ctlr_info_t * h ) ;
unsigned long ( * command_completed ) ( ctlr_info_t * h ) ;
} ;
typedef struct _drive_info_struct
{
2009-09-17 22:48:00 +04:00
unsigned char LunID [ 8 ] ;
2005-04-17 02:20:36 +04:00
int usage_count ;
2005-07-28 12:07:31 +04:00
struct request_queue * queue ;
2005-04-17 02:20:36 +04:00
sector_t nr_blocks ;
int block_size ;
int heads ;
int sectors ;
int cylinders ;
2005-09-13 12:25:22 +04:00
int raid_level ; /* set to -1 to indicate that
* the drive is not in use / configured
2009-06-02 16:48:39 +04:00
*/
int busy_configuring ; /* This is set when a drive is being removed
* to prevent it from being opened or it ' s
* queue from being started .
*/
2009-09-17 22:48:31 +04:00
struct device dev ;
2009-06-02 16:48:39 +04:00
__u8 serial_no [ 16 ] ; /* from inquiry page 0x83,
* not necc . null terminated .
*/
char vendor [ VENDOR_LEN + 1 ] ; /* SCSI vendor string */
char model [ MODEL_LEN + 1 ] ; /* SCSI model string */
char rev [ REV_LEN + 1 ] ; /* SCSI revision string */
2009-09-17 22:48:31 +04:00
char device_initialized ; /* indicates whether dev is initialized */
2005-04-17 02:20:36 +04:00
} drive_info_struct ;
2009-11-12 21:50:01 +03:00
struct Cmd_sg_list {
SGDescriptor_struct * sgchain ;
2009-11-23 11:35:06 +03:00
dma_addr_t sg_chain_dma ;
2009-11-12 21:50:01 +03:00
int chain_block_size ;
} ;
struct ctlr_info
2005-04-17 02:20:36 +04:00
{
int ctlr ;
char devname [ 8 ] ;
char * product_name ;
char firm_ver [ 4 ] ; // Firmware version
struct pci_dev * pdev ;
__u32 board_id ;
void __iomem * vaddr ;
unsigned long paddr ;
2006-12-07 07:35:01 +03:00
int nr_cmds ; /* Number of commands allowed on this controller */
2005-04-17 02:20:36 +04:00
CfgTable_struct __iomem * cfgtable ;
int interrupts_enabled ;
int major ;
int max_commands ;
int commands_outstanding ;
int max_outstanding ; /* Debug */
int num_luns ;
int highest_lun ;
int usage_count ; /* number of opens all all minor devices */
2009-11-12 21:50:01 +03:00
/* Need space for temp sg list
* number of scatter / gathers supported
* number of scatter / gathers in chained block
*/
struct scatterlist * * scatter_list ;
int maxsgentries ;
int chainsize ;
int max_cmd_sgentries ;
struct Cmd_sg_list * * cmd_sg_list ;
2006-01-08 12:03:50 +03:00
# define DOORBELL_INT 0
# define PERF_MODE_INT 1
# define SIMPLE_MODE_INT 2
# define MEMQ_MODE_INT 3
unsigned int intr [ 4 ] ;
unsigned int msix_vector ;
unsigned int msi_vector ;
2006-12-07 07:35:06 +03:00
int cciss_max_sectors ;
2006-10-01 10:27:23 +04:00
BYTE cciss_read ;
BYTE cciss_write ;
BYTE cciss_read_capacity ;
2005-04-17 02:20:36 +04:00
// information about each logical volume
2009-09-17 22:48:31 +04:00
drive_info_struct * drv [ CISS_MAX_LUN ] ;
2005-04-17 02:20:36 +04:00
struct access_method access ;
/* queue and queue Info */
2008-11-20 11:46:09 +03:00
struct hlist_head reqQ ;
struct hlist_head cmpQ ;
2005-04-17 02:20:36 +04:00
unsigned int Qdepth ;
unsigned int maxQsinceinit ;
unsigned int maxSG ;
spinlock_t lock ;
//* pointers to command and error info pool */
CommandList_struct * cmd_pool ;
dma_addr_t cmd_pool_dhandle ;
ErrorInfo_struct * errinfo_pool ;
dma_addr_t errinfo_pool_dhandle ;
unsigned long * cmd_pool_bits ;
int nr_allocs ;
int nr_frees ;
int busy_configuring ;
2005-09-13 12:25:21 +04:00
int busy_initializing ;
2009-09-17 22:46:58 +04:00
int busy_scanning ;
struct mutex busy_shutting_down ;
2005-04-17 02:20:36 +04:00
/* This element holds the zero based queue number of the last
* queue to be started . It is used for fairness .
*/
int next_to_run ;
// Disk structures we need to pass back
2006-12-07 07:35:12 +03:00
struct gendisk * gendisk [ CISS_MAX_LUN ] ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_CISS_SCSI_TAPE
void * scsi_ctlr ; /* ptr to structure containing scsi related stuff */
2005-11-04 21:30:37 +03:00
/* list of block side commands the scsi error handling sucked up */
/* and saved for later processing */
2005-04-17 02:20:36 +04:00
# endif
2005-09-13 12:25:22 +04:00
unsigned char alive ;
2009-09-17 22:46:58 +04:00
struct list_head scan_list ;
struct completion scan_wait ;
2009-06-02 16:48:39 +04:00
struct device dev ;
2005-04-17 02:20:36 +04:00
} ;
/* Defining the diffent access_menthods */
/*
* Memory mapped FIFO interface ( SMART 53 xx cards )
*/
# define SA5_DOORBELL 0x20
# define SA5_REQUEST_PORT_OFFSET 0x40
# define SA5_REPLY_INTR_MASK_OFFSET 0x34
# define SA5_REPLY_PORT_OFFSET 0x44
# define SA5_INTR_STATUS 0x30
# define SA5_SCRATCHPAD_OFFSET 0xB0
# define SA5_CTCFG_OFFSET 0xB4
# define SA5_CTMEM_OFFSET 0xB8
# define SA5_INTR_OFF 0x08
# define SA5B_INTR_OFF 0x04
# define SA5_INTR_PENDING 0x08
# define SA5B_INTR_PENDING 0x04
# define FIFO_EMPTY 0xffffffff
# define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */
# define CISS_ERROR_BIT 0x02
# define CCISS_INTR_ON 1
# define CCISS_INTR_OFF 0
/*
Send the command to the hardware
*/
static void SA5_submit_command ( ctlr_info_t * h , CommandList_struct * c )
{
# ifdef CCISS_DEBUG
printk ( " Sending %x - down to controller \n " , c - > busaddr ) ;
# endif /* CCISS_DEBUG */
writel ( c - > busaddr , h - > vaddr + SA5_REQUEST_PORT_OFFSET ) ;
h - > commands_outstanding + + ;
if ( h - > commands_outstanding > h - > max_outstanding )
h - > max_outstanding = h - > commands_outstanding ;
}
/*
* This card is the opposite of the other cards .
* 0 turns interrupts on . . .
* 0x08 turns them off . . .
*/
static void SA5_intr_mask ( ctlr_info_t * h , unsigned long val )
{
if ( val )
{ /* Turn interrupts on */
h - > interrupts_enabled = 1 ;
writel ( 0 , h - > vaddr + SA5_REPLY_INTR_MASK_OFFSET ) ;
} else /* Turn them off */
{
h - > interrupts_enabled = 0 ;
writel ( SA5_INTR_OFF ,
h - > vaddr + SA5_REPLY_INTR_MASK_OFFSET ) ;
}
}
/*
* This card is the opposite of the other cards .
* 0 turns interrupts on . . .
* 0x04 turns them off . . .
*/
static void SA5B_intr_mask ( ctlr_info_t * h , unsigned long val )
{
if ( val )
{ /* Turn interrupts on */
h - > interrupts_enabled = 1 ;
writel ( 0 , h - > vaddr + SA5_REPLY_INTR_MASK_OFFSET ) ;
} else /* Turn them off */
{
h - > interrupts_enabled = 0 ;
writel ( SA5B_INTR_OFF ,
h - > vaddr + SA5_REPLY_INTR_MASK_OFFSET ) ;
}
}
/*
* Returns true if fifo is full .
*
*/
static unsigned long SA5_fifo_full ( ctlr_info_t * h )
{
if ( h - > commands_outstanding > = h - > max_commands )
return ( 1 ) ;
else
return ( 0 ) ;
}
/*
* returns value read from hardware .
* returns FIFO_EMPTY if there is nothing to read
*/
static unsigned long SA5_completed ( ctlr_info_t * h )
{
unsigned long register_value
= readl ( h - > vaddr + SA5_REPLY_PORT_OFFSET ) ;
if ( register_value ! = FIFO_EMPTY )
{
h - > commands_outstanding - - ;
# ifdef CCISS_DEBUG
printk ( " cciss: Read %lx back from board \n " , register_value ) ;
# endif /* CCISS_DEBUG */
}
# ifdef CCISS_DEBUG
else
{
printk ( " cciss: FIFO Empty read \n " ) ;
}
# endif
return ( register_value ) ;
}
/*
* Returns true if an interrupt is pending . .
*/
static unsigned long SA5_intr_pending ( ctlr_info_t * h )
{
unsigned long register_value =
readl ( h - > vaddr + SA5_INTR_STATUS ) ;
# ifdef CCISS_DEBUG
printk ( " cciss: intr_pending %lx \n " , register_value ) ;
# endif /* CCISS_DEBUG */
if ( register_value & SA5_INTR_PENDING )
return 1 ;
return 0 ;
}
/*
* Returns true if an interrupt is pending . .
*/
static unsigned long SA5B_intr_pending ( ctlr_info_t * h )
{
unsigned long register_value =
readl ( h - > vaddr + SA5_INTR_STATUS ) ;
# ifdef CCISS_DEBUG
printk ( " cciss: intr_pending %lx \n " , register_value ) ;
# endif /* CCISS_DEBUG */
if ( register_value & SA5B_INTR_PENDING )
return 1 ;
return 0 ;
}
static struct access_method SA5_access = {
SA5_submit_command ,
SA5_intr_mask ,
SA5_fifo_full ,
SA5_intr_pending ,
SA5_completed ,
} ;
static struct access_method SA5B_access = {
SA5_submit_command ,
SA5B_intr_mask ,
SA5_fifo_full ,
SA5B_intr_pending ,
SA5_completed ,
} ;
struct board_type {
__u32 board_id ;
char * product_name ;
struct access_method * access ;
2006-12-07 07:35:01 +03:00
int nr_cmds ; /* Max cmds this kind of ctlr can handle. */
2005-04-17 02:20:36 +04:00
} ;
2005-07-28 12:07:31 +04:00
# define CCISS_LOCK(i) (&hba[i]->lock)
2005-04-17 02:20:36 +04:00
# endif /* CCISS_H */