mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 16:29:05 +00:00
[SCSI] megaraid_sas: Add struct megasas_instance_template changes
The following patch adds struct megasas_instance_template changes to the megaraid_sas driver, and changes all code to use the new instance entries: irqreturn_t (*service_isr )(int irq, void *devp); void (*tasklet)(unsigned long); u32 (*init_adapter)(struct megasas_instance *); u32 (*build_and_issue_cmd) (struct megasas_instance *, struct scsi_cmnd *); void (*issue_dcmd) (struct megasas_instance *instance, struct megasas_cmd *cmd); Signed-off-by: Adam Radford <aradford@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
b6d5d8808b
commit
cd50ba8ede
@ -1364,6 +1364,13 @@ struct megasas_instance_template {
|
||||
struct megasas_register_set __iomem *);
|
||||
int (*check_reset)(struct megasas_instance *, \
|
||||
struct megasas_register_set __iomem *);
|
||||
irqreturn_t (*service_isr)(int irq, void *devp);
|
||||
void (*tasklet)(unsigned long);
|
||||
u32 (*init_adapter)(struct megasas_instance *);
|
||||
u32 (*build_and_issue_cmd) (struct megasas_instance *,
|
||||
struct scsi_cmnd *);
|
||||
void (*issue_dcmd) (struct megasas_instance *instance,
|
||||
struct megasas_cmd *cmd);
|
||||
};
|
||||
|
||||
#define MEGASAS_IS_LOGICAL(scp) \
|
||||
|
@ -131,6 +131,20 @@ spinlock_t poll_aen_lock;
|
||||
static void
|
||||
megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
||||
u8 alt_status);
|
||||
static irqreturn_t megasas_isr(int irq, void *devp);
|
||||
static u32
|
||||
megasas_init_adapter_mfi(struct megasas_instance *instance);
|
||||
u32
|
||||
megasas_build_and_issue_cmd(struct megasas_instance *instance,
|
||||
struct scsi_cmnd *scmd);
|
||||
static void megasas_complete_cmd_dpc(unsigned long instance_addr);
|
||||
|
||||
void
|
||||
megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
|
||||
{
|
||||
instance->instancet->fire_cmd(instance,
|
||||
cmd->frame_phys_addr, 0, instance->reg_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_get_cmd - Get a command from the free pool
|
||||
@ -334,6 +348,11 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
|
||||
.read_fw_status_reg = megasas_read_fw_status_reg_xscale,
|
||||
.adp_reset = megasas_adp_reset_xscale,
|
||||
.check_reset = megasas_check_reset_xscale,
|
||||
.service_isr = megasas_isr,
|
||||
.tasklet = megasas_complete_cmd_dpc,
|
||||
.init_adapter = megasas_init_adapter_mfi,
|
||||
.build_and_issue_cmd = megasas_build_and_issue_cmd,
|
||||
.issue_dcmd = megasas_issue_dcmd,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -460,6 +479,11 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
|
||||
.read_fw_status_reg = megasas_read_fw_status_reg_ppc,
|
||||
.adp_reset = megasas_adp_reset_ppc,
|
||||
.check_reset = megasas_check_reset_ppc,
|
||||
.service_isr = megasas_isr,
|
||||
.tasklet = megasas_complete_cmd_dpc,
|
||||
.init_adapter = megasas_init_adapter_mfi,
|
||||
.build_and_issue_cmd = megasas_build_and_issue_cmd,
|
||||
.issue_dcmd = megasas_issue_dcmd,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -581,6 +605,11 @@ static struct megasas_instance_template megasas_instance_template_skinny = {
|
||||
.read_fw_status_reg = megasas_read_fw_status_reg_skinny,
|
||||
.adp_reset = megasas_adp_reset_skinny,
|
||||
.check_reset = megasas_check_reset_skinny,
|
||||
.service_isr = megasas_isr,
|
||||
.tasklet = megasas_complete_cmd_dpc,
|
||||
.init_adapter = megasas_init_adapter_mfi,
|
||||
.build_and_issue_cmd = megasas_build_and_issue_cmd,
|
||||
.issue_dcmd = megasas_issue_dcmd,
|
||||
};
|
||||
|
||||
|
||||
@ -755,6 +784,11 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
|
||||
.read_fw_status_reg = megasas_read_fw_status_reg_gen2,
|
||||
.adp_reset = megasas_adp_reset_gen2,
|
||||
.check_reset = megasas_check_reset_gen2,
|
||||
.service_isr = megasas_isr,
|
||||
.tasklet = megasas_complete_cmd_dpc,
|
||||
.init_adapter = megasas_init_adapter_mfi,
|
||||
.build_and_issue_cmd = megasas_build_and_issue_cmd,
|
||||
.issue_dcmd = megasas_issue_dcmd,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1339,6 +1373,51 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
|
||||
printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
|
||||
}
|
||||
|
||||
u32
|
||||
megasas_build_and_issue_cmd(struct megasas_instance *instance,
|
||||
struct scsi_cmnd *scmd)
|
||||
{
|
||||
struct megasas_cmd *cmd;
|
||||
u32 frame_count;
|
||||
|
||||
cmd = megasas_get_cmd(instance);
|
||||
if (!cmd)
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
/*
|
||||
* Logical drive command
|
||||
*/
|
||||
if (megasas_is_ldio(scmd))
|
||||
frame_count = megasas_build_ldio(instance, scmd, cmd);
|
||||
else
|
||||
frame_count = megasas_build_dcdb(instance, scmd, cmd);
|
||||
|
||||
if (!frame_count)
|
||||
goto out_return_cmd;
|
||||
|
||||
cmd->scmd = scmd;
|
||||
scmd->SCp.ptr = (char *)cmd;
|
||||
|
||||
/*
|
||||
* Issue the command to the FW
|
||||
*/
|
||||
atomic_inc(&instance->fw_outstanding);
|
||||
|
||||
instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
|
||||
cmd->frame_count-1, instance->reg_set);
|
||||
/*
|
||||
* Check if we have pend cmds to be completed
|
||||
*/
|
||||
if (poll_mode_io && atomic_read(&instance->fw_outstanding))
|
||||
tasklet_schedule(&instance->isr_tasklet);
|
||||
|
||||
return 0;
|
||||
out_return_cmd:
|
||||
megasas_return_cmd(instance, cmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* megasas_queue_command - Queue entry point
|
||||
* @scmd: SCSI command to be queued
|
||||
@ -1347,8 +1426,6 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
|
||||
static int
|
||||
megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
|
||||
{
|
||||
u32 frame_count;
|
||||
struct megasas_cmd *cmd;
|
||||
struct megasas_instance *instance;
|
||||
unsigned long flags;
|
||||
|
||||
@ -1387,42 +1464,13 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd
|
||||
break;
|
||||
}
|
||||
|
||||
cmd = megasas_get_cmd(instance);
|
||||
if (!cmd)
|
||||
if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
|
||||
printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
/*
|
||||
* Logical drive command
|
||||
*/
|
||||
if (megasas_is_ldio(scmd))
|
||||
frame_count = megasas_build_ldio(instance, scmd, cmd);
|
||||
else
|
||||
frame_count = megasas_build_dcdb(instance, scmd, cmd);
|
||||
|
||||
if (!frame_count)
|
||||
goto out_return_cmd;
|
||||
|
||||
cmd->scmd = scmd;
|
||||
scmd->SCp.ptr = (char *)cmd;
|
||||
|
||||
/*
|
||||
* Issue the command to the FW
|
||||
*/
|
||||
atomic_inc(&instance->fw_outstanding);
|
||||
|
||||
instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
|
||||
cmd->frame_count-1, instance->reg_set);
|
||||
/*
|
||||
* Check if we have pend cmds to be completed
|
||||
*/
|
||||
if (poll_mode_io && atomic_read(&instance->fw_outstanding))
|
||||
tasklet_schedule(&instance->isr_tasklet);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_return_cmd:
|
||||
megasas_return_cmd(instance, cmd);
|
||||
out_done:
|
||||
done(scmd);
|
||||
return 0;
|
||||
@ -3221,69 +3269,15 @@ megasas_io_completion_timer(unsigned long instance_addr)
|
||||
jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_init_mfi - Initializes the FW
|
||||
* @instance: Adapter soft state
|
||||
*
|
||||
* This is the main function for initializing MFI firmware.
|
||||
*/
|
||||
static int megasas_init_mfi(struct megasas_instance *instance)
|
||||
static u32
|
||||
megasas_init_adapter_mfi(struct megasas_instance *instance)
|
||||
{
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
u32 context_sz;
|
||||
u32 reply_q_sz;
|
||||
u32 max_sectors_1;
|
||||
u32 max_sectors_2;
|
||||
u32 tmp_sectors;
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
struct megasas_ctrl_info *ctrl_info;
|
||||
unsigned long bar_list;
|
||||
|
||||
/* Find first memory bar */
|
||||
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
|
||||
instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
|
||||
instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
|
||||
if (pci_request_selected_regions(instance->pdev, instance->bar,
|
||||
"megasas: LSI")) {
|
||||
printk(KERN_DEBUG "megasas: IO memory region busy!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
|
||||
|
||||
if (!instance->reg_set) {
|
||||
printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
|
||||
goto fail_ioremap;
|
||||
}
|
||||
|
||||
reg_set = instance->reg_set;
|
||||
|
||||
switch(instance->pdev->device)
|
||||
{
|
||||
case PCI_DEVICE_ID_LSI_SAS1078R:
|
||||
case PCI_DEVICE_ID_LSI_SAS1078DE:
|
||||
instance->instancet = &megasas_instance_template_ppc;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1078GEN2:
|
||||
case PCI_DEVICE_ID_LSI_SAS0079GEN2:
|
||||
instance->instancet = &megasas_instance_template_gen2;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
|
||||
case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
|
||||
instance->instancet = &megasas_instance_template_skinny;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1064R:
|
||||
case PCI_DEVICE_ID_DELL_PERC5:
|
||||
default:
|
||||
instance->instancet = &megasas_instance_template_xscale;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect the FW state to be READY
|
||||
*/
|
||||
if (megasas_transition_to_ready(instance))
|
||||
goto fail_ready_state;
|
||||
|
||||
/*
|
||||
* Get various operational parameters from status register
|
||||
*/
|
||||
@ -3337,6 +3331,87 @@ static int megasas_init_mfi(struct megasas_instance *instance)
|
||||
if (instance->fw_support_ieee)
|
||||
instance->flag_ieee = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_fw_init:
|
||||
|
||||
pci_free_consistent(instance->pdev, reply_q_sz,
|
||||
instance->reply_queue, instance->reply_queue_h);
|
||||
fail_reply_queue:
|
||||
megasas_free_cmds(instance);
|
||||
|
||||
fail_alloc_cmds:
|
||||
iounmap(instance->reg_set);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_init_fw - Initializes the FW
|
||||
* @instance: Adapter soft state
|
||||
*
|
||||
* This is the main function for initializing firmware
|
||||
*/
|
||||
|
||||
static int megasas_init_fw(struct megasas_instance *instance)
|
||||
{
|
||||
u32 max_sectors_1;
|
||||
u32 max_sectors_2;
|
||||
u32 tmp_sectors;
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
struct megasas_ctrl_info *ctrl_info;
|
||||
unsigned long bar_list;
|
||||
|
||||
/* Find first memory bar */
|
||||
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
|
||||
instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
|
||||
instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
|
||||
if (pci_request_selected_regions(instance->pdev, instance->bar,
|
||||
"megasas: LSI")) {
|
||||
printk(KERN_DEBUG "megasas: IO memory region busy!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
|
||||
|
||||
if (!instance->reg_set) {
|
||||
printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
|
||||
goto fail_ioremap;
|
||||
}
|
||||
|
||||
reg_set = instance->reg_set;
|
||||
|
||||
switch (instance->pdev->device) {
|
||||
case PCI_DEVICE_ID_LSI_SAS1078R:
|
||||
case PCI_DEVICE_ID_LSI_SAS1078DE:
|
||||
instance->instancet = &megasas_instance_template_ppc;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1078GEN2:
|
||||
case PCI_DEVICE_ID_LSI_SAS0079GEN2:
|
||||
instance->instancet = &megasas_instance_template_gen2;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
|
||||
case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
|
||||
instance->instancet = &megasas_instance_template_skinny;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1064R:
|
||||
case PCI_DEVICE_ID_DELL_PERC5:
|
||||
default:
|
||||
instance->instancet = &megasas_instance_template_xscale;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect the FW state to be READY
|
||||
*/
|
||||
if (megasas_transition_to_ready(instance))
|
||||
goto fail_ready_state;
|
||||
|
||||
/* Get operational params, sge flags, send init cmd to controller */
|
||||
if (instance->instancet->init_adapter(instance))
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_ERR "megasas: INIT adapter done\n");
|
||||
|
||||
/** for passthrough
|
||||
* the following function will get the PD LIST.
|
||||
*/
|
||||
@ -3392,15 +3467,7 @@ static int megasas_init_mfi(struct megasas_instance *instance)
|
||||
MEGASAS_COMPLETION_TIMER_INTERVAL);
|
||||
return 0;
|
||||
|
||||
fail_fw_init:
|
||||
|
||||
pci_free_consistent(instance->pdev, reply_q_sz,
|
||||
instance->reply_queue, instance->reply_queue_h);
|
||||
fail_reply_queue:
|
||||
megasas_free_cmds(instance);
|
||||
|
||||
fail_alloc_cmds:
|
||||
fail_ready_state:
|
||||
fail_ready_state:
|
||||
iounmap(instance->reg_set);
|
||||
|
||||
fail_ioremap:
|
||||
@ -3855,7 +3922,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/*
|
||||
* Initialize MFI Firmware
|
||||
*/
|
||||
if (megasas_init_mfi(instance))
|
||||
if (megasas_init_fw(instance))
|
||||
goto fail_init_mfi;
|
||||
|
||||
/* Try to enable MSI-X */
|
||||
@ -3870,7 +3937,7 @@ 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, megasas_isr,
|
||||
pdev->irq, instance->instancet->service_isr,
|
||||
IRQF_SHARED, "megasas", instance)) {
|
||||
printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
|
||||
goto fail_irq;
|
||||
@ -3920,7 +3987,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
instance->pdev->irq, instance);
|
||||
if (instance->msi_flag)
|
||||
pci_disable_msix(instance->pdev);
|
||||
megasas_release_mfi(instance);
|
||||
|
||||
fail_irq:
|
||||
fail_init_mfi:
|
||||
@ -3930,9 +3996,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
instance->evt_detail,
|
||||
instance->evt_detail_h);
|
||||
|
||||
if (instance->producer)
|
||||
if (instance->producer) {
|
||||
pci_free_consistent(pdev, sizeof(u32), instance->producer,
|
||||
instance->producer_h);
|
||||
megasas_release_mfi(instance);
|
||||
}
|
||||
if (instance->consumer)
|
||||
pci_free_consistent(pdev, sizeof(u32), instance->consumer,
|
||||
instance->consumer_h);
|
||||
@ -4134,7 +4202,7 @@ megasas_resume(struct pci_dev *pdev)
|
||||
* Register IRQ
|
||||
*/
|
||||
if (request_irq(instance->msi_flag ? instance->msixentry.vector :
|
||||
pdev->irq, megasas_isr,
|
||||
pdev->irq, instance->instancet->service_isr,
|
||||
IRQF_SHARED, "megasas", instance)) {
|
||||
printk(KERN_ERR "megasas: Failed to register IRQ\n");
|
||||
goto fail_irq;
|
||||
|
Loading…
x
Reference in New Issue
Block a user