aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2011-02-15 16:32:53 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-18 13:32:30 -0500
commita9a3a2739a44fc05dcaba0d4d36e52dc444c294f (patch)
treec43e58da09b90246f056a852ee698bc0028ac23f /drivers/scsi/hpsa.c
parent9e0fc764eaec082cd2ffcf82568dfdd086935934 (diff)
[SCSI] hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work
It's not enough to simple avoid putting the board into performant mode, as we have to set up the interrupts differently, etc. When I originally tested this module parameter, I tested it incorrectly without realizing it, and the driver was running in performant mode the whole time unbeknownst to me. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0f40de2a33de..66ccacfffd51 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1186,7 +1186,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
1186 sh->sg_tablesize = h->maxsgentries; 1186 sh->sg_tablesize = h->maxsgentries;
1187 h->scsi_host = sh; 1187 h->scsi_host = sh;
1188 sh->hostdata[0] = (unsigned long) h; 1188 sh->hostdata[0] = (unsigned long) h;
1189 sh->irq = h->intr[PERF_MODE_INT]; 1189 sh->irq = h->intr[h->intr_mode];
1190 sh->unique_id = sh->irq; 1190 sh->unique_id = sh->irq;
1191 error = scsi_add_host(sh, &h->pdev->dev); 1191 error = scsi_add_host(sh, &h->pdev->dev);
1192 if (error) 1192 if (error)
@@ -2902,10 +2902,14 @@ static inline u32 hpsa_tag_to_index(u32 tag)
2902 return tag >> DIRECT_LOOKUP_SHIFT; 2902 return tag >> DIRECT_LOOKUP_SHIFT;
2903} 2903}
2904 2904
2905static inline u32 hpsa_tag_discard_error_bits(u32 tag) 2905
2906static inline u32 hpsa_tag_discard_error_bits(struct ctlr_info *h, u32 tag)
2906{ 2907{
2907#define HPSA_ERROR_BITS 0x03 2908#define HPSA_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
2908 return tag & ~HPSA_ERROR_BITS; 2909#define HPSA_SIMPLE_ERROR_BITS 0x03
2910 if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
2911 return tag & ~HPSA_SIMPLE_ERROR_BITS;
2912 return tag & ~HPSA_PERF_ERROR_BITS;
2909} 2913}
2910 2914
2911/* process completion of an indexed ("direct lookup") command */ 2915/* process completion of an indexed ("direct lookup") command */
@@ -2930,7 +2934,7 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
2930 u32 tag; 2934 u32 tag;
2931 struct CommandList *c = NULL; 2935 struct CommandList *c = NULL;
2932 2936
2933 tag = hpsa_tag_discard_error_bits(raw_tag); 2937 tag = hpsa_tag_discard_error_bits(h, raw_tag);
2934 list_for_each_entry(c, &h->cmpQ, list) { 2938 list_for_each_entry(c, &h->cmpQ, list) {
2935 if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) { 2939 if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) {
2936 finish_cmd(c, raw_tag); 2940 finish_cmd(c, raw_tag);
@@ -2981,7 +2985,10 @@ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
2981 return IRQ_HANDLED; 2985 return IRQ_HANDLED;
2982} 2986}
2983 2987
2984/* Send a message CDB to the firmware. */ 2988/* Send a message CDB to the firmware. Careful, this only works
2989 * in simple mode, not performant mode due to the tag lookup.
2990 * We only ever use this immediately after a controller reset.
2991 */
2985static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, 2992static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
2986 unsigned char type) 2993 unsigned char type)
2987{ 2994{
@@ -3047,7 +3054,7 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
3047 3054
3048 for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) { 3055 for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) {
3049 tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); 3056 tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
3050 if (hpsa_tag_discard_error_bits(tag) == paddr32) 3057 if ((tag & ~HPSA_SIMPLE_ERROR_BITS) == paddr32)
3051 break; 3058 break;
3052 msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS); 3059 msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
3053 } 3060 }
@@ -3379,7 +3386,7 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h)
3379default_int_mode: 3386default_int_mode:
3380#endif /* CONFIG_PCI_MSI */ 3387#endif /* CONFIG_PCI_MSI */
3381 /* if we get here we're going to use the default interrupt mode */ 3388 /* if we get here we're going to use the default interrupt mode */
3382 h->intr[PERF_MODE_INT] = h->pdev->irq; 3389 h->intr[h->intr_mode] = h->pdev->irq;
3383} 3390}
3384 3391
3385static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id) 3392static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id)
@@ -3760,6 +3767,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3760 3767
3761 h->pdev = pdev; 3768 h->pdev = pdev;
3762 h->busy_initializing = 1; 3769 h->busy_initializing = 1;
3770 h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
3771 printk(KERN_WARNING "hpsa_simple_mode is %d\n", hpsa_simple_mode);
3763 INIT_LIST_HEAD(&h->cmpQ); 3772 INIT_LIST_HEAD(&h->cmpQ);
3764 INIT_LIST_HEAD(&h->reqQ); 3773 INIT_LIST_HEAD(&h->reqQ);
3765 spin_lock_init(&h->lock); 3774 spin_lock_init(&h->lock);
@@ -3790,20 +3799,20 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3790 h->access.set_intr_mask(h, HPSA_INTR_OFF); 3799 h->access.set_intr_mask(h, HPSA_INTR_OFF);
3791 3800
3792 if (h->msix_vector || h->msi_vector) 3801 if (h->msix_vector || h->msi_vector)
3793 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_msi, 3802 rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_msi,
3794 IRQF_DISABLED, h->devname, h); 3803 IRQF_DISABLED, h->devname, h);
3795 else 3804 else
3796 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_intx, 3805 rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_intx,
3797 IRQF_DISABLED, h->devname, h); 3806 IRQF_DISABLED, h->devname, h);
3798 if (rc) { 3807 if (rc) {
3799 dev_err(&pdev->dev, "unable to get irq %d for %s\n", 3808 dev_err(&pdev->dev, "unable to get irq %d for %s\n",
3800 h->intr[PERF_MODE_INT], h->devname); 3809 h->intr[h->intr_mode], h->devname);
3801 goto clean2; 3810 goto clean2;
3802 } 3811 }
3803 3812
3804 dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n", 3813 dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
3805 h->devname, pdev->device, 3814 h->devname, pdev->device,
3806 h->intr[PERF_MODE_INT], dac ? "" : " not"); 3815 h->intr[h->intr_mode], dac ? "" : " not");
3807 3816
3808 h->cmd_pool_bits = 3817 h->cmd_pool_bits =
3809 kmalloc(((h->nr_cmds + BITS_PER_LONG - 3818 kmalloc(((h->nr_cmds + BITS_PER_LONG -
@@ -3854,7 +3863,7 @@ clean4:
3854 h->nr_cmds * sizeof(struct ErrorInfo), 3863 h->nr_cmds * sizeof(struct ErrorInfo),
3855 h->errinfo_pool, 3864 h->errinfo_pool,
3856 h->errinfo_pool_dhandle); 3865 h->errinfo_pool_dhandle);
3857 free_irq(h->intr[PERF_MODE_INT], h); 3866 free_irq(h->intr[h->intr_mode], h);
3858clean2: 3867clean2:
3859clean1: 3868clean1:
3860 h->busy_initializing = 0; 3869 h->busy_initializing = 0;
@@ -3898,7 +3907,7 @@ static void hpsa_shutdown(struct pci_dev *pdev)
3898 */ 3907 */
3899 hpsa_flush_cache(h); 3908 hpsa_flush_cache(h);
3900 h->access.set_intr_mask(h, HPSA_INTR_OFF); 3909 h->access.set_intr_mask(h, HPSA_INTR_OFF);
3901 free_irq(h->intr[PERF_MODE_INT], h); 3910 free_irq(h->intr[h->intr_mode], h);
3902#ifdef CONFIG_PCI_MSI 3911#ifdef CONFIG_PCI_MSI
3903 if (h->msix_vector) 3912 if (h->msix_vector)
3904 pci_disable_msix(h->pdev); 3913 pci_disable_msix(h->pdev);