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

Commit 044833b5 authored by Yang, Bo's avatar Yang, Bo Committed by James Bottomley
Browse files

[SCSI] megaraid_sas: report system PDs to OS



When OS issue inquiry, it will check driver's internal pd_list.

Signed-off-by Bo Yang<bo.yang@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 81e403ce
Loading
Loading
Loading
Loading
+65 −26
Original line number Original line Diff line number Diff line
@@ -1115,8 +1115,27 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
	return 0;
	return 0;
}
}


static struct megasas_instance *megasas_lookup_instance(u16 host_no)
{
	int i;

	for (i = 0; i < megasas_mgmt_info.max_index; i++) {

		if ((megasas_mgmt_info.instance[i]) &&
		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
			return megasas_mgmt_info.instance[i];
	}

	return NULL;
}

static int megasas_slave_configure(struct scsi_device *sdev)
static int megasas_slave_configure(struct scsi_device *sdev)
{
{
	u16             pd_index = 0;
	struct  megasas_instance *instance ;

	instance = megasas_lookup_instance(sdev->host->host_no);

	/*
	/*
	* Don't export physical disk devices to the disk driver.
	* Don't export physical disk devices to the disk driver.
	*
	*
@@ -1124,18 +1143,51 @@ static int megasas_slave_configure(struct scsi_device *sdev)
	*        That will be fixed once LSI engineers have audited the
	*        That will be fixed once LSI engineers have audited the
	*        firmware for possible issues.
	*        firmware for possible issues.
	*/
	*/
	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
				sdev->type == TYPE_DISK) {
		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
								sdev->id;
		if (instance->pd_list[pd_index].driveState ==
						MR_PD_STATE_SYSTEM) {
			blk_queue_rq_timeout(sdev->request_queue,
				MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
			return 0;
		}
		return -ENXIO;
		return -ENXIO;
	}


	/*
	/*
	* The RAID firmware may require extended timeouts.
	* The RAID firmware may require extended timeouts.
	*/
	*/
	if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
	blk_queue_rq_timeout(sdev->request_queue,
	blk_queue_rq_timeout(sdev->request_queue,
		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
	return 0;
	return 0;
}
}


static int megasas_slave_alloc(struct scsi_device *sdev)
{
	u16             pd_index = 0;
	struct megasas_instance *instance ;
	instance = megasas_lookup_instance(sdev->host->host_no);
	if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
				(sdev->type == TYPE_DISK)) {
		/*
		 * Open the OS scan to the SYSTEM PD
		 */
		pd_index =
			(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
			sdev->id;
		if ((instance->pd_list[pd_index].driveState ==
					MR_PD_STATE_SYSTEM) &&
			(instance->pd_list[pd_index].driveType ==
						TYPE_DISK)) {
			return 0;
		}
		return -ENXIO;
	}
	return 0;
}

/**
/**
 * megasas_complete_cmd_dpc	 -	Returns FW's controller structure
 * megasas_complete_cmd_dpc	 -	Returns FW's controller structure
 * @instance_addr:			Address of adapter soft state
 * @instance_addr:			Address of adapter soft state
@@ -1423,6 +1475,7 @@ static struct scsi_host_template megasas_template = {
	.name = "LSI SAS based MegaRAID driver",
	.name = "LSI SAS based MegaRAID driver",
	.proc_name = "megaraid_sas",
	.proc_name = "megaraid_sas",
	.slave_configure = megasas_slave_configure,
	.slave_configure = megasas_slave_configure,
	.slave_alloc = megasas_slave_alloc,
	.queuecommand = megasas_queue_command,
	.queuecommand = megasas_queue_command,
	.eh_device_reset_handler = megasas_reset_device,
	.eh_device_reset_handler = megasas_reset_device,
	.eh_bus_reset_handler = megasas_reset_bus_host,
	.eh_bus_reset_handler = megasas_reset_bus_host,
@@ -3455,20 +3508,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
	return error;
	return error;
}
}


static struct megasas_instance *megasas_lookup_instance(u16 host_no)
{
	int i;

	for (i = 0; i < megasas_mgmt_info.max_index; i++) {

		if ((megasas_mgmt_info.instance[i]) &&
		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
			return megasas_mgmt_info.instance[i];
	}

	return NULL;
}

static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
{
{
	struct megasas_iocpacket __user *user_ioc =
	struct megasas_iocpacket __user *user_ioc =