Commit 91ca7b01 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley
Browse files

[SCSI] Add an 'Issue LIP' device attribute in fc_transport class



Ok, here's a patch to add such a common API for fc transport users.
Relevant LLD changes (lpfc and qla2xxx) also present.

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent f9a2d2e0
Loading
Loading
Loading
Loading
+5 −11
Original line number Diff line number Diff line
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
}


static ssize_t
lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
static int
lpfc_issue_lip(struct Scsi_Host *host)
{
	struct Scsi_Host *host = class_to_shost(cdev);
	struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
	int val = 0;
	LPFC_MBOXQ_t *pmboxq;
	int mbxstatus = MBXERR_ERROR;

	if ((sscanf(buf, "%d", &val) != 1) ||
	    (val != 1))
		return -EINVAL;

	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
	    (phba->hba_state != LPFC_HBA_READY))
		return -EPERM;
@@ -234,7 +228,7 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
	if (mbxstatus == MBXERR_ERROR)
		return -EIO;

	return strlen(buf);
	return 0;
}

static ssize_t
@@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
			 NULL);
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
			 NULL);
static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
			 lpfc_board_online_show, lpfc_board_online_store);

@@ -537,7 +530,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
	&class_device_attr_lpfc_max_luns,
	&class_device_attr_nport_evt_cnt,
	&class_device_attr_management_version,
	&class_device_attr_issue_lip,
	&class_device_attr_board_online,
	NULL,
};
@@ -1234,6 +1226,8 @@ struct fc_function_template lpfc_transport_functions = {

	.get_starget_port_name = lpfc_get_starget_port_name,
	.show_starget_port_name = 1,

	.issue_fc_host_lip = lpfc_issue_lip,
};

void
+10 −0
Original line number Diff line number Diff line
@@ -503,6 +503,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
}

static int
qla2x00_issue_lip(struct Scsi_Host *shost)
{
	scsi_qla_host_t *ha = to_qla_host(shost);

	set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
	return 0;
}

struct fc_function_template qla2xxx_transport_functions = {

	.show_host_node_name = 1,
@@ -526,6 +535,7 @@ struct fc_function_template qla2xxx_transport_functions = {
	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
	.show_rport_dev_loss_tmo = 1,

	.issue_fc_host_lip = qla2x00_issue_lip,
};

void
+7 −0
Original line number Diff line number Diff line
@@ -2141,6 +2141,12 @@ qla2x00_do_dpc(void *data)
			    ha->host_no));
		}

		if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
			DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
			    ha->host_no));
			qla2x00_loop_reset(ha);
		}

		if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
		    (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {

@@ -2442,6 +2448,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
	/* Schedule the DPC routine if needed */
	if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
	    test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
	    test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
	    start_dpc ||
	    test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
	    test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
+26 −2
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ static void fc_rport_terminate(struct fc_rport *rport);
 */
#define FC_STARGET_NUM_ATTRS 	3
#define FC_RPORT_NUM_ATTRS	9
#define FC_HOST_NUM_ATTRS	15
#define FC_HOST_NUM_ATTRS	16

struct fc_internal {
	struct scsi_transport_template t;
@@ -713,9 +713,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
	count++

#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field)			\
{									\
	i->private_host_attrs[count] = class_device_attr_host_##field;	\
	i->host_attrs[count] = &i->private_host_attrs[count];		\
	count++
	count++;							\
}


/* Fixed Host Attributes */
@@ -853,6 +855,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
			show_fc_private_host_tgtid_bind_type,
			store_fc_private_host_tgtid_bind_type);

static ssize_t
store_fc_private_host_issue_lip(struct class_device *cdev,
	const char *buf, size_t count)
{
	struct Scsi_Host *shost = transport_class_to_shost(cdev);
	struct fc_internal *i = to_fc_internal(shost->transportt);
	int ret;

	/* ignore any data value written to the attribute */
	if (i->f->issue_fc_host_lip) {
		ret = i->f->issue_fc_host_lip(shost);
		return ret ? ret: count;
	}

	return -ENOENT;
}

static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
			store_fc_private_host_issue_lip);

/*
 * Host Statistics Management
 */
@@ -1119,6 +1141,8 @@ fc_attach_transport(struct fc_function_template *ft)

	/* Transport-managed attributes */
	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
	if (ft->issue_fc_host_lip)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);

	BUG_ON(count > FC_HOST_NUM_ATTRS);

+2 −0
Original line number Diff line number Diff line
@@ -384,6 +384,8 @@ struct fc_function_template {
	struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
	void	(*reset_fc_host_stats)(struct Scsi_Host *);

	int	(*issue_fc_host_lip)(struct Scsi_Host *);

	/* allocation lengths for host-specific data */
	u32	 			dd_fcrport_size;