aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/hpsa.h')
-rw-r--r--drivers/scsi/hpsa.h136
1 files changed, 112 insertions, 24 deletions
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 6bd1949144b5..a0502b3ac17e 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -33,7 +33,7 @@ struct access_method {
33 struct CommandList *c); 33 struct CommandList *c);
34 void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); 34 void (*set_intr_mask)(struct ctlr_info *h, unsigned long val);
35 unsigned long (*fifo_full)(struct ctlr_info *h); 35 unsigned long (*fifo_full)(struct ctlr_info *h);
36 unsigned long (*intr_pending)(struct ctlr_info *h); 36 bool (*intr_pending)(struct ctlr_info *h);
37 unsigned long (*command_completed)(struct ctlr_info *h); 37 unsigned long (*command_completed)(struct ctlr_info *h);
38}; 38};
39 39
@@ -55,19 +55,20 @@ struct ctlr_info {
55 char *product_name; 55 char *product_name;
56 char firm_ver[4]; /* Firmware version */ 56 char firm_ver[4]; /* Firmware version */
57 struct pci_dev *pdev; 57 struct pci_dev *pdev;
58 __u32 board_id; 58 u32 board_id;
59 void __iomem *vaddr; 59 void __iomem *vaddr;
60 unsigned long paddr; 60 unsigned long paddr;
61 int nr_cmds; /* Number of commands allowed on this controller */ 61 int nr_cmds; /* Number of commands allowed on this controller */
62 struct CfgTable __iomem *cfgtable; 62 struct CfgTable __iomem *cfgtable;
63 int max_sg_entries;
63 int interrupts_enabled; 64 int interrupts_enabled;
64 int major; 65 int major;
65 int max_commands; 66 int max_commands;
66 int commands_outstanding; 67 int commands_outstanding;
67 int max_outstanding; /* Debug */ 68 int max_outstanding; /* Debug */
68 int usage_count; /* number of opens all all minor devices */ 69 int usage_count; /* number of opens all all minor devices */
69# define DOORBELL_INT 0 70# define PERF_MODE_INT 0
70# define PERF_MODE_INT 1 71# define DOORBELL_INT 1
71# define SIMPLE_MODE_INT 2 72# define SIMPLE_MODE_INT 2
72# define MEMQ_MODE_INT 3 73# define MEMQ_MODE_INT 3
73 unsigned int intr[4]; 74 unsigned int intr[4];
@@ -93,6 +94,9 @@ struct ctlr_info {
93 int nr_frees; 94 int nr_frees;
94 int busy_initializing; 95 int busy_initializing;
95 int busy_scanning; 96 int busy_scanning;
97 int scan_finished;
98 spinlock_t scan_lock;
99 wait_queue_head_t scan_wait_queue;
96 struct mutex busy_shutting_down; 100 struct mutex busy_shutting_down;
97 struct list_head scan_list; 101 struct list_head scan_list;
98 struct completion scan_wait; 102 struct completion scan_wait;
@@ -102,6 +106,24 @@ struct ctlr_info {
102 int ndevices; /* number of used elements in .dev[] array. */ 106 int ndevices; /* number of used elements in .dev[] array. */
103#define HPSA_MAX_SCSI_DEVS_PER_HBA 256 107#define HPSA_MAX_SCSI_DEVS_PER_HBA 256
104 struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA]; 108 struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
109 /*
110 * Performant mode tables.
111 */
112 u32 trans_support;
113 u32 trans_offset;
114 struct TransTable_struct *transtable;
115 unsigned long transMethod;
116
117 /*
118 * Performant mode completion buffer
119 */
120 u64 *reply_pool;
121 dma_addr_t reply_pool_dhandle;
122 u64 *reply_pool_head;
123 size_t reply_pool_size;
124 unsigned char reply_pool_wraparound;
125 u32 *blockFetchTable;
126 unsigned char *hba_inquiry_data;
105}; 127};
106#define HPSA_ABORT_MSG 0 128#define HPSA_ABORT_MSG 0
107#define HPSA_DEVICE_RESET_MSG 1 129#define HPSA_DEVICE_RESET_MSG 1
@@ -164,9 +186,16 @@ struct ctlr_info {
164#define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ 186#define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */
165 187
166#define HPSA_ERROR_BIT 0x02 188#define HPSA_ERROR_BIT 0x02
167#define HPSA_TAG_CONTAINS_INDEX(tag) ((tag) & 0x04) 189
168#define HPSA_TAG_TO_INDEX(tag) ((tag) >> 3) 190/* Performant mode flags */
169#define HPSA_TAG_DISCARD_ERROR_BITS(tag) ((tag) & ~3) 191#define SA5_PERF_INTR_PENDING 0x04
192#define SA5_PERF_INTR_OFF 0x05
193#define SA5_OUTDB_STATUS_PERF_BIT 0x01
194#define SA5_OUTDB_CLEAR_PERF_BIT 0x01
195#define SA5_OUTDB_CLEAR 0xA0
196#define SA5_OUTDB_CLEAR_PERF_BIT 0x01
197#define SA5_OUTDB_STATUS 0x9C
198
170 199
171#define HPSA_INTR_ON 1 200#define HPSA_INTR_ON 1
172#define HPSA_INTR_OFF 0 201#define HPSA_INTR_OFF 0
@@ -176,10 +205,8 @@ struct ctlr_info {
176static void SA5_submit_command(struct ctlr_info *h, 205static void SA5_submit_command(struct ctlr_info *h,
177 struct CommandList *c) 206 struct CommandList *c)
178{ 207{
179#ifdef HPSA_DEBUG 208 dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
180 printk(KERN_WARNING "hpsa: Sending %x - down to controller\n", 209 c->Header.Tag.lower);
181 c->busaddr);
182#endif /* HPSA_DEBUG */
183 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); 210 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
184 h->commands_outstanding++; 211 h->commands_outstanding++;
185 if (h->commands_outstanding > h->max_outstanding) 212 if (h->commands_outstanding > h->max_outstanding)
@@ -202,6 +229,52 @@ static void SA5_intr_mask(struct ctlr_info *h, unsigned long val)
202 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 229 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
203 } 230 }
204} 231}
232
233static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
234{
235 if (val) { /* turn on interrupts */
236 h->interrupts_enabled = 1;
237 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
238 } else {
239 h->interrupts_enabled = 0;
240 writel(SA5_PERF_INTR_OFF,
241 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
242 }
243}
244
245static unsigned long SA5_performant_completed(struct ctlr_info *h)
246{
247 unsigned long register_value = FIFO_EMPTY;
248
249 /* flush the controller write of the reply queue by reading
250 * outbound doorbell status register.
251 */
252 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
253 /* msi auto clears the interrupt pending bit. */
254 if (!(h->msi_vector || h->msix_vector)) {
255 writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR);
256 /* Do a read in order to flush the write to the controller
257 * (as per spec.)
258 */
259 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
260 }
261
262 if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
263 register_value = *(h->reply_pool_head);
264 (h->reply_pool_head)++;
265 h->commands_outstanding--;
266 } else {
267 register_value = FIFO_EMPTY;
268 }
269 /* Check for wraparound */
270 if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
271 h->reply_pool_head = h->reply_pool;
272 h->reply_pool_wraparound ^= 1;
273 }
274
275 return register_value;
276}
277
205/* 278/*
206 * Returns true if fifo is full. 279 * Returns true if fifo is full.
207 * 280 *
@@ -228,10 +301,10 @@ static unsigned long SA5_completed(struct ctlr_info *h)
228 301
229#ifdef HPSA_DEBUG 302#ifdef HPSA_DEBUG
230 if (register_value != FIFO_EMPTY) 303 if (register_value != FIFO_EMPTY)
231 printk(KERN_INFO "hpsa: Read %lx back from board\n", 304 dev_dbg(&h->pdev->dev, "Read %lx back from board\n",
232 register_value); 305 register_value);
233 else 306 else
234 printk(KERN_INFO "hpsa: FIFO Empty read\n"); 307 dev_dbg(&h->pdev->dev, "hpsa: FIFO Empty read\n");
235#endif 308#endif
236 309
237 return register_value; 310 return register_value;
@@ -239,18 +312,28 @@ static unsigned long SA5_completed(struct ctlr_info *h)
239/* 312/*
240 * Returns true if an interrupt is pending.. 313 * Returns true if an interrupt is pending..
241 */ 314 */
242static unsigned long SA5_intr_pending(struct ctlr_info *h) 315static bool SA5_intr_pending(struct ctlr_info *h)
243{ 316{
244 unsigned long register_value = 317 unsigned long register_value =
245 readl(h->vaddr + SA5_INTR_STATUS); 318 readl(h->vaddr + SA5_INTR_STATUS);
246#ifdef HPSA_DEBUG 319 dev_dbg(&h->pdev->dev, "intr_pending %lx\n", register_value);
247 printk(KERN_INFO "hpsa: intr_pending %lx\n", register_value); 320 return register_value & SA5_INTR_PENDING;
248#endif /* HPSA_DEBUG */
249 if (register_value & SA5_INTR_PENDING)
250 return 1;
251 return 0 ;
252} 321}
253 322
323static bool SA5_performant_intr_pending(struct ctlr_info *h)
324{
325 unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
326
327 if (!register_value)
328 return false;
329
330 if (h->msi_vector || h->msix_vector)
331 return true;
332
333 /* Read outbound doorbell to flush */
334 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
335 return register_value & SA5_OUTDB_STATUS_PERF_BIT;
336}
254 337
255static struct access_method SA5_access = { 338static struct access_method SA5_access = {
256 SA5_submit_command, 339 SA5_submit_command,
@@ -260,14 +343,19 @@ static struct access_method SA5_access = {
260 SA5_completed, 343 SA5_completed,
261}; 344};
262 345
346static struct access_method SA5_performant_access = {
347 SA5_submit_command,
348 SA5_performant_intr_mask,
349 SA5_fifo_full,
350 SA5_performant_intr_pending,
351 SA5_performant_completed,
352};
353
263struct board_type { 354struct board_type {
264 __u32 board_id; 355 u32 board_id;
265 char *product_name; 356 char *product_name;
266 struct access_method *access; 357 struct access_method *access;
267}; 358};
268 359
269
270/* end of old hpsa_scsi.h file */
271
272#endif /* HPSA_H */ 360#endif /* HPSA_H */
273 361