ccwdev.h 6.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/*
 *  include/asm-s390/ccwdev.h
 *  include/asm-s390x/ccwdev.h
 *
 *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Arnd Bergmann <arndb@de.ibm.com>
 *
 *  Interface for CCW device drivers
 */
#ifndef _S390_CCWDEV_H_
#define _S390_CCWDEV_H_

#include <linux/device.h>
#include <linux/mod_devicetable.h>

/* structs from asm/cio.h */
struct irb;
struct ccw1;

/* 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;
	}

H
Heiko Carstens 已提交
66
	return NULL;
L
Linus Torvalds 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
}

/* The struct ccw device is our replacement for the globally accessible
 * ioinfo array. ioinfo will mutate into a subchannel device later.
 *
 * Reference: Documentation/s390/driver-model.txt */
struct ccw_device {
	spinlock_t *ccwlock;
	struct ccw_device_private *private;	/* cio private information */
	struct ccw_device_id id;	/* id of this device, driver_info is
					   set by ccw_find_driver */
	struct ccw_driver *drv;		/* */
	struct device dev;		/* */
	int online;
	/* This is sick, but a driver can have different interrupt handlers 
	   for different ccw_devices (multi-subchannel drivers)... */
	void (*handler) (struct ccw_device *, unsigned long, struct irb *);
};


/* Each ccw driver registers with the ccw root bus */
struct ccw_driver {
	struct module *owner;		/* for automatic MOD_INC_USE_COUNT   */
	struct ccw_device_id *ids;	/* probe driver with these devs      */
	int (*probe) (struct ccw_device *); /* ask driver to probe dev 	     */
	void (*remove) (struct ccw_device *);
					/* device is no longer available     */
	int (*set_online) (struct ccw_device *);
	int (*set_offline) (struct ccw_device *);
	int (*notify) (struct ccw_device *, int);
	struct device_driver driver;	/* higher level structure, don't init
					   this from your driver	     */
	char *name;
};

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;

113
extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
L
Linus Torvalds 已提交
114
extern int ccw_device_set_options(struct ccw_device *, unsigned long);
115
extern void ccw_device_clear_options(struct ccw_device *, unsigned long);
L
Linus Torvalds 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

/* 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

/*
 * ccw_device_start()
 *
 *  Start a S/390 channel program. When the interrupt arrives, the
 *  IRQ handler is called, either immediately, delayed (dev-end missing,
 *  or sense required) or never (no IRQ handler registered).
 *  Depending on the action taken, ccw_device_start() returns:  
 *                           0	     - Success
 *			     -EBUSY  - Device busy, or status pending
 *			     -ENODEV - Device not operational
 *                           -EINVAL - Device invalid for operation
 */
extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
			    unsigned long, __u8, unsigned long);
/*
 * ccw_device_start_timeout()
 *
 * This function notifies the device driver if the channel program has not
 * completed during the specified time. If a timeout occurs, the channel
 * program is terminated via xsch(), hsch() or csch().
 */
extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *,
				    unsigned long, __u8, unsigned long, int);
/*
 * ccw_device_start_key()
 * ccw_device_start_key_timeout()
 *
 * Same as ccw_device_start() and ccw_device_start_timeout(), except a
 * storage key != default key can be provided for the I/O.
 */
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);

167 168 169
extern int __deprecated read_dev_chars(struct ccw_device *cdev, void **buffer, int length);
extern int __deprecated read_conf_data(struct ccw_device *cdev, void **buffer, int *length);
extern int __deprecated read_conf_data_lpm(struct ccw_device *cdev, void **buffer,
L
Linus Torvalds 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
			      int *length, __u8 lpm);

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 *);

#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)

extern struct ccw_device *ccw_device_probe_console(void);

// FIXME: these have to go
extern int _ccw_device_get_device_number(struct ccw_device *);
extern int _ccw_device_get_subchannel_number(struct ccw_device *);

extern void *ccw_device_get_chp_desc(struct ccw_device *, int);
#endif /* _S390_CCWDEV_H_ */