xref: /linux/drivers/s390/block/dasd_int.h (revision 5ea34a01423a27d4526f3551e8542f2f991bd4a0)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
31da177e4SLinus Torvalds  *		    Horst Hummel <Horst.Hummel@de.ibm.com>
41da177e4SLinus Torvalds  *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
51da177e4SLinus Torvalds  * Bugreports.to..: <Linux390@de.ibm.com>
6d41dd122SStefan Haberland  * Copyright IBM Corp. 1999, 2009
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #ifndef DASD_INT_H
101da177e4SLinus Torvalds #define DASD_INT_H
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds /* we keep old device allocation scheme; IOW, minors are still in 0..255 */
131da177e4SLinus Torvalds #define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS))
141da177e4SLinus Torvalds #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds /*
171da177e4SLinus Torvalds  * States a dasd device can have:
181da177e4SLinus Torvalds  *   new: the dasd_device structure is allocated.
191da177e4SLinus Torvalds  *   known: the discipline for the device is identified.
201da177e4SLinus Torvalds  *   basic: the device can do basic i/o.
2190f0094dSHorst Hummel  *   unfmt: the device could not be analyzed (format is unknown).
221da177e4SLinus Torvalds  *   ready: partition detection is done and the device is can do block io.
231da177e4SLinus Torvalds  *   online: the device accepts requests from the block device queue.
241da177e4SLinus Torvalds  *
251da177e4SLinus Torvalds  * Things to do for startup state transitions:
261da177e4SLinus Torvalds  *   new -> known: find discipline for the device and create devfs entries.
271da177e4SLinus Torvalds  *   known -> basic: request irq line for the device.
281da177e4SLinus Torvalds  *   basic -> ready: do the initial analysis, e.g. format detection,
291da177e4SLinus Torvalds  *                   do block device setup and detect partitions.
301da177e4SLinus Torvalds  *   ready -> online: schedule the device tasklet.
311da177e4SLinus Torvalds  * Things to do for shutdown state transitions:
321da177e4SLinus Torvalds  *   online -> ready: just set the new device state.
331da177e4SLinus Torvalds  *   ready -> basic: flush requests from the block device layer, clear
341da177e4SLinus Torvalds  *                   partition information and reset format information.
351da177e4SLinus Torvalds  *   basic -> known: terminate all requests and free irq.
361da177e4SLinus Torvalds  *   known -> new: remove devfs entries and forget discipline.
371da177e4SLinus Torvalds  */
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds #define DASD_STATE_NEW	  0
401da177e4SLinus Torvalds #define DASD_STATE_KNOWN  1
411da177e4SLinus Torvalds #define DASD_STATE_BASIC  2
4290f0094dSHorst Hummel #define DASD_STATE_UNFMT  3
4390f0094dSHorst Hummel #define DASD_STATE_READY  4
4490f0094dSHorst Hummel #define DASD_STATE_ONLINE 5
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds #include <linux/module.h>
471da177e4SLinus Torvalds #include <linux/wait.h>
481da177e4SLinus Torvalds #include <linux/blkdev.h>
491da177e4SLinus Torvalds #include <linux/genhd.h>
501da177e4SLinus Torvalds #include <linux/hdreg.h>
511da177e4SLinus Torvalds #include <linux/interrupt.h>
52e108cebbSvignesh babu #include <linux/log2.h>
531da177e4SLinus Torvalds #include <asm/ccwdev.h>
541da177e4SLinus Torvalds #include <linux/workqueue.h>
551da177e4SLinus Torvalds #include <asm/debug.h>
561da177e4SLinus Torvalds #include <asm/dasd.h>
571da177e4SLinus Torvalds #include <asm/idals.h>
581da177e4SLinus Torvalds 
5968b781feSStefan Haberland /* DASD discipline magic */
6068b781feSStefan Haberland #define DASD_ECKD_MAGIC 0xC5C3D2C4
6168b781feSStefan Haberland #define DASD_DIAG_MAGIC 0xC4C9C1C7
6268b781feSStefan Haberland #define DASD_FBA_MAGIC 0xC6C2C140
6368b781feSStefan Haberland 
641da177e4SLinus Torvalds /*
651da177e4SLinus Torvalds  * SECTION: Type definitions
661da177e4SLinus Torvalds  */
671da177e4SLinus Torvalds struct dasd_device;
688e09f215SStefan Weinhuber struct dasd_block;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds /* BIT DEFINITIONS FOR SENSE DATA */
711da177e4SLinus Torvalds #define DASD_SENSE_BIT_0 0x80
721da177e4SLinus Torvalds #define DASD_SENSE_BIT_1 0x40
731da177e4SLinus Torvalds #define DASD_SENSE_BIT_2 0x20
741da177e4SLinus Torvalds #define DASD_SENSE_BIT_3 0x10
751da177e4SLinus Torvalds 
76f60c768cSStefan Haberland /* BIT DEFINITIONS FOR SIM SENSE */
77f60c768cSStefan Haberland #define DASD_SIM_SENSE 0x0F
78f60c768cSStefan Haberland #define DASD_SIM_MSG_TO_OP 0x03
79f60c768cSStefan Haberland #define DASD_SIM_LOG 0x0C
80f60c768cSStefan Haberland 
812dedf0d9SStefan Haberland /* lock class for nested cdev lock */
822dedf0d9SStefan Haberland #define CDEV_NESTED_FIRST 1
832dedf0d9SStefan Haberland #define CDEV_NESTED_SECOND 2
842dedf0d9SStefan Haberland 
851da177e4SLinus Torvalds /*
861da177e4SLinus Torvalds  * SECTION: MACROs for klogd and s390 debug feature (dbf)
871da177e4SLinus Torvalds  */
881da177e4SLinus Torvalds #define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \
891da177e4SLinus Torvalds do { \
901da177e4SLinus Torvalds 	debug_sprintf_event(d_device->debug_area, \
911da177e4SLinus Torvalds 			    d_level, \
921da177e4SLinus Torvalds 			    d_str "\n", \
931da177e4SLinus Torvalds 			    d_data); \
941da177e4SLinus Torvalds } while(0)
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds #define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \
971da177e4SLinus Torvalds do { \
981da177e4SLinus Torvalds 	debug_sprintf_exception(d_device->debug_area, \
991da177e4SLinus Torvalds 				d_level, \
1001da177e4SLinus Torvalds 				d_str "\n", \
1011da177e4SLinus Torvalds 				d_data); \
1021da177e4SLinus Torvalds } while(0)
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds #define DBF_EVENT(d_level, d_str, d_data...)\
1051da177e4SLinus Torvalds do { \
1061da177e4SLinus Torvalds 	debug_sprintf_event(dasd_debug_area, \
1071da177e4SLinus Torvalds 			    d_level,\
1081da177e4SLinus Torvalds 			    d_str "\n", \
1091da177e4SLinus Torvalds 			    d_data); \
1101da177e4SLinus Torvalds } while(0)
1111da177e4SLinus Torvalds 
112b8ed5dd5SStefan Haberland #define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...)	\
113b8ed5dd5SStefan Haberland do { \
114b8ed5dd5SStefan Haberland 	struct ccw_dev_id __dev_id;			\
115b8ed5dd5SStefan Haberland 	ccw_device_get_id(d_cdev, &__dev_id);		\
116b8ed5dd5SStefan Haberland 	debug_sprintf_event(dasd_debug_area,		\
117b8ed5dd5SStefan Haberland 			    d_level,					\
118b8ed5dd5SStefan Haberland 			    "0.%x.%04x " d_str "\n",			\
119b8ed5dd5SStefan Haberland 			    __dev_id.ssid, __dev_id.devno, d_data);	\
120b8ed5dd5SStefan Haberland } while (0)
121b8ed5dd5SStefan Haberland 
1221da177e4SLinus Torvalds #define DBF_EXC(d_level, d_str, d_data...)\
1231da177e4SLinus Torvalds do { \
1241da177e4SLinus Torvalds 	debug_sprintf_exception(dasd_debug_area, \
1251da177e4SLinus Torvalds 				d_level,\
1261da177e4SLinus Torvalds 				d_str "\n", \
1271da177e4SLinus Torvalds 				d_data); \
1281da177e4SLinus Torvalds } while(0)
1291da177e4SLinus Torvalds 
130fc19f381SStefan Haberland /* limit size for an errorstring */
131fc19f381SStefan Haberland #define ERRORLENGTH 30
132fc19f381SStefan Haberland 
1331da177e4SLinus Torvalds /* definition of dbf debug levels */
1341da177e4SLinus Torvalds #define	DBF_EMERG	0	/* system is unusable			*/
1351da177e4SLinus Torvalds #define	DBF_ALERT	1	/* action must be taken immediately	*/
1361da177e4SLinus Torvalds #define	DBF_CRIT	2	/* critical conditions			*/
1371da177e4SLinus Torvalds #define	DBF_ERR		3	/* error conditions			*/
1381da177e4SLinus Torvalds #define	DBF_WARNING	4	/* warning conditions			*/
1391da177e4SLinus Torvalds #define	DBF_NOTICE	5	/* normal but significant condition	*/
1401da177e4SLinus Torvalds #define	DBF_INFO	6	/* informational			*/
1411da177e4SLinus Torvalds #define	DBF_DEBUG	6	/* debug-level messages			*/
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds /* messages to be written via klogd and dbf */
1441da177e4SLinus Torvalds #define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
1451da177e4SLinus Torvalds do { \
1461da177e4SLinus Torvalds 	printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
1472a0217d5SKay Sievers 	       dev_name(&d_device->cdev->dev), d_args); \
1481da177e4SLinus Torvalds 	DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \
1491da177e4SLinus Torvalds } while(0)
1501da177e4SLinus Torvalds 
1511da177e4SLinus Torvalds #define MESSAGE(d_loglevel,d_string,d_args...)\
1521da177e4SLinus Torvalds do { \
1531da177e4SLinus Torvalds 	printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
1541da177e4SLinus Torvalds 	DBF_EVENT(DBF_ALERT, d_string, d_args); \
1551da177e4SLinus Torvalds } while(0)
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds /* messages to be written via klogd only */
1581da177e4SLinus Torvalds #define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\
1591da177e4SLinus Torvalds do { \
1601da177e4SLinus Torvalds 	printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
1612a0217d5SKay Sievers 	       dev_name(&d_device->cdev->dev), d_args); \
1621da177e4SLinus Torvalds } while(0)
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds #define MESSAGE_LOG(d_loglevel,d_string,d_args...)\
1651da177e4SLinus Torvalds do { \
1661da177e4SLinus Torvalds 	printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
1671da177e4SLinus Torvalds } while(0)
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds struct dasd_ccw_req {
1701da177e4SLinus Torvalds 	unsigned int magic;		/* Eye catcher */
1718e09f215SStefan Weinhuber 	struct list_head devlist;	/* for dasd_device request queue */
1728e09f215SStefan Weinhuber 	struct list_head blocklist;	/* for dasd_block request queue */
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	/* Where to execute what... */
1758e09f215SStefan Weinhuber 	struct dasd_block *block;	/* the originating block device */
1768e09f215SStefan Weinhuber 	struct dasd_device *memdev;	/* the device used to allocate this */
1778e09f215SStefan Weinhuber 	struct dasd_device *startdev;	/* device the request is started on */
178f3eb5384SStefan Weinhuber 	void *cpaddr;			/* address of ccw or tcw */
179f3eb5384SStefan Weinhuber 	unsigned char cpmode;		/* 0 = cmd mode, 1 = itcw */
1801da177e4SLinus Torvalds 	char status;			/* status of this request */
1811da177e4SLinus Torvalds 	short retries;			/* A retry counter */
1821da177e4SLinus Torvalds 	unsigned long flags;        	/* flags of this request */
1831da177e4SLinus Torvalds 
1841da177e4SLinus Torvalds 	/* ... and how */
1851da177e4SLinus Torvalds 	unsigned long starttime;	/* jiffies time of request start */
1867c8faa86SStefan Haberland 	unsigned long expires;		/* expiration period in jiffies */
1871da177e4SLinus Torvalds 	char lpm;			/* logical path mask */
1881da177e4SLinus Torvalds 	void *data;			/* pointer to data area */
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	/* these are important for recovering erroneous requests          */
1916cc7f168SStefan Weinhuber 	int intrc;			/* internal error, e.g. from start_IO */
1921da177e4SLinus Torvalds 	struct irb irb;			/* device status in case of an error */
1931da177e4SLinus Torvalds 	struct dasd_ccw_req *refers;	/* ERP-chain queueing. */
1941da177e4SLinus Torvalds 	void *function; 		/* originating ERP action */
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 	/* these are for statistics only */
1971da177e4SLinus Torvalds 	unsigned long long buildclk;	/* TOD-clock of request generation */
1981da177e4SLinus Torvalds 	unsigned long long startclk;	/* TOD-clock of request start */
1991da177e4SLinus Torvalds 	unsigned long long stopclk;	/* TOD-clock of request interrupt */
2001da177e4SLinus Torvalds 	unsigned long long endclk;	/* TOD-clock of request termination */
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds         /* Callback that is called after reaching final status. */
2031da177e4SLinus Torvalds 	void (*callback)(struct dasd_ccw_req *, void *data);
2041da177e4SLinus Torvalds 	void *callback_data;
2051da177e4SLinus Torvalds };
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds /*
2081da177e4SLinus Torvalds  * dasd_ccw_req -> status can be:
2091da177e4SLinus Torvalds  */
2101da177e4SLinus Torvalds #define DASD_CQR_FILLED 	0x00	/* request is ready to be processed */
2118e09f215SStefan Weinhuber #define DASD_CQR_DONE		0x01	/* request is completed successfully */
2128e09f215SStefan Weinhuber #define DASD_CQR_NEED_ERP	0x02	/* request needs recovery action */
2138e09f215SStefan Weinhuber #define DASD_CQR_IN_ERP 	0x03	/* request is in recovery */
2148e09f215SStefan Weinhuber #define DASD_CQR_FAILED 	0x04	/* request is finally failed */
2158e09f215SStefan Weinhuber #define DASD_CQR_TERMINATED	0x05	/* request was stopped by driver */
2168e09f215SStefan Weinhuber 
2178e09f215SStefan Weinhuber #define DASD_CQR_QUEUED 	0x80	/* request is queued to be processed */
2188e09f215SStefan Weinhuber #define DASD_CQR_IN_IO		0x81	/* request is currently in IO */
2198e09f215SStefan Weinhuber #define DASD_CQR_ERROR		0x82	/* request is completed with error */
2208e09f215SStefan Weinhuber #define DASD_CQR_CLEAR_PENDING	0x83	/* request is clear pending */
2218e09f215SStefan Weinhuber #define DASD_CQR_CLEARED	0x84	/* request was cleared */
22273ac36eaSColy Li #define DASD_CQR_SUCCESS	0x85	/* request was successful */
2238e09f215SStefan Weinhuber 
2247c8faa86SStefan Haberland /* default expiration time*/
2257c8faa86SStefan Haberland #define DASD_EXPIRES	  300
2267c8faa86SStefan Haberland #define DASD_EXPIRES_MAX  40000000
2271f1ee9adSHannes Reinecke #define DASD_RETRIES	  256
2281f1ee9adSHannes Reinecke #define DASD_RETRIES_MAX  32768
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds /* per dasd_ccw_req flags */
2311da177e4SLinus Torvalds #define DASD_CQR_FLAGS_USE_ERP   0	/* use ERP for this request */
2321c01b8a5SHorst Hummel #define DASD_CQR_FLAGS_FAILFAST  1	/* FAILFAST */
233a4d26c6aSStefan Weinhuber #define DASD_CQR_VERIFY_PATH	 2	/* path verification request */
2345a27e60dSStefan Weinhuber #define DASD_CQR_ALLOW_SLOCK	 3	/* Try this request even when lock was
2355a27e60dSStefan Weinhuber 					 * stolen. Should not be combined with
2365a27e60dSStefan Weinhuber 					 * DASD_CQR_FLAGS_USE_ERP
2375a27e60dSStefan Weinhuber 					 */
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds /* Signature for error recovery functions. */
2401da177e4SLinus Torvalds typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds /*
2432dedf0d9SStefan Haberland  * Unique identifier for dasd device.
2442dedf0d9SStefan Haberland  */
2452dedf0d9SStefan Haberland #define UA_NOT_CONFIGURED  0x00
2462dedf0d9SStefan Haberland #define UA_BASE_DEVICE	   0x01
2472dedf0d9SStefan Haberland #define UA_BASE_PAV_ALIAS  0x02
2482dedf0d9SStefan Haberland #define UA_HYPER_PAV_ALIAS 0x03
2492dedf0d9SStefan Haberland 
2502dedf0d9SStefan Haberland struct dasd_uid {
2512dedf0d9SStefan Haberland 	__u8 type;
2522dedf0d9SStefan Haberland 	char vendor[4];
2532dedf0d9SStefan Haberland 	char serial[15];
2542dedf0d9SStefan Haberland 	__u16 ssid;
2552dedf0d9SStefan Haberland 	__u8 real_unit_addr;
2562dedf0d9SStefan Haberland 	__u8 base_unit_addr;
2572dedf0d9SStefan Haberland 	char vduit[33];
2582dedf0d9SStefan Haberland };
2592dedf0d9SStefan Haberland 
2602dedf0d9SStefan Haberland /*
2611da177e4SLinus Torvalds  * the struct dasd_discipline is
2621da177e4SLinus Torvalds  * sth like a table of virtual functions, if you think of dasd_eckd
2631da177e4SLinus Torvalds  * inheriting dasd...
2641da177e4SLinus Torvalds  * no, currently we are not planning to reimplement the driver in C++
2651da177e4SLinus Torvalds  */
2661da177e4SLinus Torvalds struct dasd_discipline {
2671da177e4SLinus Torvalds 	struct module *owner;
2681da177e4SLinus Torvalds 	char ebcname[8];	/* a name used for tagging and printks */
2691da177e4SLinus Torvalds 	char name[8];		/* a name used for tagging and printks */
2701da177e4SLinus Torvalds 	int max_blocks;		/* maximum number of blocks to be chained */
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds 	struct list_head list;	/* used for list of disciplines */
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds 	/*
2751da177e4SLinus Torvalds 	 * Device recognition functions. check_device is used to verify
2761da177e4SLinus Torvalds 	 * the sense data and the information returned by read device
2771da177e4SLinus Torvalds 	 * characteristics. It returns 0 if the discipline can be used
2788e09f215SStefan Weinhuber 	 * for the device in question. uncheck_device is called during
2798e09f215SStefan Weinhuber 	 * device shutdown to deregister a device from its discipline.
2808e09f215SStefan Weinhuber 	 */
2818e09f215SStefan Weinhuber 	int (*check_device) (struct dasd_device *);
2828e09f215SStefan Weinhuber 	void (*uncheck_device) (struct dasd_device *);
2838e09f215SStefan Weinhuber 
2848e09f215SStefan Weinhuber 	/*
2851da177e4SLinus Torvalds 	 * do_analysis is used in the step from device state "basic" to
2861da177e4SLinus Torvalds 	 * state "accept". It returns 0 if the device can be made ready,
2871da177e4SLinus Torvalds 	 * it returns -EMEDIUMTYPE if the device can't be made ready or
2881da177e4SLinus Torvalds 	 * -EAGAIN if do_analysis started a ccw that needs to complete
2891da177e4SLinus Torvalds 	 * before the analysis may be repeated.
2901da177e4SLinus Torvalds 	 */
2918e09f215SStefan Weinhuber 	int (*do_analysis) (struct dasd_block *);
2928e09f215SStefan Weinhuber 
2938e09f215SStefan Weinhuber 	/*
294a4d26c6aSStefan Weinhuber 	 * This function is called, when new paths become available.
295a4d26c6aSStefan Weinhuber 	 * Disciplins may use this callback to do necessary setup work,
296a4d26c6aSStefan Weinhuber 	 * e.g. verify that new path is compatible with the current
297a4d26c6aSStefan Weinhuber 	 * configuration.
298a4d26c6aSStefan Weinhuber 	 */
299a4d26c6aSStefan Weinhuber 	int (*verify_path)(struct dasd_device *, __u8);
300a4d26c6aSStefan Weinhuber 
301a4d26c6aSStefan Weinhuber 	/*
3028e09f215SStefan Weinhuber 	 * Last things to do when a device is set online, and first things
3038e09f215SStefan Weinhuber 	 * when it is set offline.
3048e09f215SStefan Weinhuber 	 */
305d42e1712SStefan Haberland 	int (*basic_to_ready) (struct dasd_device *);
3068e09f215SStefan Weinhuber 	int (*online_to_ready) (struct dasd_device *);
307d42e1712SStefan Haberland 	int (*ready_to_basic)  (struct dasd_device *);
3081da177e4SLinus Torvalds 
309d42e1712SStefan Haberland 	/* (struct dasd_device *);
3101da177e4SLinus Torvalds 	 * Device operation functions. build_cp creates a ccw chain for
3111da177e4SLinus Torvalds 	 * a block device request, start_io starts the request and
3121da177e4SLinus Torvalds 	 * term_IO cancels it (e.g. in case of a timeout). format_device
3131da177e4SLinus Torvalds 	 * returns a ccw chain to be used to format the device.
3148e09f215SStefan Weinhuber 	 * handle_terminated_request allows to examine a cqr and prepare
3158e09f215SStefan Weinhuber 	 * it for retry.
3161da177e4SLinus Torvalds 	 */
3171da177e4SLinus Torvalds 	struct dasd_ccw_req *(*build_cp) (struct dasd_device *,
3188e09f215SStefan Weinhuber 					  struct dasd_block *,
3191da177e4SLinus Torvalds 					  struct request *);
3201da177e4SLinus Torvalds 	int (*start_IO) (struct dasd_ccw_req *);
3211da177e4SLinus Torvalds 	int (*term_IO) (struct dasd_ccw_req *);
3228e09f215SStefan Weinhuber 	void (*handle_terminated_request) (struct dasd_ccw_req *);
323d42e1712SStefan Haberland 	int (*format_device) (struct dasd_device *,
3241da177e4SLinus Torvalds 			      struct format_data_t *);
3251da177e4SLinus Torvalds 	int (*free_cp) (struct dasd_ccw_req *, struct request *);
3268e09f215SStefan Weinhuber 
3271da177e4SLinus Torvalds 	/*
3281da177e4SLinus Torvalds 	 * Error recovery functions. examine_error() returns a value that
3291da177e4SLinus Torvalds 	 * indicates what to do for an error condition. If examine_error()
3301da177e4SLinus Torvalds 	 * returns 'dasd_era_recover' erp_action() is called to create a
3311da177e4SLinus Torvalds 	 * special error recovery ccw. erp_postaction() is called after
3321da177e4SLinus Torvalds 	 * an error recovery ccw has finished its execution. dump_sense
3331da177e4SLinus Torvalds 	 * is called for every error condition to print the sense data
3341da177e4SLinus Torvalds 	 * to the console.
3351da177e4SLinus Torvalds 	 */
3361da177e4SLinus Torvalds 	dasd_erp_fn_t(*erp_action) (struct dasd_ccw_req *);
3371da177e4SLinus Torvalds 	dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
3381da177e4SLinus Torvalds 	void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
3391da177e4SLinus Torvalds 			    struct irb *);
340aeec92caSStefan Haberland 	void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);
3415a27e60dSStefan Weinhuber 	void (*check_for_device_change) (struct dasd_device *,
3425a27e60dSStefan Weinhuber 					 struct dasd_ccw_req *,
3438e09f215SStefan Weinhuber 					 struct irb *);
3448e09f215SStefan Weinhuber 
3451da177e4SLinus Torvalds         /* i/o control functions. */
3468e09f215SStefan Weinhuber 	int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
3471da177e4SLinus Torvalds 	int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
3488e09f215SStefan Weinhuber 	int (*ioctl) (struct dasd_block *, unsigned int, void __user *);
349d41dd122SStefan Haberland 
350d41dd122SStefan Haberland 	/* suspend/resume functions */
351d41dd122SStefan Haberland 	int (*freeze) (struct dasd_device *);
352d41dd122SStefan Haberland 	int (*restore) (struct dasd_device *);
353501183f2SStefan Haberland 
354501183f2SStefan Haberland 	/* reload device after state change */
355501183f2SStefan Haberland 	int (*reload) (struct dasd_device *);
3562dedf0d9SStefan Haberland 
3572dedf0d9SStefan Haberland 	int (*get_uid) (struct dasd_device *, struct dasd_uid *);
358f1633031SStefan Haberland 	void (*kick_validate) (struct dasd_device *);
3591da177e4SLinus Torvalds };
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds extern struct dasd_discipline *dasd_diag_discipline_pointer;
3621da177e4SLinus Torvalds 
3633d052595SHorst Hummel /*
36420c64468SStefan Weinhuber  * Notification numbers for extended error reporting notifications:
36520c64468SStefan Weinhuber  * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's
36620c64468SStefan Weinhuber  * eer pointer) is freed. The error reporting module needs to do all necessary
36720c64468SStefan Weinhuber  * cleanup steps.
36820c64468SStefan Weinhuber  * The DASD_EER_TRIGGER notification sends the actual error reports (triggers).
36920c64468SStefan Weinhuber  */
37020c64468SStefan Weinhuber #define DASD_EER_DISABLE 0
37120c64468SStefan Weinhuber #define DASD_EER_TRIGGER 1
37220c64468SStefan Weinhuber 
37320c64468SStefan Weinhuber /* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */
37420c64468SStefan Weinhuber #define DASD_EER_FATALERROR  1
37520c64468SStefan Weinhuber #define DASD_EER_NOPATH      2
37620c64468SStefan Weinhuber #define DASD_EER_STATECHANGE 3
37720c64468SStefan Weinhuber #define DASD_EER_PPRCSUSPEND 4
37820c64468SStefan Weinhuber 
379a4d26c6aSStefan Weinhuber struct dasd_path {
380a4d26c6aSStefan Weinhuber 	__u8 opm;
381a4d26c6aSStefan Weinhuber 	__u8 tbvpm;
382a4d26c6aSStefan Weinhuber 	__u8 ppm;
383a4d26c6aSStefan Weinhuber 	__u8 npm;
384a4d26c6aSStefan Weinhuber };
385a4d26c6aSStefan Weinhuber 
3864fa52aa7SStefan Weinhuber struct dasd_profile_info {
3874fa52aa7SStefan Weinhuber 	/* legacy part of profile data, as in dasd_profile_info_t */
3884fa52aa7SStefan Weinhuber 	unsigned int dasd_io_reqs;	 /* number of requests processed */
3894fa52aa7SStefan Weinhuber 	unsigned int dasd_io_sects;	 /* number of sectors processed */
3904fa52aa7SStefan Weinhuber 	unsigned int dasd_io_secs[32];	 /* histogram of request's sizes */
3914fa52aa7SStefan Weinhuber 	unsigned int dasd_io_times[32];	 /* histogram of requests's times */
3924fa52aa7SStefan Weinhuber 	unsigned int dasd_io_timps[32];	 /* h. of requests's times per sector */
3934fa52aa7SStefan Weinhuber 	unsigned int dasd_io_time1[32];	 /* hist. of time from build to start */
3944fa52aa7SStefan Weinhuber 	unsigned int dasd_io_time2[32];	 /* hist. of time from start to irq */
3954fa52aa7SStefan Weinhuber 	unsigned int dasd_io_time2ps[32]; /* hist. of time from start to irq */
3964fa52aa7SStefan Weinhuber 	unsigned int dasd_io_time3[32];	 /* hist. of time from irq to end */
3974fa52aa7SStefan Weinhuber 	unsigned int dasd_io_nr_req[32]; /* hist. of # of requests in chanq */
3984fa52aa7SStefan Weinhuber 
3994fa52aa7SStefan Weinhuber 	/* new data */
4004fa52aa7SStefan Weinhuber 	struct timespec starttod;	   /* time of start or last reset */
4014fa52aa7SStefan Weinhuber 	unsigned int dasd_io_alias;	   /* requests using an alias */
4024fa52aa7SStefan Weinhuber 	unsigned int dasd_io_tpm;	   /* requests using transport mode */
4034fa52aa7SStefan Weinhuber 	unsigned int dasd_read_reqs;	   /* total number of read  requests */
4044fa52aa7SStefan Weinhuber 	unsigned int dasd_read_sects;	   /* total number read sectors */
4054fa52aa7SStefan Weinhuber 	unsigned int dasd_read_alias;	   /* read request using an alias */
4064fa52aa7SStefan Weinhuber 	unsigned int dasd_read_tpm;	   /* read requests in transport mode */
4074fa52aa7SStefan Weinhuber 	unsigned int dasd_read_secs[32];   /* histogram of request's sizes */
4084fa52aa7SStefan Weinhuber 	unsigned int dasd_read_times[32];  /* histogram of requests's times */
4094fa52aa7SStefan Weinhuber 	unsigned int dasd_read_time1[32];  /* hist. time from build to start */
4104fa52aa7SStefan Weinhuber 	unsigned int dasd_read_time2[32];  /* hist. of time from start to irq */
4114fa52aa7SStefan Weinhuber 	unsigned int dasd_read_time3[32];  /* hist. of time from irq to end */
4124fa52aa7SStefan Weinhuber 	unsigned int dasd_read_nr_req[32]; /* hist. of # of requests in chanq */
4134fa52aa7SStefan Weinhuber };
4144fa52aa7SStefan Weinhuber 
4154fa52aa7SStefan Weinhuber struct dasd_profile {
4164fa52aa7SStefan Weinhuber 	struct dentry *dentry;
4174fa52aa7SStefan Weinhuber 	struct dasd_profile_info *data;
4184fa52aa7SStefan Weinhuber 	spinlock_t lock;
4194fa52aa7SStefan Weinhuber };
4204fa52aa7SStefan Weinhuber 
4211da177e4SLinus Torvalds struct dasd_device {
4221da177e4SLinus Torvalds 	/* Block device stuff. */
4238e09f215SStefan Weinhuber 	struct dasd_block *block;
4248e09f215SStefan Weinhuber 
4251da177e4SLinus Torvalds         unsigned int devindex;
4261da177e4SLinus Torvalds 	unsigned long flags;	   /* per device flags */
427c6eb7b77SHorst Hummel 	unsigned short features;   /* copy of devmap-features (read-only!) */
4281da177e4SLinus Torvalds 
42920c64468SStefan Weinhuber 	/* extended error reporting stuff (eer) */
43020c64468SStefan Weinhuber 	struct dasd_ccw_req *eer_cqr;
43120c64468SStefan Weinhuber 
4321da177e4SLinus Torvalds 	/* Device discipline stuff. */
4331da177e4SLinus Torvalds 	struct dasd_discipline *discipline;
434aa88861fSPeter Oberparleiter 	struct dasd_discipline *base_discipline;
4351da177e4SLinus Torvalds 	char *private;
436a4d26c6aSStefan Weinhuber 	struct dasd_path path_data;
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds 	/* Device state and target state. */
4391da177e4SLinus Torvalds 	int state, target;
4409eb25122SStefan Haberland 	struct mutex state_mutex;
4411da177e4SLinus Torvalds 	int stopped;		/* device (ccw_device_start) was stopped */
4421da177e4SLinus Torvalds 
4438e09f215SStefan Weinhuber 	/* reference count. */
4441da177e4SLinus Torvalds         atomic_t ref_count;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds 	/* ccw queue and memory for static ccw/erp buffers. */
4471da177e4SLinus Torvalds 	struct list_head ccw_queue;
4481da177e4SLinus Torvalds 	spinlock_t mem_lock;
4491da177e4SLinus Torvalds 	void *ccw_mem;
4501da177e4SLinus Torvalds 	void *erp_mem;
4511da177e4SLinus Torvalds 	struct list_head ccw_chunks;
4521da177e4SLinus Torvalds 	struct list_head erp_chunks;
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds 	atomic_t tasklet_scheduled;
4551da177e4SLinus Torvalds         struct tasklet_struct tasklet;
4561da177e4SLinus Torvalds 	struct work_struct kick_work;
457d41dd122SStefan Haberland 	struct work_struct restore_device;
458501183f2SStefan Haberland 	struct work_struct reload_device;
459f1633031SStefan Haberland 	struct work_struct kick_validate;
4601da177e4SLinus Torvalds 	struct timer_list timer;
4611da177e4SLinus Torvalds 
4621da177e4SLinus Torvalds 	debug_info_t *debug_area;
4631da177e4SLinus Torvalds 
4641da177e4SLinus Torvalds 	struct ccw_device *cdev;
4651da177e4SLinus Torvalds 
4668e09f215SStefan Weinhuber 	/* hook for alias management */
4678e09f215SStefan Weinhuber 	struct list_head alias_list;
4687c8faa86SStefan Haberland 
4697c8faa86SStefan Haberland 	/* default expiration time in s */
4707c8faa86SStefan Haberland 	unsigned long default_expires;
4711f1ee9adSHannes Reinecke 	unsigned long default_retries;
4724fa52aa7SStefan Weinhuber 
4733d71ad32SHannes Reinecke 	unsigned long blk_timeout;
4743d71ad32SHannes Reinecke 
4754fa52aa7SStefan Weinhuber 	struct dentry *debugfs_dentry;
4764fa52aa7SStefan Weinhuber 	struct dasd_profile profile;
4778e09f215SStefan Weinhuber };
4788e09f215SStefan Weinhuber 
4798e09f215SStefan Weinhuber struct dasd_block {
4808e09f215SStefan Weinhuber 	/* Block device stuff. */
4818e09f215SStefan Weinhuber 	struct gendisk *gdp;
4828e09f215SStefan Weinhuber 	struct request_queue *request_queue;
4838e09f215SStefan Weinhuber 	spinlock_t request_queue_lock;
4848e09f215SStefan Weinhuber 	struct block_device *bdev;
4858e09f215SStefan Weinhuber 	atomic_t open_count;
4868e09f215SStefan Weinhuber 
487b44b0ab3SStefan Weinhuber 	unsigned long long blocks; /* size of volume in blocks */
4888e09f215SStefan Weinhuber 	unsigned int bp_block;	   /* bytes per block */
4898e09f215SStefan Weinhuber 	unsigned int s2b_shift;	   /* log2 (bp_block/512) */
4908e09f215SStefan Weinhuber 
4918e09f215SStefan Weinhuber 	struct dasd_device *base;
4928e09f215SStefan Weinhuber 	struct list_head ccw_queue;
4938e09f215SStefan Weinhuber 	spinlock_t queue_lock;
4948e09f215SStefan Weinhuber 
4958e09f215SStefan Weinhuber 	atomic_t tasklet_scheduled;
4968e09f215SStefan Weinhuber 	struct tasklet_struct tasklet;
4978e09f215SStefan Weinhuber 	struct timer_list timer;
4988e09f215SStefan Weinhuber 
4994fa52aa7SStefan Weinhuber 	struct dentry *debugfs_dentry;
5004fa52aa7SStefan Weinhuber 	struct dasd_profile profile;
5011da177e4SLinus Torvalds };
5021da177e4SLinus Torvalds 
5038e09f215SStefan Weinhuber 
5048e09f215SStefan Weinhuber 
5051da177e4SLinus Torvalds /* reasons why device (ccw_device_start) was stopped */
5061da177e4SLinus Torvalds #define DASD_STOPPED_NOT_ACC 1         /* not accessible */
5071da177e4SLinus Torvalds #define DASD_STOPPED_QUIESCE 2         /* Quiesced */
5081da177e4SLinus Torvalds #define DASD_STOPPED_PENDING 4         /* long busy */
5091da177e4SLinus Torvalds #define DASD_STOPPED_DC_WAIT 8         /* disconnected, wait */
5108e09f215SStefan Weinhuber #define DASD_STOPPED_SU      16        /* summary unit check handling */
511d41dd122SStefan Haberland #define DASD_STOPPED_PM      32        /* pm state transition */
512d41dd122SStefan Haberland #define DASD_UNRESUMED_PM    64        /* pm resume failed state */
5131da177e4SLinus Torvalds 
5141da177e4SLinus Torvalds /* per device flags */
5151da177e4SLinus Torvalds #define DASD_FLAG_OFFLINE	3	/* device is in offline processing */
51620c64468SStefan Weinhuber #define DASD_FLAG_EER_SNSS	4	/* A SNSS is required */
51720c64468SStefan Weinhuber #define DASD_FLAG_EER_IN_USE	5	/* A SNSS request is running */
51833b62a30SStefan Weinhuber #define DASD_FLAG_DEVICE_RO	6	/* The device itself is read-only. Don't
51933b62a30SStefan Weinhuber 					 * confuse this with the user specified
52033b62a30SStefan Weinhuber 					 * read-only feature.
52133b62a30SStefan Weinhuber 					 */
5225a27e60dSStefan Weinhuber #define DASD_FLAG_IS_RESERVED	7	/* The device is reserved */
5235a27e60dSStefan Weinhuber #define DASD_FLAG_LOCK_STOLEN	8	/* The device lock was stolen */
524c8d1c0ffSStefan Haberland #define DASD_FLAG_SUSPENDED	9	/* The device was suspended */
525d07dc5d8SStefan Haberland #define DASD_FLAG_SAFE_OFFLINE	10	/* safe offline processing requested*/
526d07dc5d8SStefan Haberland #define DASD_FLAG_SAFE_OFFLINE_RUNNING	11	/* safe offline running */
527*5ea34a01SHannes Reinecke #define DASD_FLAG_ABORTALL	12	/* Abort all noretry requests */
5285a27e60dSStefan Weinhuber 
529*5ea34a01SHannes Reinecke #define DASD_SLEEPON_START_TAG	((void *) 1)
530*5ea34a01SHannes Reinecke #define DASD_SLEEPON_END_TAG	((void *) 2)
5311da177e4SLinus Torvalds 
5321da177e4SLinus Torvalds void dasd_put_device_wake(struct dasd_device *);
5331da177e4SLinus Torvalds 
5341da177e4SLinus Torvalds /*
5351da177e4SLinus Torvalds  * Reference count inliners
5361da177e4SLinus Torvalds  */
5371da177e4SLinus Torvalds static inline void
5381da177e4SLinus Torvalds dasd_get_device(struct dasd_device *device)
5391da177e4SLinus Torvalds {
5401da177e4SLinus Torvalds 	atomic_inc(&device->ref_count);
5411da177e4SLinus Torvalds }
5421da177e4SLinus Torvalds 
5431da177e4SLinus Torvalds static inline void
5441da177e4SLinus Torvalds dasd_put_device(struct dasd_device *device)
5451da177e4SLinus Torvalds {
5461da177e4SLinus Torvalds 	if (atomic_dec_return(&device->ref_count) == 0)
5471da177e4SLinus Torvalds 		dasd_put_device_wake(device);
5481da177e4SLinus Torvalds }
5491da177e4SLinus Torvalds 
5501da177e4SLinus Torvalds /*
5511da177e4SLinus Torvalds  * The static memory in ccw_mem and erp_mem is managed by a sorted
5521da177e4SLinus Torvalds  * list of free memory chunks.
5531da177e4SLinus Torvalds  */
5541da177e4SLinus Torvalds struct dasd_mchunk
5551da177e4SLinus Torvalds {
5561da177e4SLinus Torvalds 	struct list_head list;
5571da177e4SLinus Torvalds 	unsigned long size;
5581da177e4SLinus Torvalds } __attribute__ ((aligned(8)));
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds static inline void
5611da177e4SLinus Torvalds dasd_init_chunklist(struct list_head *chunk_list, void *mem,
5621da177e4SLinus Torvalds 		    unsigned long size)
5631da177e4SLinus Torvalds {
5641da177e4SLinus Torvalds 	struct dasd_mchunk *chunk;
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 	INIT_LIST_HEAD(chunk_list);
5671da177e4SLinus Torvalds 	chunk = (struct dasd_mchunk *) mem;
5681da177e4SLinus Torvalds 	chunk->size = size - sizeof(struct dasd_mchunk);
5691da177e4SLinus Torvalds 	list_add(&chunk->list, chunk_list);
5701da177e4SLinus Torvalds }
5711da177e4SLinus Torvalds 
5721da177e4SLinus Torvalds static inline void *
5731da177e4SLinus Torvalds dasd_alloc_chunk(struct list_head *chunk_list, unsigned long size)
5741da177e4SLinus Torvalds {
5751da177e4SLinus Torvalds 	struct dasd_mchunk *chunk, *tmp;
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds 	size = (size + 7L) & -8L;
5781da177e4SLinus Torvalds 	list_for_each_entry(chunk, chunk_list, list) {
5791da177e4SLinus Torvalds 		if (chunk->size < size)
5801da177e4SLinus Torvalds 			continue;
5811da177e4SLinus Torvalds 		if (chunk->size > size + sizeof(struct dasd_mchunk)) {
5821da177e4SLinus Torvalds 			char *endaddr = (char *) (chunk + 1) + chunk->size;
5831da177e4SLinus Torvalds 			tmp = (struct dasd_mchunk *) (endaddr - size) - 1;
5841da177e4SLinus Torvalds 			tmp->size = size;
5851da177e4SLinus Torvalds 			chunk->size -= size + sizeof(struct dasd_mchunk);
5861da177e4SLinus Torvalds 			chunk = tmp;
5871da177e4SLinus Torvalds 		} else
5881da177e4SLinus Torvalds 			list_del(&chunk->list);
5891da177e4SLinus Torvalds 		return (void *) (chunk + 1);
5901da177e4SLinus Torvalds 	}
5911da177e4SLinus Torvalds 	return NULL;
5921da177e4SLinus Torvalds }
5931da177e4SLinus Torvalds 
5941da177e4SLinus Torvalds static inline void
5951da177e4SLinus Torvalds dasd_free_chunk(struct list_head *chunk_list, void *mem)
5961da177e4SLinus Torvalds {
5971da177e4SLinus Torvalds 	struct dasd_mchunk *chunk, *tmp;
5981da177e4SLinus Torvalds 	struct list_head *p, *left;
5991da177e4SLinus Torvalds 
6001da177e4SLinus Torvalds 	chunk = (struct dasd_mchunk *)
6011da177e4SLinus Torvalds 		((char *) mem - sizeof(struct dasd_mchunk));
6021da177e4SLinus Torvalds 	/* Find out the left neighbour in chunk_list. */
6031da177e4SLinus Torvalds 	left = chunk_list;
6041da177e4SLinus Torvalds 	list_for_each(p, chunk_list) {
6051da177e4SLinus Torvalds 		if (list_entry(p, struct dasd_mchunk, list) > chunk)
6061da177e4SLinus Torvalds 			break;
6071da177e4SLinus Torvalds 		left = p;
6081da177e4SLinus Torvalds 	}
6091da177e4SLinus Torvalds 	/* Try to merge with right neighbour = next element from left. */
6101da177e4SLinus Torvalds 	if (left->next != chunk_list) {
6111da177e4SLinus Torvalds 		tmp = list_entry(left->next, struct dasd_mchunk, list);
6121da177e4SLinus Torvalds 		if ((char *) (chunk + 1) + chunk->size == (char *) tmp) {
6131da177e4SLinus Torvalds 			list_del(&tmp->list);
6141da177e4SLinus Torvalds 			chunk->size += tmp->size + sizeof(struct dasd_mchunk);
6151da177e4SLinus Torvalds 		}
6161da177e4SLinus Torvalds 	}
6171da177e4SLinus Torvalds 	/* Try to merge with left neighbour. */
6181da177e4SLinus Torvalds 	if (left != chunk_list) {
6191da177e4SLinus Torvalds 		tmp = list_entry(left, struct dasd_mchunk, list);
6201da177e4SLinus Torvalds 		if ((char *) (tmp + 1) + tmp->size == (char *) chunk) {
6211da177e4SLinus Torvalds 			tmp->size += chunk->size + sizeof(struct dasd_mchunk);
6221da177e4SLinus Torvalds 			return;
6231da177e4SLinus Torvalds 		}
6241da177e4SLinus Torvalds 	}
6251da177e4SLinus Torvalds 	__list_add(&chunk->list, left, left->next);
6261da177e4SLinus Torvalds }
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds /*
6291da177e4SLinus Torvalds  * Check if bsize is in { 512, 1024, 2048, 4096 }
6301da177e4SLinus Torvalds  */
6311da177e4SLinus Torvalds static inline int
6321da177e4SLinus Torvalds dasd_check_blocksize(int bsize)
6331da177e4SLinus Torvalds {
634e108cebbSvignesh babu 	if (bsize < 512 || bsize > 4096 || !is_power_of_2(bsize))
6351da177e4SLinus Torvalds 		return -EMEDIUMTYPE;
6361da177e4SLinus Torvalds 	return 0;
6371da177e4SLinus Torvalds }
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds /* externals in dasd.c */
6401da177e4SLinus Torvalds #define DASD_PROFILE_OFF	 0
6414fa52aa7SStefan Weinhuber #define DASD_PROFILE_ON 	 1
6424fa52aa7SStefan Weinhuber #define DASD_PROFILE_GLOBAL_ONLY 2
6431da177e4SLinus Torvalds 
6441da177e4SLinus Torvalds extern debug_info_t *dasd_debug_area;
6454fa52aa7SStefan Weinhuber extern struct dasd_profile_info dasd_global_profile_data;
6464fa52aa7SStefan Weinhuber extern unsigned int dasd_global_profile_level;
64783d5cde4SAlexey Dobriyan extern const struct block_device_operations dasd_device_operations;
6481da177e4SLinus Torvalds 
649e18b890bSChristoph Lameter extern struct kmem_cache *dasd_page_cache;
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds struct dasd_ccw_req *
65268b781feSStefan Haberland dasd_kmalloc_request(int , int, int, struct dasd_device *);
6531da177e4SLinus Torvalds struct dasd_ccw_req *
65468b781feSStefan Haberland dasd_smalloc_request(int , int, int, struct dasd_device *);
6551da177e4SLinus Torvalds void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *);
6561da177e4SLinus Torvalds void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *);
6575915a873SStefan Haberland void dasd_wakeup_cb(struct dasd_ccw_req *, void *);
6581da177e4SLinus Torvalds 
6591da177e4SLinus Torvalds static inline int
6601da177e4SLinus Torvalds dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device)
6611da177e4SLinus Torvalds {
6621da177e4SLinus Torvalds 	return set_normalized_cda(ccw, cda);
6631da177e4SLinus Torvalds }
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds struct dasd_device *dasd_alloc_device(void);
6661da177e4SLinus Torvalds void dasd_free_device(struct dasd_device *);
6671da177e4SLinus Torvalds 
6688e09f215SStefan Weinhuber struct dasd_block *dasd_alloc_block(void);
6698e09f215SStefan Weinhuber void dasd_free_block(struct dasd_block *);
6708e09f215SStefan Weinhuber 
6713d71ad32SHannes Reinecke enum blk_eh_timer_return dasd_times_out(struct request *req);
6723d71ad32SHannes Reinecke 
6731da177e4SLinus Torvalds void dasd_enable_device(struct dasd_device *);
6741da177e4SLinus Torvalds void dasd_set_target_state(struct dasd_device *, int);
6751da177e4SLinus Torvalds void dasd_kick_device(struct dasd_device *);
676d41dd122SStefan Haberland void dasd_restore_device(struct dasd_device *);
677501183f2SStefan Haberland void dasd_reload_device(struct dasd_device *);
6781da177e4SLinus Torvalds 
6791da177e4SLinus Torvalds void dasd_add_request_head(struct dasd_ccw_req *);
6801da177e4SLinus Torvalds void dasd_add_request_tail(struct dasd_ccw_req *);
6811da177e4SLinus Torvalds int  dasd_start_IO(struct dasd_ccw_req *);
6821da177e4SLinus Torvalds int  dasd_term_IO(struct dasd_ccw_req *);
6838e09f215SStefan Weinhuber void dasd_schedule_device_bh(struct dasd_device *);
6848e09f215SStefan Weinhuber void dasd_schedule_block_bh(struct dasd_block *);
6851da177e4SLinus Torvalds int  dasd_sleep_on(struct dasd_ccw_req *);
686d42e1712SStefan Haberland int  dasd_sleep_on_queue(struct list_head *);
6871da177e4SLinus Torvalds int  dasd_sleep_on_immediatly(struct dasd_ccw_req *);
6881da177e4SLinus Torvalds int  dasd_sleep_on_interruptible(struct dasd_ccw_req *);
6898e09f215SStefan Weinhuber void dasd_device_set_timer(struct dasd_device *, int);
6908e09f215SStefan Weinhuber void dasd_device_clear_timer(struct dasd_device *);
6918e09f215SStefan Weinhuber void dasd_block_set_timer(struct dasd_block *, int);
6928e09f215SStefan Weinhuber void dasd_block_clear_timer(struct dasd_block *);
6931da177e4SLinus Torvalds int  dasd_cancel_req(struct dasd_ccw_req *);
6948e09f215SStefan Weinhuber int dasd_flush_device_queue(struct dasd_device *);
6951da177e4SLinus Torvalds int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *);
6961da177e4SLinus Torvalds void dasd_generic_remove (struct ccw_device *cdev);
6971da177e4SLinus Torvalds int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
6981da177e4SLinus Torvalds int dasd_generic_set_offline (struct ccw_device *cdev);
6991da177e4SLinus Torvalds int dasd_generic_notify(struct ccw_device *, int);
700a4d26c6aSStefan Weinhuber int dasd_generic_last_path_gone(struct dasd_device *);
701a4d26c6aSStefan Weinhuber int dasd_generic_path_operational(struct dasd_device *);
7024679e893SStefan Haberland void dasd_generic_shutdown(struct ccw_device *);
703a4d26c6aSStefan Weinhuber 
7048e09f215SStefan Weinhuber void dasd_generic_handle_state_change(struct dasd_device *);
705d41dd122SStefan Haberland int dasd_generic_pm_freeze(struct ccw_device *);
706d41dd122SStefan Haberland int dasd_generic_restore_device(struct ccw_device *);
707a23ed009SStefan Haberland enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *);
708a4d26c6aSStefan Weinhuber void dasd_generic_path_event(struct ccw_device *, int *);
709a4d26c6aSStefan Weinhuber int dasd_generic_verify_path(struct dasd_device *, __u8);
7101da177e4SLinus Torvalds 
71168b781feSStefan Haberland int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
712f3eb5384SStefan Weinhuber char *dasd_get_sense(struct irb *);
71317283b56SCornelia Huck 
714eb6e199bSStefan Weinhuber void dasd_device_set_stop_bits(struct dasd_device *, int);
715eb6e199bSStefan Weinhuber void dasd_device_remove_stop_bits(struct dasd_device *, int);
716eb6e199bSStefan Weinhuber 
71733b62a30SStefan Weinhuber int dasd_device_is_ro(struct dasd_device *);
71833b62a30SStefan Weinhuber 
7194fa52aa7SStefan Weinhuber void dasd_profile_reset(struct dasd_profile *);
7204fa52aa7SStefan Weinhuber int dasd_profile_on(struct dasd_profile *);
7214fa52aa7SStefan Weinhuber void dasd_profile_off(struct dasd_profile *);
7224fa52aa7SStefan Weinhuber void dasd_global_profile_reset(void);
7234fa52aa7SStefan Weinhuber char *dasd_get_user_string(const char __user *, size_t);
72433b62a30SStefan Weinhuber 
7251da177e4SLinus Torvalds /* externals in dasd_devmap.c */
7261da177e4SLinus Torvalds extern int dasd_max_devindex;
7271da177e4SLinus Torvalds extern int dasd_probeonly;
7281da177e4SLinus Torvalds extern int dasd_autodetect;
72940545573SHorst Hummel extern int dasd_nopav;
730f3eb5384SStefan Weinhuber extern int dasd_nofcx;
7311da177e4SLinus Torvalds 
7321da177e4SLinus Torvalds int dasd_devmap_init(void);
7331da177e4SLinus Torvalds void dasd_devmap_exit(void);
7341da177e4SLinus Torvalds 
7351da177e4SLinus Torvalds struct dasd_device *dasd_create_device(struct ccw_device *);
7361da177e4SLinus Torvalds void dasd_delete_device(struct dasd_device *);
7371da177e4SLinus Torvalds 
738f24acd45SHorst Hummel int dasd_get_feature(struct ccw_device *, int);
739f24acd45SHorst Hummel int dasd_set_feature(struct ccw_device *, int, int);
740f24acd45SHorst Hummel 
7411da177e4SLinus Torvalds int dasd_add_sysfs_files(struct ccw_device *);
7421da177e4SLinus Torvalds void dasd_remove_sysfs_files(struct ccw_device *);
7431da177e4SLinus Torvalds 
7441da177e4SLinus Torvalds struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
745a00bfd71SMartin Schwidefsky struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
7461da177e4SLinus Torvalds struct dasd_device *dasd_device_from_devindex(int);
7471da177e4SLinus Torvalds 
74865f8da47SStefan Weinhuber void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *);
74965f8da47SStefan Weinhuber struct dasd_device *dasd_device_from_gendisk(struct gendisk *);
75065f8da47SStefan Weinhuber 
7511da177e4SLinus Torvalds int dasd_parse(void);
75269f90f6aSCornelia Huck int dasd_busid_known(const char *);
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds /* externals in dasd_gendisk.c */
7551da177e4SLinus Torvalds int  dasd_gendisk_init(void);
7561da177e4SLinus Torvalds void dasd_gendisk_exit(void);
7578e09f215SStefan Weinhuber int dasd_gendisk_alloc(struct dasd_block *);
7588e09f215SStefan Weinhuber void dasd_gendisk_free(struct dasd_block *);
7598e09f215SStefan Weinhuber int dasd_scan_partitions(struct dasd_block *);
7608e09f215SStefan Weinhuber void dasd_destroy_partitions(struct dasd_block *);
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds /* externals in dasd_ioctl.c */
76357a7c0bcSAl Viro int  dasd_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long);
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds /* externals in dasd_proc.c */
7661da177e4SLinus Torvalds int dasd_proc_init(void);
7671da177e4SLinus Torvalds void dasd_proc_exit(void);
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds /* externals in dasd_erp.c */
7701da177e4SLinus Torvalds struct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *);
7711da177e4SLinus Torvalds struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *);
7721da177e4SLinus Torvalds struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
7731da177e4SLinus Torvalds 					    struct dasd_device *);
7741da177e4SLinus Torvalds void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
7751da177e4SLinus Torvalds void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
776fc19f381SStefan Haberland void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds /* externals in dasd_3990_erp.c */
7791da177e4SLinus Torvalds struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
780f60c768cSStefan Haberland void dasd_3990_erp_handle_sim(struct dasd_device *, char *);
7811da177e4SLinus Torvalds 
78220c64468SStefan Weinhuber /* externals in dasd_eer.c */
78320c64468SStefan Weinhuber #ifdef CONFIG_DASD_EER
78420c64468SStefan Weinhuber int dasd_eer_init(void);
78520c64468SStefan Weinhuber void dasd_eer_exit(void);
78620c64468SStefan Weinhuber int dasd_eer_enable(struct dasd_device *);
78720c64468SStefan Weinhuber void dasd_eer_disable(struct dasd_device *);
78820c64468SStefan Weinhuber void dasd_eer_write(struct dasd_device *, struct dasd_ccw_req *cqr,
78920c64468SStefan Weinhuber 		    unsigned int id);
79020c64468SStefan Weinhuber void dasd_eer_snss(struct dasd_device *);
79120c64468SStefan Weinhuber 
79220c64468SStefan Weinhuber static inline int dasd_eer_enabled(struct dasd_device *device)
79320c64468SStefan Weinhuber {
79420c64468SStefan Weinhuber 	return device->eer_cqr != NULL;
79520c64468SStefan Weinhuber }
79620c64468SStefan Weinhuber #else
79720c64468SStefan Weinhuber #define dasd_eer_init()		(0)
79820c64468SStefan Weinhuber #define dasd_eer_exit()		do { } while (0)
79920c64468SStefan Weinhuber #define dasd_eer_enable(d)	(0)
80020c64468SStefan Weinhuber #define dasd_eer_disable(d)	do { } while (0)
80120c64468SStefan Weinhuber #define dasd_eer_write(d,c,i)	do { } while (0)
80220c64468SStefan Weinhuber #define dasd_eer_snss(d)	do { } while (0)
80320c64468SStefan Weinhuber #define dasd_eer_enabled(d)	(0)
80420c64468SStefan Weinhuber #endif	/* CONFIG_DASD_ERR */
80520c64468SStefan Weinhuber 
8061da177e4SLinus Torvalds #endif				/* DASD_H */
807