18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 48c2ecf20Sopenharmony_ci * Horst Hummel <Horst.Hummel@de.ibm.com> 58c2ecf20Sopenharmony_ci * Martin Schwidefsky <schwidefsky@de.ibm.com> 68c2ecf20Sopenharmony_ci * Bugreports.to..: <Linux390@de.ibm.com> 78c2ecf20Sopenharmony_ci * Copyright IBM Corp. 1999, 2009 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef DASD_INT_H 118c2ecf20Sopenharmony_ci#define DASD_INT_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* we keep old device allocation scheme; IOW, minors are still in 0..255 */ 148c2ecf20Sopenharmony_ci#define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS)) 158c2ecf20Sopenharmony_ci#define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1) 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * States a dasd device can have: 198c2ecf20Sopenharmony_ci * new: the dasd_device structure is allocated. 208c2ecf20Sopenharmony_ci * known: the discipline for the device is identified. 218c2ecf20Sopenharmony_ci * basic: the device can do basic i/o. 228c2ecf20Sopenharmony_ci * unfmt: the device could not be analyzed (format is unknown). 238c2ecf20Sopenharmony_ci * ready: partition detection is done and the device is can do block io. 248c2ecf20Sopenharmony_ci * online: the device accepts requests from the block device queue. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Things to do for startup state transitions: 278c2ecf20Sopenharmony_ci * new -> known: find discipline for the device and create devfs entries. 288c2ecf20Sopenharmony_ci * known -> basic: request irq line for the device. 298c2ecf20Sopenharmony_ci * basic -> ready: do the initial analysis, e.g. format detection, 308c2ecf20Sopenharmony_ci * do block device setup and detect partitions. 318c2ecf20Sopenharmony_ci * ready -> online: schedule the device tasklet. 328c2ecf20Sopenharmony_ci * Things to do for shutdown state transitions: 338c2ecf20Sopenharmony_ci * online -> ready: just set the new device state. 348c2ecf20Sopenharmony_ci * ready -> basic: flush requests from the block device layer, clear 358c2ecf20Sopenharmony_ci * partition information and reset format information. 368c2ecf20Sopenharmony_ci * basic -> known: terminate all requests and free irq. 378c2ecf20Sopenharmony_ci * known -> new: remove devfs entries and forget discipline. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define DASD_STATE_NEW 0 418c2ecf20Sopenharmony_ci#define DASD_STATE_KNOWN 1 428c2ecf20Sopenharmony_ci#define DASD_STATE_BASIC 2 438c2ecf20Sopenharmony_ci#define DASD_STATE_UNFMT 3 448c2ecf20Sopenharmony_ci#define DASD_STATE_READY 4 458c2ecf20Sopenharmony_ci#define DASD_STATE_ONLINE 5 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#include <linux/module.h> 488c2ecf20Sopenharmony_ci#include <linux/wait.h> 498c2ecf20Sopenharmony_ci#include <linux/blkdev.h> 508c2ecf20Sopenharmony_ci#include <linux/genhd.h> 518c2ecf20Sopenharmony_ci#include <linux/hdreg.h> 528c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 538c2ecf20Sopenharmony_ci#include <linux/log2.h> 548c2ecf20Sopenharmony_ci#include <asm/ccwdev.h> 558c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 568c2ecf20Sopenharmony_ci#include <asm/debug.h> 578c2ecf20Sopenharmony_ci#include <asm/dasd.h> 588c2ecf20Sopenharmony_ci#include <asm/idals.h> 598c2ecf20Sopenharmony_ci#include <linux/bitops.h> 608c2ecf20Sopenharmony_ci#include <linux/blk-mq.h> 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* DASD discipline magic */ 638c2ecf20Sopenharmony_ci#define DASD_ECKD_MAGIC 0xC5C3D2C4 648c2ecf20Sopenharmony_ci#define DASD_DIAG_MAGIC 0xC4C9C1C7 658c2ecf20Sopenharmony_ci#define DASD_FBA_MAGIC 0xC6C2C140 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * SECTION: Type definitions 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistruct dasd_device; 718c2ecf20Sopenharmony_cistruct dasd_block; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* BIT DEFINITIONS FOR SENSE DATA */ 748c2ecf20Sopenharmony_ci#define DASD_SENSE_BIT_0 0x80 758c2ecf20Sopenharmony_ci#define DASD_SENSE_BIT_1 0x40 768c2ecf20Sopenharmony_ci#define DASD_SENSE_BIT_2 0x20 778c2ecf20Sopenharmony_ci#define DASD_SENSE_BIT_3 0x10 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* BIT DEFINITIONS FOR SIM SENSE */ 808c2ecf20Sopenharmony_ci#define DASD_SIM_SENSE 0x0F 818c2ecf20Sopenharmony_ci#define DASD_SIM_MSG_TO_OP 0x03 828c2ecf20Sopenharmony_ci#define DASD_SIM_LOG 0x0C 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* lock class for nested cdev lock */ 858c2ecf20Sopenharmony_ci#define CDEV_NESTED_FIRST 1 868c2ecf20Sopenharmony_ci#define CDEV_NESTED_SECOND 2 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* 898c2ecf20Sopenharmony_ci * SECTION: MACROs for klogd and s390 debug feature (dbf) 908c2ecf20Sopenharmony_ci */ 918c2ecf20Sopenharmony_ci#define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \ 928c2ecf20Sopenharmony_cido { \ 938c2ecf20Sopenharmony_ci debug_sprintf_event(d_device->debug_area, \ 948c2ecf20Sopenharmony_ci d_level, \ 958c2ecf20Sopenharmony_ci d_str "\n", \ 968c2ecf20Sopenharmony_ci d_data); \ 978c2ecf20Sopenharmony_ci} while(0) 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci#define DBF_EVENT(d_level, d_str, d_data...)\ 1008c2ecf20Sopenharmony_cido { \ 1018c2ecf20Sopenharmony_ci debug_sprintf_event(dasd_debug_area, \ 1028c2ecf20Sopenharmony_ci d_level,\ 1038c2ecf20Sopenharmony_ci d_str "\n", \ 1048c2ecf20Sopenharmony_ci d_data); \ 1058c2ecf20Sopenharmony_ci} while(0) 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci#define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...) \ 1088c2ecf20Sopenharmony_cido { \ 1098c2ecf20Sopenharmony_ci struct ccw_dev_id __dev_id; \ 1108c2ecf20Sopenharmony_ci ccw_device_get_id(d_cdev, &__dev_id); \ 1118c2ecf20Sopenharmony_ci debug_sprintf_event(dasd_debug_area, \ 1128c2ecf20Sopenharmony_ci d_level, \ 1138c2ecf20Sopenharmony_ci "0.%x.%04x " d_str "\n", \ 1148c2ecf20Sopenharmony_ci __dev_id.ssid, __dev_id.devno, d_data); \ 1158c2ecf20Sopenharmony_ci} while (0) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/* limit size for an errorstring */ 1188c2ecf20Sopenharmony_ci#define ERRORLENGTH 30 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* definition of dbf debug levels */ 1218c2ecf20Sopenharmony_ci#define DBF_EMERG 0 /* system is unusable */ 1228c2ecf20Sopenharmony_ci#define DBF_ALERT 1 /* action must be taken immediately */ 1238c2ecf20Sopenharmony_ci#define DBF_CRIT 2 /* critical conditions */ 1248c2ecf20Sopenharmony_ci#define DBF_ERR 3 /* error conditions */ 1258c2ecf20Sopenharmony_ci#define DBF_WARNING 4 /* warning conditions */ 1268c2ecf20Sopenharmony_ci#define DBF_NOTICE 5 /* normal but significant condition */ 1278c2ecf20Sopenharmony_ci#define DBF_INFO 6 /* informational */ 1288c2ecf20Sopenharmony_ci#define DBF_DEBUG 6 /* debug-level messages */ 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* messages to be written via klogd and dbf */ 1318c2ecf20Sopenharmony_ci#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\ 1328c2ecf20Sopenharmony_cido { \ 1338c2ecf20Sopenharmony_ci printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \ 1348c2ecf20Sopenharmony_ci dev_name(&d_device->cdev->dev), d_args); \ 1358c2ecf20Sopenharmony_ci DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \ 1368c2ecf20Sopenharmony_ci} while(0) 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#define MESSAGE(d_loglevel,d_string,d_args...)\ 1398c2ecf20Sopenharmony_cido { \ 1408c2ecf20Sopenharmony_ci printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \ 1418c2ecf20Sopenharmony_ci DBF_EVENT(DBF_ALERT, d_string, d_args); \ 1428c2ecf20Sopenharmony_ci} while(0) 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/* messages to be written via klogd only */ 1458c2ecf20Sopenharmony_ci#define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\ 1468c2ecf20Sopenharmony_cido { \ 1478c2ecf20Sopenharmony_ci printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \ 1488c2ecf20Sopenharmony_ci dev_name(&d_device->cdev->dev), d_args); \ 1498c2ecf20Sopenharmony_ci} while(0) 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\ 1528c2ecf20Sopenharmony_cido { \ 1538c2ecf20Sopenharmony_ci printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \ 1548c2ecf20Sopenharmony_ci} while(0) 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* Macro to calculate number of blocks per page */ 1578c2ecf20Sopenharmony_ci#define BLOCKS_PER_PAGE(blksize) (PAGE_SIZE / blksize) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistruct dasd_ccw_req { 1608c2ecf20Sopenharmony_ci unsigned int magic; /* Eye catcher */ 1618c2ecf20Sopenharmony_ci int intrc; /* internal error, e.g. from start_IO */ 1628c2ecf20Sopenharmony_ci struct list_head devlist; /* for dasd_device request queue */ 1638c2ecf20Sopenharmony_ci struct list_head blocklist; /* for dasd_block request queue */ 1648c2ecf20Sopenharmony_ci struct dasd_block *block; /* the originating block device */ 1658c2ecf20Sopenharmony_ci struct dasd_device *memdev; /* the device used to allocate this */ 1668c2ecf20Sopenharmony_ci struct dasd_device *startdev; /* device the request is started on */ 1678c2ecf20Sopenharmony_ci struct dasd_device *basedev; /* base device if no block->base */ 1688c2ecf20Sopenharmony_ci void *cpaddr; /* address of ccw or tcw */ 1698c2ecf20Sopenharmony_ci short retries; /* A retry counter */ 1708c2ecf20Sopenharmony_ci unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */ 1718c2ecf20Sopenharmony_ci char status; /* status of this request */ 1728c2ecf20Sopenharmony_ci char lpm; /* logical path mask */ 1738c2ecf20Sopenharmony_ci unsigned long flags; /* flags of this request */ 1748c2ecf20Sopenharmony_ci struct dasd_queue *dq; 1758c2ecf20Sopenharmony_ci unsigned long starttime; /* jiffies time of request start */ 1768c2ecf20Sopenharmony_ci unsigned long expires; /* expiration period in jiffies */ 1778c2ecf20Sopenharmony_ci void *data; /* pointer to data area */ 1788c2ecf20Sopenharmony_ci struct irb irb; /* device status in case of an error */ 1798c2ecf20Sopenharmony_ci struct dasd_ccw_req *refers; /* ERP-chain queueing. */ 1808c2ecf20Sopenharmony_ci void *function; /* originating ERP action */ 1818c2ecf20Sopenharmony_ci void *mem_chunk; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci unsigned long buildclk; /* TOD-clock of request generation */ 1848c2ecf20Sopenharmony_ci unsigned long startclk; /* TOD-clock of request start */ 1858c2ecf20Sopenharmony_ci unsigned long stopclk; /* TOD-clock of request interrupt */ 1868c2ecf20Sopenharmony_ci unsigned long endclk; /* TOD-clock of request termination */ 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci void (*callback)(struct dasd_ccw_req *, void *data); 1898c2ecf20Sopenharmony_ci void *callback_data; 1908c2ecf20Sopenharmony_ci unsigned int proc_bytes; /* bytes for partial completion */ 1918c2ecf20Sopenharmony_ci unsigned int trkcount; /* count formatted tracks */ 1928c2ecf20Sopenharmony_ci}; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci/* 1958c2ecf20Sopenharmony_ci * dasd_ccw_req -> status can be: 1968c2ecf20Sopenharmony_ci */ 1978c2ecf20Sopenharmony_ci#define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ 1988c2ecf20Sopenharmony_ci#define DASD_CQR_DONE 0x01 /* request is completed successfully */ 1998c2ecf20Sopenharmony_ci#define DASD_CQR_NEED_ERP 0x02 /* request needs recovery action */ 2008c2ecf20Sopenharmony_ci#define DASD_CQR_IN_ERP 0x03 /* request is in recovery */ 2018c2ecf20Sopenharmony_ci#define DASD_CQR_FAILED 0x04 /* request is finally failed */ 2028c2ecf20Sopenharmony_ci#define DASD_CQR_TERMINATED 0x05 /* request was stopped by driver */ 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#define DASD_CQR_QUEUED 0x80 /* request is queued to be processed */ 2058c2ecf20Sopenharmony_ci#define DASD_CQR_IN_IO 0x81 /* request is currently in IO */ 2068c2ecf20Sopenharmony_ci#define DASD_CQR_ERROR 0x82 /* request is completed with error */ 2078c2ecf20Sopenharmony_ci#define DASD_CQR_CLEAR_PENDING 0x83 /* request is clear pending */ 2088c2ecf20Sopenharmony_ci#define DASD_CQR_CLEARED 0x84 /* request was cleared */ 2098c2ecf20Sopenharmony_ci#define DASD_CQR_SUCCESS 0x85 /* request was successful */ 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci/* default expiration time*/ 2128c2ecf20Sopenharmony_ci#define DASD_EXPIRES 300 2138c2ecf20Sopenharmony_ci#define DASD_EXPIRES_MAX 40000000 2148c2ecf20Sopenharmony_ci#define DASD_RETRIES 256 2158c2ecf20Sopenharmony_ci#define DASD_RETRIES_MAX 32768 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* per dasd_ccw_req flags */ 2188c2ecf20Sopenharmony_ci#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ 2198c2ecf20Sopenharmony_ci#define DASD_CQR_FLAGS_FAILFAST 1 /* FAILFAST */ 2208c2ecf20Sopenharmony_ci#define DASD_CQR_VERIFY_PATH 2 /* path verification request */ 2218c2ecf20Sopenharmony_ci#define DASD_CQR_ALLOW_SLOCK 3 /* Try this request even when lock was 2228c2ecf20Sopenharmony_ci * stolen. Should not be combined with 2238c2ecf20Sopenharmony_ci * DASD_CQR_FLAGS_USE_ERP 2248c2ecf20Sopenharmony_ci */ 2258c2ecf20Sopenharmony_ci/* 2268c2ecf20Sopenharmony_ci * The following flags are used to suppress output of certain errors. 2278c2ecf20Sopenharmony_ci */ 2288c2ecf20Sopenharmony_ci#define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */ 2298c2ecf20Sopenharmony_ci#define DASD_CQR_SUPPRESS_FP 5 /* Suppress 'File Protected' error*/ 2308c2ecf20Sopenharmony_ci#define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */ 2318c2ecf20Sopenharmony_ci#define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */ 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci#define DASD_REQ_PER_DEV 4 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/* Signature for error recovery functions. */ 2368c2ecf20Sopenharmony_citypedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci/* 2398c2ecf20Sopenharmony_ci * A single CQR can only contain a maximum of 255 CCWs. It is limited by 2408c2ecf20Sopenharmony_ci * the locate record and locate record extended count value which can only hold 2418c2ecf20Sopenharmony_ci * 1 Byte max. 2428c2ecf20Sopenharmony_ci */ 2438c2ecf20Sopenharmony_ci#define DASD_CQR_MAX_CCW 255 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci/* 2468c2ecf20Sopenharmony_ci * Unique identifier for dasd device. 2478c2ecf20Sopenharmony_ci */ 2488c2ecf20Sopenharmony_ci#define UA_NOT_CONFIGURED 0x00 2498c2ecf20Sopenharmony_ci#define UA_BASE_DEVICE 0x01 2508c2ecf20Sopenharmony_ci#define UA_BASE_PAV_ALIAS 0x02 2518c2ecf20Sopenharmony_ci#define UA_HYPER_PAV_ALIAS 0x03 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistruct dasd_uid { 2548c2ecf20Sopenharmony_ci __u8 type; 2558c2ecf20Sopenharmony_ci char vendor[4]; 2568c2ecf20Sopenharmony_ci char serial[15]; 2578c2ecf20Sopenharmony_ci __u16 ssid; 2588c2ecf20Sopenharmony_ci __u8 real_unit_addr; 2598c2ecf20Sopenharmony_ci __u8 base_unit_addr; 2608c2ecf20Sopenharmony_ci char vduit[33]; 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci/* 2648c2ecf20Sopenharmony_ci * the struct dasd_discipline is 2658c2ecf20Sopenharmony_ci * sth like a table of virtual functions, if you think of dasd_eckd 2668c2ecf20Sopenharmony_ci * inheriting dasd... 2678c2ecf20Sopenharmony_ci * no, currently we are not planning to reimplement the driver in C++ 2688c2ecf20Sopenharmony_ci */ 2698c2ecf20Sopenharmony_cistruct dasd_discipline { 2708c2ecf20Sopenharmony_ci struct module *owner; 2718c2ecf20Sopenharmony_ci char ebcname[8]; /* a name used for tagging and printks */ 2728c2ecf20Sopenharmony_ci char name[8]; /* a name used for tagging and printks */ 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci struct list_head list; /* used for list of disciplines */ 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* 2778c2ecf20Sopenharmony_ci * Device recognition functions. check_device is used to verify 2788c2ecf20Sopenharmony_ci * the sense data and the information returned by read device 2798c2ecf20Sopenharmony_ci * characteristics. It returns 0 if the discipline can be used 2808c2ecf20Sopenharmony_ci * for the device in question. uncheck_device is called during 2818c2ecf20Sopenharmony_ci * device shutdown to deregister a device from its discipline. 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_ci int (*check_device) (struct dasd_device *); 2848c2ecf20Sopenharmony_ci void (*uncheck_device) (struct dasd_device *); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* 2878c2ecf20Sopenharmony_ci * do_analysis is used in the step from device state "basic" to 2888c2ecf20Sopenharmony_ci * state "accept". It returns 0 if the device can be made ready, 2898c2ecf20Sopenharmony_ci * it returns -EMEDIUMTYPE if the device can't be made ready or 2908c2ecf20Sopenharmony_ci * -EAGAIN if do_analysis started a ccw that needs to complete 2918c2ecf20Sopenharmony_ci * before the analysis may be repeated. 2928c2ecf20Sopenharmony_ci */ 2938c2ecf20Sopenharmony_ci int (*do_analysis) (struct dasd_block *); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci /* 2968c2ecf20Sopenharmony_ci * This function is called, when new paths become available. 2978c2ecf20Sopenharmony_ci * Disciplins may use this callback to do necessary setup work, 2988c2ecf20Sopenharmony_ci * e.g. verify that new path is compatible with the current 2998c2ecf20Sopenharmony_ci * configuration. 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_ci int (*pe_handler)(struct dasd_device *, __u8); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* 3048c2ecf20Sopenharmony_ci * Last things to do when a device is set online, and first things 3058c2ecf20Sopenharmony_ci * when it is set offline. 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_ci int (*basic_to_ready) (struct dasd_device *); 3088c2ecf20Sopenharmony_ci int (*online_to_ready) (struct dasd_device *); 3098c2ecf20Sopenharmony_ci int (*basic_to_known)(struct dasd_device *); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci /* 3128c2ecf20Sopenharmony_ci * Initialize block layer request queue. 3138c2ecf20Sopenharmony_ci */ 3148c2ecf20Sopenharmony_ci void (*setup_blk_queue)(struct dasd_block *); 3158c2ecf20Sopenharmony_ci /* (struct dasd_device *); 3168c2ecf20Sopenharmony_ci * Device operation functions. build_cp creates a ccw chain for 3178c2ecf20Sopenharmony_ci * a block device request, start_io starts the request and 3188c2ecf20Sopenharmony_ci * term_IO cancels it (e.g. in case of a timeout). format_device 3198c2ecf20Sopenharmony_ci * formats the device and check_device_format compares the format of 3208c2ecf20Sopenharmony_ci * a device with the expected format_data. 3218c2ecf20Sopenharmony_ci * handle_terminated_request allows to examine a cqr and prepare 3228c2ecf20Sopenharmony_ci * it for retry. 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci struct dasd_ccw_req *(*build_cp) (struct dasd_device *, 3258c2ecf20Sopenharmony_ci struct dasd_block *, 3268c2ecf20Sopenharmony_ci struct request *); 3278c2ecf20Sopenharmony_ci int (*start_IO) (struct dasd_ccw_req *); 3288c2ecf20Sopenharmony_ci int (*term_IO) (struct dasd_ccw_req *); 3298c2ecf20Sopenharmony_ci void (*handle_terminated_request) (struct dasd_ccw_req *); 3308c2ecf20Sopenharmony_ci int (*format_device) (struct dasd_device *, 3318c2ecf20Sopenharmony_ci struct format_data_t *, int); 3328c2ecf20Sopenharmony_ci int (*check_device_format)(struct dasd_device *, 3338c2ecf20Sopenharmony_ci struct format_check_t *, int); 3348c2ecf20Sopenharmony_ci int (*free_cp) (struct dasd_ccw_req *, struct request *); 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci /* 3378c2ecf20Sopenharmony_ci * Error recovery functions. examine_error() returns a value that 3388c2ecf20Sopenharmony_ci * indicates what to do for an error condition. If examine_error() 3398c2ecf20Sopenharmony_ci * returns 'dasd_era_recover' erp_action() is called to create a 3408c2ecf20Sopenharmony_ci * special error recovery ccw. erp_postaction() is called after 3418c2ecf20Sopenharmony_ci * an error recovery ccw has finished its execution. dump_sense 3428c2ecf20Sopenharmony_ci * is called for every error condition to print the sense data 3438c2ecf20Sopenharmony_ci * to the console. 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_ci dasd_erp_fn_t(*erp_action) (struct dasd_ccw_req *); 3468c2ecf20Sopenharmony_ci dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); 3478c2ecf20Sopenharmony_ci void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, 3488c2ecf20Sopenharmony_ci struct irb *); 3498c2ecf20Sopenharmony_ci void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *); 3508c2ecf20Sopenharmony_ci void (*check_for_device_change) (struct dasd_device *, 3518c2ecf20Sopenharmony_ci struct dasd_ccw_req *, 3528c2ecf20Sopenharmony_ci struct irb *); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci /* i/o control functions. */ 3558c2ecf20Sopenharmony_ci int (*fill_geometry) (struct dasd_block *, struct hd_geometry *); 3568c2ecf20Sopenharmony_ci int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); 3578c2ecf20Sopenharmony_ci int (*ioctl) (struct dasd_block *, unsigned int, void __user *); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci /* suspend/resume functions */ 3608c2ecf20Sopenharmony_ci int (*freeze) (struct dasd_device *); 3618c2ecf20Sopenharmony_ci int (*restore) (struct dasd_device *); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci /* reload device after state change */ 3648c2ecf20Sopenharmony_ci int (*reload) (struct dasd_device *); 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci int (*get_uid) (struct dasd_device *, struct dasd_uid *); 3678c2ecf20Sopenharmony_ci void (*kick_validate) (struct dasd_device *); 3688c2ecf20Sopenharmony_ci int (*check_attention)(struct dasd_device *, __u8); 3698c2ecf20Sopenharmony_ci int (*host_access_count)(struct dasd_device *); 3708c2ecf20Sopenharmony_ci int (*hosts_print)(struct dasd_device *, struct seq_file *); 3718c2ecf20Sopenharmony_ci void (*handle_hpf_error)(struct dasd_device *, struct irb *); 3728c2ecf20Sopenharmony_ci void (*disable_hpf)(struct dasd_device *); 3738c2ecf20Sopenharmony_ci int (*hpf_enabled)(struct dasd_device *); 3748c2ecf20Sopenharmony_ci void (*reset_path)(struct dasd_device *, __u8); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci /* 3778c2ecf20Sopenharmony_ci * Extent Space Efficient (ESE) relevant functions 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_ci int (*is_ese)(struct dasd_device *); 3808c2ecf20Sopenharmony_ci /* Capacity */ 3818c2ecf20Sopenharmony_ci int (*space_allocated)(struct dasd_device *); 3828c2ecf20Sopenharmony_ci int (*space_configured)(struct dasd_device *); 3838c2ecf20Sopenharmony_ci int (*logical_capacity)(struct dasd_device *); 3848c2ecf20Sopenharmony_ci int (*release_space)(struct dasd_device *, struct format_data_t *); 3858c2ecf20Sopenharmony_ci /* Extent Pool */ 3868c2ecf20Sopenharmony_ci int (*ext_pool_id)(struct dasd_device *); 3878c2ecf20Sopenharmony_ci int (*ext_size)(struct dasd_device *); 3888c2ecf20Sopenharmony_ci int (*ext_pool_cap_at_warnlevel)(struct dasd_device *); 3898c2ecf20Sopenharmony_ci int (*ext_pool_warn_thrshld)(struct dasd_device *); 3908c2ecf20Sopenharmony_ci int (*ext_pool_oos)(struct dasd_device *); 3918c2ecf20Sopenharmony_ci int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); 3928c2ecf20Sopenharmony_ci struct dasd_ccw_req *(*ese_format)(struct dasd_device *, 3938c2ecf20Sopenharmony_ci struct dasd_ccw_req *, struct irb *); 3948c2ecf20Sopenharmony_ci int (*ese_read)(struct dasd_ccw_req *, struct irb *); 3958c2ecf20Sopenharmony_ci}; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ciextern struct dasd_discipline *dasd_diag_discipline_pointer; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci/* 4008c2ecf20Sopenharmony_ci * Notification numbers for extended error reporting notifications: 4018c2ecf20Sopenharmony_ci * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's 4028c2ecf20Sopenharmony_ci * eer pointer) is freed. The error reporting module needs to do all necessary 4038c2ecf20Sopenharmony_ci * cleanup steps. 4048c2ecf20Sopenharmony_ci * The DASD_EER_TRIGGER notification sends the actual error reports (triggers). 4058c2ecf20Sopenharmony_ci */ 4068c2ecf20Sopenharmony_ci#define DASD_EER_DISABLE 0 4078c2ecf20Sopenharmony_ci#define DASD_EER_TRIGGER 1 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci/* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */ 4108c2ecf20Sopenharmony_ci#define DASD_EER_FATALERROR 1 4118c2ecf20Sopenharmony_ci#define DASD_EER_NOPATH 2 4128c2ecf20Sopenharmony_ci#define DASD_EER_STATECHANGE 3 4138c2ecf20Sopenharmony_ci#define DASD_EER_PPRCSUSPEND 4 4148c2ecf20Sopenharmony_ci#define DASD_EER_NOSPC 5 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci/* DASD path handling */ 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci#define DASD_PATH_OPERATIONAL 1 4198c2ecf20Sopenharmony_ci#define DASD_PATH_TBV 2 4208c2ecf20Sopenharmony_ci#define DASD_PATH_PP 3 4218c2ecf20Sopenharmony_ci#define DASD_PATH_NPP 4 4228c2ecf20Sopenharmony_ci#define DASD_PATH_MISCABLED 5 4238c2ecf20Sopenharmony_ci#define DASD_PATH_NOHPF 6 4248c2ecf20Sopenharmony_ci#define DASD_PATH_CUIR 7 4258c2ecf20Sopenharmony_ci#define DASD_PATH_IFCC 8 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci#define DASD_THRHLD_MAX 4294967295U 4288c2ecf20Sopenharmony_ci#define DASD_INTERVAL_MAX 4294967295U 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_cistruct dasd_path { 4318c2ecf20Sopenharmony_ci unsigned long flags; 4328c2ecf20Sopenharmony_ci u8 cssid; 4338c2ecf20Sopenharmony_ci u8 ssid; 4348c2ecf20Sopenharmony_ci u8 chpid; 4358c2ecf20Sopenharmony_ci struct dasd_conf_data *conf_data; 4368c2ecf20Sopenharmony_ci atomic_t error_count; 4378c2ecf20Sopenharmony_ci unsigned long errorclk; 4388c2ecf20Sopenharmony_ci}; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistruct dasd_profile_info { 4428c2ecf20Sopenharmony_ci /* legacy part of profile data, as in dasd_profile_info_t */ 4438c2ecf20Sopenharmony_ci unsigned int dasd_io_reqs; /* number of requests processed */ 4448c2ecf20Sopenharmony_ci unsigned int dasd_io_sects; /* number of sectors processed */ 4458c2ecf20Sopenharmony_ci unsigned int dasd_io_secs[32]; /* histogram of request's sizes */ 4468c2ecf20Sopenharmony_ci unsigned int dasd_io_times[32]; /* histogram of requests's times */ 4478c2ecf20Sopenharmony_ci unsigned int dasd_io_timps[32]; /* h. of requests's times per sector */ 4488c2ecf20Sopenharmony_ci unsigned int dasd_io_time1[32]; /* hist. of time from build to start */ 4498c2ecf20Sopenharmony_ci unsigned int dasd_io_time2[32]; /* hist. of time from start to irq */ 4508c2ecf20Sopenharmony_ci unsigned int dasd_io_time2ps[32]; /* hist. of time from start to irq */ 4518c2ecf20Sopenharmony_ci unsigned int dasd_io_time3[32]; /* hist. of time from irq to end */ 4528c2ecf20Sopenharmony_ci unsigned int dasd_io_nr_req[32]; /* hist. of # of requests in chanq */ 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci /* new data */ 4558c2ecf20Sopenharmony_ci struct timespec64 starttod; /* time of start or last reset */ 4568c2ecf20Sopenharmony_ci unsigned int dasd_io_alias; /* requests using an alias */ 4578c2ecf20Sopenharmony_ci unsigned int dasd_io_tpm; /* requests using transport mode */ 4588c2ecf20Sopenharmony_ci unsigned int dasd_read_reqs; /* total number of read requests */ 4598c2ecf20Sopenharmony_ci unsigned int dasd_read_sects; /* total number read sectors */ 4608c2ecf20Sopenharmony_ci unsigned int dasd_read_alias; /* read request using an alias */ 4618c2ecf20Sopenharmony_ci unsigned int dasd_read_tpm; /* read requests in transport mode */ 4628c2ecf20Sopenharmony_ci unsigned int dasd_read_secs[32]; /* histogram of request's sizes */ 4638c2ecf20Sopenharmony_ci unsigned int dasd_read_times[32]; /* histogram of requests's times */ 4648c2ecf20Sopenharmony_ci unsigned int dasd_read_time1[32]; /* hist. time from build to start */ 4658c2ecf20Sopenharmony_ci unsigned int dasd_read_time2[32]; /* hist. of time from start to irq */ 4668c2ecf20Sopenharmony_ci unsigned int dasd_read_time3[32]; /* hist. of time from irq to end */ 4678c2ecf20Sopenharmony_ci unsigned int dasd_read_nr_req[32]; /* hist. of # of requests in chanq */ 4688c2ecf20Sopenharmony_ci unsigned long dasd_sum_times; /* sum of request times */ 4698c2ecf20Sopenharmony_ci unsigned long dasd_sum_time_str; /* sum of time from build to start */ 4708c2ecf20Sopenharmony_ci unsigned long dasd_sum_time_irq; /* sum of time from start to irq */ 4718c2ecf20Sopenharmony_ci unsigned long dasd_sum_time_end; /* sum of time from irq to end */ 4728c2ecf20Sopenharmony_ci}; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistruct dasd_profile { 4758c2ecf20Sopenharmony_ci struct dentry *dentry; 4768c2ecf20Sopenharmony_ci struct dasd_profile_info *data; 4778c2ecf20Sopenharmony_ci spinlock_t lock; 4788c2ecf20Sopenharmony_ci}; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_cistruct dasd_format_entry { 4818c2ecf20Sopenharmony_ci struct list_head list; 4828c2ecf20Sopenharmony_ci sector_t track; 4838c2ecf20Sopenharmony_ci}; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistruct dasd_device { 4868c2ecf20Sopenharmony_ci /* Block device stuff. */ 4878c2ecf20Sopenharmony_ci struct dasd_block *block; 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci unsigned int devindex; 4908c2ecf20Sopenharmony_ci unsigned long flags; /* per device flags */ 4918c2ecf20Sopenharmony_ci unsigned short features; /* copy of devmap-features (read-only!) */ 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci /* extended error reporting stuff (eer) */ 4948c2ecf20Sopenharmony_ci struct dasd_ccw_req *eer_cqr; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci /* Device discipline stuff. */ 4978c2ecf20Sopenharmony_ci struct dasd_discipline *discipline; 4988c2ecf20Sopenharmony_ci struct dasd_discipline *base_discipline; 4998c2ecf20Sopenharmony_ci void *private; 5008c2ecf20Sopenharmony_ci struct dasd_path path[8]; 5018c2ecf20Sopenharmony_ci __u8 opm; 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci /* Device state and target state. */ 5048c2ecf20Sopenharmony_ci int state, target; 5058c2ecf20Sopenharmony_ci struct mutex state_mutex; 5068c2ecf20Sopenharmony_ci int stopped; /* device (ccw_device_start) was stopped */ 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci /* reference count. */ 5098c2ecf20Sopenharmony_ci atomic_t ref_count; 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci /* ccw queue and memory for static ccw/erp buffers. */ 5128c2ecf20Sopenharmony_ci struct list_head ccw_queue; 5138c2ecf20Sopenharmony_ci spinlock_t mem_lock; 5148c2ecf20Sopenharmony_ci void *ccw_mem; 5158c2ecf20Sopenharmony_ci void *erp_mem; 5168c2ecf20Sopenharmony_ci void *ese_mem; 5178c2ecf20Sopenharmony_ci struct list_head ccw_chunks; 5188c2ecf20Sopenharmony_ci struct list_head erp_chunks; 5198c2ecf20Sopenharmony_ci struct list_head ese_chunks; 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci atomic_t tasklet_scheduled; 5228c2ecf20Sopenharmony_ci struct tasklet_struct tasklet; 5238c2ecf20Sopenharmony_ci struct work_struct kick_work; 5248c2ecf20Sopenharmony_ci struct work_struct restore_device; 5258c2ecf20Sopenharmony_ci struct work_struct reload_device; 5268c2ecf20Sopenharmony_ci struct work_struct kick_validate; 5278c2ecf20Sopenharmony_ci struct work_struct suc_work; 5288c2ecf20Sopenharmony_ci struct work_struct requeue_requests; 5298c2ecf20Sopenharmony_ci struct timer_list timer; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci debug_info_t *debug_area; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci struct ccw_device *cdev; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci /* hook for alias management */ 5368c2ecf20Sopenharmony_ci struct list_head alias_list; 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci /* default expiration time in s */ 5398c2ecf20Sopenharmony_ci unsigned long default_expires; 5408c2ecf20Sopenharmony_ci unsigned long default_retries; 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci unsigned long blk_timeout; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci unsigned long path_thrhld; 5458c2ecf20Sopenharmony_ci unsigned long path_interval; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci struct dentry *debugfs_dentry; 5488c2ecf20Sopenharmony_ci struct dentry *hosts_dentry; 5498c2ecf20Sopenharmony_ci struct dasd_profile profile; 5508c2ecf20Sopenharmony_ci struct dasd_format_entry format_entry; 5518c2ecf20Sopenharmony_ci}; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistruct dasd_block { 5548c2ecf20Sopenharmony_ci /* Block device stuff. */ 5558c2ecf20Sopenharmony_ci struct gendisk *gdp; 5568c2ecf20Sopenharmony_ci struct request_queue *request_queue; 5578c2ecf20Sopenharmony_ci spinlock_t request_queue_lock; 5588c2ecf20Sopenharmony_ci struct blk_mq_tag_set tag_set; 5598c2ecf20Sopenharmony_ci struct block_device *bdev; 5608c2ecf20Sopenharmony_ci atomic_t open_count; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci unsigned long blocks; /* size of volume in blocks */ 5638c2ecf20Sopenharmony_ci unsigned int bp_block; /* bytes per block */ 5648c2ecf20Sopenharmony_ci unsigned int s2b_shift; /* log2 (bp_block/512) */ 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci struct dasd_device *base; 5678c2ecf20Sopenharmony_ci struct list_head ccw_queue; 5688c2ecf20Sopenharmony_ci spinlock_t queue_lock; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci atomic_t tasklet_scheduled; 5718c2ecf20Sopenharmony_ci struct tasklet_struct tasklet; 5728c2ecf20Sopenharmony_ci struct timer_list timer; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci struct dentry *debugfs_dentry; 5758c2ecf20Sopenharmony_ci struct dasd_profile profile; 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci struct list_head format_list; 5788c2ecf20Sopenharmony_ci spinlock_t format_lock; 5798c2ecf20Sopenharmony_ci atomic_t trkcount; 5808c2ecf20Sopenharmony_ci}; 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_cistruct dasd_attention_data { 5838c2ecf20Sopenharmony_ci struct dasd_device *device; 5848c2ecf20Sopenharmony_ci __u8 lpum; 5858c2ecf20Sopenharmony_ci}; 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_cistruct dasd_queue { 5888c2ecf20Sopenharmony_ci spinlock_t lock; 5898c2ecf20Sopenharmony_ci}; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci/* reasons why device (ccw_device_start) was stopped */ 5928c2ecf20Sopenharmony_ci#define DASD_STOPPED_NOT_ACC 1 /* not accessible */ 5938c2ecf20Sopenharmony_ci#define DASD_STOPPED_QUIESCE 2 /* Quiesced */ 5948c2ecf20Sopenharmony_ci#define DASD_STOPPED_PENDING 4 /* long busy */ 5958c2ecf20Sopenharmony_ci#define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */ 5968c2ecf20Sopenharmony_ci#define DASD_STOPPED_SU 16 /* summary unit check handling */ 5978c2ecf20Sopenharmony_ci#define DASD_STOPPED_PM 32 /* pm state transition */ 5988c2ecf20Sopenharmony_ci#define DASD_UNRESUMED_PM 64 /* pm resume failed state */ 5998c2ecf20Sopenharmony_ci#define DASD_STOPPED_NOSPC 128 /* no space left */ 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci/* per device flags */ 6028c2ecf20Sopenharmony_ci#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 6038c2ecf20Sopenharmony_ci#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ 6048c2ecf20Sopenharmony_ci#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ 6058c2ecf20Sopenharmony_ci#define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't 6068c2ecf20Sopenharmony_ci * confuse this with the user specified 6078c2ecf20Sopenharmony_ci * read-only feature. 6088c2ecf20Sopenharmony_ci */ 6098c2ecf20Sopenharmony_ci#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */ 6108c2ecf20Sopenharmony_ci#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */ 6118c2ecf20Sopenharmony_ci#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */ 6128c2ecf20Sopenharmony_ci#define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/ 6138c2ecf20Sopenharmony_ci#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */ 6148c2ecf20Sopenharmony_ci#define DASD_FLAG_ABORTALL 12 /* Abort all noretry requests */ 6158c2ecf20Sopenharmony_ci#define DASD_FLAG_PATH_VERIFY 13 /* Path verification worker running */ 6168c2ecf20Sopenharmony_ci#define DASD_FLAG_SUC 14 /* unhandled summary unit check */ 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci#define DASD_SLEEPON_START_TAG ((void *) 1) 6198c2ecf20Sopenharmony_ci#define DASD_SLEEPON_END_TAG ((void *) 2) 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_civoid dasd_put_device_wake(struct dasd_device *); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci/* 6248c2ecf20Sopenharmony_ci * Reference count inliners 6258c2ecf20Sopenharmony_ci */ 6268c2ecf20Sopenharmony_cistatic inline void 6278c2ecf20Sopenharmony_cidasd_get_device(struct dasd_device *device) 6288c2ecf20Sopenharmony_ci{ 6298c2ecf20Sopenharmony_ci atomic_inc(&device->ref_count); 6308c2ecf20Sopenharmony_ci} 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_cistatic inline void 6338c2ecf20Sopenharmony_cidasd_put_device(struct dasd_device *device) 6348c2ecf20Sopenharmony_ci{ 6358c2ecf20Sopenharmony_ci if (atomic_dec_return(&device->ref_count) == 0) 6368c2ecf20Sopenharmony_ci dasd_put_device_wake(device); 6378c2ecf20Sopenharmony_ci} 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci/* 6408c2ecf20Sopenharmony_ci * The static memory in ccw_mem and erp_mem is managed by a sorted 6418c2ecf20Sopenharmony_ci * list of free memory chunks. 6428c2ecf20Sopenharmony_ci */ 6438c2ecf20Sopenharmony_cistruct dasd_mchunk 6448c2ecf20Sopenharmony_ci{ 6458c2ecf20Sopenharmony_ci struct list_head list; 6468c2ecf20Sopenharmony_ci unsigned long size; 6478c2ecf20Sopenharmony_ci} __attribute__ ((aligned(8))); 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_cistatic inline void 6508c2ecf20Sopenharmony_cidasd_init_chunklist(struct list_head *chunk_list, void *mem, 6518c2ecf20Sopenharmony_ci unsigned long size) 6528c2ecf20Sopenharmony_ci{ 6538c2ecf20Sopenharmony_ci struct dasd_mchunk *chunk; 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_ci INIT_LIST_HEAD(chunk_list); 6568c2ecf20Sopenharmony_ci chunk = (struct dasd_mchunk *) mem; 6578c2ecf20Sopenharmony_ci chunk->size = size - sizeof(struct dasd_mchunk); 6588c2ecf20Sopenharmony_ci list_add(&chunk->list, chunk_list); 6598c2ecf20Sopenharmony_ci} 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_cistatic inline void * 6628c2ecf20Sopenharmony_cidasd_alloc_chunk(struct list_head *chunk_list, unsigned long size) 6638c2ecf20Sopenharmony_ci{ 6648c2ecf20Sopenharmony_ci struct dasd_mchunk *chunk, *tmp; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci size = (size + 7L) & -8L; 6678c2ecf20Sopenharmony_ci list_for_each_entry(chunk, chunk_list, list) { 6688c2ecf20Sopenharmony_ci if (chunk->size < size) 6698c2ecf20Sopenharmony_ci continue; 6708c2ecf20Sopenharmony_ci if (chunk->size > size + sizeof(struct dasd_mchunk)) { 6718c2ecf20Sopenharmony_ci char *endaddr = (char *) (chunk + 1) + chunk->size; 6728c2ecf20Sopenharmony_ci tmp = (struct dasd_mchunk *) (endaddr - size) - 1; 6738c2ecf20Sopenharmony_ci tmp->size = size; 6748c2ecf20Sopenharmony_ci chunk->size -= size + sizeof(struct dasd_mchunk); 6758c2ecf20Sopenharmony_ci chunk = tmp; 6768c2ecf20Sopenharmony_ci } else 6778c2ecf20Sopenharmony_ci list_del(&chunk->list); 6788c2ecf20Sopenharmony_ci return (void *) (chunk + 1); 6798c2ecf20Sopenharmony_ci } 6808c2ecf20Sopenharmony_ci return NULL; 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_cistatic inline void 6848c2ecf20Sopenharmony_cidasd_free_chunk(struct list_head *chunk_list, void *mem) 6858c2ecf20Sopenharmony_ci{ 6868c2ecf20Sopenharmony_ci struct dasd_mchunk *chunk, *tmp; 6878c2ecf20Sopenharmony_ci struct list_head *p, *left; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci chunk = (struct dasd_mchunk *) 6908c2ecf20Sopenharmony_ci ((char *) mem - sizeof(struct dasd_mchunk)); 6918c2ecf20Sopenharmony_ci /* Find out the left neighbour in chunk_list. */ 6928c2ecf20Sopenharmony_ci left = chunk_list; 6938c2ecf20Sopenharmony_ci list_for_each(p, chunk_list) { 6948c2ecf20Sopenharmony_ci if (list_entry(p, struct dasd_mchunk, list) > chunk) 6958c2ecf20Sopenharmony_ci break; 6968c2ecf20Sopenharmony_ci left = p; 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci /* Try to merge with right neighbour = next element from left. */ 6998c2ecf20Sopenharmony_ci if (left->next != chunk_list) { 7008c2ecf20Sopenharmony_ci tmp = list_entry(left->next, struct dasd_mchunk, list); 7018c2ecf20Sopenharmony_ci if ((char *) (chunk + 1) + chunk->size == (char *) tmp) { 7028c2ecf20Sopenharmony_ci list_del(&tmp->list); 7038c2ecf20Sopenharmony_ci chunk->size += tmp->size + sizeof(struct dasd_mchunk); 7048c2ecf20Sopenharmony_ci } 7058c2ecf20Sopenharmony_ci } 7068c2ecf20Sopenharmony_ci /* Try to merge with left neighbour. */ 7078c2ecf20Sopenharmony_ci if (left != chunk_list) { 7088c2ecf20Sopenharmony_ci tmp = list_entry(left, struct dasd_mchunk, list); 7098c2ecf20Sopenharmony_ci if ((char *) (tmp + 1) + tmp->size == (char *) chunk) { 7108c2ecf20Sopenharmony_ci tmp->size += chunk->size + sizeof(struct dasd_mchunk); 7118c2ecf20Sopenharmony_ci return; 7128c2ecf20Sopenharmony_ci } 7138c2ecf20Sopenharmony_ci } 7148c2ecf20Sopenharmony_ci __list_add(&chunk->list, left, left->next); 7158c2ecf20Sopenharmony_ci} 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci/* 7188c2ecf20Sopenharmony_ci * Check if bsize is in { 512, 1024, 2048, 4096 } 7198c2ecf20Sopenharmony_ci */ 7208c2ecf20Sopenharmony_cistatic inline int 7218c2ecf20Sopenharmony_cidasd_check_blocksize(int bsize) 7228c2ecf20Sopenharmony_ci{ 7238c2ecf20Sopenharmony_ci if (bsize < 512 || bsize > 4096 || !is_power_of_2(bsize)) 7248c2ecf20Sopenharmony_ci return -EMEDIUMTYPE; 7258c2ecf20Sopenharmony_ci return 0; 7268c2ecf20Sopenharmony_ci} 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci/* 7298c2ecf20Sopenharmony_ci * return the callback data of the original request in case there are 7308c2ecf20Sopenharmony_ci * ERP requests build on top of it 7318c2ecf20Sopenharmony_ci */ 7328c2ecf20Sopenharmony_cistatic inline void *dasd_get_callback_data(struct dasd_ccw_req *cqr) 7338c2ecf20Sopenharmony_ci{ 7348c2ecf20Sopenharmony_ci while (cqr->refers) 7358c2ecf20Sopenharmony_ci cqr = cqr->refers; 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci return cqr->callback_data; 7388c2ecf20Sopenharmony_ci} 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci/* externals in dasd.c */ 7418c2ecf20Sopenharmony_ci#define DASD_PROFILE_OFF 0 7428c2ecf20Sopenharmony_ci#define DASD_PROFILE_ON 1 7438c2ecf20Sopenharmony_ci#define DASD_PROFILE_GLOBAL_ONLY 2 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ciextern debug_info_t *dasd_debug_area; 7468c2ecf20Sopenharmony_ciextern struct dasd_profile dasd_global_profile; 7478c2ecf20Sopenharmony_ciextern unsigned int dasd_global_profile_level; 7488c2ecf20Sopenharmony_ciextern const struct block_device_operations dasd_device_operations; 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ciextern struct kmem_cache *dasd_page_cache; 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistruct dasd_ccw_req * 7538c2ecf20Sopenharmony_cidasd_smalloc_request(int, int, int, struct dasd_device *, struct dasd_ccw_req *); 7548c2ecf20Sopenharmony_cistruct dasd_ccw_req *dasd_fmalloc_request(int, int, int, struct dasd_device *); 7558c2ecf20Sopenharmony_civoid dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *); 7568c2ecf20Sopenharmony_civoid dasd_ffree_request(struct dasd_ccw_req *, struct dasd_device *); 7578c2ecf20Sopenharmony_civoid dasd_wakeup_cb(struct dasd_ccw_req *, void *); 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_cistruct dasd_device *dasd_alloc_device(void); 7608c2ecf20Sopenharmony_civoid dasd_free_device(struct dasd_device *); 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_cistruct dasd_block *dasd_alloc_block(void); 7638c2ecf20Sopenharmony_civoid dasd_free_block(struct dasd_block *); 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_cienum blk_eh_timer_return dasd_times_out(struct request *req, bool reserved); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_civoid dasd_enable_device(struct dasd_device *); 7688c2ecf20Sopenharmony_civoid dasd_set_target_state(struct dasd_device *, int); 7698c2ecf20Sopenharmony_civoid dasd_kick_device(struct dasd_device *); 7708c2ecf20Sopenharmony_civoid dasd_restore_device(struct dasd_device *); 7718c2ecf20Sopenharmony_civoid dasd_reload_device(struct dasd_device *); 7728c2ecf20Sopenharmony_civoid dasd_schedule_requeue(struct dasd_device *); 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_civoid dasd_add_request_head(struct dasd_ccw_req *); 7758c2ecf20Sopenharmony_civoid dasd_add_request_tail(struct dasd_ccw_req *); 7768c2ecf20Sopenharmony_ciint dasd_start_IO(struct dasd_ccw_req *); 7778c2ecf20Sopenharmony_ciint dasd_term_IO(struct dasd_ccw_req *); 7788c2ecf20Sopenharmony_civoid dasd_schedule_device_bh(struct dasd_device *); 7798c2ecf20Sopenharmony_civoid dasd_schedule_block_bh(struct dasd_block *); 7808c2ecf20Sopenharmony_ciint dasd_sleep_on(struct dasd_ccw_req *); 7818c2ecf20Sopenharmony_ciint dasd_sleep_on_queue(struct list_head *); 7828c2ecf20Sopenharmony_ciint dasd_sleep_on_immediatly(struct dasd_ccw_req *); 7838c2ecf20Sopenharmony_ciint dasd_sleep_on_queue_interruptible(struct list_head *); 7848c2ecf20Sopenharmony_ciint dasd_sleep_on_interruptible(struct dasd_ccw_req *); 7858c2ecf20Sopenharmony_civoid dasd_device_set_timer(struct dasd_device *, int); 7868c2ecf20Sopenharmony_civoid dasd_device_clear_timer(struct dasd_device *); 7878c2ecf20Sopenharmony_civoid dasd_block_set_timer(struct dasd_block *, int); 7888c2ecf20Sopenharmony_civoid dasd_block_clear_timer(struct dasd_block *); 7898c2ecf20Sopenharmony_ciint dasd_cancel_req(struct dasd_ccw_req *); 7908c2ecf20Sopenharmony_ciint dasd_flush_device_queue(struct dasd_device *); 7918c2ecf20Sopenharmony_ciint dasd_generic_probe (struct ccw_device *, struct dasd_discipline *); 7928c2ecf20Sopenharmony_civoid dasd_generic_free_discipline(struct dasd_device *); 7938c2ecf20Sopenharmony_civoid dasd_generic_remove (struct ccw_device *cdev); 7948c2ecf20Sopenharmony_ciint dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); 7958c2ecf20Sopenharmony_ciint dasd_generic_set_offline (struct ccw_device *cdev); 7968c2ecf20Sopenharmony_ciint dasd_generic_notify(struct ccw_device *, int); 7978c2ecf20Sopenharmony_ciint dasd_generic_last_path_gone(struct dasd_device *); 7988c2ecf20Sopenharmony_ciint dasd_generic_path_operational(struct dasd_device *); 7998c2ecf20Sopenharmony_civoid dasd_generic_shutdown(struct ccw_device *); 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_civoid dasd_generic_handle_state_change(struct dasd_device *); 8028c2ecf20Sopenharmony_ciint dasd_generic_pm_freeze(struct ccw_device *); 8038c2ecf20Sopenharmony_ciint dasd_generic_restore_device(struct ccw_device *); 8048c2ecf20Sopenharmony_cienum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); 8058c2ecf20Sopenharmony_civoid dasd_generic_path_event(struct ccw_device *, int *); 8068c2ecf20Sopenharmony_ciint dasd_generic_verify_path(struct dasd_device *, __u8); 8078c2ecf20Sopenharmony_civoid dasd_generic_space_exhaust(struct dasd_device *, struct dasd_ccw_req *); 8088c2ecf20Sopenharmony_civoid dasd_generic_space_avail(struct dasd_device *); 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ciint dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 8118c2ecf20Sopenharmony_cichar *dasd_get_sense(struct irb *); 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_civoid dasd_device_set_stop_bits(struct dasd_device *, int); 8148c2ecf20Sopenharmony_civoid dasd_device_remove_stop_bits(struct dasd_device *, int); 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ciint dasd_device_is_ro(struct dasd_device *); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_civoid dasd_profile_reset(struct dasd_profile *); 8198c2ecf20Sopenharmony_ciint dasd_profile_on(struct dasd_profile *); 8208c2ecf20Sopenharmony_civoid dasd_profile_off(struct dasd_profile *); 8218c2ecf20Sopenharmony_cichar *dasd_get_user_string(const char __user *, size_t); 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci/* externals in dasd_devmap.c */ 8248c2ecf20Sopenharmony_ciextern int dasd_max_devindex; 8258c2ecf20Sopenharmony_ciextern int dasd_probeonly; 8268c2ecf20Sopenharmony_ciextern int dasd_autodetect; 8278c2ecf20Sopenharmony_ciextern int dasd_nopav; 8288c2ecf20Sopenharmony_ciextern int dasd_nofcx; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ciint dasd_devmap_init(void); 8318c2ecf20Sopenharmony_civoid dasd_devmap_exit(void); 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_cistruct dasd_device *dasd_create_device(struct ccw_device *); 8348c2ecf20Sopenharmony_civoid dasd_delete_device(struct dasd_device *); 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ciint dasd_get_feature(struct ccw_device *, int); 8378c2ecf20Sopenharmony_ciint dasd_set_feature(struct ccw_device *, int, int); 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ciint dasd_add_sysfs_files(struct ccw_device *); 8408c2ecf20Sopenharmony_civoid dasd_remove_sysfs_files(struct ccw_device *); 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_cistruct dasd_device *dasd_device_from_cdev(struct ccw_device *); 8438c2ecf20Sopenharmony_cistruct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); 8448c2ecf20Sopenharmony_cistruct dasd_device *dasd_device_from_devindex(int); 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_civoid dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *); 8478c2ecf20Sopenharmony_cistruct dasd_device *dasd_device_from_gendisk(struct gendisk *); 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ciint dasd_parse(void) __init; 8508c2ecf20Sopenharmony_ciint dasd_busid_known(const char *); 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci/* externals in dasd_gendisk.c */ 8538c2ecf20Sopenharmony_ciint dasd_gendisk_init(void); 8548c2ecf20Sopenharmony_civoid dasd_gendisk_exit(void); 8558c2ecf20Sopenharmony_ciint dasd_gendisk_alloc(struct dasd_block *); 8568c2ecf20Sopenharmony_civoid dasd_gendisk_free(struct dasd_block *); 8578c2ecf20Sopenharmony_ciint dasd_scan_partitions(struct dasd_block *); 8588c2ecf20Sopenharmony_civoid dasd_destroy_partitions(struct dasd_block *); 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci/* externals in dasd_ioctl.c */ 8618c2ecf20Sopenharmony_ciint dasd_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long); 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci/* externals in dasd_proc.c */ 8648c2ecf20Sopenharmony_ciint dasd_proc_init(void); 8658c2ecf20Sopenharmony_civoid dasd_proc_exit(void); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci/* externals in dasd_erp.c */ 8688c2ecf20Sopenharmony_cistruct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *); 8698c2ecf20Sopenharmony_cistruct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *); 8708c2ecf20Sopenharmony_cistruct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int, 8718c2ecf20Sopenharmony_ci struct dasd_device *); 8728c2ecf20Sopenharmony_civoid dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *); 8738c2ecf20Sopenharmony_civoid dasd_log_sense(struct dasd_ccw_req *, struct irb *); 8748c2ecf20Sopenharmony_civoid dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb); 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_ci/* externals in dasd_3990_erp.c */ 8778c2ecf20Sopenharmony_cistruct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *); 8788c2ecf20Sopenharmony_civoid dasd_3990_erp_handle_sim(struct dasd_device *, char *); 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci/* externals in dasd_eer.c */ 8818c2ecf20Sopenharmony_ci#ifdef CONFIG_DASD_EER 8828c2ecf20Sopenharmony_ciint dasd_eer_init(void); 8838c2ecf20Sopenharmony_civoid dasd_eer_exit(void); 8848c2ecf20Sopenharmony_ciint dasd_eer_enable(struct dasd_device *); 8858c2ecf20Sopenharmony_civoid dasd_eer_disable(struct dasd_device *); 8868c2ecf20Sopenharmony_civoid dasd_eer_write(struct dasd_device *, struct dasd_ccw_req *cqr, 8878c2ecf20Sopenharmony_ci unsigned int id); 8888c2ecf20Sopenharmony_civoid dasd_eer_snss(struct dasd_device *); 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_cistatic inline int dasd_eer_enabled(struct dasd_device *device) 8918c2ecf20Sopenharmony_ci{ 8928c2ecf20Sopenharmony_ci return device->eer_cqr != NULL; 8938c2ecf20Sopenharmony_ci} 8948c2ecf20Sopenharmony_ci#else 8958c2ecf20Sopenharmony_ci#define dasd_eer_init() (0) 8968c2ecf20Sopenharmony_ci#define dasd_eer_exit() do { } while (0) 8978c2ecf20Sopenharmony_ci#define dasd_eer_enable(d) (0) 8988c2ecf20Sopenharmony_ci#define dasd_eer_disable(d) do { } while (0) 8998c2ecf20Sopenharmony_ci#define dasd_eer_write(d,c,i) do { } while (0) 9008c2ecf20Sopenharmony_ci#define dasd_eer_snss(d) do { } while (0) 9018c2ecf20Sopenharmony_ci#define dasd_eer_enabled(d) (0) 9028c2ecf20Sopenharmony_ci#endif /* CONFIG_DASD_ERR */ 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci/* DASD path handling functions */ 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci/* 9088c2ecf20Sopenharmony_ci * helper functions to modify bit masks for a given channel path for a device 9098c2ecf20Sopenharmony_ci */ 9108c2ecf20Sopenharmony_cistatic inline int dasd_path_is_operational(struct dasd_device *device, int chp) 9118c2ecf20Sopenharmony_ci{ 9128c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_OPERATIONAL, &device->path[chp].flags); 9138c2ecf20Sopenharmony_ci} 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_cistatic inline int dasd_path_need_verify(struct dasd_device *device, int chp) 9168c2ecf20Sopenharmony_ci{ 9178c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_TBV, &device->path[chp].flags); 9188c2ecf20Sopenharmony_ci} 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_cistatic inline void dasd_path_verify(struct dasd_device *device, int chp) 9218c2ecf20Sopenharmony_ci{ 9228c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_TBV, &device->path[chp].flags); 9238c2ecf20Sopenharmony_ci} 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_verify(struct dasd_device *device, int chp) 9268c2ecf20Sopenharmony_ci{ 9278c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_TBV, &device->path[chp].flags); 9288c2ecf20Sopenharmony_ci} 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_all_verify(struct dasd_device *device) 9318c2ecf20Sopenharmony_ci{ 9328c2ecf20Sopenharmony_ci int chp; 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 9358c2ecf20Sopenharmony_ci dasd_path_clear_verify(device, chp); 9368c2ecf20Sopenharmony_ci} 9378c2ecf20Sopenharmony_ci 9388c2ecf20Sopenharmony_cistatic inline void dasd_path_operational(struct dasd_device *device, int chp) 9398c2ecf20Sopenharmony_ci{ 9408c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_OPERATIONAL, &device->path[chp].flags); 9418c2ecf20Sopenharmony_ci device->opm |= (0x80 >> chp); 9428c2ecf20Sopenharmony_ci} 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_cistatic inline void dasd_path_nonpreferred(struct dasd_device *device, int chp) 9458c2ecf20Sopenharmony_ci{ 9468c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_NPP, &device->path[chp].flags); 9478c2ecf20Sopenharmony_ci} 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_cistatic inline int dasd_path_is_nonpreferred(struct dasd_device *device, int chp) 9508c2ecf20Sopenharmony_ci{ 9518c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_NPP, &device->path[chp].flags); 9528c2ecf20Sopenharmony_ci} 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_nonpreferred(struct dasd_device *device, 9558c2ecf20Sopenharmony_ci int chp) 9568c2ecf20Sopenharmony_ci{ 9578c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_NPP, &device->path[chp].flags); 9588c2ecf20Sopenharmony_ci} 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_cistatic inline void dasd_path_preferred(struct dasd_device *device, int chp) 9618c2ecf20Sopenharmony_ci{ 9628c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_PP, &device->path[chp].flags); 9638c2ecf20Sopenharmony_ci} 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_cistatic inline int dasd_path_is_preferred(struct dasd_device *device, int chp) 9668c2ecf20Sopenharmony_ci{ 9678c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_PP, &device->path[chp].flags); 9688c2ecf20Sopenharmony_ci} 9698c2ecf20Sopenharmony_ci 9708c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_preferred(struct dasd_device *device, 9718c2ecf20Sopenharmony_ci int chp) 9728c2ecf20Sopenharmony_ci{ 9738c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_PP, &device->path[chp].flags); 9748c2ecf20Sopenharmony_ci} 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_oper(struct dasd_device *device, int chp) 9778c2ecf20Sopenharmony_ci{ 9788c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_OPERATIONAL, &device->path[chp].flags); 9798c2ecf20Sopenharmony_ci device->opm &= ~(0x80 >> chp); 9808c2ecf20Sopenharmony_ci} 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_cable(struct dasd_device *device, int chp) 9838c2ecf20Sopenharmony_ci{ 9848c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_MISCABLED, &device->path[chp].flags); 9858c2ecf20Sopenharmony_ci} 9868c2ecf20Sopenharmony_ci 9878c2ecf20Sopenharmony_cistatic inline void dasd_path_cuir(struct dasd_device *device, int chp) 9888c2ecf20Sopenharmony_ci{ 9898c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_CUIR, &device->path[chp].flags); 9908c2ecf20Sopenharmony_ci} 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_cistatic inline int dasd_path_is_cuir(struct dasd_device *device, int chp) 9938c2ecf20Sopenharmony_ci{ 9948c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_CUIR, &device->path[chp].flags); 9958c2ecf20Sopenharmony_ci} 9968c2ecf20Sopenharmony_ci 9978c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_cuir(struct dasd_device *device, int chp) 9988c2ecf20Sopenharmony_ci{ 9998c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_CUIR, &device->path[chp].flags); 10008c2ecf20Sopenharmony_ci} 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_cistatic inline void dasd_path_ifcc(struct dasd_device *device, int chp) 10038c2ecf20Sopenharmony_ci{ 10048c2ecf20Sopenharmony_ci set_bit(DASD_PATH_IFCC, &device->path[chp].flags); 10058c2ecf20Sopenharmony_ci} 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_cistatic inline int dasd_path_is_ifcc(struct dasd_device *device, int chp) 10088c2ecf20Sopenharmony_ci{ 10098c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_IFCC, &device->path[chp].flags); 10108c2ecf20Sopenharmony_ci} 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_ifcc(struct dasd_device *device, int chp) 10138c2ecf20Sopenharmony_ci{ 10148c2ecf20Sopenharmony_ci clear_bit(DASD_PATH_IFCC, &device->path[chp].flags); 10158c2ecf20Sopenharmony_ci} 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_cistatic inline void dasd_path_clear_nohpf(struct dasd_device *device, int chp) 10188c2ecf20Sopenharmony_ci{ 10198c2ecf20Sopenharmony_ci __clear_bit(DASD_PATH_NOHPF, &device->path[chp].flags); 10208c2ecf20Sopenharmony_ci} 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_cistatic inline void dasd_path_miscabled(struct dasd_device *device, int chp) 10238c2ecf20Sopenharmony_ci{ 10248c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_MISCABLED, &device->path[chp].flags); 10258c2ecf20Sopenharmony_ci} 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_cistatic inline int dasd_path_is_miscabled(struct dasd_device *device, int chp) 10288c2ecf20Sopenharmony_ci{ 10298c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_MISCABLED, &device->path[chp].flags); 10308c2ecf20Sopenharmony_ci} 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_cistatic inline void dasd_path_nohpf(struct dasd_device *device, int chp) 10338c2ecf20Sopenharmony_ci{ 10348c2ecf20Sopenharmony_ci __set_bit(DASD_PATH_NOHPF, &device->path[chp].flags); 10358c2ecf20Sopenharmony_ci} 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_cistatic inline int dasd_path_is_nohpf(struct dasd_device *device, int chp) 10388c2ecf20Sopenharmony_ci{ 10398c2ecf20Sopenharmony_ci return test_bit(DASD_PATH_NOHPF, &device->path[chp].flags); 10408c2ecf20Sopenharmony_ci} 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci/* 10438c2ecf20Sopenharmony_ci * get functions for path masks 10448c2ecf20Sopenharmony_ci * will return a path masks for the given device 10458c2ecf20Sopenharmony_ci */ 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_opm(struct dasd_device *device) 10488c2ecf20Sopenharmony_ci{ 10498c2ecf20Sopenharmony_ci return device->opm; 10508c2ecf20Sopenharmony_ci} 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_tbvpm(struct dasd_device *device) 10538c2ecf20Sopenharmony_ci{ 10548c2ecf20Sopenharmony_ci int chp; 10558c2ecf20Sopenharmony_ci __u8 tbvpm = 0x00; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 10588c2ecf20Sopenharmony_ci if (dasd_path_need_verify(device, chp)) 10598c2ecf20Sopenharmony_ci tbvpm |= 0x80 >> chp; 10608c2ecf20Sopenharmony_ci return tbvpm; 10618c2ecf20Sopenharmony_ci} 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_nppm(struct dasd_device *device) 10648c2ecf20Sopenharmony_ci{ 10658c2ecf20Sopenharmony_ci int chp; 10668c2ecf20Sopenharmony_ci __u8 npm = 0x00; 10678c2ecf20Sopenharmony_ci 10688c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) { 10698c2ecf20Sopenharmony_ci if (dasd_path_is_nonpreferred(device, chp)) 10708c2ecf20Sopenharmony_ci npm |= 0x80 >> chp; 10718c2ecf20Sopenharmony_ci } 10728c2ecf20Sopenharmony_ci return npm; 10738c2ecf20Sopenharmony_ci} 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_ppm(struct dasd_device *device) 10768c2ecf20Sopenharmony_ci{ 10778c2ecf20Sopenharmony_ci int chp; 10788c2ecf20Sopenharmony_ci __u8 ppm = 0x00; 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 10818c2ecf20Sopenharmony_ci if (dasd_path_is_preferred(device, chp)) 10828c2ecf20Sopenharmony_ci ppm |= 0x80 >> chp; 10838c2ecf20Sopenharmony_ci return ppm; 10848c2ecf20Sopenharmony_ci} 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_cablepm(struct dasd_device *device) 10878c2ecf20Sopenharmony_ci{ 10888c2ecf20Sopenharmony_ci int chp; 10898c2ecf20Sopenharmony_ci __u8 cablepm = 0x00; 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 10928c2ecf20Sopenharmony_ci if (dasd_path_is_miscabled(device, chp)) 10938c2ecf20Sopenharmony_ci cablepm |= 0x80 >> chp; 10948c2ecf20Sopenharmony_ci return cablepm; 10958c2ecf20Sopenharmony_ci} 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_cuirpm(struct dasd_device *device) 10988c2ecf20Sopenharmony_ci{ 10998c2ecf20Sopenharmony_ci int chp; 11008c2ecf20Sopenharmony_ci __u8 cuirpm = 0x00; 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11038c2ecf20Sopenharmony_ci if (dasd_path_is_cuir(device, chp)) 11048c2ecf20Sopenharmony_ci cuirpm |= 0x80 >> chp; 11058c2ecf20Sopenharmony_ci return cuirpm; 11068c2ecf20Sopenharmony_ci} 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_ifccpm(struct dasd_device *device) 11098c2ecf20Sopenharmony_ci{ 11108c2ecf20Sopenharmony_ci int chp; 11118c2ecf20Sopenharmony_ci __u8 ifccpm = 0x00; 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11148c2ecf20Sopenharmony_ci if (dasd_path_is_ifcc(device, chp)) 11158c2ecf20Sopenharmony_ci ifccpm |= 0x80 >> chp; 11168c2ecf20Sopenharmony_ci return ifccpm; 11178c2ecf20Sopenharmony_ci} 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_hpfpm(struct dasd_device *device) 11208c2ecf20Sopenharmony_ci{ 11218c2ecf20Sopenharmony_ci int chp; 11228c2ecf20Sopenharmony_ci __u8 hpfpm = 0x00; 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11258c2ecf20Sopenharmony_ci if (dasd_path_is_nohpf(device, chp)) 11268c2ecf20Sopenharmony_ci hpfpm |= 0x80 >> chp; 11278c2ecf20Sopenharmony_ci return hpfpm; 11288c2ecf20Sopenharmony_ci} 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci/* 11318c2ecf20Sopenharmony_ci * add functions for path masks 11328c2ecf20Sopenharmony_ci * the existing path mask will be extended by the given path mask 11338c2ecf20Sopenharmony_ci */ 11348c2ecf20Sopenharmony_cistatic inline void dasd_path_add_tbvpm(struct dasd_device *device, __u8 pm) 11358c2ecf20Sopenharmony_ci{ 11368c2ecf20Sopenharmony_ci int chp; 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11398c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 11408c2ecf20Sopenharmony_ci dasd_path_verify(device, chp); 11418c2ecf20Sopenharmony_ci} 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_cistatic inline __u8 dasd_path_get_notoperpm(struct dasd_device *device) 11448c2ecf20Sopenharmony_ci{ 11458c2ecf20Sopenharmony_ci int chp; 11468c2ecf20Sopenharmony_ci __u8 nopm = 0x00; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11498c2ecf20Sopenharmony_ci if (dasd_path_is_nohpf(device, chp) || 11508c2ecf20Sopenharmony_ci dasd_path_is_ifcc(device, chp) || 11518c2ecf20Sopenharmony_ci dasd_path_is_cuir(device, chp) || 11528c2ecf20Sopenharmony_ci dasd_path_is_miscabled(device, chp)) 11538c2ecf20Sopenharmony_ci nopm |= 0x80 >> chp; 11548c2ecf20Sopenharmony_ci return nopm; 11558c2ecf20Sopenharmony_ci} 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_cistatic inline void dasd_path_add_opm(struct dasd_device *device, __u8 pm) 11588c2ecf20Sopenharmony_ci{ 11598c2ecf20Sopenharmony_ci int chp; 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11628c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) { 11638c2ecf20Sopenharmony_ci dasd_path_operational(device, chp); 11648c2ecf20Sopenharmony_ci /* 11658c2ecf20Sopenharmony_ci * if the path is used 11668c2ecf20Sopenharmony_ci * it should not be in one of the negative lists 11678c2ecf20Sopenharmony_ci */ 11688c2ecf20Sopenharmony_ci dasd_path_clear_nohpf(device, chp); 11698c2ecf20Sopenharmony_ci dasd_path_clear_cuir(device, chp); 11708c2ecf20Sopenharmony_ci dasd_path_clear_cable(device, chp); 11718c2ecf20Sopenharmony_ci dasd_path_clear_ifcc(device, chp); 11728c2ecf20Sopenharmony_ci } 11738c2ecf20Sopenharmony_ci} 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_cistatic inline void dasd_path_add_cablepm(struct dasd_device *device, __u8 pm) 11768c2ecf20Sopenharmony_ci{ 11778c2ecf20Sopenharmony_ci int chp; 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11808c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 11818c2ecf20Sopenharmony_ci dasd_path_miscabled(device, chp); 11828c2ecf20Sopenharmony_ci} 11838c2ecf20Sopenharmony_ci 11848c2ecf20Sopenharmony_cistatic inline void dasd_path_add_cuirpm(struct dasd_device *device, __u8 pm) 11858c2ecf20Sopenharmony_ci{ 11868c2ecf20Sopenharmony_ci int chp; 11878c2ecf20Sopenharmony_ci 11888c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11898c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 11908c2ecf20Sopenharmony_ci dasd_path_cuir(device, chp); 11918c2ecf20Sopenharmony_ci} 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_cistatic inline void dasd_path_add_ifccpm(struct dasd_device *device, __u8 pm) 11948c2ecf20Sopenharmony_ci{ 11958c2ecf20Sopenharmony_ci int chp; 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 11988c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 11998c2ecf20Sopenharmony_ci dasd_path_ifcc(device, chp); 12008c2ecf20Sopenharmony_ci} 12018c2ecf20Sopenharmony_ci 12028c2ecf20Sopenharmony_cistatic inline void dasd_path_add_nppm(struct dasd_device *device, __u8 pm) 12038c2ecf20Sopenharmony_ci{ 12048c2ecf20Sopenharmony_ci int chp; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 12078c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 12088c2ecf20Sopenharmony_ci dasd_path_nonpreferred(device, chp); 12098c2ecf20Sopenharmony_ci} 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_cistatic inline void dasd_path_add_nohpfpm(struct dasd_device *device, __u8 pm) 12128c2ecf20Sopenharmony_ci{ 12138c2ecf20Sopenharmony_ci int chp; 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 12168c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 12178c2ecf20Sopenharmony_ci dasd_path_nohpf(device, chp); 12188c2ecf20Sopenharmony_ci} 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_cistatic inline void dasd_path_add_ppm(struct dasd_device *device, __u8 pm) 12218c2ecf20Sopenharmony_ci{ 12228c2ecf20Sopenharmony_ci int chp; 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 12258c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 12268c2ecf20Sopenharmony_ci dasd_path_preferred(device, chp); 12278c2ecf20Sopenharmony_ci} 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci/* 12308c2ecf20Sopenharmony_ci * set functions for path masks 12318c2ecf20Sopenharmony_ci * the existing path mask will be replaced by the given path mask 12328c2ecf20Sopenharmony_ci */ 12338c2ecf20Sopenharmony_cistatic inline void dasd_path_set_tbvpm(struct dasd_device *device, __u8 pm) 12348c2ecf20Sopenharmony_ci{ 12358c2ecf20Sopenharmony_ci int chp; 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 12388c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 12398c2ecf20Sopenharmony_ci dasd_path_verify(device, chp); 12408c2ecf20Sopenharmony_ci else 12418c2ecf20Sopenharmony_ci dasd_path_clear_verify(device, chp); 12428c2ecf20Sopenharmony_ci} 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_cistatic inline void dasd_path_set_opm(struct dasd_device *device, __u8 pm) 12458c2ecf20Sopenharmony_ci{ 12468c2ecf20Sopenharmony_ci int chp; 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) { 12498c2ecf20Sopenharmony_ci dasd_path_clear_oper(device, chp); 12508c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) { 12518c2ecf20Sopenharmony_ci dasd_path_operational(device, chp); 12528c2ecf20Sopenharmony_ci /* 12538c2ecf20Sopenharmony_ci * if the path is used 12548c2ecf20Sopenharmony_ci * it should not be in one of the negative lists 12558c2ecf20Sopenharmony_ci */ 12568c2ecf20Sopenharmony_ci dasd_path_clear_nohpf(device, chp); 12578c2ecf20Sopenharmony_ci dasd_path_clear_cuir(device, chp); 12588c2ecf20Sopenharmony_ci dasd_path_clear_cable(device, chp); 12598c2ecf20Sopenharmony_ci dasd_path_clear_ifcc(device, chp); 12608c2ecf20Sopenharmony_ci } 12618c2ecf20Sopenharmony_ci } 12628c2ecf20Sopenharmony_ci} 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_ci/* 12658c2ecf20Sopenharmony_ci * remove functions for path masks 12668c2ecf20Sopenharmony_ci * the existing path mask will be cleared with the given path mask 12678c2ecf20Sopenharmony_ci */ 12688c2ecf20Sopenharmony_cistatic inline void dasd_path_remove_opm(struct dasd_device *device, __u8 pm) 12698c2ecf20Sopenharmony_ci{ 12708c2ecf20Sopenharmony_ci int chp; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) { 12738c2ecf20Sopenharmony_ci if (pm & (0x80 >> chp)) 12748c2ecf20Sopenharmony_ci dasd_path_clear_oper(device, chp); 12758c2ecf20Sopenharmony_ci } 12768c2ecf20Sopenharmony_ci} 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci/* 12798c2ecf20Sopenharmony_ci * add the newly available path to the to be verified pm and remove it from 12808c2ecf20Sopenharmony_ci * normal operation until it is verified 12818c2ecf20Sopenharmony_ci */ 12828c2ecf20Sopenharmony_cistatic inline void dasd_path_available(struct dasd_device *device, int chp) 12838c2ecf20Sopenharmony_ci{ 12848c2ecf20Sopenharmony_ci dasd_path_clear_oper(device, chp); 12858c2ecf20Sopenharmony_ci dasd_path_verify(device, chp); 12868c2ecf20Sopenharmony_ci} 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_cistatic inline void dasd_path_notoper(struct dasd_device *device, int chp) 12898c2ecf20Sopenharmony_ci{ 12908c2ecf20Sopenharmony_ci dasd_path_clear_oper(device, chp); 12918c2ecf20Sopenharmony_ci dasd_path_clear_preferred(device, chp); 12928c2ecf20Sopenharmony_ci dasd_path_clear_nonpreferred(device, chp); 12938c2ecf20Sopenharmony_ci} 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_ci/* 12968c2ecf20Sopenharmony_ci * remove all paths from normal operation 12978c2ecf20Sopenharmony_ci */ 12988c2ecf20Sopenharmony_cistatic inline void dasd_path_no_path(struct dasd_device *device) 12998c2ecf20Sopenharmony_ci{ 13008c2ecf20Sopenharmony_ci int chp; 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_ci for (chp = 0; chp < 8; chp++) 13038c2ecf20Sopenharmony_ci dasd_path_notoper(device, chp); 13048c2ecf20Sopenharmony_ci 13058c2ecf20Sopenharmony_ci dasd_path_clear_all_verify(device); 13068c2ecf20Sopenharmony_ci} 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_ci/* end - path handling */ 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci#endif /* DASD_H */ 1311