Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 271128
b: refs/heads/master
c: c8e858f
h: refs/heads/master
v: v3
  • Loading branch information
adam radford authored and James Bottomley committed Oct 16, 2011
1 parent 198ff0a commit 3136fb5
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 60 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 36807e6799dcd8f961137b74c7edce10c6fcb1d2
refs/heads/master: c8e858fe72230dd2ad07abcbec7c9f201672a8b4
11 changes: 9 additions & 2 deletions trunk/drivers/scsi/megaraid/megaraid_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ struct megasas_ctrl_info {
#define MEGASAS_INT_CMDS 32
#define MEGASAS_SKINNY_INT_CMDS 5

#define MEGASAS_MAX_MSIX_QUEUES 16
/*
* FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
* SGLs based on the size of dma_addr_t
Expand Down Expand Up @@ -1278,6 +1279,11 @@ struct megasas_aen_event {
struct megasas_instance *instance;
};

struct megasas_irq_context {
struct megasas_instance *instance;
u32 MSIxIndex;
};

struct megasas_instance {

u32 *producer;
Expand Down Expand Up @@ -1351,8 +1357,9 @@ struct megasas_instance {

/* Ptr to hba specific information */
void *ctrl_context;
u8 msi_flag;
struct msix_entry msixentry;
unsigned int msix_vectors;
struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
u64 map_id;
struct megasas_cmd *map_update_cmd;
unsigned long bar;
Expand Down
156 changes: 121 additions & 35 deletions trunk/drivers/scsi/megaraid/megaraid_sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2536,7 +2536,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
instance->reg_set)
) == 0) {
/* Hardware may not set outbound_intr_status in MSI-X mode */
if (!instance->msi_flag)
if (!instance->msix_vectors)
return IRQ_NONE;
}

Expand Down Expand Up @@ -2594,16 +2594,14 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
*/
static irqreturn_t megasas_isr(int irq, void *devp)
{
struct megasas_instance *instance;
struct megasas_irq_context *irq_context = devp;
struct megasas_instance *instance = irq_context->instance;
unsigned long flags;
irqreturn_t rc;

if (atomic_read(
&(((struct megasas_instance *)devp)->fw_reset_no_pci_access)))
if (atomic_read(&instance->fw_reset_no_pci_access))
return IRQ_HANDLED;

instance = (struct megasas_instance *)devp;

spin_lock_irqsave(&instance->hba_lock, flags);
rc = megasas_deplete_reply_queue(instance, DID_OK);
spin_unlock_irqrestore(&instance->hba_lock, flags);
Expand Down Expand Up @@ -3488,6 +3486,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
struct megasas_register_set __iomem *reg_set;
struct megasas_ctrl_info *ctrl_info;
unsigned long bar_list;
int i;

/* Find first memory bar */
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
Expand Down Expand Up @@ -3541,9 +3540,33 @@ static int megasas_init_fw(struct megasas_instance *instance)
/* Check if MSI-X is supported while in ready state */
msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
0x4000000) >> 0x1a;
if (msix_enable && !msix_disable &&
!pci_enable_msix(instance->pdev, &instance->msixentry, 1))
instance->msi_flag = 1;
if (msix_enable && !msix_disable) {
/* Check max MSI-X vectors */
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
instance->msix_vectors = (readl(&instance->reg_set->
outbound_scratch_pad_2
) & 0x1F) + 1;
} else
instance->msix_vectors = 1;
/* Don't bother allocating more MSI-X vectors than cpus */
instance->msix_vectors = min(instance->msix_vectors,
(unsigned int)num_online_cpus());
for (i = 0; i < instance->msix_vectors; i++)
instance->msixentry[i].entry = i;
i = pci_enable_msix(instance->pdev, instance->msixentry,
instance->msix_vectors);
if (i >= 0) {
if (i) {
if (!pci_enable_msix(instance->pdev,
instance->msixentry, i))
instance->msix_vectors = i;
else
instance->msix_vectors = 0;
}
} else
instance->msix_vectors = 0;
}

/* Get operational params, sge flags, send init cmd to controller */
if (instance->instancet->init_adapter(instance))
Expand Down Expand Up @@ -3958,7 +3981,7 @@ megasas_set_dma_mask(struct pci_dev *pdev)
static int __devinit
megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
int rval, pos;
int rval, pos, i, j;
struct Scsi_Host *host;
struct megasas_instance *instance;
u16 control = 0;
Expand Down Expand Up @@ -4126,11 +4149,32 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/*
* Register IRQ
*/
if (request_irq(instance->msi_flag ? instance->msixentry.vector :
pdev->irq, instance->instancet->service_isr,
IRQF_SHARED, "megasas", instance)) {
printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
goto fail_irq;
if (instance->msix_vectors) {
for (i = 0 ; i < instance->msix_vectors; i++) {
instance->irq_context[i].instance = instance;
instance->irq_context[i].MSIxIndex = i;
if (request_irq(instance->msixentry[i].vector,
instance->instancet->service_isr, 0,
"megasas",
&instance->irq_context[i])) {
printk(KERN_DEBUG "megasas: Failed to "
"register IRQ for vector %d.\n", i);
for (j = 0 ; j < i ; j++)
free_irq(
instance->msixentry[j].vector,
&instance->irq_context[j]);
goto fail_irq;
}
}
} else {
instance->irq_context[0].instance = instance;
instance->irq_context[0].MSIxIndex = 0;
if (request_irq(pdev->irq, instance->instancet->service_isr,
IRQF_SHARED, "megasas",
&instance->irq_context[0])) {
printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
goto fail_irq;
}
}

instance->instancet->enable_intr(instance->reg_set);
Expand Down Expand Up @@ -4174,16 +4218,20 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)

