diff options
Diffstat (limited to 'drivers/s390')
| -rw-r--r-- | drivers/s390/block/dasd_eckd.c | 45 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_erp.c | 2 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_fba.c | 25 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_int.h | 3 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_ioctl.c | 1 | ||||
| -rw-r--r-- | drivers/s390/block/dcssblk.c | 7 | ||||
| -rw-r--r-- | drivers/s390/block/xpram.c | 2 | ||||
| -rw-r--r-- | drivers/s390/char/monreader.c | 4 | ||||
| -rw-r--r-- | drivers/s390/char/sclp_rw.h | 5 | ||||
| -rw-r--r-- | drivers/s390/char/vmwatchdog.c | 8 | ||||
| -rw-r--r-- | drivers/s390/crypto/ap_bus.c | 9 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 68 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 8 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 56 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 25 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 7 | 
16 files changed, 150 insertions, 125 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index f8b1f04f26b..c11770f5b36 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1696,8 +1696,7 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,  		DBF_DEV_EVENT(DBF_ERR, device, "%s",  			    "unsolicited interrupt received "  			    "(sense available)"); -		device->discipline->dump_sense_dbf(device, NULL, irb, -						   "unsolicited"); +		device->discipline->dump_sense_dbf(device, irb, "unsolicited");  	}  	dasd_schedule_device_bh(device); @@ -2941,42 +2940,20 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)  }  static void -dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, -			 struct irb *irb, char *reason) +dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb, +			 char *reason)  {  	u64 *sense; -	int sl; -	struct tsb *tsb; -	sense = NULL; -	tsb = NULL; -	if (req && scsw_is_tm(&req->irb.scsw)) { -		if (irb->scsw.tm.tcw) -			tsb = tcw_get_tsb( -				(struct tcw *)(unsigned long)irb->scsw.tm.tcw); -		if (tsb && (irb->scsw.tm.fcxs == 0x01)) { -			switch (tsb->flags & 0x07) { -			case 1:	/* tsa_iostat */ -				sense = (u64 *)tsb->tsa.iostat.sense; -			break; -			case 2: /* ts_ddpc */ -				sense = (u64 *)tsb->tsa.ddpc.sense; -			break; -			case 3: /* tsa_intrg */ -			break; -			} -		} -	} else { -		if (irb->esw.esw0.erw.cons) -			sense = (u64 *)irb->ecw; -	} +	sense = (u64 *) dasd_get_sense(irb);  	if (sense) { -		for (sl = 0; sl < 4; sl++) { -			DBF_DEV_EVENT(DBF_EMERG, device, -				      "%s: %016llx %016llx %016llx %016llx", -				      reason, sense[0], sense[1], sense[2], -				      sense[3]); -		} +		DBF_DEV_EVENT(DBF_EMERG, device, +			      "%s: %s %02x%02x%02x %016llx %016llx %016llx " +			      "%016llx", reason, +			      scsw_is_tm(&irb->scsw) ? "t" : "c", +			      scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), +			      scsw_dstat(&irb->scsw), sense[0], sense[1], +			      sense[2], sense[3]);  	} else {  		DBF_DEV_EVENT(DBF_EMERG, device, "%s",  			      "SORRY - NO VALID SENSE AVAILABLE\n"); diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index d970ce2814b..cb8f9cef742 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -172,7 +172,7 @@ dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)  	device = cqr->startdev;  	/* dump sense data to s390 debugfeature*/  	if (device->discipline && device->discipline->dump_sense_dbf) -		device->discipline->dump_sense_dbf(device, cqr, irb, "log"); +		device->discipline->dump_sense_dbf(device, irb, "log");  }  EXPORT_SYMBOL(dasd_log_sense_dbf); diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index e21ee735f92..31849ad5e59 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -241,7 +241,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,  	/* check for unsolicited interrupts */  	DBF_DEV_EVENT(DBF_WARNING, device, "%s",  		    "unsolicited interrupt received"); -	device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited"); +	device->discipline->dump_sense_dbf(device, irb, "unsolicited");  	dasd_schedule_device_bh(device);  	return;  }; @@ -444,17 +444,20 @@ dasd_fba_fill_info(struct dasd_device * device,  }  static void -dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, -			 struct irb *irb, char *reason) +dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb, +			char *reason)  { -	int sl; -	if (irb->esw.esw0.erw.cons) { -		for (sl = 0; sl < 4; sl++) { -			DBF_DEV_EVENT(DBF_EMERG, device, -				      "%s: %08x %08x %08x %08x", -				      reason, irb->ecw[8 * 0], irb->ecw[8 * 1], -				      irb->ecw[8 * 2], irb->ecw[8 * 3]); -		} +	u64 *sense; + +	sense = (u64 *) dasd_get_sense(irb); +	if (sense) { +		DBF_DEV_EVENT(DBF_EMERG, device, +			      "%s: %s %02x%02x%02x %016llx %016llx %016llx " +			      "%016llx", reason, +			      scsw_is_tm(&irb->scsw) ? "t" : "c", +			      scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), +			      scsw_dstat(&irb->scsw), sense[0], sense[1], +			      sense[2], sense[3]);  	} else {  		DBF_DEV_EVENT(DBF_EMERG, device, "%s",  			      "SORRY - NO VALID SENSE AVAILABLE\n"); diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index fd63b2f2bda..b699ca356ac 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -284,8 +284,7 @@ struct dasd_discipline {  	dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);  	void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,  			    struct irb *); -	void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *, -			    struct irb *, char *); +	void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);  	void (*handle_unsolicited_interrupt) (struct dasd_device *,  					      struct irb *); diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 4ce3f72ee1c..df918ef2796 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -16,6 +16,7 @@  #include <linux/major.h>  #include <linux/fs.h>  #include <linux/blkpg.h> +#include <linux/smp_lock.h>  #include <asm/ccwdev.h>  #include <asm/cmb.h> diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 016f9e9d259..d34617682a6 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -964,7 +964,8 @@ static int dcssblk_freeze(struct device *dev)  			break;  	}  	if (rc) -		pr_err("Suspend failed because device %s is writeable.\n", +		pr_err("Suspending the system failed because DCSS device %s " +		       "is writable\n",  		       dev_info->segment_name);  	return rc;  } @@ -987,8 +988,8 @@ static int dcssblk_restore(struct device *dev)  				goto out_panic;  			}  			if (start != entry->start || end != entry->end) { -				pr_err("Mismatch of start / end address after " -				       "resuming device %s\n", +				pr_err("The address range of DCSS %s changed " +				       "while the system was suspended\n",  				       entry->segment_name);  				goto out_panic;  			} diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 2e9e1ecd6d8..db442cd6621 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -443,7 +443,7 @@ fail:   */  static void xpram_resume_error(const char *message)  { -	pr_err("Resume error: %s\n", message); +	pr_err("Resuming the system failed: %s\n", message);  	panic("xpram resume error\n");  } diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 7892550d793..3234e90bd7f 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -320,7 +320,7 @@ static int mon_open(struct inode *inode, struct file *filp)  		goto out_path;  	}  	filp->private_data = monpriv; -	dev_set_drvdata(&monreader_device, monpriv); +	dev_set_drvdata(monreader_device, monpriv);  	unlock_kernel();  	return nonseekable_open(inode, filp); @@ -463,7 +463,7 @@ static struct miscdevice mon_dev = {   *****************************************************************************/  static int monreader_freeze(struct device *dev)  { -	struct mon_private *monpriv = dev_get_drvdata(&dev); +	struct mon_private *monpriv = dev_get_drvdata(dev);  	int rc;  	if (!monpriv) diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h index 85f491ea929..7a7bfc947d9 100644 --- a/drivers/s390/char/sclp_rw.h +++ b/drivers/s390/char/sclp_rw.h @@ -92,5 +92,10 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short);  void sclp_set_htab(struct sclp_buffer *, unsigned short);  int sclp_chars_in_buffer(struct sclp_buffer *); +#ifdef CONFIG_SCLP_CONSOLE  void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); +#else +static inline void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) { } +#endif +  #endif	/* __SCLP_RW_H__ */ diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index cb7854c10c0..f2bc287b69e 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c @@ -250,14 +250,14 @@ static int vmwdt_resume(void)  static int vmwdt_suspend(void)  {  	if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { -		pr_err("The watchdog is in use. " -			"This prevents hibernation or suspend.\n"); +		pr_err("The system cannot be suspended while the watchdog" +			" is in use\n");  		return NOTIFY_BAD;  	}  	if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {  		clear_bit(VMWDT_OPEN, &vmwdt_is_open); -		pr_err("The watchdog is running. " -			"This prevents hibernation or suspend.\n"); +		pr_err("The system cannot be suspended while the watchdog" +			" is running\n");  		return NOTIFY_BAD;  	}  	return NOTIFY_DONE; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 727a809636d..ed3dcdea7fe 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1145,12 +1145,17 @@ ap_config_timeout(unsigned long ptr)   */  static inline void ap_schedule_poll_timer(void)  { +	ktime_t hr_time;  	if (ap_using_interrupts() || ap_suspend_flag)  		return;  	if (hrtimer_is_queued(&ap_poll_timer))  		return; -	hrtimer_start(&ap_poll_timer, ktime_set(0, poll_timeout), -		      HRTIMER_MODE_ABS); +	if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) { +		hr_time = ktime_set(0, poll_timeout); +		hrtimer_forward_now(&ap_poll_timer, hr_time); +		hrtimer_restart(&ap_poll_timer); +	} +	return;  }  /** diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 8030e25152f..c75d6f35cb5 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -553,40 +553,35 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,  		_zfcp_erp_unit_reopen(unit, clear, id, ref);  } -static void zfcp_erp_strategy_followup_actions(struct zfcp_erp_action *act) +static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)  { -	struct zfcp_adapter *adapter = act->adapter; -	struct zfcp_port *port = act->port; -	struct zfcp_unit *unit = act->unit; -	u32 status = act->status; - -	/* initiate follow-up actions depending on success of finished action */  	switch (act->action) { -  	case ZFCP_ERP_ACTION_REOPEN_ADAPTER: -		if (status == ZFCP_ERP_SUCCEEDED) -			_zfcp_erp_port_reopen_all(adapter, 0, "ersfa_1", NULL); -		else -			_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_2", NULL); +		_zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1", NULL);  		break; -  	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: -		if (status == ZFCP_ERP_SUCCEEDED) -			_zfcp_erp_port_reopen(port, 0, "ersfa_3", NULL); -		else -			_zfcp_erp_adapter_reopen(adapter, 0, "ersfa_4", NULL); +		_zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2", NULL);  		break; -  	case ZFCP_ERP_ACTION_REOPEN_PORT: -		if (status == ZFCP_ERP_SUCCEEDED) -			_zfcp_erp_unit_reopen_all(port, 0, "ersfa_5", NULL); -		else -			_zfcp_erp_port_forced_reopen(port, 0, "ersfa_6", NULL); +		_zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);  		break; -  	case ZFCP_ERP_ACTION_REOPEN_UNIT: -		if (status != ZFCP_ERP_SUCCEEDED) -			_zfcp_erp_port_reopen(unit->port, 0, "ersfa_7", NULL); +		_zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL); +		break; +	} +} + +static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act) +{ +	switch (act->action) { +	case ZFCP_ERP_ACTION_REOPEN_ADAPTER: +		_zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1", NULL); +		break; +	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: +		_zfcp_erp_port_reopen(act->port, 0, "ersfs_2", NULL); +		break; +	case ZFCP_ERP_ACTION_REOPEN_PORT: +		_zfcp_erp_unit_reopen_all(act->port, 0, "ersfs_3", NULL);  		break;  	}  } @@ -801,7 +796,7 @@ static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)  			return ZFCP_ERP_FAILED;  	case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: -		if (status & ZFCP_STATUS_PORT_PHYS_OPEN) +		if (!(status & ZFCP_STATUS_PORT_PHYS_OPEN))  			return ZFCP_ERP_SUCCEEDED;  	}  	return ZFCP_ERP_FAILED; @@ -853,11 +848,17 @@ void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)  					      gid_pn_work);  	retval = zfcp_fc_ns_gid_pn(&port->erp_action); -	if (retval == -ENOMEM) -		zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM); -	port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; -	if (retval) -		zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED); +	if (!retval) { +		port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; +		goto out; +	} +	if (retval == -ENOMEM) { +		zfcp_erp_notify(&port->erp_action, ZFCP_STATUS_ERP_LOWMEM); +		goto out; +	} +	/* all other error condtions */ +	zfcp_erp_notify(&port->erp_action, 0); +out:  	zfcp_port_put(port);  } @@ -1289,7 +1290,10 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)  	retval = zfcp_erp_strategy_statechange(erp_action, retval);  	if (retval == ZFCP_ERP_EXIT)  		goto unlock; -	zfcp_erp_strategy_followup_actions(erp_action); +	if (retval == ZFCP_ERP_SUCCEEDED) +		zfcp_erp_strategy_followup_success(erp_action); +	if (retval == ZFCP_ERP_FAILED) +		zfcp_erp_strategy_followup_failed(erp_action);   unlock:  	write_unlock(&adapter->erp_lock); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 2f0705d76b7..47daebfa7e5 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -79,11 +79,9 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)  	mutex_unlock(&wka_port->mutex); -	wait_event_timeout( -		wka_port->completion_wq, -		wka_port->status == ZFCP_WKA_PORT_ONLINE || -		wka_port->status == ZFCP_WKA_PORT_OFFLINE, -		HZ >> 1); +	wait_event(wka_port->completion_wq, +		   wka_port->status == ZFCP_WKA_PORT_ONLINE || +		   wka_port->status == ZFCP_WKA_PORT_OFFLINE);  	if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {  		atomic_inc(&wka_port->refcount); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c57658f3d34..47795fbf081 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -670,8 +670,11 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)  			       zfcp_fsf_sbal_check(adapter), 5 * HZ);  	if (ret > 0)  		return 0; -	if (!ret) +	if (!ret) {  		atomic_inc(&adapter->qdio_outb_full); +		/* assume hanging outbound queue, try queue recovery */ +		zfcp_erp_adapter_reopen(adapter, 0, "fsrsg_1", NULL); +	}  	spin_lock_bh(&adapter->req_q_lock);  	return -EIO; @@ -722,7 +725,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,  		req = zfcp_fsf_alloc_qtcb(pool);  	if (unlikely(!req)) -		return ERR_PTR(-EIO); +		return ERR_PTR(-ENOMEM);  	if (adapter->req_no == 0)  		adapter->req_no++; @@ -1010,6 +1013,23 @@ skip_fsfstatus:  		send_ct->handler(send_ct->handler_data);  } +static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale, +					    struct scatterlist *sg_req, +					    struct scatterlist *sg_resp) +{ +	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; +	sbale[2].addr   = sg_virt(sg_req); +	sbale[2].length = sg_req->length; +	sbale[3].addr   = sg_virt(sg_resp); +	sbale[3].length = sg_resp->length; +	sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; +} + +static int zfcp_fsf_one_sbal(struct scatterlist *sg) +{ +	return sg_is_last(sg) && sg->length <= PAGE_SIZE; +} +  static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,  				       struct scatterlist *sg_req,  				       struct scatterlist *sg_resp, @@ -1020,30 +1040,30 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,  	int bytes;  	if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) { -		if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE || -		    !sg_is_last(sg_req) || !sg_is_last(sg_resp)) +		if (!zfcp_fsf_one_sbal(sg_req) || !zfcp_fsf_one_sbal(sg_resp))  			return -EOPNOTSUPP; -		sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; -		sbale[2].addr   = sg_virt(sg_req); -		sbale[2].length = sg_req->length; -		sbale[3].addr   = sg_virt(sg_resp); -		sbale[3].length = sg_resp->length; -		sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; +		zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp); +		return 0; +	} + +	/* use single, unchained SBAL if it can hold the request */ +	if (zfcp_fsf_one_sbal(sg_req) && zfcp_fsf_one_sbal(sg_resp)) { +		zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);  		return 0;  	}  	bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,  					sg_req, max_sbals);  	if (bytes <= 0) -		return -ENOMEM; +		return -EIO;  	req->qtcb->bottom.support.req_buf_length = bytes;  	req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;  	bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,  					sg_resp, max_sbals);  	if (bytes <= 0) -		return -ENOMEM; +		return -EIO;  	req->qtcb->bottom.support.resp_buf_length = bytes;  	return 0; @@ -1607,10 +1627,10 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)  	case FSF_ACCESS_DENIED:  		wka_port->status = ZFCP_WKA_PORT_OFFLINE;  		break; -	case FSF_PORT_ALREADY_OPEN: -		break;  	case FSF_GOOD:  		wka_port->handle = header->port_handle; +		/* fall through */ +	case FSF_PORT_ALREADY_OPEN:  		wka_port->status = ZFCP_WKA_PORT_ONLINE;  	}  out: @@ -1731,15 +1751,16 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)  		zfcp_fsf_access_denied_port(req, port);  		break;  	case FSF_PORT_BOXED: -		zfcp_erp_port_boxed(port, "fscpph2", req); -		req->status |= ZFCP_STATUS_FSFREQ_ERROR | -			       ZFCP_STATUS_FSFREQ_RETRY;  		/* can't use generic zfcp_erp_modify_port_status because  		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */  		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);  		list_for_each_entry(unit, &port->unit_list_head, list)  			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,  					  &unit->status); +		zfcp_erp_port_boxed(port, "fscpph2", req); +		req->status |= ZFCP_STATUS_FSFREQ_ERROR | +			       ZFCP_STATUS_FSFREQ_RETRY; +  		break;  	case FSF_ADAPTER_STATUS_AVAILABLE:  		switch (header->fsf_status_qual.word[0]) { @@ -2541,7 +2562,6 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,  	bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg,  					FSF_MAX_SBALS_PER_REQ);  	if (bytes != ZFCP_CFDC_MAX_SIZE) { -		retval = -ENOMEM;  		zfcp_fsf_req_free(req);  		goto out;  	} diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 967ede73f4c..6925a178468 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -167,20 +167,21 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)  	struct zfcp_unit *unit = scpnt->device->hostdata;  	struct zfcp_fsf_req *old_req, *abrt_req;  	unsigned long flags; -	unsigned long old_req_id = (unsigned long) scpnt->host_scribble; +	unsigned long old_reqid = (unsigned long) scpnt->host_scribble;  	int retval = SUCCESS;  	int retry = 3; +	char *dbf_tag;  	/* avoid race condition between late normal completion and abort */  	write_lock_irqsave(&adapter->abort_lock, flags);  	spin_lock(&adapter->req_list_lock); -	old_req = zfcp_reqlist_find(adapter, old_req_id); +	old_req = zfcp_reqlist_find(adapter, old_reqid);  	spin_unlock(&adapter->req_list_lock);  	if (!old_req) {  		write_unlock_irqrestore(&adapter->abort_lock, flags);  		zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, -					  old_req_id); +					  old_reqid);  		return FAILED; /* completion could be in progress */  	}  	old_req->data = NULL; @@ -189,7 +190,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)  	write_unlock_irqrestore(&adapter->abort_lock, flags);  	while (retry--) { -		abrt_req = zfcp_fsf_abort_fcp_command(old_req_id, unit); +		abrt_req = zfcp_fsf_abort_fcp_command(old_reqid, unit);  		if (abrt_req)  			break; @@ -197,7 +198,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)  		if (!(atomic_read(&adapter->status) &  		      ZFCP_STATUS_COMMON_RUNNING)) {  			zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, -						  old_req_id); +						  old_reqid);  			return SUCCESS;  		}  	} @@ -208,13 +209,14 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)  		   abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);  	if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) -		zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, abrt_req, 0); +		dbf_tag = "okay";  	else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) -		zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, abrt_req, 0); +		dbf_tag = "lte2";  	else { -		zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, abrt_req, 0); +		dbf_tag = "fail";  		retval = FAILED;  	} +	zfcp_scsi_dbf_event_abort(dbf_tag, adapter, scpnt, abrt_req, old_reqid);  	zfcp_fsf_req_free(abrt_req);  	return retval;  } @@ -534,6 +536,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)  	struct fc_rport_identifiers ids;  	struct fc_rport *rport; +	if (port->rport) +		return; +  	ids.node_name = port->wwnn;  	ids.port_name = port->wwpn;  	ids.port_id = port->d_id; @@ -557,8 +562,10 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port)  {  	struct fc_rport *rport = port->rport; -	if (rport) +	if (rport) {  		fc_remote_port_delete(rport); +		port->rport = NULL; +	}  }  void zfcp_scsi_schedule_rport_register(struct zfcp_port *port) diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 3e51e64d110..0fe5cce818c 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -494,9 +494,14 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,  	struct Scsi_Host *scsi_host = class_to_shost(dev);  	struct zfcp_adapter *adapter =  		(struct zfcp_adapter *) scsi_host->hostdata[0]; +	u64 util; + +	spin_lock_bh(&adapter->qdio_stat_lock); +	util = adapter->req_q_util; +	spin_unlock_bh(&adapter->qdio_stat_lock);  	return sprintf(buf, "%d %llu\n", atomic_read(&adapter->qdio_outb_full), -		       (unsigned long long)adapter->req_q_util); +		       (unsigned long long)util);  }  static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);  |