2005-04-16 15:20:36 -07:00
/*
2012-07-20 11:15:04 +02:00
* Copyright IBM Corp . 2002 , 2009
2005-04-16 15:20:36 -07:00
*
2009-06-16 10:30:20 +02:00
* Author ( s ) : Arnd Bergmann < arndb @ de . ibm . com >
2005-04-16 15:20:36 -07:00
*
2009-06-16 10:30:20 +02:00
* Interface for CCW device drivers
2005-04-16 15:20:36 -07:00
*/
# ifndef _S390_CCWDEV_H_
# define _S390_CCWDEV_H_
# include <linux/device.h>
# include <linux/mod_devicetable.h>
2008-07-14 09:58:51 +02:00
# include <asm/fcx.h>
2011-10-30 15:16:04 +01:00
# include <asm/irq.h>
2012-12-13 13:38:51 +01:00
# include <asm/schid.h>
2005-04-16 15:20:36 -07:00
/* structs from asm/cio.h */
struct irb ;
struct ccw1 ;
2007-05-10 15:45:42 +02:00
struct ccw_dev_id ;
2005-04-16 15:20:36 -07:00
/* simplified initializers for struct ccw_device:
* CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
* entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
# define CCW_DEVICE(cu, cum) \
. cu_type = ( cu ) , . cu_model = ( cum ) , \
. match_flags = ( CCW_DEVICE_ID_MATCH_CU_TYPE \
| ( cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0 ) )
# define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm) \
. cu_type = ( cu ) , . cu_model = ( cum ) , . dev_type = ( dev ) , . dev_model = ( devm ) , \
. match_flags = CCW_DEVICE_ID_MATCH_CU_TYPE \
| ( ( cum ) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0 ) \
| CCW_DEVICE_ID_MATCH_DEVICE_TYPE \
| ( ( devm ) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0 )
/* scan through an array of device ids and return the first
* entry that matches the device .
*
* the array must end with an entry containing zero match_flags
*/
static inline const struct ccw_device_id *
ccw_device_id_match ( const struct ccw_device_id * array ,
const struct ccw_device_id * match )
{
const struct ccw_device_id * id = array ;
for ( id = array ; id - > match_flags ; id + + ) {
if ( ( id - > match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE )
& & ( id - > cu_type ! = match - > cu_type ) )
continue ;
if ( ( id - > match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL )
& & ( id - > cu_model ! = match - > cu_model ) )
continue ;
if ( ( id - > match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE )
& & ( id - > dev_type ! = match - > dev_type ) )
continue ;
if ( ( id - > match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL )
& & ( id - > dev_model ! = match - > dev_model ) )
continue ;
return id ;
}
2006-07-12 16:41:55 +02:00
return NULL ;
2005-04-16 15:20:36 -07:00
}
2007-10-12 16:11:17 +02:00
/**
* struct ccw_device - channel attached device
* @ ccwlock : pointer to device lock
* @ id : id of this device
* @ drv : ccw driver for this device
* @ dev : embedded device structure
* @ online : online status of device
* @ handler : interrupt handler
2005-04-16 15:20:36 -07:00
*
2007-10-12 16:11:17 +02:00
* @ handler is a member of the device rather than the driver since a driver
* can have different interrupt handlers for different ccw devices
* ( multi - subchannel drivers ) .
*/
2005-04-16 15:20:36 -07:00
struct ccw_device {
spinlock_t * ccwlock ;
2007-10-12 16:11:17 +02:00
/* private: */
2005-04-16 15:20:36 -07:00
struct ccw_device_private * private ; /* cio private information */
2007-10-12 16:11:17 +02:00
/* public: */
struct ccw_device_id id ;
struct ccw_driver * drv ;
struct device dev ;
2005-04-16 15:20:36 -07:00
int online ;
void ( * handler ) ( struct ccw_device * , unsigned long , struct irb * ) ;
} ;
2010-10-25 16:10:34 +02:00
/*
* Possible events used by the path_event notifier .
*/
# define PE_NONE 0x0
# define PE_PATH_GONE 0x1 /* A path is no longer available. */
# define PE_PATH_AVAILABLE 0x2 / * A path has become available and
was successfully verified . */
# define PE_PATHGROUP_ESTABLISHED 0x4 / * A pathgroup was reset and had
to be established again . */
2010-05-26 23:27:08 +02:00
/*
* Possible CIO actions triggered by the unit check handler .
*/
enum uc_todo {
UC_TODO_RETRY ,
UC_TODO_RETRY_ON_NEW_PATH ,
UC_TODO_STOP
} ;
2005-04-16 15:20:36 -07:00
2007-10-12 16:11:17 +02:00
/**
* struct ccw driver - device driver for channel attached devices
* @ ids : ids supported by this driver
* @ probe : function called on probe
* @ remove : function called on remove
* @ set_online : called when setting device online
* @ set_offline : called when setting device offline
* @ notify : notify driver of device state changes
2010-10-25 16:10:34 +02:00
* @ path_event : notify driver of channel path events
2007-10-12 16:11:21 +02:00
* @ shutdown : called at device shutdown
2009-06-16 10:30:20 +02:00
* @ prepare : prepare for pm state transition
* @ complete : undo work done in @ prepare
* @ freeze : callback for freezing during hibernation snapshotting
* @ thaw : undo work done in @ freeze
* @ restore : callback for restoring after hibernation
2010-05-26 23:27:08 +02:00
* @ uc_handler : callback for unit check handler
2007-10-12 16:11:17 +02:00
* @ driver : embedded device driver structure
2011-10-30 15:16:04 +01:00
* @ int_class : interruption class to use for accounting interrupts
2007-10-12 16:11:17 +02:00
*/
2005-04-16 15:20:36 -07:00
struct ccw_driver {
2007-10-12 16:11:17 +02:00
struct ccw_device_id * ids ;
int ( * probe ) ( struct ccw_device * ) ;
2005-04-16 15:20:36 -07:00
void ( * remove ) ( struct ccw_device * ) ;
int ( * set_online ) ( struct ccw_device * ) ;
int ( * set_offline ) ( struct ccw_device * ) ;
int ( * notify ) ( struct ccw_device * , int ) ;
2010-10-25 16:10:34 +02:00
void ( * path_event ) ( struct ccw_device * , int * ) ;
2007-10-12 16:11:21 +02:00
void ( * shutdown ) ( struct ccw_device * ) ;
2009-06-16 10:30:20 +02:00
int ( * prepare ) ( struct ccw_device * ) ;
void ( * complete ) ( struct ccw_device * ) ;
int ( * freeze ) ( struct ccw_device * ) ;
int ( * thaw ) ( struct ccw_device * ) ;
int ( * restore ) ( struct ccw_device * ) ;
2010-05-26 23:27:08 +02:00
enum uc_todo ( * uc_handler ) ( struct ccw_device * , struct irb * ) ;
2007-10-12 16:11:17 +02:00
struct device_driver driver ;
2011-10-30 15:16:04 +01:00
enum interruption_class int_class ;
2005-04-16 15:20:36 -07:00
} ;
extern struct ccw_device * get_ccwdev_by_busid ( struct ccw_driver * cdrv ,
const char * bus_id ) ;
/* devices drivers call these during module load and unload.
* When a driver is registered , its probe method is called
* when new devices for its type pop up */
extern int ccw_driver_register ( struct ccw_driver * driver ) ;
extern void ccw_driver_unregister ( struct ccw_driver * driver ) ;
struct ccw1 ;
2007-02-12 15:47:18 +01:00
extern int ccw_device_set_options_mask ( struct ccw_device * , unsigned long ) ;
2005-04-16 15:20:36 -07:00
extern int ccw_device_set_options ( struct ccw_device * , unsigned long ) ;
2007-02-12 15:47:18 +01:00
extern void ccw_device_clear_options ( struct ccw_device * , unsigned long ) ;
2009-12-07 12:51:30 +01:00
int ccw_device_is_pathgroup ( struct ccw_device * cdev ) ;
int ccw_device_is_multipath ( struct ccw_device * cdev ) ;
2005-04-16 15:20:36 -07:00
/* Allow for i/o completion notification after primary interrupt status. */
# define CCWDEV_EARLY_NOTIFICATION 0x0001
/* Report all interrupt conditions. */
# define CCWDEV_REPORT_ALL 0x0002
/* Try to perform path grouping. */
# define CCWDEV_DO_PATHGROUP 0x0004
/* Allow forced onlining of boxed devices. */
# define CCWDEV_ALLOW_FORCE 0x0008
2009-12-07 12:51:30 +01:00
/* Try to use multipath mode. */
# define CCWDEV_DO_MULTIPATH 0x0010
2005-04-16 15:20:36 -07:00
extern int ccw_device_start ( struct ccw_device * , struct ccw1 * ,
unsigned long , __u8 , unsigned long ) ;
extern int ccw_device_start_timeout ( struct ccw_device * , struct ccw1 * ,
unsigned long , __u8 , unsigned long , int ) ;
extern int ccw_device_start_key ( struct ccw_device * , struct ccw1 * ,
unsigned long , __u8 , __u8 , unsigned long ) ;
extern int ccw_device_start_timeout_key ( struct ccw_device * , struct ccw1 * ,
unsigned long , __u8 , __u8 ,
unsigned long , int ) ;
extern int ccw_device_resume ( struct ccw_device * ) ;
extern int ccw_device_halt ( struct ccw_device * , unsigned long ) ;
extern int ccw_device_clear ( struct ccw_device * , unsigned long ) ;
2008-07-14 09:58:51 +02:00
int ccw_device_tm_start_key ( struct ccw_device * cdev , struct tcw * tcw ,
unsigned long intparm , u8 lpm , u8 key ) ;
int ccw_device_tm_start_key ( struct ccw_device * , struct tcw * ,
unsigned long , u8 , u8 ) ;
int ccw_device_tm_start_timeout_key ( struct ccw_device * , struct tcw * ,
unsigned long , u8 , u8 , int ) ;
int ccw_device_tm_start ( struct ccw_device * , struct tcw * ,
unsigned long , u8 ) ;
int ccw_device_tm_start_timeout ( struct ccw_device * , struct tcw * ,
unsigned long , u8 , int ) ;
int ccw_device_tm_intrg ( struct ccw_device * cdev ) ;
2005-04-16 15:20:36 -07:00
2011-01-05 12:47:56 +01:00
int ccw_device_get_mdc ( struct ccw_device * cdev , u8 mask ) ;
2005-04-16 15:20:36 -07:00
extern int ccw_device_set_online ( struct ccw_device * cdev ) ;
extern int ccw_device_set_offline ( struct ccw_device * cdev ) ;
extern struct ciw * ccw_device_get_ciw ( struct ccw_device * , __u32 cmd ) ;
extern __u8 ccw_device_get_path_mask ( struct ccw_device * ) ;
2007-05-10 15:45:42 +02:00
extern void ccw_device_get_id ( struct ccw_device * , struct ccw_dev_id * ) ;
2005-04-16 15:20:36 -07:00
# define get_ccwdev_lock(x) (x)->ccwlock
# define to_ccwdev(n) container_of(n, struct ccw_device, dev)
# define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
2014-01-27 13:28:10 +01:00
extern struct ccw_device * ccw_device_create_console ( struct ccw_driver * ) ;
extern void ccw_device_destroy_console ( struct ccw_device * ) ;
extern int ccw_device_enable_console ( struct ccw_device * ) ;
2013-04-13 12:53:21 +02:00
extern void ccw_device_wait_idle ( struct ccw_device * ) ;
2013-04-13 12:56:51 +02:00
extern int ccw_device_force_console ( struct ccw_device * ) ;
2005-04-16 15:20:36 -07:00
2010-08-09 18:12:50 +02:00
int ccw_device_siosl ( struct ccw_device * ) ;
2012-05-30 16:03:22 +02:00
extern void ccw_device_get_schid ( struct ccw_device * , struct subchannel_id * ) ;
2014-05-07 13:27:21 +02:00
struct channel_path_desc * ccw_device_get_chp_desc ( struct ccw_device * , int ) ;
2005-04-16 15:20:36 -07:00
# endif /* _S390_CCWDEV_H_ */