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