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

Commit 61aa1620 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] zfcp: Flush SCSI registration work when adding unit
  [SCSI] zfcp: Fix timer initialization for ct and els requests
  [SCSI] zfcp: Warn about storage devices with broken PLOGI data
  [SCSI] zfcp: Handle WWPN mismatch in PLOGI payload
  [SCSI] zfcp: fix kfree handling in zfcp_init_device_setup
  [SCSI] fix memory leak in initialization
parents d4f452f8 9e820afd
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -128,12 +128,13 @@ out_ccwdev:
static void __init zfcp_init_device_setup(char *devstr)
{
	char *token;
	char *str;
	char *str, *str_saved;
	char busid[ZFCP_BUS_ID_SIZE];
	u64 wwpn, lun;

	/* duplicate devstr and keep the original for sysfs presentation*/
	str = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
	str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
	str = str_saved;
	if (!str)
		return;

@@ -152,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr)
	if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun))
		goto err_out;

	kfree(str);
	kfree(str_saved);
	zfcp_init_device_configure(busid, wwpn, lun);
	return;

err_out:
	kfree(str);
	kfree(str_saved);
	pr_err("%s is not a valid SCSI device\n", devstr);
}

+10 −12
Original line number Diff line number Diff line
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
		if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
			return zfcp_erp_open_ptp_port(act);
		if (!port->d_id) {
			zfcp_port_get(port);
			if (!queue_work(adapter->work_queue,
					&port->gid_pn_work))
				zfcp_port_put(port);
			zfcp_fc_trigger_did_lookup(port);
			return ZFCP_ERP_EXIT;
		}
		return zfcp_erp_port_strategy_open_port(act);
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
	case ZFCP_ERP_STEP_PORT_OPENING:
		/* D_ID might have changed during open */
		if (p_status & ZFCP_STATUS_COMMON_OPEN) {
			if (port->d_id)
				return ZFCP_ERP_SUCCEEDED;
			else {
				act->step = ZFCP_ERP_STEP_PORT_CLOSING;
				return ZFCP_ERP_CONTINUES;
			if (!port->d_id) {
				zfcp_fc_trigger_did_lookup(port);
				return ZFCP_ERP_EXIT;
			}
			return ZFCP_ERP_SUCCEEDED;
		}
		if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) {
			port->d_id = 0;
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
{
	struct zfcp_port *port = erp_action->port;
	int p_status = atomic_read(&port->status);

	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
	if ((p_status & ZFCP_STATUS_COMMON_NOESC) &&
	    !(p_status & ZFCP_STATUS_COMMON_OPEN))
		goto close_init_done;

	switch (erp_action->step) {
	case ZFCP_ERP_STEP_UNINITIALIZED:
		zfcp_erp_port_strategy_clearstati(port);
		if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
		if (p_status & ZFCP_STATUS_COMMON_OPEN)
			return zfcp_erp_port_strategy_close(erp_action);
		break;

	case ZFCP_ERP_STEP_PORT_CLOSING:
		if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
		if (p_status & ZFCP_STATUS_COMMON_OPEN)
			return ZFCP_ERP_FAILED;
		break;
	}
+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
extern void _zfcp_fc_scan_ports_later(struct work_struct *);
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fc_port_did_lookup(struct work_struct *);
extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
extern void zfcp_fc_test_link(struct zfcp_port *);
extern void zfcp_fc_link_test_work(struct work_struct *);
+11 −0
Original line number Diff line number Diff line
@@ -360,6 +360,17 @@ out:
	zfcp_port_put(port);
}

/**
 * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request
 * @port: The zfcp_port to lookup the d_id for.
 */
void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
{
	zfcp_port_get(port);
	if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
		zfcp_port_put(port);
}

/**
 * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
 * @port: zfcp_port structure
+10 −3
Original line number Diff line number Diff line
@@ -1079,7 +1079,7 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
	/* common settings for ct/gs and els requests */
	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
	req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
	zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
	zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);

	return 0;
}
@@ -1475,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
		plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
		if (req->qtcb->bottom.support.els1_length >=
		    FSF_PLOGI_MIN_LEN) {
			if (plogi->serv_param.wwpn != port->wwpn)
			if (plogi->serv_param.wwpn != port->wwpn) {
				port->d_id = 0;
			else {
				dev_warn(&port->adapter->ccw_device->dev,
					 "A port opened with WWPN 0x%016Lx "
					 "returned data that identifies it as "
					 "WWPN 0x%016Lx\n",
					 (unsigned long long) port->wwpn,
					 (unsigned long long)
					  plogi->serv_param.wwpn);
			} else {
				port->wwnn = plogi->serv_param.wwnn;
				zfcp_fc_plogi_evaluate(port, plogi);
			}
Loading