2005-04-16 15:20:36 -07:00
# ifndef S390_CIO_H
# define S390_CIO_H
2006-07-12 16:39:50 +02:00
# include <linux/mutex.h>
2007-04-27 16:01:31 +02:00
# include <linux/device.h>
2008-07-14 09:58:44 +02:00
# include <linux/mod_devicetable.h>
2007-04-27 16:01:35 +02:00
# include <asm/chpid.h>
2008-07-14 09:58:51 +02:00
# include <asm/cio.h>
# include <asm/fcx.h>
2008-07-14 09:59:05 +02:00
# include <asm/schid.h>
2007-04-27 16:01:35 +02:00
# include "chsc.h"
2005-04-16 15:20:36 -07:00
/*
* path management control word
*/
struct pmcw {
2008-01-26 14:10:43 +01:00
u32 intparm ; /* interruption parameter */
u32 qf : 1 ; /* qdio facility */
2008-07-14 09:58:48 +02:00
u32 w : 1 ;
2008-01-26 14:10:43 +01:00
u32 isc : 3 ; /* interruption sublass */
u32 res5 : 3 ; /* reserved zeros */
u32 ena : 1 ; /* enabled */
u32 lm : 2 ; /* limit mode */
u32 mme : 2 ; /* measurement-mode enable */
u32 mp : 1 ; /* multipath mode */
u32 tf : 1 ; /* timing facility */
u32 dnv : 1 ; /* device number valid */
u32 dev : 16 ; /* device number */
u8 lpm ; /* logical path mask */
u8 pnom ; /* path not operational mask */
u8 lpum ; /* last path used mask */
u8 pim ; /* path installed mask */
u16 mbi ; /* measurement-block index */
u8 pom ; /* path operational mask */
u8 pam ; /* path available mask */
u8 chpid [ 8 ] ; /* CHPID 0-7 (if available) */
u32 unused1 : 8 ; /* reserved zeros */
u32 st : 3 ; /* subchannel type */
u32 unused2 : 18 ; /* reserved zeros */
u32 mbfc : 1 ; /* measurement block format control */
u32 xmwme : 1 ; /* extended measurement word mode enable */
u32 csense : 1 ; /* concurrent sense; can be enabled ...*/
2005-04-16 15:20:36 -07:00
/* ... per MSCH, however, if facility */
/* ... is not installed, this results */
/* ... in an operand exception. */
} __attribute__ ( ( packed ) ) ;
2008-12-25 13:39:13 +01:00
/* Target SCHIB configuration. */
struct schib_config {
u64 mba ;
u32 intparm ;
u16 mbi ;
u32 isc : 3 ;
u32 ena : 1 ;
u32 mme : 2 ;
u32 mp : 1 ;
u32 csense : 1 ;
u32 mbfc : 1 ;
} __attribute__ ( ( packed ) ) ;
2005-04-16 15:20:36 -07:00
/*
* subchannel information block
*/
struct schib {
struct pmcw pmcw ; /* path management control word */
2008-07-14 09:58:50 +02:00
union scsw scsw ; /* subchannel status word */
2005-04-16 15:20:36 -07:00
__u64 mba ; /* measurement block address */
__u8 mda [ 4 ] ; /* model dependent area */
} __attribute__ ( ( packed , aligned ( 4 ) ) ) ;
2011-12-01 13:32:19 +01:00
/*
* When rescheduled , todo ' s with higher values will overwrite those
* with lower values .
*/
2009-12-07 12:51:18 +01:00
enum sch_todo {
SCH_TODO_NOTHING ,
2011-12-01 13:32:19 +01:00
SCH_TODO_EVAL ,
2009-12-07 12:51:18 +01:00
SCH_TODO_UNREG ,
} ;
2005-04-16 15:20:36 -07:00
/* subchannel data structure used by I/O subroutines */
struct subchannel {
2006-01-06 00:19:21 -08:00
struct subchannel_id schid ;
2006-12-08 15:54:26 +01:00
spinlock_t * lock ; /* subchannel lock */
2006-07-12 16:39:50 +02:00
struct mutex reg_mutex ;
2005-04-16 15:20:36 -07:00
enum {
SUBCHANNEL_TYPE_IO = 0 ,
SUBCHANNEL_TYPE_CHSC = 1 ,
2008-01-26 14:10:45 +01:00
SUBCHANNEL_TYPE_MSG = 2 ,
2005-04-16 15:20:36 -07:00
SUBCHANNEL_TYPE_ADM = 3 ,
} st ; /* subchannel type */
__u8 vpm ; /* verified path mask */
__u8 lpm ; /* logical path mask */
__u8 opm ; /* operational path mask */
struct schib schib ; /* subchannel information block */
2008-04-30 13:38:39 +02:00
int isc ; /* desired interruption subclass */
2007-04-27 16:01:35 +02:00
struct chsc_ssd_info ssd_info ; /* subchannel description */
2005-04-16 15:20:36 -07:00
struct device dev ; /* entry in device tree */
struct css_driver * driver ;
2009-12-07 12:51:18 +01:00
enum sch_todo todo ;
struct work_struct todo_work ;
2008-12-25 13:39:13 +01:00
struct schib_config config ;
2005-04-16 15:20:36 -07:00
} __attribute__ ( ( aligned ( 8 ) ) ) ;
2014-05-27 14:40:39 +02:00
DECLARE_PER_CPU ( struct irb , cio_irb ) ;
2005-04-16 15:20:36 -07:00
# define to_subchannel(n) container_of(n, struct subchannel, dev)
2006-01-06 00:19:21 -08:00
extern int cio_validate_subchannel ( struct subchannel * , struct subchannel_id ) ;
2008-04-30 13:38:39 +02:00
extern int cio_enable_subchannel ( struct subchannel * , u32 ) ;
2005-04-16 15:20:36 -07:00
extern int cio_disable_subchannel ( struct subchannel * ) ;
extern int cio_cancel ( struct subchannel * ) ;
extern int cio_clear ( struct subchannel * ) ;
extern int cio_resume ( struct subchannel * ) ;
extern int cio_halt ( struct subchannel * ) ;
extern int cio_start ( struct subchannel * , struct ccw1 * , __u8 ) ;
extern int cio_start_key ( struct subchannel * , struct ccw1 * , __u8 , __u8 ) ;
extern int cio_cancel ( struct subchannel * ) ;
extern int cio_set_options ( struct subchannel * , int ) ;
2008-12-25 13:39:12 +01:00
extern int cio_update_schib ( struct subchannel * sch ) ;
2008-12-25 13:39:13 +01:00
extern int cio_commit_config ( struct subchannel * sch ) ;
2006-01-06 00:19:21 -08:00
2008-07-14 09:58:51 +02:00
int cio_tm_start_key ( struct subchannel * sch , struct tcw * tcw , u8 lpm , u8 key ) ;
int cio_tm_intrg ( struct subchannel * sch ) ;
2005-04-16 15:20:36 -07:00
/* Use with care. */
# ifdef CONFIG_CCW_CONSOLE
extern struct subchannel * cio_probe_console ( void ) ;
2006-01-06 00:19:21 -08:00
extern int cio_is_console ( struct subchannel_id ) ;
2013-04-13 13:03:54 +02:00
extern void cio_register_early_subchannels ( void ) ;
2013-04-13 12:53:21 +02:00
extern void cio_tsch ( struct subchannel * sch ) ;
2005-04-16 15:20:36 -07:00
# else
2006-01-06 00:19:21 -08:00
# define cio_is_console(schid) 0
2013-04-13 13:03:54 +02:00
static inline void cio_register_early_subchannels ( void ) { }
2005-04-16 15:20:36 -07:00
# endif
# endif