pci_set_drvdata(pdev, NULL);
instance->instancet->disable_intr(instance->reg_set);
free_irq(instance->msi_flag ? instance->msixentry.vector :
instance->pdev->irq, instance);
if (instance->msix_vectors)
for (i = 0 ; i < instance->msix_vectors; i++)
free_irq(instance->msixentry[i].vector,
&instance->irq_context[i]);
else
free_irq(instance->pdev->irq, &instance->irq_context[0]);
fail_irq:
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
megasas_release_fusion(instance);
else
megasas_release_mfi(instance);
fail_init_mfi:
if (instance->msi_flag)
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
fail_alloc_dma_buf:
if (instance->evt_detail)
Expand Down Expand Up @@ -4299,6 +4347,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct Scsi_Host *host;
struct megasas_instance *instance;
int i;

instance = pci_get_drvdata(pdev);
host = instance->host;
Expand All @@ -4322,9 +4371,14 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)

pci_set_drvdata(instance->pdev, instance);
instance->instancet->disable_intr(instance->reg_set);
free_irq(instance->msi_flag ? instance->msixentry.vector :
instance->pdev->irq, instance);
if (instance->msi_flag)

if (instance->msix_vectors)
for (i = 0 ; i < instance->msix_vectors; i++)
free_irq(instance->msixentry[i].vector,
&instance->irq_context[i]);
else
free_irq(instance->pdev->irq, &instance->irq_context[0]);
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);

pci_save_state(pdev);
Expand All @@ -4342,7 +4396,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
static int
megasas_resume(struct pci_dev *pdev)
{
int rval;
int rval, i, j;
struct Scsi_Host *host;
struct megasas_instance *instance;

Expand Down Expand Up @@ -4380,8 +4434,9 @@ megasas_resume(struct pci_dev *pdev)
goto fail_ready_state;

/* Now re-enable MSI-X */
if (instance->msi_flag)
pci_enable_msix(instance->pdev, &instance->msixentry, 1);
if (instance->msix_vectors)
pci_enable_msix(instance->pdev, instance->msixentry,
instance->msix_vectors);

switch (instance->pdev->device) {
case PCI_DEVICE_ID_LSI_FUSION:
Expand Down Expand Up @@ -4411,11 +4466,32 @@ megasas_resume(struct pci_dev *pdev)
/*
* Register IRQ
*/
if (request_irq(instance->msi_flag ? instance->msixentry.vector :
pdev->irq, instance->instancet->service_isr,
IRQF_SHARED, "megasas", instance)) {
printk(KERN_ERR "megasas: Failed to register IRQ\n");
goto fail_irq;
if (instance->msix_vectors) {
for (i = 0 ; i < instance->msix_vectors; i++) {
instance->irq_context[i].instance = instance;
instance->irq_context[i].MSIxIndex = i;
if (request_irq(instance->msixentry[i].vector,
instance->instancet->service_isr, 0,
"megasas",
&instance->irq_context[i])) {
printk(KERN_DEBUG "megasas: Failed to "
"register IRQ for vector %d.\n", i);
for (j = 0 ; j < i ; j++)
free_irq(
instance->msixentry[j].vector,
&instance->irq_context[j]);
goto fail_irq;
}
}
} else {
instance->irq_context[0].instance = instance;
instance->irq_context[0].MSIxIndex = 0;
if (request_irq(pdev->irq, instance->instancet->service_isr,
IRQF_SHARED, "megasas",
&instance->irq_context[0])) {
printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
goto fail_irq;
}
}

instance->instancet->enable_intr(instance->reg_set);
Expand Down Expand Up @@ -4512,9 +4588,13 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)

instance->instancet->disable_intr(instance->reg_set);

free_irq(instance->msi_flag ? instance->msixentry.vector :
instance->pdev->irq, instance);
if (instance->msi_flag)
if (instance->msix_vectors)
for (i = 0 ; i < instance->msix_vectors; i++)
free_irq(instance->msixentry[i].vector,
&instance->irq_context[i]);
else
free_irq(instance->pdev->irq, &instance->irq_context[0]);
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);

switch (instance->pdev->device) {
Expand Down Expand Up @@ -4560,14 +4640,20 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
*/
static void megasas_shutdown(struct pci_dev *pdev)
{
int i;
struct megasas_instance *instance = pci_get_drvdata(pdev);

instance->unload = 1;
megasas_flush_cache(instance);
megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
instance->instancet->disable_intr(instance->reg_set);
free_irq(instance->msi_flag ? instance->msixentry.vector :
instance->pdev->irq, instance);
if (instance->msi_flag)
if (instance->msix_vectors)
for (i = 0 ; i < instance->msix_vectors; i++)
free_irq(instance->msixentry[i].vector,
&instance->irq_context[i]);
else
free_irq(instance->pdev->irq, &instance->irq_context[0]);
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
}

Expand Down
Loading

0 comments on commit 3136fb5

Please sign in to comment.