forked from mirrors/linux
		
	vfio-ccw: Register a chp_event callback for vfio-ccw
Register the chp_event callback to receive channel path related events for the subchannels managed by vfio-ccw. Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Eric Farman <farman@linux.ibm.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Message-Id: <20200505122745.53208-3-farman@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
		
							parent
							
								
									9a44ce6c9b
								
							
						
					
					
						commit
						b7701dfbf9
					
				
					 1 changed files with 47 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
 | 
			
		||||
#include <asm/isc.h>
 | 
			
		||||
 | 
			
		||||
#include "chp.h"
 | 
			
		||||
#include "ioasm.h"
 | 
			
		||||
#include "css.h"
 | 
			
		||||
#include "vfio_ccw_private.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -262,6 +263,51 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)
 | 
			
		|||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int vfio_ccw_chp_event(struct subchannel *sch,
 | 
			
		||||
			      struct chp_link *link, int event)
 | 
			
		||||
{
 | 
			
		||||
	struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
 | 
			
		||||
	int mask = chp_ssd_get_mask(&sch->ssd_info, link);
 | 
			
		||||
	int retry = 255;
 | 
			
		||||
 | 
			
		||||
	if (!private || !mask)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	VFIO_CCW_MSG_EVENT(2, "%pUl (%x.%x.%04x): mask=0x%x event=%d\n",
 | 
			
		||||
			   mdev_uuid(private->mdev), sch->schid.cssid,
 | 
			
		||||
			   sch->schid.ssid, sch->schid.sch_no,
 | 
			
		||||
			   mask, event);
 | 
			
		||||
 | 
			
		||||
	if (cio_update_schib(sch))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case CHP_VARY_OFF:
 | 
			
		||||
		/* Path logically turned off */
 | 
			
		||||
		sch->opm &= ~mask;
 | 
			
		||||
		sch->lpm &= ~mask;
 | 
			
		||||
		if (sch->schib.pmcw.lpum & mask)
 | 
			
		||||
			cio_cancel_halt_clear(sch, &retry);
 | 
			
		||||
		break;
 | 
			
		||||
	case CHP_OFFLINE:
 | 
			
		||||
		/* Path is gone */
 | 
			
		||||
		if (sch->schib.pmcw.lpum & mask)
 | 
			
		||||
			cio_cancel_halt_clear(sch, &retry);
 | 
			
		||||
		break;
 | 
			
		||||
	case CHP_VARY_ON:
 | 
			
		||||
		/* Path logically turned on */
 | 
			
		||||
		sch->opm |= mask;
 | 
			
		||||
		sch->lpm |= mask;
 | 
			
		||||
		break;
 | 
			
		||||
	case CHP_ONLINE:
 | 
			
		||||
		/* Path became available */
 | 
			
		||||
		sch->lpm |= mask & sch->opm;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct css_device_id vfio_ccw_sch_ids[] = {
 | 
			
		||||
	{ .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
 | 
			
		||||
	{ /* end of list */ },
 | 
			
		||||
| 
						 | 
				
			
			@ -279,6 +325,7 @@ static struct css_driver vfio_ccw_sch_driver = {
 | 
			
		|||
	.remove = vfio_ccw_sch_remove,
 | 
			
		||||
	.shutdown = vfio_ccw_sch_shutdown,
 | 
			
		||||
	.sch_event = vfio_ccw_sch_event,
 | 
			
		||||
	.chp_event = vfio_ccw_chp_event,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int __init vfio_ccw_debug_init(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue