diff options
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 73 |
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); | |||
104 | static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | 104 | static 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; |