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