X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fmegaraid%2Fmegaraid_sas.c;h=39729460b00e243b8be2b9257d9f71e11b769895;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=a8c9627a15c4d59cdf013c4503da34818b3b8f98;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a8c9627a1..39729460b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.01 + * Version : v00.00.02.04 * * Authors: * Sreenivas Bagalkote @@ -55,25 +55,19 @@ static struct pci_device_id megasas_pci_table[] = { { PCI_VENDOR_ID_LSI_LOGIC, - PCI_DEVICE_ID_LSI_SAS1064R, /* xscale IOP */ + PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_LSI_LOGIC, - PCI_DEVICE_ID_LSI_SAS1078R, /* ppc IOP */ + PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP PCI_ANY_ID, PCI_ANY_ID, }, - { - PCI_VENDOR_ID_LSI_LOGIC, - PCI_DEVICE_ID_LSI_VERDE_ZCR, /* xscale IOP, vega */ - PCI_ANY_ID, - PCI_ANY_ID, - }, { PCI_VENDOR_ID_DELL, - PCI_DEVICE_ID_DELL_PERC5, /* xscale IOP */ + PCI_DEVICE_ID_DELL_PERC5, // xscale IOP PCI_ANY_ID, PCI_ANY_ID, }, @@ -295,14 +289,9 @@ static struct megasas_instance_template megasas_instance_template_ppc = { * @regs: MFI register set */ static inline void -megasas_disable_intr(struct megasas_instance *instance) +megasas_disable_intr(struct megasas_register_set __iomem * regs) { u32 mask = 0x1f; - struct megasas_register_set __iomem *regs = instance->reg_set; - - if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R) - mask = 0xffffffff; - writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ @@ -752,6 +741,7 @@ static int megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) { u32 frame_count; + unsigned long flags; struct megasas_cmd *cmd; struct megasas_instance *instance; @@ -786,7 +776,9 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) /* * Issue the command to the FW */ - atomic_inc(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding++; + spin_unlock_irqrestore(&instance->instance_lock, flags); instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set); @@ -834,20 +826,19 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) for (i = 0; i < wait_time; i++) { - int outstanding = atomic_read(&instance->fw_outstanding); - - if (!outstanding) + if (!instance->fw_outstanding) break; if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { printk(KERN_NOTICE "megasas: [%2d]waiting for %d " - "commands to complete\n",i,outstanding); + "commands to complete\n", i, + instance->fw_outstanding); } msleep(1000); } - if (atomic_read(&instance->fw_outstanding)) { + if (instance->fw_outstanding) { instance->hw_crit_error = 1; return FAILED; } @@ -1059,6 +1050,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr; + unsigned long flags; if (cmd->scmd) { cmd->scmd->SCp.ptr = (char *)0; @@ -1090,7 +1082,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, if (exception) { - atomic_dec(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding--; + spin_unlock_irqrestore(&instance->instance_lock, flags); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -1138,7 +1132,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, break; } - atomic_dec(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding--; + spin_unlock_irqrestore(&instance->instance_lock, flags); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -1271,7 +1267,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) /* * Bring it to READY state; assuming max wait 2 secs */ - megasas_disable_intr(instance); + megasas_disable_intr(instance->reg_set); writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); max_wait = 10; @@ -1767,11 +1763,6 @@ static int megasas_init_mfi(struct megasas_instance *instance) init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); - /* - * disable the intr before firing the init frame to FW - */ - megasas_disable_intr(instance); - /* * Issue the init frame in polled mode */ @@ -2180,12 +2171,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) */ INIT_LIST_HEAD(&instance->cmd_pool); - atomic_set(&instance->fw_outstanding,0); - init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); spin_lock_init(&instance->cmd_pool_lock); + spin_lock_init(&instance->instance_lock); sema_init(&instance->aen_mutex, 1); sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); @@ -2207,7 +2197,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* * Register IRQ */ - if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) { + if (request_irq(pdev->irq, megasas_isr, SA_SHIRQ, "megasas", instance)) { printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); goto fail_irq; } @@ -2250,7 +2240,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) megasas_mgmt_info.max_index--; pci_set_drvdata(pdev, NULL); - megasas_disable_intr(instance); + megasas_disable_intr(instance->reg_set); free_irq(instance->pdev->irq, instance); megasas_release_mfi(instance); @@ -2380,7 +2370,7 @@ static void megasas_detach_one(struct pci_dev *pdev) pci_set_drvdata(instance->pdev, NULL); - megasas_disable_intr(instance); + megasas_disable_intr(instance->reg_set); free_irq(instance->pdev->irq, instance);