aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c73
1 files changed, 46 insertions, 27 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index cdfe5a16de2a..e002cd466e9a 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -104,7 +104,9 @@ static DEFINE_SPINLOCK(ipr_driver_lock);
104static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { 104static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
105 { /* Gemstone, Citrine, Obsidian, and Obsidian-E */ 105 { /* Gemstone, Citrine, Obsidian, and Obsidian-E */
106 .mailbox = 0x0042C, 106 .mailbox = 0x0042C,
107 .max_cmds = 100,
107 .cache_line_size = 0x20, 108 .cache_line_size = 0x20,
109 .clear_isr = 1,
108 { 110 {
109 .set_interrupt_mask_reg = 0x0022C, 111 .set_interrupt_mask_reg = 0x0022C,
110 .clr_interrupt_mask_reg = 0x00230, 112 .clr_interrupt_mask_reg = 0x00230,
@@ -126,7 +128,9 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
126 }, 128 },
127 { /* Snipe and Scamp */ 129 { /* Snipe and Scamp */
128 .mailbox = 0x0052C, 130 .mailbox = 0x0052C,
131 .max_cmds = 100,
129 .cache_line_size = 0x20, 132 .cache_line_size = 0x20,
133 .clear_isr = 1,
130 { 134 {
131 .set_interrupt_mask_reg = 0x00288, 135 .set_interrupt_mask_reg = 0x00288,
132 .clr_interrupt_mask_reg = 0x0028C, 136 .clr_interrupt_mask_reg = 0x0028C,
@@ -148,7 +152,9 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
148 }, 152 },
149 { /* CRoC */ 153 { /* CRoC */
150 .mailbox = 0x00044, 154 .mailbox = 0x00044,
155 .max_cmds = 1000,
151 .cache_line_size = 0x20, 156 .cache_line_size = 0x20,
157 .clear_isr = 0,
152 { 158 {
153 .set_interrupt_mask_reg = 0x00010, 159 .set_interrupt_mask_reg = 0x00010,
154 .clr_interrupt_mask_reg = 0x00018, 160 .clr_interrupt_mask_reg = 0x00018,
@@ -847,8 +853,6 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
847 853
848 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); 854 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
849 855
850 mb();
851
852 ipr_send_command(ipr_cmd); 856 ipr_send_command(ipr_cmd);
853} 857}
854 858
@@ -982,8 +986,6 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
982 986
983 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); 987 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
984 988
985 mb();
986
987 ipr_send_command(ipr_cmd); 989 ipr_send_command(ipr_cmd);
988 } else { 990 } else {
989 list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); 991 list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
@@ -4339,8 +4341,7 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
4339 4341
4340 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 4342 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
4341 if ((res->bus == starget->channel) && 4343 if ((res->bus == starget->channel) &&
4342 (res->target == starget->id) && 4344 (res->target == starget->id)) {
4343 (res->lun == 0)) {
4344 return res; 4345 return res;
4345 } 4346 }
4346 } 4347 }
@@ -4414,12 +4415,14 @@ static void ipr_target_destroy(struct scsi_target *starget)
4414 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; 4415 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
4415 4416
4416 if (ioa_cfg->sis64) { 4417 if (ioa_cfg->sis64) {
4417 if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) 4418 if (!ipr_find_starget(starget)) {
4418 clear_bit(starget->id, ioa_cfg->array_ids); 4419 if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
4419 else if (starget->channel == IPR_VSET_VIRTUAL_BUS) 4420 clear_bit(starget->id, ioa_cfg->array_ids);
4420 clear_bit(starget->id, ioa_cfg->vset_ids); 4421 else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
4421 else if (starget->channel == 0) 4422 clear_bit(starget->id, ioa_cfg->vset_ids);
4422 clear_bit(starget->id, ioa_cfg->target_ids); 4423 else if (starget->channel == 0)
4424 clear_bit(starget->id, ioa_cfg->target_ids);
4425 }
4423 } 4426 }
4424 4427
4425 if (sata_port) { 4428 if (sata_port) {
@@ -5048,12 +5051,14 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
5048 del_timer(&ioa_cfg->reset_cmd->timer); 5051 del_timer(&ioa_cfg->reset_cmd->timer);
5049 ipr_reset_ioa_job(ioa_cfg->reset_cmd); 5052 ipr_reset_ioa_job(ioa_cfg->reset_cmd);
5050 } else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) { 5053 } else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) {
5051 if (ipr_debug && printk_ratelimit()) 5054 if (ioa_cfg->clear_isr) {
5052 dev_err(&ioa_cfg->pdev->dev, 5055 if (ipr_debug && printk_ratelimit())
5053 "Spurious interrupt detected. 0x%08X\n", int_reg); 5056 dev_err(&ioa_cfg->pdev->dev,
5054 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); 5057 "Spurious interrupt detected. 0x%08X\n", int_reg);
5055 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); 5058 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
5056 return IRQ_NONE; 5059 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
5060 return IRQ_NONE;
5061 }
5057 } else { 5062 } else {
5058 if (int_reg & IPR_PCII_IOA_UNIT_CHECKED) 5063 if (int_reg & IPR_PCII_IOA_UNIT_CHECKED)
5059 ioa_cfg->ioa_unit_checked = 1; 5064 ioa_cfg->ioa_unit_checked = 1;
@@ -5153,6 +5158,9 @@ static irqreturn_t ipr_isr(int irq, void *devp)
5153 } 5158 }
5154 } 5159 }
5155 5160
5161 if (ipr_cmd && !ioa_cfg->clear_isr)
5162 break;
5163
5156 if (ipr_cmd != NULL) { 5164 if (ipr_cmd != NULL) {
5157 /* Clear the PCI interrupt */ 5165 /* Clear the PCI interrupt */
5158 num_hrrq = 0; 5166 num_hrrq = 0;
@@ -5854,14 +5862,12 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
5854 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); 5862 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
5855 } 5863 }
5856 5864
5857 if (likely(rc == 0)) { 5865 if (unlikely(rc != 0)) {
5858 mb(); 5866 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
5859 ipr_send_command(ipr_cmd); 5867 return SCSI_MLQUEUE_HOST_BUSY;
5860 } else {
5861 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
5862 return SCSI_MLQUEUE_HOST_BUSY;
5863 } 5868 }
5864 5869
5870 ipr_send_command(ipr_cmd);
5865 return 0; 5871 return 0;
5866} 5872}
5867 5873
@@ -6239,8 +6245,6 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
6239 return AC_ERR_INVALID; 6245 return AC_ERR_INVALID;
6240 } 6246 }
6241 6247
6242 mb();
6243
6244 ipr_send_command(ipr_cmd); 6248 ipr_send_command(ipr_cmd);
6245 6249
6246 return 0; 6250 return 0;
@@ -8277,6 +8281,10 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
8277 if (ioa_cfg->ipr_cmd_pool) 8281 if (ioa_cfg->ipr_cmd_pool)
8278 pci_pool_destroy (ioa_cfg->ipr_cmd_pool); 8282 pci_pool_destroy (ioa_cfg->ipr_cmd_pool);
8279 8283
8284 kfree(ioa_cfg->ipr_cmnd_list);
8285 kfree(ioa_cfg->ipr_cmnd_list_dma);
8286 ioa_cfg->ipr_cmnd_list = NULL;
8287 ioa_cfg->ipr_cmnd_list_dma = NULL;
8280 ioa_cfg->ipr_cmd_pool = NULL; 8288 ioa_cfg->ipr_cmd_pool = NULL;
8281} 8289}
8282 8290
@@ -8352,11 +8360,19 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
8352 int i; 8360 int i;
8353 8361
8354 ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, 8362 ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev,
8355 sizeof(struct ipr_cmnd), 16, 0); 8363 sizeof(struct ipr_cmnd), 512, 0);
8356 8364
8357 if (!ioa_cfg->ipr_cmd_pool) 8365 if (!ioa_cfg->ipr_cmd_pool)
8358 return -ENOMEM; 8366 return -ENOMEM;
8359 8367
8368 ioa_cfg->ipr_cmnd_list = kcalloc(IPR_NUM_CMD_BLKS, sizeof(struct ipr_cmnd *), GFP_KERNEL);
8369 ioa_cfg->ipr_cmnd_list_dma = kcalloc(IPR_NUM_CMD_BLKS, sizeof(dma_addr_t), GFP_KERNEL);
8370
8371 if (!ioa_cfg->ipr_cmnd_list || !ioa_cfg->ipr_cmnd_list_dma) {
8372 ipr_free_cmd_blks(ioa_cfg);
8373 return -ENOMEM;
8374 }
8375
8360 for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { 8376 for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
8361 ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr); 8377 ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
8362 8378
@@ -8584,6 +8600,7 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
8584 host->max_channel = IPR_MAX_BUS_TO_SCAN; 8600 host->max_channel = IPR_MAX_BUS_TO_SCAN;
8585 host->unique_id = host->host_no; 8601 host->unique_id = host->host_no;
8586 host->max_cmd_len = IPR_MAX_CDB_LEN; 8602 host->max_cmd_len = IPR_MAX_CDB_LEN;
8603 host->can_queue = ioa_cfg->max_cmds;
8587 pci_set_drvdata(pdev, ioa_cfg); 8604 pci_set_drvdata(pdev, ioa_cfg);
8588 8605
8589 p = &ioa_cfg->chip_cfg->regs; 8606 p = &ioa_cfg->chip_cfg->regs;
@@ -8768,6 +8785,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
8768 /* set SIS 32 or SIS 64 */ 8785 /* set SIS 32 or SIS 64 */
8769 ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0; 8786 ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
8770 ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; 8787 ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
8788 ioa_cfg->clear_isr = ioa_cfg->chip_cfg->clear_isr;
8789 ioa_cfg->max_cmds = ioa_cfg->chip_cfg->max_cmds;
8771 8790
8772 if (ipr_transop_timeout) 8791 if (ipr_transop_timeout)
8773 ioa_cfg->transop_timeout = ipr_transop_timeout; 8792 ioa_cfg->transop_timeout = ipr_transop_timeout;