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		16
10 #define NWD_SHIFT	4
11 #define MAX_PART	16
12 
13 #define IO_OK		0
14 #define IO_ERROR	1
15 
16 #define MAJOR_NR COMPAQ_CISS_MAJOR
17 
18 struct ctlr_info;
19 typedef struct ctlr_info ctlr_info_t;
20 
21 struct access_method {
22 	void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
23 	void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
24 	unsigned long (*fifo_full)(ctlr_info_t *h);
25 	unsigned long (*intr_pending)(ctlr_info_t *h);
26 	unsigned long (*command_completed)(ctlr_info_t *h);
27 };
28 typedef struct _drive_info_struct
29 {
30  	__u32   	LunID;
31 	int 		usage_count;
32 	unsigned int 	nr_blocks;
33 	int		block_size;
34 	int 		heads;
35 	int		sectors;
36 	int 		cylinders;
37 	int 		raid_level;
38 } drive_info_struct;
39 
40 struct ctlr_info
41 {
42 	int	ctlr;
43 	int	major;
44 	char	devname[8];
45 	char    *product_name;
46 	char	firm_ver[4]; // Firmware version
47 	struct pci_dev *pdev;
48 	__u32	board_id;
49 	unsigned long vaddr;
50 	unsigned long paddr;
51 	unsigned long io_mem_addr;
52 	unsigned long io_mem_length;
53 	CfgTable_struct *cfgtable;
54 	unsigned int	intr;
55 	int	interrupts_enabled;
56 	int 	max_commands;
57 	int	commands_outstanding;
58 	int 	max_outstanding; /* Debug */
59 	int	num_luns;
60 	int 	highest_lun;
61 	int	usage_count;  /* number of opens all all minor devices */
62 
63 	// information about each logical volume
64 	drive_info_struct drv[CISS_MAX_LUN];
65 
66 	struct access_method access;
67 
68 	/* queue and queue Info */
69 	CommandList_struct *reqQ;
70 	CommandList_struct  *cmpQ;
71 	unsigned int Qdepth;
72 	unsigned int maxQsinceinit;
73 	unsigned int maxSG;
74 
75 	//* pointers to command and error info pool */
76 	CommandList_struct 	*cmd_pool;
77 	dma_addr_t		cmd_pool_dhandle;
78 	ErrorInfo_struct 	*errinfo_pool;
79 	dma_addr_t		errinfo_pool_dhandle;
80         __u32   		*cmd_pool_bits;
81 	int			nr_allocs;
82 	int			nr_frees;
83 
84 	// Disk structures we need to pass back
85 	struct gendisk   gendisk;
86 	   // indexed by minor numbers
87 	struct hd_struct hd[256];
88 	int              sizes[256];
89 	int              blocksizes[256];
90 	int              hardsizes[256];
91 	int busy_configuring;
92 #ifdef CONFIG_CISS_SCSI_TAPE
93 	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
94 #endif
95 #ifdef CONFIG_CISS_MONITOR_THREAD
96 	struct timer_list watchdog;
97 	struct task_struct *monitor_thread;
98 	unsigned int monitor_period;
99 	unsigned int monitor_deadline;
100 	unsigned char alive;
101 	unsigned char monitor_started;
102 #define CCISS_MIN_PERIOD 10
103 #define CCISS_MAX_PERIOD 3600
104 #define CTLR_IS_ALIVE(h) (h->alive)
105 #define ASSERT_CTLR_ALIVE(h) {	h->alive = 1; \
106 				h->monitor_period = 0; \
107 				h->monitor_started = 0; }
108 #define MONITOR_STATUS_PATTERN "Status: %s\n"
109 #define CTLR_STATUS(h) CTLR_IS_ALIVE(h) ? "operational" : "failed"
110 #define MONITOR_PERIOD_PATTERN "Monitor thread period: %d\n"
111 #define MONITOR_PERIOD_VALUE(h) (h->monitor_period)
112 #define MONITOR_DEADLINE_PATTERN "Monitor thread deadline: %d\n"
113 #define MONITOR_DEADLINE_VALUE(h) (h->monitor_deadline)
114 #define START_MONITOR_THREAD(h, cmd, count, cciss_monitor, rc) \
115 	start_monitor_thread(h, cmd, count, cciss_monitor, rc)
116 #else
117 
118 #define MONITOR_PERIOD_PATTERN "%s"
119 #define MONITOR_PERIOD_VALUE(h) ""
120 #define MONITOR_DEADLINE_PATTERN "%s"
121 #define MONITOR_DEADLINE_VALUE(h) ""
122 #define MONITOR_STATUS_PATTERN "%s\n"
123 #define CTLR_STATUS(h) ""
124 #define CTLR_IS_ALIVE(h) (1)
125 #define ASSERT_CTLR_ALIVE(h)
126 #define START_MONITOR_THREAD(a,b,c,d,rc) (*rc == 0)
127 
128 #endif
129 };
130 
131 /*  Defining the diffent access_menthods */
132 /*
133  * Memory mapped FIFO interface (SMART 53xx cards)
134  */
135 #define SA5_DOORBELL	0x20
136 #define SA5_REQUEST_PORT_OFFSET	0x40
137 #define SA5_REPLY_INTR_MASK_OFFSET	0x34
138 #define SA5_REPLY_PORT_OFFSET		0x44
139 #define SA5_INTR_STATUS		0x30
140 #define SA5_SCRATCHPAD_OFFSET	0xB0
141 
142 #define SA5_CTCFG_OFFSET	0xB4
143 #define SA5_CTMEM_OFFSET	0xB8
144 
145 #define SA5_INTR_OFF		0x08
146 #define SA5B_INTR_OFF		0x04
147 #define SA5_INTR_PENDING	0x08
148 #define SA5B_INTR_PENDING	0x04
149 #define FIFO_EMPTY		0xffffffff
150 
151 #define  CISS_ERROR_BIT		0x02
152 
153 #define CCISS_INTR_ON 	1
154 #define CCISS_INTR_OFF	0
155 /*
156 	Send the command to the hardware
157 */
SA5_submit_command(ctlr_info_t * h,CommandList_struct * c)158 static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
159 {
160 #ifdef CCISS_DEBUG
161 	 printk("Sending %x - down to controller\n", c->busaddr );
162 #endif /* CCISS_DEBUG */
163          writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
164 	 h->commands_outstanding++;
165 	 if ( h->commands_outstanding > h->max_outstanding)
166 		h->max_outstanding = h->commands_outstanding;
167 }
168 
169 /*
170  *  This card is the opposite of the other cards.
171  *   0 turns interrupts on...
172  *   0x08 turns them off...
173  */
SA5_intr_mask(ctlr_info_t * h,unsigned long val)174 static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
175 {
176 	if (val)
177 	{ /* Turn interrupts on */
178 		h->interrupts_enabled = 1;
179 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
180 	} else /* Turn them off */
181 	{
182 		h->interrupts_enabled = 0;
183         	writel( SA5_INTR_OFF,
184 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
185 	}
186 }
187 /*
188  *  This card is the opposite of the other cards.
189  *   0 turns interrupts on...
190  *   0x04 turns them off...
191  */
SA5B_intr_mask(ctlr_info_t * h,unsigned long val)192 static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
193 {
194         if (val)
195         { /* Turn interrupts on */
196 		h->interrupts_enabled = 1;
197                 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
198         } else /* Turn them off */
199         {
200 		h->interrupts_enabled = 0;
201                 writel( SA5B_INTR_OFF,
202                         h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
203         }
204 }
205 /*
206  *  Returns true if fifo is full.
207  *
208  */
SA5_fifo_full(ctlr_info_t * h)209 static unsigned long SA5_fifo_full(ctlr_info_t *h)
210 {
211 	if( h->commands_outstanding >= h->max_commands)
212 		return(1);
213 	else
214 		return(0);
215 
216 }
217 /*
218  *   returns value read from hardware.
219  *     returns FIFO_EMPTY if there is nothing to read
220  */
SA5_completed(ctlr_info_t * h)221 static unsigned long SA5_completed(ctlr_info_t *h)
222 {
223 	unsigned long register_value
224 		= readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
225 	if(register_value != FIFO_EMPTY)
226 	{
227 		h->commands_outstanding--;
228 #ifdef CCISS_DEBUG
229 		printk("cciss:  Read %lx back from board\n", register_value);
230 #endif /* CCISS_DEBUG */
231 	}
232 #ifdef CCISS_DEBUG
233 	else
234 	{
235 		printk("cciss:  FIFO Empty read\n");
236 	}
237 #endif
238 	return ( register_value);
239 
240 }
241 /*
242  *	Returns true if an interrupt is pending..
243  */
SA5_intr_pending(ctlr_info_t * h)244 static unsigned long SA5_intr_pending(ctlr_info_t *h)
245 {
246 	unsigned long register_value  =
247 		readl(h->vaddr + SA5_INTR_STATUS);
248 #ifdef CCISS_DEBUG
249 	printk("cciss: intr_pending %lx\n", register_value);
250 #endif  /* CCISS_DEBUG */
251 	if( register_value &  SA5_INTR_PENDING)
252 		return  1;
253 	return 0 ;
254 }
255 
256 /*
257  *      Returns true if an interrupt is pending..
258  */
SA5B_intr_pending(ctlr_info_t * h)259 static unsigned long SA5B_intr_pending(ctlr_info_t *h)
260 {
261         unsigned long register_value  =
262                 readl(h->vaddr + SA5_INTR_STATUS);
263 #ifdef CCISS_DEBUG
264         printk("cciss: intr_pending %lx\n", register_value);
265 #endif  /* CCISS_DEBUG */
266         if( register_value &  SA5B_INTR_PENDING)
267                 return  1;
268         return 0 ;
269 }
270 
271 
272 static struct access_method SA5_access = {
273 	SA5_submit_command,
274 	SA5_intr_mask,
275 	SA5_fifo_full,
276 	SA5_intr_pending,
277 	SA5_completed,
278 };
279 
280 static struct access_method SA5B_access = {
281         SA5_submit_command,
282         SA5B_intr_mask,
283         SA5_fifo_full,
284         SA5B_intr_pending,
285         SA5_completed,
286 };
287 
288 struct board_type {
289 	__u32	board_id;
290 	char	*product_name;
291 	struct access_method *access;
292 };
293 #endif /* CCISS_H */
294 
295