aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Brace <brace@beardog.cce.hp.com>2010-02-04 09:42:40 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-17 14:20:26 -0500
commit303932fd4ff63e8650d5d5da6cc286a8b5f8318d (patch)
treef48d9a236ffa5a43ed873d429243a12ceb19aa93
parent900c54404a9456b3ff10745e5e8f64b12c3a6ef7 (diff)
[SCSI] hpsa: Allow multiple command completions per interrupt.
This is done by adding support for the so-called "performant mode" (that's really what they called it). Smart Array controllers have a mode which enables multiple command completions to be delivered with a single interrupt, "performant" mode. We want to use that mode, as some newer controllers will be requiring this mode. Signed-off-by: Don Brace <brace@beardog.cce.hp.com> Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Mike Miller <mikem@beardog.cce.hp.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/hpsa.c286
-rw-r--r--drivers/scsi/hpsa.h106
-rw-r--r--drivers/scsi/hpsa_cmd.h78
3 files changed, 404 insertions, 66 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 314854b455d2..e518766f9fe0 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -150,6 +150,11 @@ static int check_for_unit_attention(struct ctlr_info *h,
150 struct CommandList *c); 150 struct CommandList *c);
151static void check_ioctl_unit_attention(struct ctlr_info *h, 151static void check_ioctl_unit_attention(struct ctlr_info *h,
152 struct CommandList *c); 152 struct CommandList *c);
153/* performant mode helper functions */
154static void calc_bucket_map(int *bucket, int num_buckets,
155 int nsgs, int *bucket_map);
156static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
157static inline u32 next_command(struct ctlr_info *h);
153 158
154static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); 159static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
155static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); 160static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
@@ -173,10 +178,8 @@ static struct scsi_host_template hpsa_driver_template = {
173 .name = "hpsa", 178 .name = "hpsa",
174 .proc_name = "hpsa", 179 .proc_name = "hpsa",
175 .queuecommand = hpsa_scsi_queue_command, 180 .queuecommand = hpsa_scsi_queue_command,
176 .can_queue = 512,
177 .this_id = -1, 181 .this_id = -1,
178 .sg_tablesize = MAXSGENTRIES, 182 .sg_tablesize = MAXSGENTRIES,
179 .cmd_per_lun = 512,
180 .use_clustering = ENABLE_CLUSTERING, 183 .use_clustering = ENABLE_CLUSTERING,
181 .eh_device_reset_handler = hpsa_eh_device_reset_handler, 184 .eh_device_reset_handler = hpsa_eh_device_reset_handler,
182 .ioctl = hpsa_ioctl, 185 .ioctl = hpsa_ioctl,
@@ -394,10 +397,44 @@ static inline void addQ(struct hlist_head *list, struct CommandList *c)
394 hlist_add_head(&c->list, list); 397 hlist_add_head(&c->list, list);
395} 398}
396 399
400static inline u32 next_command(struct ctlr_info *h)
401{
402 u32 a;
403
404 if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
405 return h->access.command_completed(h);
406
407 if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
408 a = *(h->reply_pool_head); /* Next cmd in ring buffer */
409 (h->reply_pool_head)++;
410 h->commands_outstanding--;
411 } else {
412 a = FIFO_EMPTY;
413 }
414 /* Check for wraparound */
415 if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
416 h->reply_pool_head = h->reply_pool;
417 h->reply_pool_wraparound ^= 1;
418 }
419 return a;
420}
421
422/* set_performant_mode: Modify the tag for cciss performant
423 * set bit 0 for pull model, bits 3-1 for block fetch
424 * register number
425 */
426static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
427{
428 if (likely(h->transMethod == CFGTBL_Trans_Performant))
429 c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
430}
431
397static void enqueue_cmd_and_start_io(struct ctlr_info *h, 432static void enqueue_cmd_and_start_io(struct ctlr_info *h,
398 struct CommandList *c) 433 struct CommandList *c)
399{ 434{
400 unsigned long flags; 435 unsigned long flags;
436
437 set_performant_mode(h, c);
401 spin_lock_irqsave(&h->lock, flags); 438 spin_lock_irqsave(&h->lock, flags);
402 addQ(&h->reqQ, c); 439 addQ(&h->reqQ, c);
403 h->Qdepth++; 440 h->Qdepth++;
@@ -1116,9 +1153,11 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
1116 sh->max_cmd_len = MAX_COMMAND_SIZE; 1153 sh->max_cmd_len = MAX_COMMAND_SIZE;
1117 sh->max_lun = HPSA_MAX_LUN; 1154 sh->max_lun = HPSA_MAX_LUN;
1118 sh->max_id = HPSA_MAX_LUN; 1155 sh->max_id = HPSA_MAX_LUN;
1156 sh->can_queue = h->nr_cmds;
1157 sh->cmd_per_lun = h->nr_cmds;
1119 h->scsi_host = sh; 1158 h->scsi_host = sh;
1120 sh->hostdata[0] = (unsigned long) h; 1159 sh->hostdata[0] = (unsigned long) h;
1121 sh->irq = h->intr[SIMPLE_MODE_INT]; 1160 sh->irq = h->intr[PERF_MODE_INT];
1122 sh->unique_id = sh->irq; 1161 sh->unique_id = sh->irq;
1123 error = scsi_add_host(sh, &h->pdev->dev); 1162 error = scsi_add_host(sh, &h->pdev->dev);
1124 if (error) 1163 if (error)
@@ -1843,7 +1882,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
1843 c->scsi_cmd = cmd; 1882 c->scsi_cmd = cmd;
1844 c->Header.ReplyQueue = 0; /* unused in simple mode */ 1883 c->Header.ReplyQueue = 0; /* unused in simple mode */
1845 memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); 1884 memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
1846 c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ 1885 c->Header.Tag.lower = (c->cmdindex << DIRECT_LOOKUP_SHIFT);
1886 c->Header.Tag.lower |= DIRECT_LOOKUP_BIT;
1847 1887
1848 /* Fill in the request block... */ 1888 /* Fill in the request block... */
1849 1889
@@ -2700,8 +2740,9 @@ static inline bool interrupt_pending(struct ctlr_info *h)
2700 2740
2701static inline long interrupt_not_for_us(struct ctlr_info *h) 2741static inline long interrupt_not_for_us(struct ctlr_info *h)
2702{ 2742{
2703 return ((h->access.intr_pending(h) == 0) || 2743 return !(h->msi_vector || h->msix_vector) &&
2704 (h->interrupts_enabled == 0)); 2744 ((h->access.intr_pending(h) == 0) ||
2745 (h->interrupts_enabled == 0));
2705} 2746}
2706 2747
2707static inline int bad_tag(struct ctlr_info *h, u32 tag_index, 2748static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
@@ -2725,13 +2766,13 @@ static inline void finish_cmd(struct CommandList *c, u32 raw_tag)
2725 2766
2726static inline u32 hpsa_tag_contains_index(u32 tag) 2767static inline u32 hpsa_tag_contains_index(u32 tag)
2727{ 2768{
2728#define DIRECT_LOOKUP_BIT 0x04 2769#define DIRECT_LOOKUP_BIT 0x10
2729 return tag & DIRECT_LOOKUP_BIT; 2770 return tag & DIRECT_LOOKUP_BIT;
2730} 2771}
2731 2772
2732static inline u32 hpsa_tag_to_index(u32 tag) 2773static inline u32 hpsa_tag_to_index(u32 tag)
2733{ 2774{
2734#define DIRECT_LOOKUP_SHIFT 3 2775#define DIRECT_LOOKUP_SHIFT 5
2735 return tag >> DIRECT_LOOKUP_SHIFT; 2776 return tag >> DIRECT_LOOKUP_SHIFT;
2736} 2777}
2737 2778
@@ -2741,42 +2782,61 @@ static inline u32 hpsa_tag_discard_error_bits(u32 tag)
2741 return tag & ~HPSA_ERROR_BITS; 2782 return tag & ~HPSA_ERROR_BITS;
2742} 2783}
2743 2784
2785/* process completion of an indexed ("direct lookup") command */
2786static inline u32 process_indexed_cmd(struct ctlr_info *h,
2787 u32 raw_tag)
2788{
2789 u32 tag_index;
2790 struct CommandList *c;
2791
2792 tag_index = hpsa_tag_to_index(raw_tag);
2793 if (bad_tag(h, tag_index, raw_tag))
2794 return next_command(h);
2795 c = h->cmd_pool + tag_index;
2796 finish_cmd(c, raw_tag);
2797 return next_command(h);
2798}
2799
2800/* process completion of a non-indexed command */
2801static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
2802 u32 raw_tag)
2803{
2804 u32 tag;
2805 struct CommandList *c = NULL;
2806 struct hlist_node *tmp;
2807
2808 tag = hpsa_tag_discard_error_bits(raw_tag);
2809 hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
2810 if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) {
2811 finish_cmd(c, raw_tag);
2812 return next_command(h);
2813 }
2814 }
2815 bad_tag(h, h->nr_cmds + 1, raw_tag);
2816 return next_command(h);
2817}
2818
2744static irqreturn_t do_hpsa_intr(int irq, void *dev_id) 2819static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
2745{ 2820{
2746 struct ctlr_info *h = dev_id; 2821 struct ctlr_info *h = dev_id;
2747 struct CommandList *c;
2748 unsigned long flags; 2822 unsigned long flags;
2749 u32 raw_tag, tag, tag_index; 2823 u32 raw_tag;
2750 struct hlist_node *tmp;
2751 2824
2752 if (interrupt_not_for_us(h)) 2825 if (interrupt_not_for_us(h))
2753 return IRQ_NONE; 2826 return IRQ_NONE;
2754 spin_lock_irqsave(&h->lock, flags); 2827 spin_lock_irqsave(&h->lock, flags);
2755 while (interrupt_pending(h)) { 2828 raw_tag = get_next_completion(h);
2756 while ((raw_tag = get_next_completion(h)) != FIFO_EMPTY) { 2829 while (raw_tag != FIFO_EMPTY) {
2757 if (likely(hpsa_tag_contains_index(raw_tag))) { 2830 if (hpsa_tag_contains_index(raw_tag))
2758 tag_index = hpsa_tag_to_index(raw_tag); 2831 raw_tag = process_indexed_cmd(h, raw_tag);
2759 if (bad_tag(h, tag_index, raw_tag)) 2832 else
2760 return IRQ_HANDLED; 2833 raw_tag = process_nonindexed_cmd(h, raw_tag);
2761 c = h->cmd_pool + tag_index;
2762 finish_cmd(c, raw_tag);
2763 continue;
2764 }
2765 tag = hpsa_tag_discard_error_bits(raw_tag);
2766 c = NULL;
2767 hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
2768 if (c->busaddr == tag) {
2769 finish_cmd(c, raw_tag);
2770 break;
2771 }
2772 }
2773 }
2774 } 2834 }
2775 spin_unlock_irqrestore(&h->lock, flags); 2835 spin_unlock_irqrestore(&h->lock, flags);
2776 return IRQ_HANDLED; 2836 return IRQ_HANDLED;
2777} 2837}
2778 2838
2779/* Send a message CDB to the firmware. */ 2839/* Send a message CDB to the firmwart. */
2780static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, 2840static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
2781 unsigned char type) 2841 unsigned char type)
2782{ 2842{
@@ -3108,7 +3168,7 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h,
3108default_int_mode: 3168default_int_mode:
3109#endif /* CONFIG_PCI_MSI */ 3169#endif /* CONFIG_PCI_MSI */
3110 /* if we get here we're going to use the default interrupt mode */ 3170 /* if we get here we're going to use the default interrupt mode */
3111 h->intr[SIMPLE_MODE_INT] = pdev->irq; 3171 h->intr[PERF_MODE_INT] = pdev->irq;
3112} 3172}
3113 3173
3114static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) 3174static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
@@ -3118,6 +3178,7 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
3118 u64 cfg_offset; 3178 u64 cfg_offset;
3119 u32 cfg_base_addr; 3179 u32 cfg_base_addr;
3120 u64 cfg_base_addr_index; 3180 u64 cfg_base_addr_index;
3181 u32 trans_offset;
3121 int i, prod_index, err; 3182 int i, prod_index, err;
3122 3183
3123 subsystem_vendor_id = pdev->subsystem_vendor; 3184 subsystem_vendor_id = pdev->subsystem_vendor;
@@ -3211,11 +3272,14 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
3211 h->cfgtable = remap_pci_mem(pci_resource_start(pdev, 3272 h->cfgtable = remap_pci_mem(pci_resource_start(pdev,
3212 cfg_base_addr_index) + cfg_offset, 3273 cfg_base_addr_index) + cfg_offset,
3213 sizeof(h->cfgtable)); 3274 sizeof(h->cfgtable));
3214 h->board_id = board_id; 3275 /* Find performant mode table. */
3215 3276 trans_offset = readl(&(h->cfgtable->TransMethodOffset));
3216 /* Query controller for max supported commands: */ 3277 h->transtable = remap_pci_mem(pci_resource_start(pdev,
3217 h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); 3278 cfg_base_addr_index)+cfg_offset+trans_offset,
3279 sizeof(*h->transtable));
3218 3280
3281 h->board_id = board_id;
3282 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
3219 h->product_name = products[prod_index].product_name; 3283 h->product_name = products[prod_index].product_name;
3220 h->access = *(products[prod_index].access); 3284 h->access = *(products[prod_index].access);
3221 /* Allow room for some ioctls */ 3285 /* Allow room for some ioctls */
@@ -3314,7 +3378,12 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3314 } 3378 }
3315 } 3379 }
3316 3380
3317 BUILD_BUG_ON(sizeof(struct CommandList) % 8); 3381 /* Command structures must be aligned on a 32-byte boundary because
3382 * the 5 lower bits of the address are used by the hardware. and by
3383 * the driver. See comments in hpsa.h for more info.
3384 */
3385#define COMMANDLIST_ALIGNMENT 32
3386 BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT);
3318 h = kzalloc(sizeof(*h), GFP_KERNEL); 3387 h = kzalloc(sizeof(*h), GFP_KERNEL);
3319 if (!h) 3388 if (!h)
3320 return -ENOMEM; 3389 return -ENOMEM;
@@ -3349,17 +3418,17 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3349 3418
3350 /* make sure the board interrupts are off */ 3419 /* make sure the board interrupts are off */
3351 h->access.set_intr_mask(h, HPSA_INTR_OFF); 3420 h->access.set_intr_mask(h, HPSA_INTR_OFF);
3352 rc = request_irq(h->intr[SIMPLE_MODE_INT], do_hpsa_intr, 3421 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr,
3353 IRQF_DISABLED | IRQF_SHARED, h->devname, h); 3422 IRQF_DISABLED, h->devname, h);
3354 if (rc) { 3423 if (rc) {
3355 dev_err(&pdev->dev, "unable to get irq %d for %s\n", 3424 dev_err(&pdev->dev, "unable to get irq %d for %s\n",
3356 h->intr[SIMPLE_MODE_INT], h->devname); 3425 h->intr[PERF_MODE_INT], h->devname);
3357 goto clean2; 3426 goto clean2;
3358 } 3427 }
3359 3428
3360 dev_info(&pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", 3429 dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
3361 h->devname, pdev->device, pci_name(pdev), 3430 h->devname, pdev->device,
3362 h->intr[SIMPLE_MODE_INT], dac ? "" : " not"); 3431 h->intr[PERF_MODE_INT], dac ? "" : " not");
3363 3432
3364 h->cmd_pool_bits = 3433 h->cmd_pool_bits =
3365 kmalloc(((h->nr_cmds + BITS_PER_LONG - 3434 kmalloc(((h->nr_cmds + BITS_PER_LONG -
@@ -3389,6 +3458,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3389 /* Turn the interrupts on so we can service requests */ 3458 /* Turn the interrupts on so we can service requests */
3390 h->access.set_intr_mask(h, HPSA_INTR_ON); 3459 h->access.set_intr_mask(h, HPSA_INTR_ON);
3391 3460
3461 hpsa_put_ctlr_into_performant_mode(h);
3392 hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ 3462 hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
3393 h->busy_initializing = 0; 3463 h->busy_initializing = 0;
3394 return 1; 3464 return 1;
@@ -3404,7 +3474,7 @@ clean4:
3404 h->nr_cmds * sizeof(struct ErrorInfo), 3474 h->nr_cmds * sizeof(struct ErrorInfo),
3405 h->errinfo_pool, 3475 h->errinfo_pool,
3406 h->errinfo_pool_dhandle); 3476 h->errinfo_pool_dhandle);
3407 free_irq(h->intr[SIMPLE_MODE_INT], h); 3477 free_irq(h->intr[PERF_MODE_INT], h);
3408clean2: 3478clean2:
3409clean1: 3479clean1:
3410 h->busy_initializing = 0; 3480 h->busy_initializing = 0;
@@ -3448,7 +3518,7 @@ static void hpsa_shutdown(struct pci_dev *pdev)
3448 */ 3518 */
3449 hpsa_flush_cache(h); 3519 hpsa_flush_cache(h);
3450 h->access.set_intr_mask(h, HPSA_INTR_OFF); 3520 h->access.set_intr_mask(h, HPSA_INTR_OFF);
3451 free_irq(h->intr[2], h); 3521 free_irq(h->intr[PERF_MODE_INT], h);
3452#ifdef CONFIG_PCI_MSI 3522#ifdef CONFIG_PCI_MSI
3453 if (h->msix_vector) 3523 if (h->msix_vector)
3454 pci_disable_msix(h->pdev); 3524 pci_disable_msix(h->pdev);
@@ -3477,7 +3547,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
3477 pci_free_consistent(h->pdev, 3547 pci_free_consistent(h->pdev,
3478 h->nr_cmds * sizeof(struct ErrorInfo), 3548 h->nr_cmds * sizeof(struct ErrorInfo),
3479 h->errinfo_pool, h->errinfo_pool_dhandle); 3549 h->errinfo_pool, h->errinfo_pool_dhandle);
3550 pci_free_consistent(h->pdev, h->reply_pool_size,
3551 h->reply_pool, h->reply_pool_dhandle);
3480 kfree(h->cmd_pool_bits); 3552 kfree(h->cmd_pool_bits);
3553 kfree(h->blockFetchTable);
3481 /* 3554 /*
3482 * Deliberately omit pci_disable_device(): it does something nasty to 3555 * Deliberately omit pci_disable_device(): it does something nasty to
3483 * Smart Array controllers that pci_enable_device does not undo 3556 * Smart Array controllers that pci_enable_device does not undo
@@ -3509,6 +3582,129 @@ static struct pci_driver hpsa_pci_driver = {
3509 .resume = hpsa_resume, 3582 .resume = hpsa_resume,
3510}; 3583};
3511 3584
3585/* Fill in bucket_map[], given nsgs (the max number of
3586 * scatter gather elements supported) and bucket[],
3587 * which is an array of 8 integers. The bucket[] array
3588 * contains 8 different DMA transfer sizes (in 16
3589 * byte increments) which the controller uses to fetch
3590 * commands. This function fills in bucket_map[], which
3591 * maps a given number of scatter gather elements to one of
3592 * the 8 DMA transfer sizes. The point of it is to allow the
3593 * controller to only do as much DMA as needed to fetch the
3594 * command, with the DMA transfer size encoded in the lower
3595 * bits of the command address.
3596 */
3597static void calc_bucket_map(int bucket[], int num_buckets,
3598 int nsgs, int *bucket_map)
3599{
3600 int i, j, b, size;
3601
3602 /* even a command with 0 SGs requires 4 blocks */
3603#define MINIMUM_TRANSFER_BLOCKS 4
3604#define NUM_BUCKETS 8
3605 /* Note, bucket_map must have nsgs+1 entries. */
3606 for (i = 0; i <= nsgs; i++) {
3607 /* Compute size of a command with i SG entries */
3608 size = i + MINIMUM_TRANSFER_BLOCKS;
3609 b = num_buckets; /* Assume the biggest bucket */
3610 /* Find the bucket that is just big enough */
3611 for (j = 0; j < 8; j++) {
3612 if (bucket[j] >= size) {
3613 b = j;
3614 break;
3615 }
3616 }
3617 /* for a command with i SG entries, use bucket b. */
3618 bucket_map[i] = b;
3619 }
3620}
3621
3622static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
3623{
3624 u32 trans_support;
3625 u64 trans_offset;
3626 /* 5 = 1 s/g entry or 4k
3627 * 6 = 2 s/g entry or 8k
3628 * 8 = 4 s/g entry or 16k
3629 * 10 = 6 s/g entry or 24k
3630 */
3631 int bft[8] = {5, 6, 8, 10, 12, 20, 28, 35}; /* for scatter/gathers */
3632 int i = 0;
3633 int l = 0;
3634 unsigned long register_value;
3635
3636 trans_support = readl(&(h->cfgtable->TransportSupport));
3637 if (!(trans_support & PERFORMANT_MODE))
3638 return;
3639
3640 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
3641 h->max_sg_entries = 32;
3642 /* Performant mode ring buffer and supporting data structures */
3643 h->reply_pool_size = h->max_commands * sizeof(u64);
3644 h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size,
3645 &(h->reply_pool_dhandle));
3646
3647 /* Need a block fetch table for performant mode */
3648 h->blockFetchTable = kmalloc(((h->max_sg_entries+1) *
3649 sizeof(u32)), GFP_KERNEL);
3650
3651 if ((h->reply_pool == NULL)
3652 || (h->blockFetchTable == NULL))
3653 goto clean_up;
3654
3655 h->reply_pool_wraparound = 1; /* spec: init to 1 */
3656
3657 /* Controller spec: zero out this buffer. */
3658 memset(h->reply_pool, 0, h->reply_pool_size);
3659 h->reply_pool_head = h->reply_pool;
3660
3661 trans_offset = readl(&(h->cfgtable->TransMethodOffset));
3662 bft[7] = h->max_sg_entries + 4;
3663 calc_bucket_map(bft, ARRAY_SIZE(bft), 32, h->blockFetchTable);
3664 for (i = 0; i < 8; i++)
3665 writel(bft[i], &h->transtable->BlockFetch[i]);
3666
3667 /* size of controller ring buffer */
3668 writel(h->max_commands, &h->transtable->RepQSize);
3669 writel(1, &h->transtable->RepQCount);
3670 writel(0, &h->transtable->RepQCtrAddrLow32);
3671 writel(0, &h->transtable->RepQCtrAddrHigh32);
3672 writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32);
3673 writel(0, &h->transtable->RepQAddr0High32);
3674 writel(CFGTBL_Trans_Performant,
3675 &(h->cfgtable->HostWrite.TransportRequest));
3676 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
3677 /* under certain very rare conditions, this can take awhile.
3678 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
3679 * as we enter this code.) */
3680 for (l = 0; l < MAX_CONFIG_WAIT; l++) {
3681 register_value = readl(h->vaddr + SA5_DOORBELL);
3682 if (!(register_value & CFGTBL_ChangeReq))
3683 break;
3684 /* delay and try again */
3685 set_current_state(TASK_INTERRUPTIBLE);
3686 schedule_timeout(10);
3687 }
3688 register_value = readl(&(h->cfgtable->TransportActive));
3689 if (!(register_value & CFGTBL_Trans_Performant)) {
3690 dev_warn(&h->pdev->dev, "unable to get board into"
3691 " performant mode\n");
3692 return;
3693 }
3694
3695 /* Change the access methods to the performant access methods */
3696 h->access = SA5_performant_access;
3697 h->transMethod = CFGTBL_Trans_Performant;
3698
3699 return;
3700
3701clean_up:
3702 if (h->reply_pool)
3703 pci_free_consistent(h->pdev, h->reply_pool_size,
3704 h->reply_pool, h->reply_pool_dhandle);
3705 kfree(h->blockFetchTable);
3706}
3707
3512/* 3708/*
3513 * This is it. Register the PCI driver information for the cards we control 3709 * This is it. Register the PCI driver information for the cards we control
3514 * the OS will call our registered routines when it finds one of our cards. 3710 * the OS will call our registered routines when it finds one of our cards.
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 0eab386a03be..0ba1aa3f4d4d 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -60,14 +60,15 @@ struct ctlr_info {
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];
@@ -102,6 +103,23 @@ struct ctlr_info {
102 int ndevices; /* number of used elements in .dev[] array. */ 103 int ndevices; /* number of used elements in .dev[] array. */
103#define HPSA_MAX_SCSI_DEVS_PER_HBA 256 104#define HPSA_MAX_SCSI_DEVS_PER_HBA 256
104 struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA]; 105 struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
106 /*
107 * Performant mode tables.
108 */
109 u32 trans_support;
110 u32 trans_offset;
111 struct TransTable_struct *transtable;
112 unsigned long transMethod;
113
114 /*
115 * Performant mode completion buffer
116 */
117 u64 *reply_pool;
118 dma_addr_t reply_pool_dhandle;
119 u64 *reply_pool_head;
120 size_t reply_pool_size;
121 unsigned char reply_pool_wraparound;
122 u32 *blockFetchTable;
105}; 123};
106#define HPSA_ABORT_MSG 0 124#define HPSA_ABORT_MSG 0
107#define HPSA_DEVICE_RESET_MSG 1 125#define HPSA_DEVICE_RESET_MSG 1
@@ -165,6 +183,16 @@ struct ctlr_info {
165 183
166#define HPSA_ERROR_BIT 0x02 184#define HPSA_ERROR_BIT 0x02
167 185
186/* Performant mode flags */
187#define SA5_PERF_INTR_PENDING 0x04
188#define SA5_PERF_INTR_OFF 0x05
189#define SA5_OUTDB_STATUS_PERF_BIT 0x01
190#define SA5_OUTDB_CLEAR_PERF_BIT 0x01
191#define SA5_OUTDB_CLEAR 0xA0
192#define SA5_OUTDB_CLEAR_PERF_BIT 0x01
193#define SA5_OUTDB_STATUS 0x9C
194
195
168#define HPSA_INTR_ON 1 196#define HPSA_INTR_ON 1
169#define HPSA_INTR_OFF 0 197#define HPSA_INTR_OFF 0
170/* 198/*
@@ -173,7 +201,8 @@ struct ctlr_info {
173static void SA5_submit_command(struct ctlr_info *h, 201static void SA5_submit_command(struct ctlr_info *h,
174 struct CommandList *c) 202 struct CommandList *c)
175{ 203{
176 dev_dbg(&h->pdev->dev, "Sending %x\n", c->busaddr); 204 dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
205 c->Header.Tag.lower);
177 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); 206 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
178 h->commands_outstanding++; 207 h->commands_outstanding++;
179 if (h->commands_outstanding > h->max_outstanding) 208 if (h->commands_outstanding > h->max_outstanding)
@@ -196,6 +225,52 @@ static void SA5_intr_mask(struct ctlr_info *h, unsigned long val)
196 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 225 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
197 } 226 }
198} 227}
228
229static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
230{
231 if (val) { /* turn on interrupts */
232 h->interrupts_enabled = 1;
233 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
234 } else {
235 h->interrupts_enabled = 0;
236 writel(SA5_PERF_INTR_OFF,
237 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
238 }
239}
240
241static unsigned long SA5_performant_completed(struct ctlr_info *h)
242{
243 unsigned long register_value = FIFO_EMPTY;
244
245 /* flush the controller write of the reply queue by reading
246 * outbound doorbell status register.
247 */
248 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
249 /* msi auto clears the interrupt pending bit. */
250 if (!(h->msi_vector || h->msix_vector)) {
251 writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR);
252 /* Do a read in order to flush the write to the controller
253 * (as per spec.)
254 */
255 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
256 }
257
258 if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
259 register_value = *(h->reply_pool_head);
260 (h->reply_pool_head)++;
261 h->commands_outstanding--;
262 } else {
263 register_value = FIFO_EMPTY;
264 }
265 /* Check for wraparound */
266 if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
267 h->reply_pool_head = h->reply_pool;
268 h->reply_pool_wraparound ^= 1;
269 }
270
271 return register_value;
272}
273
199/* 274/*
200 * Returns true if fifo is full. 275 * Returns true if fifo is full.
201 * 276 *
@@ -241,6 +316,20 @@ static bool SA5_intr_pending(struct ctlr_info *h)
241 return register_value & SA5_INTR_PENDING; 316 return register_value & SA5_INTR_PENDING;
242} 317}
243 318
319static bool SA5_performant_intr_pending(struct ctlr_info *h)
320{
321 unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
322
323 if (!register_value)
324 return false;
325
326 if (h->msi_vector || h->msix_vector)
327 return true;
328
329 /* Read outbound doorbell to flush */
330 register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
331 return register_value & SA5_OUTDB_STATUS_PERF_BIT;
332}
244 333
245static struct access_method SA5_access = { 334static struct access_method SA5_access = {
246 SA5_submit_command, 335 SA5_submit_command,
@@ -250,14 +339,19 @@ static struct access_method SA5_access = {
250 SA5_completed, 339 SA5_completed,
251}; 340};
252 341
342static struct access_method SA5_performant_access = {
343 SA5_submit_command,
344 SA5_performant_intr_mask,
345 SA5_fifo_full,
346 SA5_performant_intr_pending,
347 SA5_performant_completed,
348};
349
253struct board_type { 350struct board_type {
254 u32 board_id; 351 u32 board_id;
255 char *product_name; 352 char *product_name;
256 struct access_method *access; 353 struct access_method *access;
257}; 354};
258 355
259
260/* end of old hpsa_scsi.h file */
261
262#endif /* HPSA_H */ 356#endif /* HPSA_H */
263 357
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 88bb3b0a21d3..3e0abdf76689 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -101,6 +101,7 @@
101#define CFGTBL_AccCmds 0x00000001l 101#define CFGTBL_AccCmds 0x00000001l
102 102
103#define CFGTBL_Trans_Simple 0x00000002l 103#define CFGTBL_Trans_Simple 0x00000002l
104#define CFGTBL_Trans_Performant 0x00000004l
104 105
105#define CFGTBL_BusType_Ultra2 0x00000001l 106#define CFGTBL_BusType_Ultra2 0x00000001l
106#define CFGTBL_BusType_Ultra3 0x00000002l 107#define CFGTBL_BusType_Ultra3 0x00000002l
@@ -267,12 +268,31 @@ struct ErrorInfo {
267#define CMD_IOCTL_PEND 0x01 268#define CMD_IOCTL_PEND 0x01
268#define CMD_SCSI 0x03 269#define CMD_SCSI 0x03
269 270
271/* This structure needs to be divisible by 32 for new
272 * indexing method and performant mode.
273 */
274#define PAD32 32
275#define PAD64DIFF 0
276#define USEEXTRA ((sizeof(void *) - 4)/4)
277#define PADSIZE (PAD32 + PAD64DIFF * USEEXTRA)
278
279#define DIRECT_LOOKUP_SHIFT 5
280#define DIRECT_LOOKUP_BIT 0x10
281
282#define HPSA_ERROR_BIT 0x02
270struct ctlr_info; /* defined in hpsa.h */ 283struct ctlr_info; /* defined in hpsa.h */
271/* The size of this structure needs to be divisible by 8 284/* The size of this structure needs to be divisible by 32
272 * on all architectures, because the controller uses 2 285 * on all architectures because low 5 bits of the addresses
273 * lower bits of the address, and the driver uses 1 lower 286 * are used as follows:
274 * bit (3 bits total.) 287 *
288 * bit 0: to device, used to indicate "performant mode" command
289 * from device, indidcates error status.
290 * bit 1-3: to device, indicates block fetch table entry for
291 * reducing DMA in fetching commands from host memory.
292 * bit 4: used to indicate whether tag is "direct lookup" (index),
293 * or a bus address.
275 */ 294 */
295
276struct CommandList { 296struct CommandList {
277 struct CommandListHeader Header; 297 struct CommandListHeader Header;
278 struct RequestBlock Request; 298 struct RequestBlock Request;
@@ -291,6 +311,14 @@ struct CommandList {
291 struct completion *waiting; 311 struct completion *waiting;
292 int retry_count; 312 int retry_count;
293 void *scsi_cmd; 313 void *scsi_cmd;
314
315/* on 64 bit architectures, to get this to be 32-byte-aligned
316 * it so happens we need no padding, on 32 bit systems,
317 * we need 8 bytes of padding. This does that.
318 */
319#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8)
320 u8 pad[COMMANDLIST_PAD];
321
294}; 322};
295 323
296/* Configuration Table Structure */ 324/* Configuration Table Structure */
@@ -301,18 +329,38 @@ struct HostWrite {
301 u32 CoalIntCount; 329 u32 CoalIntCount;
302}; 330};
303 331
332#define SIMPLE_MODE 0x02
333#define PERFORMANT_MODE 0x04
334#define MEMQ_MODE 0x08
335
304struct CfgTable { 336struct CfgTable {
305 u8 Signature[4]; 337 u8 Signature[4];
306 u32 SpecValence; 338 u32 SpecValence;
307 u32 TransportSupport; 339 u32 TransportSupport;
308 u32 TransportActive; 340 u32 TransportActive;
309 struct HostWrite HostWrite; 341 struct HostWrite HostWrite;
310 u32 CmdsOutMax; 342 u32 CmdsOutMax;
311 u32 BusTypes; 343 u32 BusTypes;
312 u32 Reserved; 344 u32 TransMethodOffset;
313 u8 ServerName[16]; 345 u8 ServerName[16];
314 u32 HeartBeat; 346 u32 HeartBeat;
315 u32 SCSI_Prefetch; 347 u32 SCSI_Prefetch;
348 u32 MaxScatterGatherElements;
349 u32 MaxLogicalUnits;
350 u32 MaxPhysicalDevices;
351 u32 MaxPhysicalDrivesPerLogicalUnit;
352 u32 MaxPerformantModeCommands;
353};
354
355#define NUM_BLOCKFETCH_ENTRIES 8
356struct TransTable_struct {
357 u32 BlockFetch[NUM_BLOCKFETCH_ENTRIES];
358 u32 RepQSize;
359 u32 RepQCount;
360 u32 RepQCtrAddrLow32;
361 u32 RepQCtrAddrHigh32;
362 u32 RepQAddr0Low32;
363 u32 RepQAddr0High32;
316}; 364};
317 365
318struct hpsa_pci_info { 366struct hpsa_pci_info {