1#ifndef CCISS_H
2#define CCISS_H
3
4#include <linux/genhd.h>
5
6#include "cciss_cmd.h"
7
8
9#define NWD_SHIFT	4
10#define MAX_PART	(1 << NWD_SHIFT)
11
12#define IO_OK		0
13#define IO_ERROR	1
14
15struct ctlr_info;
16typedef struct ctlr_info ctlr_info_t;
17
18struct access_method {
19	void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
20	void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
21	unsigned long (*fifo_full)(ctlr_info_t *h);
22	unsigned long (*intr_pending)(ctlr_info_t *h);
23	unsigned long (*command_completed)(ctlr_info_t *h);
24};
25typedef struct _drive_info_struct
26{
27 	__u32   LunID;
28	int 	usage_count;
29	struct request_queue *queue;
30	sector_t nr_blocks;
31	int	block_size;
32	int 	heads;
33	int	sectors;
34	int 	cylinders;
35	int	raid_level; /* set to -1 to indicate that
36			     * the drive is not in use/configured
37			    */
38	int	busy_configuring; /*This is set when the drive is being removed
39				   *to prevent it from being opened or it's queue
40				   *from being started.
41				  */
42} drive_info_struct;
43
44#ifdef CONFIG_CISS_SCSI_TAPE
45
46struct sendcmd_reject_list {
47	int ncompletions;
48	unsigned long *complete; /* array of NR_CMDS tags */
49};
50
51#endif
52struct ctlr_info
53{
54	int	ctlr;
55	char	devname[8];
56	char    *product_name;
57	char	firm_ver[4]; // Firmware version
58	struct pci_dev *pdev;
59	__u32	board_id;
60	void __iomem *vaddr;
61	unsigned long paddr;
62	int 	nr_cmds; /* Number of commands allowed on this controller */
63	CfgTable_struct __iomem *cfgtable;
64	int	interrupts_enabled;
65	int	major;
66	int 	max_commands;
67	int	commands_outstanding;
68	int 	max_outstanding; /* Debug */
69	int	num_luns;
70	int 	highest_lun;
71	int	usage_count;  /* number of opens all all minor devices */
72#	define DOORBELL_INT	0
73#	define PERF_MODE_INT	1
74#	define SIMPLE_MODE_INT	2
75#	define MEMQ_MODE_INT	3
76	unsigned int intr[4];
77	unsigned int msix_vector;
78	unsigned int msi_vector;
79	int 	cciss_max_sectors;
80	BYTE	cciss_read;
81	BYTE	cciss_write;
82	BYTE	cciss_read_capacity;
83
84	// information about each logical volume
85	drive_info_struct drv[CISS_MAX_LUN];
86
87	struct access_method access;
88
89	/* queue and queue Info */
90	CommandList_struct *reqQ;
91	CommandList_struct  *cmpQ;
92	unsigned int Qdepth;
93	unsigned int maxQsinceinit;
94	unsigned int maxSG;
95	spinlock_t lock;
96
97	//* pointers to command and error info pool */
98	CommandList_struct 	*cmd_pool;
99	dma_addr_t		cmd_pool_dhandle;
100	ErrorInfo_struct 	*errinfo_pool;
101	dma_addr_t		errinfo_pool_dhandle;
102        unsigned long  		*cmd_pool_bits;
103	int			nr_allocs;
104	int			nr_frees;
105	int			busy_configuring;
106	int			busy_initializing;
107
108	/* This element holds the zero based queue number of the last
109	 * queue to be started.  It is used for fairness.
110	*/
111	int			next_to_run;
112
113	// Disk structures we need to pass back
114	struct gendisk   *gendisk[CISS_MAX_LUN];
115#ifdef CONFIG_CISS_SCSI_TAPE
116	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
117	/* list of block side commands the scsi error handling sucked up */
118	/* and saved for later processing */
119	struct sendcmd_reject_list scsi_rejects;
120#endif
121	unsigned char alive;
122};
123
124/*  Defining the diffent access_menthods */
125/*
126 * Memory mapped FIFO interface (SMART 53xx cards)
127 */
128#define SA5_DOORBELL	0x20
129#define SA5_REQUEST_PORT_OFFSET	0x40
130#define SA5_REPLY_INTR_MASK_OFFSET	0x34
131#define SA5_REPLY_PORT_OFFSET		0x44
132#define SA5_INTR_STATUS		0x30
133#define SA5_SCRATCHPAD_OFFSET	0xB0
134
135#define SA5_CTCFG_OFFSET	0xB4
136#define SA5_CTMEM_OFFSET	0xB8
137
138#define SA5_INTR_OFF		0x08
139#define SA5B_INTR_OFF		0x04
140#define SA5_INTR_PENDING	0x08
141#define SA5B_INTR_PENDING	0x04
142#define FIFO_EMPTY		0xffffffff
143#define CCISS_FIRMWARE_READY	0xffff0000 /* value in scratchpad register */
144
145#define  CISS_ERROR_BIT		0x02
146
147#define CCISS_INTR_ON 	1
148#define CCISS_INTR_OFF	0
149/*
150	Send the command to the hardware
151*/
152static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
153{
154#ifdef CCISS_DEBUG
155	 printk("Sending %x - down to controller\n", c->busaddr );
156#endif /* CCISS_DEBUG */
157         writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
158	 h->commands_outstanding++;
159	 if ( h->commands_outstanding > h->max_outstanding)
160		h->max_outstanding = h->commands_outstanding;
161}
162
163/*
164 *  This card is the opposite of the other cards.
165 *   0 turns interrupts on...
166 *   0x08 turns them off...
167 */
168static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
169{
170	if (val)
171	{ /* Turn interrupts on */
172		h->interrupts_enabled = 1;
173		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
174	} else /* Turn them off */
175	{
176		h->interrupts_enabled = 0;
177        	writel( SA5_INTR_OFF,
178			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
179	}
180}
181/*
182 *  This card is the opposite of the other cards.
183 *   0 turns interrupts on...
184 *   0x04 turns them off...
185 */
186static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
187{
188        if (val)
189        { /* Turn interrupts on */
190		h->interrupts_enabled = 1;
191                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
192        } else /* Turn them off */
193        {
194		h->interrupts_enabled = 0;
195                writel( SA5B_INTR_OFF,
196                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
197        }
198}
199/*
200 *  Returns true if fifo is full.
201 *
202 */
203static unsigned long SA5_fifo_full(ctlr_info_t *h)
204{
205	if( h->commands_outstanding >= h->max_commands)
206		return(1);
207	else
208		return(0);
209
210}
211/*
212 *   returns value read from hardware.
213 *     returns FIFO_EMPTY if there is nothing to read
214 */
215static unsigned long SA5_completed(ctlr_info_t *h)
216{
217	unsigned long register_value
218		= readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
219	if(register_value != FIFO_EMPTY)
220	{
221		h->commands_outstanding--;
222#ifdef CCISS_DEBUG
223		printk("cciss:  Read %lx back from board\n", register_value);
224#endif /* CCISS_DEBUG */
225	}
226#ifdef CCISS_DEBUG
227	else
228	{
229		printk("cciss:  FIFO Empty read\n");
230	}
231#endif
232	return ( register_value);
233
234}
235/*
236 *	Returns true if an interrupt is pending..
237 */
238static unsigned long SA5_intr_pending(ctlr_info_t *h)
239{
240	unsigned long register_value  =
241		readl(h->vaddr + SA5_INTR_STATUS);
242#ifdef CCISS_DEBUG
243	printk("cciss: intr_pending %lx\n", register_value);
244#endif  /* CCISS_DEBUG */
245	if( register_value &  SA5_INTR_PENDING)
246		return  1;
247	return 0 ;
248}
249
250/*
251 *      Returns true if an interrupt is pending..
252 */
253static unsigned long SA5B_intr_pending(ctlr_info_t *h)
254{
255        unsigned long register_value  =
256                readl(h->vaddr + SA5_INTR_STATUS);
257#ifdef CCISS_DEBUG
258        printk("cciss: intr_pending %lx\n", register_value);
259#endif  /* CCISS_DEBUG */
260        if( register_value &  SA5B_INTR_PENDING)
261                return  1;
262        return 0 ;
263}
264
265
266static struct access_method SA5_access = {
267	SA5_submit_command,
268	SA5_intr_mask,
269	SA5_fifo_full,
270	SA5_intr_pending,
271	SA5_completed,
272};
273
274static struct access_method SA5B_access = {
275        SA5_submit_command,
276        SA5B_intr_mask,
277        SA5_fifo_full,
278        SA5B_intr_pending,
279        SA5_completed,
280};
281
282struct board_type {
283	__u32	board_id;
284	char	*product_name;
285	struct access_method *access;
286	int nr_cmds; /* Max cmds this kind of ctlr can handle. */
287};
288
289#define CCISS_LOCK(i)	(&hba[i]->lock)
290
291#endif /* CCISS_H */
292