aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJoseph Handzik <joseph.t.handzik@beardog.cce.hp.com>2011-08-08 05:40:15 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-08-08 05:40:15 -0400
commit13049537007dee73a76f0a30fcbc24d02c6fa9e4 (patch)
tree2bc62c056f42ef8792c3912fef5ce5ca318df993 /drivers/block
parent322a8b034003c0d46d39af85bf24fee27b902f48 (diff)
cciss: Adds simple mode functionality
Signed-off-by: Joseph Handzik <joseph.t.handzik@beardog.cce.hp.com> Acked-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c56
-rw-r--r--drivers/block/cciss.h1
2 files changed, 46 insertions, 11 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 8f4ef656a1a..61f0b5b6a41 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -68,6 +68,10 @@ static int cciss_tape_cmds = 6;
68module_param(cciss_tape_cmds, int, 0644); 68module_param(cciss_tape_cmds, int, 0644);
69MODULE_PARM_DESC(cciss_tape_cmds, 69MODULE_PARM_DESC(cciss_tape_cmds,
70 "number of commands to allocate for tape devices (default: 6)"); 70 "number of commands to allocate for tape devices (default: 6)");
71static int cciss_simple_mode;
72module_param(cciss_simple_mode, int, S_IRUGO|S_IWUSR);
73MODULE_PARM_DESC(cciss_simple_mode,
74 "Use 'simple mode' rather than 'performant mode'");
71 75
72static DEFINE_MUTEX(cciss_mutex); 76static DEFINE_MUTEX(cciss_mutex);
73static struct proc_dir_entry *proc_cciss; 77static struct proc_dir_entry *proc_cciss;
@@ -176,6 +180,7 @@ static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol,
176 unsigned int block_size, InquiryData_struct *inq_buff, 180 unsigned int block_size, InquiryData_struct *inq_buff,
177 drive_info_struct *drv); 181 drive_info_struct *drv);
178static void __devinit cciss_interrupt_mode(ctlr_info_t *); 182static void __devinit cciss_interrupt_mode(ctlr_info_t *);
183static int __devinit cciss_enter_simple_mode(struct ctlr_info *h);
179static void start_io(ctlr_info_t *h); 184static void start_io(ctlr_info_t *h);
180static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, 185static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
181 __u8 page_code, unsigned char scsi3addr[], 186 __u8 page_code, unsigned char scsi3addr[],
@@ -388,7 +393,7 @@ static void cciss_seq_show_header(struct seq_file *seq)
388 h->product_name, 393 h->product_name,
389 (unsigned long)h->board_id, 394 (unsigned long)h->board_id,
390 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], 395 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
391 h->firm_ver[3], (unsigned int)h->intr[PERF_MODE_INT], 396 h->firm_ver[3], (unsigned int)h->intr[h->intr_mode],
392 h->num_luns, 397 h->num_luns,
393 h->Qdepth, h->commands_outstanding, 398 h->Qdepth, h->commands_outstanding,
394 h->maxQsinceinit, h->max_outstanding, h->maxSG); 399 h->maxQsinceinit, h->max_outstanding, h->maxSG);
@@ -3984,6 +3989,9 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
3984{ 3989{
3985 __u32 trans_support; 3990 __u32 trans_support;
3986 3991
3992 if (cciss_simple_mode)
3993 return;
3994
3987 dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); 3995 dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n");
3988 /* Attempt to put controller into performant mode if supported */ 3996 /* Attempt to put controller into performant mode if supported */
3989 /* Does board support performant mode? */ 3997 /* Does board support performant mode? */
@@ -4081,7 +4089,7 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *h)
4081default_int_mode: 4089default_int_mode:
4082#endif /* CONFIG_PCI_MSI */ 4090#endif /* CONFIG_PCI_MSI */
4083 /* if we get here we're going to use the default interrupt mode */ 4091 /* if we get here we're going to use the default interrupt mode */
4084 h->intr[PERF_MODE_INT] = h->pdev->irq; 4092 h->intr[h->intr_mode] = h->pdev->irq;
4085 return; 4093 return;
4086} 4094}
4087 4095
@@ -4341,6 +4349,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
4341 } 4349 }
4342 cciss_enable_scsi_prefetch(h); 4350 cciss_enable_scsi_prefetch(h);
4343 cciss_p600_dma_prefetch_quirk(h); 4351 cciss_p600_dma_prefetch_quirk(h);
4352 err = cciss_enter_simple_mode(h);
4353 if (err)
4354 goto err_out_free_res;
4344 cciss_put_controller_into_performant_mode(h); 4355 cciss_put_controller_into_performant_mode(h);
4345 return 0; 4356 return 0;
4346 4357
@@ -4843,20 +4854,20 @@ static int cciss_request_irq(ctlr_info_t *h,
4843 irqreturn_t (*intxhandler)(int, void *)) 4854 irqreturn_t (*intxhandler)(int, void *))
4844{ 4855{
4845 if (h->msix_vector || h->msi_vector) { 4856 if (h->msix_vector || h->msi_vector) {
4846 if (!request_irq(h->intr[PERF_MODE_INT], msixhandler, 4857 if (!request_irq(h->intr[h->intr_mode], msixhandler,
4847 IRQF_DISABLED, h->devname, h)) 4858 IRQF_DISABLED, h->devname, h))
4848 return 0; 4859 return 0;
4849 dev_err(&h->pdev->dev, "Unable to get msi irq %d" 4860 dev_err(&h->pdev->dev, "Unable to get msi irq %d"
4850 " for %s\n", h->intr[PERF_MODE_INT], 4861 " for %s\n", h->intr[h->intr_mode],
4851 h->devname); 4862 h->devname);
4852 return -1; 4863 return -1;
4853 } 4864 }
4854 4865
4855 if (!request_irq(h->intr[PERF_MODE_INT], intxhandler, 4866 if (!request_irq(h->intr[h->intr_mode], intxhandler,
4856 IRQF_DISABLED, h->devname, h)) 4867 IRQF_DISABLED, h->devname, h))
4857 return 0; 4868 return 0;
4858 dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", 4869 dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
4859 h->intr[PERF_MODE_INT], h->devname); 4870 h->intr[h->intr_mode], h->devname);
4860 return -1; 4871 return -1;
4861} 4872}
4862 4873
@@ -4887,7 +4898,7 @@ static void cciss_undo_allocations_after_kdump_soft_reset(ctlr_info_t *h)
4887{ 4898{
4888 int ctlr = h->ctlr; 4899 int ctlr = h->ctlr;
4889 4900
4890 free_irq(h->intr[PERF_MODE_INT], h); 4901 free_irq(h->intr[h->intr_mode], h);
4891#ifdef CONFIG_PCI_MSI 4902#ifdef CONFIG_PCI_MSI
4892 if (h->msix_vector) 4903 if (h->msix_vector)
4893 pci_disable_msix(h->pdev); 4904 pci_disable_msix(h->pdev);
@@ -4953,6 +4964,7 @@ reinit_after_soft_reset:
4953 h = hba[i]; 4964 h = hba[i];
4954 h->pdev = pdev; 4965 h->pdev = pdev;
4955 h->busy_initializing = 1; 4966 h->busy_initializing = 1;
4967 h->intr_mode = cciss_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
4956 INIT_LIST_HEAD(&h->cmpQ); 4968 INIT_LIST_HEAD(&h->cmpQ);
4957 INIT_LIST_HEAD(&h->reqQ); 4969 INIT_LIST_HEAD(&h->reqQ);
4958 mutex_init(&h->busy_shutting_down); 4970 mutex_init(&h->busy_shutting_down);
@@ -5009,7 +5021,7 @@ reinit_after_soft_reset:
5009 5021
5010 dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", 5022 dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
5011 h->devname, pdev->device, pci_name(pdev), 5023 h->devname, pdev->device, pci_name(pdev),
5012 h->intr[PERF_MODE_INT], dac ? "" : " not"); 5024 h->intr[h->intr_mode], dac ? "" : " not");
5013 5025
5014 if (cciss_allocate_cmd_pool(h)) 5026 if (cciss_allocate_cmd_pool(h))
5015 goto clean4; 5027 goto clean4;
@@ -5056,7 +5068,7 @@ reinit_after_soft_reset:
5056 spin_lock_irqsave(&h->lock, flags); 5068 spin_lock_irqsave(&h->lock, flags);
5057 h->access.set_intr_mask(h, CCISS_INTR_OFF); 5069 h->access.set_intr_mask(h, CCISS_INTR_OFF);
5058 spin_unlock_irqrestore(&h->lock, flags); 5070 spin_unlock_irqrestore(&h->lock, flags);
5059 free_irq(h->intr[PERF_MODE_INT], h); 5071 free_irq(h->intr[h->intr_mode], h);
5060 rc = cciss_request_irq(h, cciss_msix_discard_completions, 5072 rc = cciss_request_irq(h, cciss_msix_discard_completions,
5061 cciss_intx_discard_completions); 5073 cciss_intx_discard_completions);
5062 if (rc) { 5074 if (rc) {
@@ -5133,7 +5145,7 @@ clean4:
5133 cciss_free_cmd_pool(h); 5145 cciss_free_cmd_pool(h);
5134 cciss_free_scatterlists(h); 5146 cciss_free_scatterlists(h);
5135 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); 5147 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
5136 free_irq(h->intr[PERF_MODE_INT], h); 5148 free_irq(h->intr[h->intr_mode], h);
5137clean2: 5149clean2:
5138 unregister_blkdev(h->major, h->devname); 5150 unregister_blkdev(h->major, h->devname);
5139clean1: 5151clean1:
@@ -5172,9 +5184,31 @@ static void cciss_shutdown(struct pci_dev *pdev)
5172 if (return_code != IO_OK) 5184 if (return_code != IO_OK)
5173 dev_warn(&h->pdev->dev, "Error flushing cache\n"); 5185 dev_warn(&h->pdev->dev, "Error flushing cache\n");
5174 h->access.set_intr_mask(h, CCISS_INTR_OFF); 5186 h->access.set_intr_mask(h, CCISS_INTR_OFF);
5175 free_irq(h->intr[PERF_MODE_INT], h); 5187 free_irq(h->intr[h->intr_mode], h);
5176} 5188}
5177 5189
5190static int __devinit cciss_enter_simple_mode(struct ctlr_info *h)
5191{
5192 u32 trans_support;
5193
5194 trans_support = readl(&(h->cfgtable->TransportSupport));
5195 if (!(trans_support & SIMPLE_MODE))
5196 return -ENOTSUPP;
5197
5198 h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
5199 writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
5200 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
5201 cciss_wait_for_mode_change_ack(h);
5202 print_cfg_table(h);
5203 if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) {
5204 dev_warn(&h->pdev->dev, "unable to get board into simple mode\n");
5205 return -ENODEV;
5206 }
5207 h->transMethod = CFGTBL_Trans_Simple;
5208 return 0;
5209}
5210
5211
5178static void __devexit cciss_remove_one(struct pci_dev *pdev) 5212static void __devexit cciss_remove_one(struct pci_dev *pdev)
5179{ 5213{
5180 ctlr_info_t *h; 5214 ctlr_info_t *h;
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index c049548e68b..7fda30e4a24 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -92,6 +92,7 @@ struct ctlr_info
92 unsigned int intr[4]; 92 unsigned int intr[4];
93 unsigned int msix_vector; 93 unsigned int msix_vector;
94 unsigned int msi_vector; 94 unsigned int msi_vector;
95 int intr_mode;
95 int cciss_max_sectors; 96 int cciss_max_sectors;
96 BYTE cciss_read; 97 BYTE cciss_read;
97 BYTE cciss_write; 98 BYTE cciss_write;