[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: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
		
							parent
							
								
									f9a2d2e0c8
								
							
						
					
					
						commit
						91ca7b01ec
					
				| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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) || | ||||
|  | ||||
| @ -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); | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user