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