X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fmegaraid%2Fmegaraid_sas.c;fp=drivers%2Fscsi%2Fmegaraid%2Fmegaraid_sas.c;h=a8c9627a15c4d59cdf013c4503da34818b3b8f98;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=39729460b00e243b8be2b9257d9f71e11b769895;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;p=linux-2.6.git diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 39729460b..a8c9627a1 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.02.04 + * Version : v00.00.03.01 * * Authors: * Sreenivas Bagalkote @@ -55,19 +55,25 @@ 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, }, @@ -289,9 +295,14 @@ static struct megasas_instance_template megasas_instance_template_ppc = { * @regs: MFI register set */ static inline void -megasas_disable_intr(struct megasas_register_set __iomem * regs) +megasas_disable_intr(struct megasas_instance *instance) { 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 */ @@ -741,7 +752,6 @@ 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; @@ -776,9 +786,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) /* * Issue the command to the FW */ - spin_lock_irqsave(&instance->instance_lock, flags); - instance->fw_outstanding++; - spin_unlock_irqrestore(&instance->instance_lock, flags); + atomic_inc(&instance->fw_outstanding); instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set); @@ -826,19 +834,20 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) for (i = 0; i < wait_time; i++) { - if (!instance->fw_outstanding) + int outstanding = atomic_read(&instance->fw_outstanding); + + if (!outstanding) break; if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { printk(KERN_NOTICE "megasas: [%2d]waiting for %d " - "commands to complete\n", i, - instance->fw_outstanding); + "commands to complete\n",i,outstanding); } msleep(1000); } - if (instance->fw_outstanding) { + if (atomic_read(&instance->fw_outstanding)) { instance->hw_crit_error = 1; return FAILED; } @@ -1050,7 +1059,6 @@ 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; @@ -1082,9 +1090,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, if (exception) { - spin_lock_irqsave(&instance->instance_lock, flags); - instance->fw_outstanding--; - spin_unlock_irqrestore(&instance->instance_lock, flags); + atomic_dec(&instance->fw_outstanding); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -1132,9 +1138,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, break; } - spin_lock_irqsave(&instance->instance_lock, flags); - instance->fw_outstanding--; - spin_unlock_irqrestore(&instance->instance_lock, flags); + atomic_dec(&instance->fw_outstanding); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -1267,7 +1271,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) /* * Bring it to READY state; assuming max wait 2 secs */ - megasas_disable_intr(instance->reg_set); + megasas_disable_intr(instance); writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); max_wait = 10; @@ -1763,6 +1767,11 @@ 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 */ @@ -2171,11 +2180,12 @@ 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); @@ -2197,7 +2207,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* * Register IRQ */ - if (request_irq(pdev->irq, megasas_isr, SA_SHIRQ, "megasas", instance)) { + if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) { printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); goto fail_irq; } @@ -2240,7 +2250,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->reg_set); + megasas_disable_intr(instance); free_irq(instance->pdev->irq, instance); megasas_release_mfi(instance); @@ -2370,7 +2380,7 @@ static void megasas_detach_one(struct pci_dev *pdev) pci_set_drvdata(instance->pdev, NULL); - megasas_disable_intr(instance->reg_set); + megasas_disable_intr(instance); free_irq(instance->pdev->irq, instance);