Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd50ba8e authored by Adam Radford's avatar Adam Radford Committed by James Bottomley
Browse files

[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: default avatarAdam Radford <aradford@gmail.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent b6d5d880
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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)						\
+173 −105
Original line number Diff line number Diff line
@@ -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,14 +3467,6 @@ 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:
	iounmap(instance->reg_set);

@@ -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;